NUnitTestFixtureBuilder
NUnitTestFixtureBuilder is able to build a fixture given
a class marked with a TestFixtureAttribute or an unmarked
class containing test methods. In the first case, it is
called by the attribute and in the second directly by
NUnitSuiteBuilder.
using NUnit.Framework.Interfaces;
using System;
using System.Reflection;
namespace NUnit.Framework.Internal.Builders
{
public class NUnitTestFixtureBuilder
{
private const string NO_TYPE_ARGS_MSG = "Fixture type contains generic parameters. You must either provide Type arguments or specify constructor arguments that allow NUnit to deduce the Type arguments.";
private const string PARALLEL_NOT_ALLOWED_MSG = "ParallelizableAttribute is only allowed on test methods and fixtures";
private ITestCaseBuilder _testBuilder = new DefaultTestCaseBuilder();
public TestSuite BuildFrom(ITypeInfo typeInfo)
{
TestFixture testFixture = new TestFixture(typeInfo, null);
if (testFixture.RunState != 0)
CheckTestFixtureIsValid(testFixture);
testFixture.ApplyAttributesToTest(typeInfo.Type.GetTypeInfo());
AddTestCasesToFixture(testFixture);
return testFixture;
}
public TestSuite BuildFrom(ITypeInfo typeInfo, ITestFixtureData testFixtureData)
{
Guard.ArgumentNotNull(testFixtureData, "testFixtureData");
object[] array = testFixtureData.Arguments;
if (typeInfo.ContainsGenericParameters) {
Type[] typeArgsOut = testFixtureData.TypeArgs;
if (typeArgsOut == null || typeArgsOut.Length == 0) {
int num = 0;
object[] array2 = array;
for (int i = 0; i < array2.Length && array2[i] is Type; i++) {
num++;
}
typeArgsOut = new Type[num];
for (int j = 0; j < num; j++) {
typeArgsOut[j] = (Type)array[j];
}
if (num > 0) {
object[] array3 = new object[array.Length - num];
for (int k = 0; k < array3.Length; k++) {
array3[k] = array[num + k];
}
array = array3;
}
}
if (typeArgsOut.Length != 0 || TypeHelper.CanDeduceTypeArgsFromArgs(typeInfo.Type, array, ref typeArgsOut))
typeInfo = typeInfo.MakeGenericType(typeArgsOut);
}
TestFixture testFixture = new TestFixture(typeInfo, array);
string name = testFixture.Name;
if (testFixtureData.TestName != null)
testFixture.Name = testFixtureData.TestName;
else if (array != null && array.Length != 0) {
testFixture.Name = typeInfo.GetDisplayName(array);
}
if (testFixture.Name != name) {
string namespace = typeInfo.Namespace;
testFixture.FullName = ((namespace != null && namespace != "") ? (namespace + "." + testFixture.Name) : testFixture.Name);
}
if (testFixture.RunState != 0)
testFixture.RunState = testFixtureData.RunState;
foreach (string key in testFixtureData.Properties.Keys) {
foreach (object item in testFixtureData.Properties[key]) {
testFixture.Properties.Add(key, item);
}
}
if (testFixture.RunState != 0)
CheckTestFixtureIsValid(testFixture);
testFixture.ApplyAttributesToTest(typeInfo.Type.GetTypeInfo());
AddTestCasesToFixture(testFixture);
return testFixture;
}
private void AddTestCasesToFixture(TestFixture fixture)
{
if (fixture.TypeInfo.ContainsGenericParameters)
fixture.MakeInvalid("Fixture type contains generic parameters. You must either provide Type arguments or specify constructor arguments that allow NUnit to deduce the Type arguments.");
else {
IMethodInfo[] methods = fixture.TypeInfo.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (IMethodInfo methodInfo in methods) {
Test test = BuildTestCase(methodInfo, fixture);
if (test != null)
fixture.Add(test);
else if (methodInfo.IsDefined<ParallelizableAttribute>(false)) {
fixture.MakeInvalid("ParallelizableAttribute is only allowed on test methods and fixtures");
}
}
}
}
private Test BuildTestCase(IMethodInfo method, TestSuite suite)
{
if (!_testBuilder.CanBuildFrom(method, suite))
return null;
return _testBuilder.BuildFrom(method, suite);
}
private static void CheckTestFixtureIsValid(TestFixture fixture)
{
if (fixture.TypeInfo.ContainsGenericParameters)
fixture.MakeInvalid("Fixture type contains generic parameters. You must either provide Type arguments or specify constructor arguments that allow NUnit to deduce the Type arguments.");
else if (!fixture.TypeInfo.IsStaticClass) {
Type[] typeArray = Reflect.GetTypeArray(fixture.Arguments);
if (!fixture.TypeInfo.HasConstructor(typeArray))
fixture.MakeInvalid("No suitable constructor was found");
}
}
private static bool IsStaticClass(Type type)
{
if (type.GetTypeInfo().get_IsAbstract())
return type.GetTypeInfo().get_IsSealed();
return false;
}
}
}