Beispiel #1
0
            internal static Exception Intercept(object invocation)
            {
                var invocationDescriptor = GetInvocationDescriptor(invocation);

#if ASYNC
                if (AsyncToSyncAdapter.IsAsyncOperation(invocationDescriptor.Delegate))
                {
                    try
                    {
                        AsyncToSyncAdapter.Await(invocationDescriptor.Invoke);
                        return(null);
                    }
                    catch (Exception ex)
                    {
                        return(ex);
                    }
                }
#endif
                {
                    using (new TestExecutionContext.IsolatedContext())
                    {
                        try
                        {
                            invocationDescriptor.Invoke();
                            return(null);
                        }
                        catch (Exception ex)
                        {
                            return(ex);
                        }
                    }
                }
            }
            public override ConstraintResult ApplyTo <TActual>(TActual actual)
            {
                var @delegate = ConstraintUtils.RequireActual <Delegate>(actual, nameof(actual));

                var invokeMethod = @delegate.GetType().GetTypeInfo().GetMethod("Invoke");

                if (invokeMethod.GetParameters().Length != 0)
                {
                    throw new ArgumentException("Delegate must be parameterless.", nameof(actual));
                }

                var stopwatch = new System.Diagnostics.Stopwatch();

                if (AsyncToSyncAdapter.IsAsyncOperation(@delegate))
                {
                    stopwatch.Start();
                    AsyncToSyncAdapter.Await(() => @delegate.DynamicInvoke());
                    stopwatch.Stop();
                }
                else
                {
                    stopwatch.Start();
                    @delegate.DynamicInvoke();
                    stopwatch.Stop();
                }

                return(new Result(this, stopwatch.ElapsedMilliseconds));
            }
        private static object InvokeDelegate <T>(ActualValueDelegate <T> del)
        {
            if (AsyncToSyncAdapter.IsAsyncOperation(del))
            {
                return(AsyncToSyncAdapter.Await(() => del.Invoke()));
            }

            return(del());
        }
Beispiel #4
0
        /// <summary>
        /// Applies the constraint to an ActualValueDelegate that returns
        /// the value to be tested. The default implementation simply evaluates
        /// the delegate but derived classes may override it to provide for
        /// delayed processing.
        /// </summary>
        /// <param name="del">An ActualValueDelegate</param>
        /// <returns>A ConstraintResult</returns>
        public virtual ConstraintResult ApplyTo <TActual>(ActualValueDelegate <TActual> del)
        {
            if (AsyncToSyncAdapter.IsAsyncOperation(del))
            {
                return(ApplyTo(AsyncToSyncAdapter.Await(() => del.Invoke())));
            }

            return(ApplyTo(GetTestObject(del)));
        }
        private object RunTestMethod(TestExecutionContext context)
        {
            if (AsyncToSyncAdapter.IsAsyncOperation(testMethod.Method.MethodInfo))
            {
                return(AsyncToSyncAdapter.Await(() => InvokeTestMethod(context)));
            }

            return(InvokeTestMethod(context));
        }
Beispiel #6
0
        /// <summary>
        /// Applies the constraint to an ActualValueDelegate that returns
        /// the value to be tested. The default implementation simply evaluates
        /// the delegate but derived classes may override it to provide for
        /// delayed processing.
        /// </summary>
        /// <param name="del">An ActualValueDelegate</param>
        /// <returns>A ConstraintResult</returns>
        /// <remarks>
        /// The value has already been validated when this method is called.
        /// </remarks>
        protected virtual ConstraintResult ApplyConstraint <T>(ActualValueDelegate <T> del)
        {
#if NYI // async
            if (AsyncToSyncAdapter.IsAsyncOperation(del))
            {
                return(ApplyConstraint(AsyncToSyncAdapter.Await(() => del.Invoke())));
            }
#endif

            return(ApplyConstraint(del()));
        }
Beispiel #7
0
        private static void RunSetUpOrTearDownMethod(TestExecutionContext context, MethodInfo method)
        {
            Guard.ArgumentNotAsyncVoid(method, nameof(method));
#if ASYNC
            if (AsyncToSyncAdapter.IsAsyncOperation(method))
            {
                AsyncToSyncAdapter.Await(() => InvokeMethod(method, context));
            }
            else
#endif
            InvokeMethod(method, context);
        }
Beispiel #8
0
        /// <summary>
        /// Throws an <see cref="ArgumentException"/> if the specified delegate is <c>async void</c>.
        /// </summary>
        public static void ArgumentNotAsyncVoid(MethodInfo method, string paramName)
        {
            if (method.ReturnType != typeof(void))
            {
                return;
            }
            if (!AsyncToSyncAdapter.IsAsyncOperation(method))
            {
                return;
            }

            throw new ArgumentException("Async void methods are not supported. Please use 'async Task' instead.", paramName);
        }
        private void RunSetUpOrTearDownMethod(TestExecutionContext context, IMethodInfo method)
        {
            Guard.ArgumentNotAsyncVoid(method.MethodInfo, nameof(method));
            _methodValidator?.Validate(method.MethodInfo);

            if (AsyncToSyncAdapter.IsAsyncOperation(method.MethodInfo))
            {
                AsyncToSyncAdapter.Await(() => InvokeMethod(method, context));
            }
            else
            {
                InvokeMethod(method, context);
            }
        }
Beispiel #10
0
        public static Exception?ThrowsAsync(IResolveConstraint expression, AsyncTestDelegate code, string?message, params object?[]?args)
        {
            Exception?caughtException = null;

            try
            {
                AsyncToSyncAdapter.Await(code.Invoke);
            }
            catch (Exception e)
            {
                caughtException = e;
            }

            Assert.That(caughtException, expression, message, args);

            return(caughtException);
        }
Beispiel #11
0
        private object RunTestMethod(TestExecutionContext context)
        {
#if ASYNC
            if (AsyncToSyncAdapter.IsAsyncOperation(testMethod.Method.MethodInfo))
            {
                try
                {
                    return(AsyncToSyncAdapter.Await(() => InvokeTestMethod(context)));
                }
                catch (Exception e)
                {
                    throw new NUnitException("Rethrown", e);
                }
            }
#endif
            return(InvokeTestMethod(context));
        }
        /// <summary>
        /// Executes the code and returns success if an exception is thrown.
        /// </summary>
        /// <param name="actual">A delegate representing the code to be tested</param>
        /// <returns>True if an exception is thrown, otherwise false</returns>
        public override ConstraintResult ApplyTo <TActual>(TActual actual)
        {
            TestDelegate code            = actual as TestDelegate;
            Exception    caughtException = null;

            if (code != null)
            {
                try
                {
                    code();
                }
                catch (Exception ex)
                {
                    caughtException = ex;
                }
            }
#if ASYNC
            AsyncTestDelegate asyncCode = actual as AsyncTestDelegate;
            if (asyncCode != null)
            {
                try
                {
                    AsyncToSyncAdapter.Await(asyncCode.Invoke);
                }
                catch (Exception ex)
                {
                    caughtException = ex;
                }
            }
            if (code == null && asyncCode == null)
#else
            else
#endif
            {
                throw new ArgumentException(string.Format("The actual value must be a TestDelegate or AsyncTestDelegate but was {0}", actual.GetType().Name), nameof(actual));
            }
            return(new ThrowsExceptionConstraintResult(this, caughtException));
        }
Beispiel #13
0
        public static void Multiple(AsyncTestDelegate testDelegate)
        {
            TestExecutionContext context = TestExecutionContext.CurrentContext;

            Guard.OperationValid(context != null, "There is no current test execution context.");

            context.MultipleAssertLevel++;

            try
            {
                AsyncToSyncAdapter.Await(testDelegate.Invoke);
            }
            finally
            {
                context.MultipleAssertLevel--;
            }

            if (context.MultipleAssertLevel == 0 && context.CurrentResult.PendingFailures > 0)
            {
                context.CurrentResult.RecordTestCompletion();
                throw new MultipleAssertException(context.CurrentResult);
            }
        }
        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);
                }
            }

            var returnType = testMethod.Method.ReturnType.Type;

            if (AsyncToSyncAdapter.IsAsyncOperation(testMethod.Method.MethodInfo))
            {
                if (returnType == typeof(void))
                {
                    return(MarkAsNotRunnable(testMethod, "Async test method must have non-void return type"));
                }

                var voidResult = Reflect.IsVoidOrUnit(AwaitAdapter.GetResultType(returnType));

                if (!voidResult && (parms == null || !parms.HasExpectedResult))
                {
                    return(MarkAsNotRunnable(testMethod,
                                             "Async test method must return an awaitable with a void result when no result is expected"));
                }

                if (voidResult && 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 (Reflect.IsVoidOrUnit(returnType))
            {
                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)
            {
                if (!new GenericMethodHelper(testMethod.Method.MethodInfo).TryGetTypeArguments(arglist, out var 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 && parms.TestName.Trim() == "")
            {
                return(MarkAsNotRunnable(testMethod, "Test name cannot be all white-space or empty."));
            }

            if (arglist != null && parameters != null)
            {
                TypeHelper.ConvertArgumentList(arglist, parameters);
            }

            return(true);
        }
Beispiel #15
0
        /// <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 (AsyncToSyncAdapter.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 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)
            {
                Type[] typeArguments;
                if (!new GenericMethodHelper(testMethod.Method.MethodInfo).TryGetTypeArguments(arglist, out typeArguments))
                {
                    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);
        }