TestCaseSourceAttribute
TestCaseSourceAttribute indicates the source to be used to
provide test cases for a test method.
using NUnit.Compatibility;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Builders;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace NUnit.Framework
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class TestCaseSourceAttribute : NUnitAttribute, ITestBuilder, IImplyFixture
{
private NUnitTestCaseBuilder _builder = new NUnitTestCaseBuilder();
private const string SourceMustBeStatic = "The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.";
private const string ParamGivenToField = "You have specified a data source field but also given a set of parameters. Fields cannot take parameters, please revise the 3rd parameter passed to the TestCaseSourceAttribute and either remove it or specify a method.";
private const string ParamGivenToProperty = "You have specified a data source property but also given a set of parameters. Properties cannot take parameters, please revise the 3rd parameter passed to the TestCaseSource attribute and either remove it or specify a method.";
private const string NumberOfArgsDoesNotMatch = "You have given the wrong number of arguments to the method in the TestCaseSourceAttribute, please check the number of parameters passed in the object is correct in the 3rd parameter for the TestCaseSourceAttribute and this matches the number of parameters in the target method and try again.";
public object[] MethodParams { get; set; }
public string SourceName { get; set; }
public Type SourceType { get; set; }
public string Category { get; set; }
public TestCaseSourceAttribute(string sourceName)
{
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType, string sourceName, object[] methodParams)
{
MethodParams = methodParams;
SourceType = sourceType;
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType, string sourceName)
{
SourceType = sourceType;
SourceName = sourceName;
}
public TestCaseSourceAttribute(string sourceName, object[] methodParams)
{
MethodParams = methodParams;
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType)
{
SourceType = sourceType;
}
public IEnumerable<TestMethod> BuildFrom(IMethodInfo method, Test suite)
{
foreach (TestCaseParameters item in GetTestCasesFor(method)) {
yield return _builder.BuildTestMethod(method, suite, item);
}
}
private IEnumerable<ITestCaseData> GetTestCasesFor(IMethodInfo method)
{
List<ITestCaseData> list = new List<ITestCaseData>();
try {
IEnumerable testCaseSource = GetTestCaseSource(method);
if (testCaseSource != null) {
foreach (object item in testCaseSource) {
object obj;
if (item != null)
obj = (item as ITestCaseData);
else {
ITestCaseData testCaseData = new TestCaseParameters(new object[1]);
obj = testCaseData;
}
ITestCaseData testCaseData2 = (ITestCaseData)obj;
if (testCaseData2 == null) {
object[] array = item as object[];
if (array == null && item is Array) {
Array array2 = item as Array;
int num = method.GetParameters().Length;
if (array2 != null && array2.Rank == 1 && array2.Length == num) {
array = new object[array2.Length];
for (int i = 0; i < array2.Length; i++) {
array[i] = array2.GetValue(i);
}
}
}
if (array != null) {
IParameterInfo[] parameters = method.GetParameters();
int num2 = parameters.Length;
int num3 = array.Length;
if (num2 == 1) {
Type parameterType = parameters[0].ParameterType;
if ((num3 == 0 || typeof(object[]).IsAssignableFrom(parameterType)) && (num3 > 1 || TypeExtensions.IsAssignableFrom(parameterType, array.GetType())))
array = new object[1] {
item
};
}
} else
array = new object[1] {
item
};
testCaseData2 = new TestCaseParameters(array);
}
if (Category != null) {
string[] array3 = Category.Split(new char[1] {
','
});
foreach (string value in array3) {
testCaseData2.Properties.Add("Category", value);
}
}
list.Add(testCaseData2);
}
return list;
}
return list;
} catch (Exception exception) {
list.Clear();
list.Add(new TestCaseParameters(exception));
return list;
}
}
private IEnumerable GetTestCaseSource(IMethodInfo method)
{
Type type = SourceType ?? method.TypeInfo.Type;
if (SourceName == null)
return Reflect.Construct(type, null) as IEnumerable;
MemberInfo[] member = TypeExtensions.GetMember(type, SourceName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
if (member.Length == 1) {
MemberInfo memberInfo = member[0];
FieldInfo fieldInfo = memberInfo as FieldInfo;
if ((object)fieldInfo != null) {
if (!fieldInfo.IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null)
return ReturnErrorAsParameter("You have specified a data source field but also given a set of parameters. Fields cannot take parameters, please revise the 3rd parameter passed to the TestCaseSourceAttribute and either remove it or specify a method.");
return (IEnumerable)fieldInfo.GetValue(null);
}
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if ((object)propertyInfo != null) {
if (!propertyInfo.GetGetMethod(true).IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null)
return ReturnErrorAsParameter("You have specified a data source property but also given a set of parameters. Properties cannot take parameters, please revise the 3rd parameter passed to the TestCaseSource attribute and either remove it or specify a method.");
return (IEnumerable)propertyInfo.GetValue(null, null);
}
MethodInfo methodInfo = memberInfo as MethodInfo;
if ((object)methodInfo != null) {
if (!methodInfo.IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null && methodInfo.GetParameters().Length != MethodParams.Length)
return ReturnErrorAsParameter("You have given the wrong number of arguments to the method in the TestCaseSourceAttribute, please check the number of parameters passed in the object is correct in the 3rd parameter for the TestCaseSourceAttribute and this matches the number of parameters in the target method and try again.");
return (IEnumerable)methodInfo.Invoke(null, MethodParams);
}
}
return null;
}
private static IEnumerable ReturnErrorAsParameter(string errorMessage)
{
TestCaseParameters testCaseParameters = new TestCaseParameters();
testCaseParameters.RunState = RunState.NotRunnable;
testCaseParameters.Properties.Set("_SKIPREASON", errorMessage);
return new TestCaseParameters[1] {
testCaseParameters
};
}
}
}