/// <summary> /// Helper method that checks the signature of a TestMethod and /// any supplied parameters to determine if the test is valid. /// /// Currently, NUnitTestMethods are required to be public, /// non-abstract methods, either static or instance, /// returning void. They may take arguments but the _values must /// be provided or the TestMethod is not considered runnable. /// /// Methods not meeting these criteria will be marked as /// non-runnable and the method will return false in that case. /// </summary> /// <param name="testMethod">The TestMethod to be checked. If it /// is found to be non-runnable, it will be modified.</param> /// <param name="parms">Parameters to be used for this test, or null</param> /// <returns>True if the method signature is valid, false if not</returns> /// <remarks> /// The return value is no longer used internally, but is retained /// for testing purposes. /// </remarks> private static bool CheckTestMethodSignature(TestMethod testMethod, 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; #if NETCF if (testMethod.Method.IsGenericMethodDefinition) { if (parms != null && parms.Arguments != null) { testMethod.Method = testMethod.Method.MakeGenericMethodEx(parms.Arguments); if (testMethod.Method == null) { return(MarkAsNotRunnable(testMethod, "Cannot determine generic types by probing")); } parameters = testMethod.Method.GetParameters(); } else { parameters = new IParameterInfo[0]; } } else { parameters = testMethod.Method.GetParameters(); } int minArgsNeeded = parameters.Length; #else parameters = testMethod.Method.GetParameters(); int minArgsNeeded = 0; foreach (var parameter in parameters) { // IsOptional is supported since .NET 1.1 if (!parameter.IsOptional) { minArgsNeeded++; } } #endif int maxArgsNeeded = parameters.Length; object[] arglist = null; int argsProvided = 0; if (parms != null) { testMethod.parms = parms; testMethod.RunState = parms.RunState; arglist = parms.Arguments; if (arglist != null) { argsProvided = arglist.Length; } if (testMethod.RunState != RunState.Runnable) { return(false); } } #if NETCF ITypeInfo returnType = testMethod.Method.IsGenericMethodDefinition && (parms == null || parms.Arguments == null) ? new TypeWrapper(typeof(void)) : testMethod.Method.ReturnType; #else ITypeInfo returnType = testMethod.Method.ReturnType; #endif #if NET_4_0 || NET_4_5 || PORTABLE if (AsyncInvocationRegion.IsAsyncOperation(testMethod.Method.MethodInfo)) { if (returnType.IsType(typeof(void))) { return(MarkAsNotRunnable(testMethod, "Async test method must have non-void return type")); } var returnsGenericTask = returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(System.Threading.Tasks.Task <>); if (returnsGenericTask && (parms == null || !parms.HasExpectedResult)) { return(MarkAsNotRunnable(testMethod, "Async test method must have non-generic Task return type when no result is expected")); } if (!returnsGenericTask && parms != null && parms.HasExpectedResult) { return(MarkAsNotRunnable(testMethod, "Async test method must have Task<T> return type when a result is expected")); } } else #endif if (returnType.IsType(typeof(void))) { 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 (argsProvided > 0 && maxArgsNeeded == 0) { return(MarkAsNotRunnable(testMethod, "Arguments provided for method not taking any")); } if (argsProvided == 0 && minArgsNeeded > 0) { return(MarkAsNotRunnable(testMethod, "No arguments were provided")); } if (argsProvided < minArgsNeeded) { return(MarkAsNotRunnable(testMethod, string.Format("Not enough arguments provided, provide at least {0} arguments.", minArgsNeeded))); } if (argsProvided > maxArgsNeeded) { return(MarkAsNotRunnable(testMethod, string.Format("Too many arguments provided, provide at most {0} arguments.", maxArgsNeeded))); } if (testMethod.Method.IsGenericMethodDefinition && arglist != null) { var typeArguments = new GenericMethodHelper(testMethod.Method.MethodInfo).GetTypeArguments(arglist); foreach (Type o in typeArguments) { if (o == null || o == TypeHelper.NonmatchingType) { return(MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method")); } } testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments); parameters = testMethod.Method.GetParameters(); } if (arglist != null && parameters != null) { TypeHelper.ConvertArgumentList(arglist, parameters); } return(true); }
/// <summary> /// Helper method that checks the signature of a TestMethod and /// any supplied parameters to determine if the test is valid. /// /// Currently, NUnitTestMethods are required to be public, /// non-abstract methods, either static or instance, /// returning void. They may take arguments but the _values must /// be provided or the TestMethod is not considered runnable. /// /// Methods not meeting these criteria will be marked as /// non-runnable and the method will return false in that case. /// </summary> /// <param name="testMethod">The TestMethod to be checked. If it /// is found to be non-runnable, it will be modified.</param> /// <param name="parms">Parameters to be used for this test, or null</param> /// <returns>True if the method signature is valid, false if not</returns> /// <remarks> /// The return value is no longer used internally, but is retained /// for testing purposes. /// </remarks> private static bool CheckTestMethodSignature(TestMethod testMethod, 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; #if NETCF if (testMethod.Method.IsGenericMethodDefinition) { if (parms != null && parms.Arguments != null) { var mi = testMethod.Method.MakeGenericMethodEx(parms.Arguments); if (mi == null) return MarkAsNotRunnable(testMethod, "Cannot determine generic types by probing"); testMethod.Method = mi; parameters = testMethod.Method.GetParameters(); } else parameters = new IParameterInfo[0]; } else parameters = testMethod.Method.GetParameters(); int minArgsNeeded = parameters.Length; #else parameters = testMethod.Method.GetParameters(); int minArgsNeeded = 0; foreach (var parameter in parameters) { // IsOptional is supported since .NET 1.1 if (!parameter.IsOptional) minArgsNeeded++; } #endif int maxArgsNeeded = parameters.Length; object[] arglist = null; int argsProvided = 0; if (parms != null) { testMethod.parms = parms; testMethod.RunState = parms.RunState; arglist = parms.Arguments; if (arglist != null) argsProvided = arglist.Length; if (testMethod.RunState != RunState.Runnable) return false; } #if NETCF ITypeInfo returnType = testMethod.Method.IsGenericMethodDefinition && (parms == null || parms.Arguments == null) ? new TypeWrapper(typeof(void)) : testMethod.Method.ReturnType; #else ITypeInfo returnType = testMethod.Method.ReturnType; #endif #if NET_4_0 || NET_4_5 || PORTABLE if (AsyncInvocationRegion.IsAsyncOperation(testMethod.Method.MethodInfo)) { if (returnType.IsType(typeof(void))) return MarkAsNotRunnable(testMethod, "Async test method must have non-void return type"); var returnsGenericTask = returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(System.Threading.Tasks.Task<>); if (returnsGenericTask && (parms == null || !parms.HasExpectedResult)) return MarkAsNotRunnable(testMethod, "Async test method must have non-generic Task return type when no result is expected"); if (!returnsGenericTask && parms != null && parms.HasExpectedResult) return MarkAsNotRunnable(testMethod, "Async test method must have Task<T> return type when a result is expected"); } else #endif if (returnType.IsType(typeof(void))) { 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 (argsProvided > 0 && maxArgsNeeded == 0) return MarkAsNotRunnable(testMethod, "Arguments provided for method not taking any"); if (argsProvided == 0 && minArgsNeeded > 0) return MarkAsNotRunnable(testMethod, "No arguments were provided"); if (argsProvided < minArgsNeeded) return MarkAsNotRunnable(testMethod, string.Format("Not enough arguments provided, provide at least {0} arguments.", minArgsNeeded)); if (argsProvided > maxArgsNeeded) return MarkAsNotRunnable(testMethod, string.Format("Too many arguments provided, provide at most {0} arguments.", maxArgsNeeded)); if (testMethod.Method.IsGenericMethodDefinition && arglist != null) { var typeArguments = new GenericMethodHelper(testMethod.Method.MethodInfo).GetTypeArguments(arglist); foreach (Type o in typeArguments) if (o == null || o == TypeHelper.NonmatchingType) return MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method"); testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments); parameters = testMethod.Method.GetParameters(); } if (arglist != null && parameters != null) TypeHelper.ConvertArgumentList(arglist, parameters); return true; }
/// <summary> /// Helper method that checks the signature of a TestMethod and /// any supplied parameters to determine if the test is valid. /// /// Currently, NUnitTestMethods are required to be public, /// non-abstract methods, either static or instance, /// returning void. They may take arguments but the _values must /// be provided or the TestMethod is not considered runnable. /// /// Methods not meeting these criteria will be marked as /// non-runnable and the method will return false in that case. /// </summary> /// <param name="testMethod">The TestMethod to be checked. If it /// is found to be non-runnable, it will be modified.</param> /// <param name="parms">Parameters to be used for this test, or null</param> /// <returns>True if the method signature is valid, false if not</returns> /// <remarks> /// The return value is no longer used internally, but is retained /// for testing purposes. /// </remarks> private static bool CheckTestMethodSignature(TestMethod testMethod, 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; parameters = testMethod.Method.GetParameters(); int minArgsNeeded = 0; foreach (var parameter in parameters) { // IsOptional is supported since .NET 1.1 if (!parameter.IsOptional) { minArgsNeeded++; } } int maxArgsNeeded = parameters.Length; object[] arglist = null; int argsProvided = 0; if (parms != null) { testMethod.parms = parms; testMethod.RunState = parms.RunState; arglist = parms.Arguments; if (arglist != null) { argsProvided = arglist.Length; } if (testMethod.RunState != RunState.Runnable) { return(false); } } ITypeInfo returnType = testMethod.Method.ReturnType; #if ASYNC if (AwaitUtils.IsAsyncVoid(testMethod.Method.MethodInfo)) { return(MarkAsNotRunnable(testMethod, "Async test method must have non-void return type")); } if (AwaitUtils.IsAwaitable(testMethod.Method.MethodInfo)) { var resultType = AwaitUtils.GetAwaitableResultType(testMethod.Method.MethodInfo); if (parms != null && parms.HasExpectedResult) { if (resultType == typeof(void)) { return(MarkAsNotRunnable(testMethod, "Async test method must not return void when awaited when a result is expected")); } } else { if (resultType != typeof(void)) { return(MarkAsNotRunnable(testMethod, "Async test method must return void when awaited when no result is expected")); } } } else #endif if (returnType.IsType(typeof(void))) { 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 (argsProvided > 0 && maxArgsNeeded == 0) { return(MarkAsNotRunnable(testMethod, "Arguments provided for method with no parameters")); } if (argsProvided == 0 && minArgsNeeded > 0) { return(MarkAsNotRunnable(testMethod, "No arguments were provided")); } if (argsProvided < minArgsNeeded) { return(MarkAsNotRunnable(testMethod, string.Format("Not enough arguments provided, provide at least {0} arguments.", minArgsNeeded))); } if (argsProvided > maxArgsNeeded) { return(MarkAsNotRunnable(testMethod, string.Format("Too many arguments provided, provide at most {0} arguments.", maxArgsNeeded))); } if (testMethod.Method.IsGenericMethodDefinition && arglist != null) { var typeArguments = new GenericMethodHelper(testMethod.Method.MethodInfo).GetTypeArguments(arglist); foreach (Type o in typeArguments) { if (o == null || o == TypeHelper.NonmatchingType) { return(MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method")); } } testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments); parameters = testMethod.Method.GetParameters(); } if (arglist != null && parameters != null) { TypeHelper.ConvertArgumentList(arglist, parameters); } return(true); }