NUnitTestCaseBuilder
NUnitTestCaseBuilder is a utility class used by attributes
that build test cases.
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Extensions;
using System;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Internal.Builders
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class NUnitTestCaseBuilder
{
private readonly Randomizer _randomizer = Randomizer.CreateRandomizer();
private readonly TestNameGenerator _nameGenerator;
public NUnitTestCaseBuilder()
{
_nameGenerator = new TestNameGenerator();
}
public TestMethod BuildTestMethod(IMethodInfo method, [System.Runtime.CompilerServices.Nullable(2)] Test parentSuite, [System.Runtime.CompilerServices.Nullable(2)] TestCaseParameters parms)
{
TestMethod testMethod = new TestMethod(method, parentSuite) {
Seed = _randomizer.Next()
};
try {
MethodInfoCache.TestMethodMetadata metadata = MethodInfoCache.Get(method);
CheckTestMethodAttributes(testMethod, metadata);
CheckTestMethodSignature(testMethod, metadata, parms);
if (parms == null || parms.Arguments.Length == 0)
testMethod.ApplyAttributesToTest(method.MethodInfo);
string fullName = testMethod.Method.TypeInfo.FullName;
if (parentSuite != null)
fullName = parentSuite.FullName;
if (parms != null) {
parms.ApplyToTest(testMethod);
if (parms.TestName != null)
testMethod.Name = ((parms.TestName.IndexOf('{') >= 0) ? new TestNameGenerator(parms.TestName).GetDisplayName(testMethod, parms.OriginalArguments) : parms.TestName);
else if (parms.ArgDisplayNames != null) {
testMethod.Name = testMethod.Name + "(" + string.Join(", ", parms.ArgDisplayNames) + ")";
} else {
testMethod.Name = _nameGenerator.GetDisplayName(testMethod, parms.OriginalArguments);
}
} else
testMethod.Name = _nameGenerator.GetDisplayName(testMethod, null);
testMethod.FullName = fullName + "." + testMethod.Name;
return testMethod;
} catch (Exception exception) {
testMethod.MakeInvalid(exception, "Failure building TestMethod");
return testMethod;
}
}
private static bool CheckTestMethodAttributes(TestMethod testMethod, MethodInfoCache.TestMethodMetadata metadata)
{
if (metadata.RepeatTestAttributes.Length > 1)
return MarkAsNotRunnable(testMethod, "Multiple attributes that repeat a test may cause issues.");
return true;
}
private static bool CheckTestMethodSignature(TestMethod testMethod, MethodInfoCache.TestMethodMetadata metadata, [System.Runtime.CompilerServices.Nullable(2)] TestCaseParameters parms)
{
if (testMethod.Method.IsAbstract)
return MarkAsNotRunnable(testMethod, "Method is abstract");
if (!testMethod.Method.IsPublic)
return MarkAsNotRunnable(testMethod, "Method is not public");
IParameterInfo[] parameters = metadata.Parameters;
int num = 0;
IParameterInfo[] array = parameters;
foreach (IParameterInfo parameterInfo in array) {
if (!parameterInfo.IsOptional)
num++;
}
int num2 = parameters.Length;
object[] array2 = null;
int num3 = 0;
if (parms != null) {
testMethod.Parms = parms;
testMethod.RunState = parms.RunState;
array2 = parms.Arguments;
if (array2 != null)
num3 = array2.Length;
if (testMethod.RunState != RunState.Runnable)
return false;
}
Type type = testMethod.Method.ReturnType.Type;
if (metadata.IsAsyncOperation) {
if (type == typeof(void))
return MarkAsNotRunnable(testMethod, "Async test method must have non-void return type");
bool flag = Reflect.IsVoidOrUnit(AwaitAdapter.GetResultType(type));
if (!flag && (parms == null || !parms.HasExpectedResult))
return MarkAsNotRunnable(testMethod, "Async test method must return an awaitable with a void result when no result is expected");
if (flag && parms != null && parms.HasExpectedResult)
return MarkAsNotRunnable(testMethod, "Async test method must return an awaitable with a non-void result when a result is expected");
} else if (metadata.IsVoidOrUnit) {
if (parms != null && parms.HasExpectedResult)
return MarkAsNotRunnable(testMethod, "Method returning void cannot have an expected result");
} else if (parms == null || !parms.HasExpectedResult) {
return MarkAsNotRunnable(testMethod, "Method has non-void return value, but no result is expected");
}
if (parameters.LastParameterAcceptsCancellationToken() && (array2 == null || !array2.LastArgumentIsCancellationToken()))
num3++;
if (num3 > 0 && num2 == 0)
return MarkAsNotRunnable(testMethod, "Arguments provided for method with no parameters");
if (num3 == 0 && num > 0)
return MarkAsNotRunnable(testMethod, "No arguments were provided");
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler;
if (num3 < num) {
defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(59, 1);
defaultInterpolatedStringHandler.AppendLiteral("Not enough arguments provided, provide at least ");
defaultInterpolatedStringHandler.AppendFormatted(num);
defaultInterpolatedStringHandler.AppendLiteral(" arguments.");
return MarkAsNotRunnable(testMethod, defaultInterpolatedStringHandler.ToStringAndClear());
}
if (num3 > num2) {
defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(56, 1);
defaultInterpolatedStringHandler.AppendLiteral("Too many arguments provided, provide at most ");
defaultInterpolatedStringHandler.AppendFormatted(num2);
defaultInterpolatedStringHandler.AppendLiteral(" arguments.");
return MarkAsNotRunnable(testMethod, defaultInterpolatedStringHandler.ToStringAndClear());
}
if (testMethod.Method.IsGenericMethodDefinition) {
Type[] typeArguments = parms?.TypeArgs;
if (typeArguments == null && (array2 == null || !new GenericMethodHelper(testMethod.Method.MethodInfo).TryGetTypeArguments(array2, out typeArguments)))
return MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method");
testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments);
parameters = testMethod.Method.GetParameters();
}
if (parms != null && parms.TestName != null && string.IsNullOrWhiteSpace(parms.TestName))
return MarkAsNotRunnable(testMethod, "Test name cannot be all white-space or empty.");
if (array2 != null && parameters != null)
TypeHelper.ConvertArgumentList(array2, parameters);
return true;
}
private static bool MarkAsNotRunnable(TestMethod testMethod, string reason)
{
testMethod.MakeInvalid(reason);
return false;
}
}
}