/// <summary> /// Construct one or more TestMethods from a given MethodInfo, /// using available parameter data. /// </summary> /// <param name="method">The MethodInfo for which tests are to be constructed.</param> /// <param name="suite">The suite to which the tests will be added.</param> /// <returns>One or more TestMethods</returns> public IEnumerable<TestMethod> BuildFrom(MethodInfo method, Test suite) { List<TestMethod> tests = new List<TestMethod>(); #if NETCF if (method.ContainsGenericParameters) { var genericParams = method.GetGenericArguments(); var numGenericParams = genericParams.Length; var o = new object(); var tryArgs = Enumerable.Repeat(o, numGenericParams).ToArray(); MethodInfo mi; try { // This fails if the generic method has constraints // that are not met by object. mi = method.MakeGenericMethodEx(tryArgs); if (mi == null) return tests; } catch { return tests; } var par = mi.GetParameters(); if (par.Length == 0) return tests; var sourceData = par.Select(p => _dataProvider.GetDataFor(p)).ToArray(); foreach (var parms in _strategy.GetTestCases(sourceData)) { mi = method.MakeGenericMethodEx(parms.Arguments); if (mi == null) { var tm = new TestMethod(method, suite); tm.RunState = RunState.NotRunnable; tm.Properties.Set(PropertyNames.SkipReason, "Incompatible arguments"); tests.Add(tm); } else tests.Add(_builder.BuildTestMethod(mi, suite, (TestCaseParameters)parms)); } return tests; } #endif ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length > 0) { IEnumerable[] sources = new IEnumerable[parameters.Length]; try { for (int i = 0; i < parameters.Length; i++) sources[i] = _dataProvider.GetDataFor(parameters[i]); } catch (InvalidDataSourceException ex) { var parms = new TestCaseParameters(); parms.RunState = RunState.NotRunnable; parms.Properties.Set(PropertyNames.SkipReason, ex.Message); tests.Add(_builder.BuildTestMethod(method, suite, parms)); return tests; } foreach (var parms in _strategy.GetTestCases(sources)) tests.Add(_builder.BuildTestMethod(method, suite, (TestCaseParameters)parms)); } return tests; }
private TestCaseParameters GetParametersForTestCase(MethodInfo method) { TestCaseParameters parms; try { #if NETCF var tmethod = method.MakeGenericMethodEx(Arguments); if (tmethod == null) throw new NotSupportedException("Cannot determine generic types from probing"); method = tmethod; #endif ParameterInfo[] parameters = method.GetParameters(); int argsNeeded = parameters.Length; int argsProvided = Arguments.Length; parms = new TestCaseParameters(this); // Special handling for params arguments if (argsNeeded > 0 && argsProvided >= argsNeeded - 1) { ParameterInfo lastParameter = parameters[argsNeeded - 1]; Type lastParameterType = lastParameter.ParameterType; Type elementType = lastParameterType.GetElementType(); if (lastParameterType.IsArray && lastParameter.IsDefined(typeof(ParamArrayAttribute), false)) { if (argsProvided == argsNeeded) { Type lastArgumentType = parms.Arguments[argsProvided - 1].GetType(); if (!lastParameterType.IsAssignableFrom(lastArgumentType)) { Array array = Array.CreateInstance(elementType, 1); array.SetValue(parms.Arguments[argsProvided - 1], 0); parms.Arguments[argsProvided - 1] = array; } } else { object[] newArglist = new object[argsNeeded]; for (int i = 0; i < argsNeeded && i < argsProvided; i++) newArglist[i] = parms.Arguments[i]; int length = argsProvided - argsNeeded + 1; Array array = Array.CreateInstance(elementType, length); for (int i = 0; i < length; i++) array.SetValue(parms.Arguments[argsNeeded + i - 1], i); newArglist[argsNeeded - 1] = array; parms.Arguments = newArglist; argsProvided = argsNeeded; } } } //if (method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(object[])) // parms.Arguments = new object[]{parms.Arguments}; // Special handling when sole argument is an object[] if (argsNeeded == 1 && method.GetParameters()[0].ParameterType == typeof(object[])) { if (argsProvided > 1 || argsProvided == 1 && parms.Arguments[0].GetType() != typeof(object[])) { parms.Arguments = new object[] { parms.Arguments }; } } if (argsProvided == argsNeeded) PerformSpecialConversions(parms.Arguments, parameters); } catch (Exception ex) { parms = new TestCaseParameters(ex); } return parms; }
/// <summary> /// Returns a set of ITestCaseDataItems for use as arguments /// to a parameterized test method. /// </summary> /// <param name="method">The method for which data is needed.</param> /// <returns></returns> private IEnumerable<ITestCaseData> GetTestCasesFor(MethodInfo method) { List<ITestCaseData> data = new List<ITestCaseData>(); try { IEnumerable source = GetTestCaseSource(method); if (source != null) { #if NETCF ParameterInfo[] parameters = method.IsGenericMethodDefinition ? new ParameterInfo[0] : method.GetParameters(); #else ParameterInfo[] parameters = method.GetParameters(); #endif foreach (object item in source) { var parms = item as ITestCaseData; if (parms == null) { object[] args = item as object[]; if (args != null) { #if NETCF if (method.IsGenericMethodDefinition) { var mi = method.MakeGenericMethodEx(args); parameters = mi == null ? new ParameterInfo[0] : mi.GetParameters(); } #endif if (args.Length != parameters.Length) args = new object[] { item }; } // else if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(item.GetType())) // { // args = new object[] { item }; // } else if (item is Array) { Array array = item as Array; #if NETCF if (array.Rank == 1 && (method.IsGenericMethodDefinition || array.Length == parameters.Length)) #else if (array.Rank == 1 && array.Length == parameters.Length) #endif { args = new object[array.Length]; for (int i = 0; i < array.Length; i++) args[i] = array.GetValue(i); #if NETCF if (method.IsGenericMethodDefinition) { var mi = method.MakeGenericMethodEx(args); if (mi == null || array.Length != mi.GetParameters().Length) args = new object[] {item}; } #endif } else { args = new object[] { item }; } } else { args = new object[] { item }; } parms = new TestCaseParameters(args); } if (this.Category != null) foreach (string cat in this.Category.Split(new char[] { ',' })) parms.Properties.Add(PropertyNames.Category, cat); data.Add(parms); } } } catch (Exception ex) { data.Clear(); data.Add(new TestCaseParameters(ex)); } return data; }