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.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Internal.Builders
{
[NullableContext(1)]
[Nullable(0)]
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 readonly ITestCaseBuilder _testBuilder = new DefaultTestCaseBuilder();
public TestSuite BuildFrom(ITypeInfo typeInfo, IPreFilter filter)
{
TestFixture testFixture = new TestFixture(typeInfo, (object[])null);
if (testFixture.RunState != 0)
CheckTestFixtureIsValid(testFixture);
testFixture.ApplyAttributesToTest(typeInfo.Type.Assembly.GetAttributes<FixtureLifeCycleAttribute>());
testFixture.ApplyAttributesToTest(typeInfo.Type);
AddTestCasesToFixture(testFixture, filter);
return testFixture;
}
public TestSuite BuildFrom(ITypeInfo typeInfo, IPreFilter filter, 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;
foreach (object obj in array2) {
if (!(obj is Type))
break;
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 {
string[] array4 = (testFixtureData as TestParameters)?.ArgDisplayNames;
if (array4 != null) {
testFixture.Name = typeInfo.GetDisplayName();
if (array4.Length != 0) {
TestFixture testFixture2 = testFixture;
testFixture2.Name = testFixture2.Name + "(" + string.Join(", ", array4) + ")";
}
} else if (array != null && array.Length != 0) {
testFixture.Name = typeInfo.GetDisplayName(array);
}
}
if (testFixture.Name != name) {
string namespace = typeInfo.Namespace;
testFixture.FullName = ((!string.IsNullOrEmpty(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);
AddTestCasesToFixture(testFixture, filter);
return testFixture;
}
private void AddTestCasesToFixture(TestFixture fixture, IPreFilter filter)
{
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);
IMethodInfo[] array = methods;
foreach (IMethodInfo methodInfo in array) {
if (filter.IsMatch(fixture.TypeInfo.Type, methodInfo.MethodInfo)) {
Test test = BuildTestCase(methodInfo, fixture);
if (test != null)
fixture.Add(test);
else if (methodInfo.MethodInfo.HasAttribute<ParallelizableAttribute>(false)) {
fixture.MakeInvalid("ParallelizableAttribute is only allowed on test methods and fixtures");
}
}
}
}
}
[return: Nullable(2)]
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 (!Reflect.GetConstructors(fixture.TypeInfo.Type, typeArray).Any())
fixture.MakeInvalid("No suitable constructor was found");
}
}
}
}