// -----------------------------------------
// SoundScribe (TM) and related software.
//
// Copyright (C) 2007-2011 Vannatech
// http://www.vannatech.com
// All rights reserved.
//
// This source code is subject to the MIT License.
// http://www.opensource.org/licenses/mit-license.php
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// -----------------------------------------
using System;
using System.Linq;
using CoreAudioTests.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vannatech.CoreAudio.Interfaces;
using Vannatech.CoreAudio.Constants;
using System.Collections.Generic;
using Vannatech.CoreAudio.Enumerations;
namespace CoreAudioTests.DeviceTopologyApi
{
// TODO: Create a custom test manager for IConnector tests, and properly dispose of COM interfaces.
///
/// Tests all methods of the IConnector interface.
///
[TestClass]
public class IConnectorTest
{
///
/// Tests that each available connector in the system may be connectors to other connectors.
///
[TestMethod]
public void IConnector_ConnectTo()
{
int result = 0;
IEnumerable inputConnectors, outputConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out inputConnectors, out outputConnectors);
foreach (var cIn in inputConnectors)
{
bool isConnected;
IConnector inOrig = null;
cIn.IsConnected(out isConnected);
if (isConnected)
cIn.GetConnectedTo(out inOrig);
// New try connection to each output connector
foreach (var cOut in outputConnectors)
{
IConnector outOrig;
cOut.GetConnectedTo(out outOrig);
// Start by disconnecting the connectors
cIn.Disconnect();
cOut.Disconnect();
// Connect the input and output
result = cIn.ConnectTo(cOut);
AssertCoreAudio.IsHResultOk(result);
// Verify the connection was made.
string cInId, idVerify;
((IPart)cIn).GetGlobalId(out cInId);
cOut.GetConnectorIdConnectedTo(out idVerify);
Assert.AreEqual(cInId, idVerify, "The connector IDs do not match.");
// Return the output connector to original state.
cOut.Disconnect();
cOut.ConnectTo(outOrig);
}
// Return the input connector to original state.
cIn.Disconnect();
if (inOrig != null)
cIn.ConnectTo(inOrig);
}
}
///
/// Tests that each available connector in the system may be disconnected.
///
[TestMethod]
public void IConnector_Disconnect()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
bool isConnected;
IConnector conOrig = null;
con.IsConnected(out isConnected);
if (isConnected)
con.GetConnectedTo(out conOrig);
result = con.Disconnect();
// HRESULT should either be S_OK, or E_NOTFOUND
// E_NOTFOUND is returned when Disconnect method is called on a connector that is already disconnected.
if (isConnected) AssertCoreAudio.IsHResultOk(result);
else Assert.AreEqual(TestUtilities.HRESULTS.E_NOTFOUND, (uint)result, "A disconnected connector did not return E_NOTFOUND HRESULT.");
// Verify connected state is now false.
con.IsConnected(out isConnected);
Assert.IsFalse(isConnected, "The connector was not properly disconnected.");
// Return connector to original state.
if (conOrig != null)
con.ConnectTo(conOrig);
}
}
///
/// Tests that the global ID may be received, for each available connector in the system.
///
[TestMethod]
public void IConnector_GetConnectorIdConnectedTo()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
bool isConnected;
con.IsConnected(out isConnected);
if (isConnected)
{
IConnector cTo;
con.GetConnectedTo(out cTo);
string expectedId, idConTo;
((IPart)cTo).GetGlobalId(out expectedId);
result = con.GetConnectorIdConnectedTo(out idConTo);
AssertCoreAudio.IsHResultOk(result);
Assert.AreEqual(expectedId, idConTo, "The connected to ID does not match the actual ID of the part.");
}
}
}
///
/// Tests that the other connector may be received, for each applicable connector in the system.
///
[TestMethod]
public void IConnector_GetConnectedTo()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
IConnector cTo;
result = con.GetConnectedTo(out cTo);
// A result of E_NOTFOUND is valid in this context.
if ((uint)result == TestUtilities.HRESULTS.E_NOTFOUND) continue;
// Otherwise the result should be S_OK
AssertCoreAudio.IsHResultOk(result);
}
}
///
/// Tests that the data flow may be received, for each available connector in the system.
///
[TestMethod]
public void IConnector_GetDataFlow()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
var valOne = DataFlow.In;
var valTwo = DataFlow.Out;
result = con.GetDataFlow(out valOne);
AssertCoreAudio.IsHResultOk(result);
result = con.GetDataFlow(out valTwo);
AssertCoreAudio.IsHResultOk(result);
Assert.AreEqual(valOne, valTwo, "The data flow was not received.");
}
}
///
/// Tests that the local device ID may be received, for each available connector in the system.
///
[TestMethod]
public void IConnector_GetDeviceIdConnectedTo()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
bool isConnected;
con.IsConnected(out isConnected);
if (isConnected)
{
IConnector cTo;
con.GetConnectedTo(out cTo);
IDeviceTopology topology;
((IPart)cTo).GetTopologyObject(out topology);
string expectedId, devIdConTo;
topology.GetDeviceId(out expectedId);
result = con.GetDeviceIdConnectedTo(out devIdConTo);
AssertCoreAudio.IsHResultOk(result);
Assert.AreEqual(expectedId, devIdConTo, "The connected to device ID does not match the actual device ID.");
}
}
}
///
/// Tests that the connector type may be received, for each available connector in the system.
///
[TestMethod]
public void IConnector_GetType()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
// Try confiming that the type is changed from unknown.
var cType = ConnectorType.Unknown_Connector;
result = con.GetType(out cType);
AssertCoreAudio.IsHResultOk(result);
if (cType == ConnectorType.Unknown_Connector)
{
// If it's still unknown, verify that this is correct.
var cType2 = ConnectorType.Network;
con.GetType(out cType2);
AssertCoreAudio.IsHResultOk(result);
Assert.AreEqual(ConnectorType.Unknown_Connector, cType2, "The connector type was not received.");
}
else
{
// The value being changed is enough to verify correctness of the method.
}
}
}
///
/// Tests that the connected state may be received, for each available connector in the system.
///
[TestMethod]
public void IConnector_IsConnected()
{
int result = 0;
IEnumerable allConnectors;
ToConnectors(TestUtilities.CreateIPartCollection(), out allConnectors);
foreach (var con in allConnectors)
{
var valOne = true;
var valTwo = false;
result = con.IsConnected(out valOne);
AssertCoreAudio.IsHResultOk(result);
result = con.IsConnected(out valTwo);
AssertCoreAudio.IsHResultOk(result);
Assert.AreEqual(valOne, valTwo, "The connected state was not received.");
}
}
#region Helper Methods
///
/// Takes a collection of IPart objects and returns the subset of the collection that are IConnector objects.
///
/// A collection that may contain both subunits and connectors.
/// A collection of connectors contained within the part collection.
private static void ToConnectors(IEnumerable allParts, out IEnumerable allConnectors)
{
var cList = new List();
IEnumerable cIns, cOuts;
ToConnectors(allParts, out cIns, out cOuts);
cList.AddRange(cIns);
cList.AddRange(cIns);
allConnectors = cList;
}
///
/// Takes a collection of IPart objects and returns the subset of the collection that are separated input and output IConnector objects.
///
/// A collection that may contain both subunits and connectors.
/// A collection of input connectors contained within the part collection.
/// A collection of output connectors contained within the part collection.
private static void ToConnectors(IEnumerable allParts, out IEnumerable inputConnectors, out IEnumerable outputConnectors)
{
var inList = new List();
var outList = new List();
foreach (IPart part in allParts)
{
PartType pType;
part.GetPartType(out pType);
if (pType == PartType.Connector)
{
DataFlow flow;
var connector = (IConnector)part;
connector.GetDataFlow(out flow);
switch (flow)
{
case DataFlow.In:
inList.Add(connector);
break;
case DataFlow.Out:
outList.Add(connector);
break;
}
}
}
if (!inList.Any()) Assert.Inconclusive("The test cannot be run properly. No connectors were found.");
if (!outList.Any()) Assert.Inconclusive("The test cannot be run properly. No connectors were found.");
inputConnectors = inList;
outputConnectors = outList;
}
#endregion
}
}