1 // ***********************************************************************
2 // Copyright (c) 2010 Charlie Poole
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
25 #define NUNIT_FRAMEWORK
30 using NUnit.Framework.Interfaces;
32 namespace NUnit.Framework.Internal.Commands
35 /// TestMethodCommand is the lowest level concrete command
36 /// used to run actual test cases.
38 public class TestMethodCommand : TestCommand
40 private readonly TestMethod testMethod;
41 private readonly object[] arguments;
44 /// Initializes a new instance of the <see cref="TestMethodCommand"/> class.
46 /// <param name="testMethod">The test.</param>
47 public TestMethodCommand(TestMethod testMethod) : base(testMethod)
49 this.testMethod = testMethod;
50 this.arguments = testMethod.Arguments;
54 /// Runs the test, saving a TestResult in the execution context, as
55 /// well as returning it. If the test has an expected result, it
56 /// is asserts on that value. Since failed tests and errors throw
57 /// an exception, this command must be wrapped in an outer command,
58 /// will handle that exception and records the failure. This role
59 /// is usually played by the SetUpTearDown command.
61 /// <param name="context">The execution context</param>
62 public override TestResult Execute(TestExecutionContext context)
64 // TODO: Decide if we should handle exceptions here
65 object result = RunTestMethod(context);
67 if (testMethod.HasExpectedResult)
68 NUnit.Framework.Assert.AreEqual(testMethod.ExpectedResult, result);
70 context.CurrentResult.SetResult(ResultState.Success);
71 // TODO: Set assert count here?
72 //context.CurrentResult.AssertCount = context.AssertCount;
73 return context.CurrentResult;
76 private object RunTestMethod(TestExecutionContext context)
78 #if NET_4_0 || NET_4_5 || PORTABLE
79 if (AsyncInvocationRegion.IsAsyncOperation(testMethod.Method.MethodInfo))
80 return RunAsyncTestMethod(context);
83 return RunNonAsyncTestMethod(context);
86 #if NET_4_0 || NET_4_5 || PORTABLE
87 private object RunAsyncTestMethod(TestExecutionContext context)
89 using (AsyncInvocationRegion region = AsyncInvocationRegion.Create(testMethod.Method.MethodInfo))
91 object result = Reflect.InvokeMethod(testMethod.Method.MethodInfo, context.TestObject, arguments);
95 return region.WaitForPendingOperationsToComplete(result);
99 throw new NUnitException("Rethrown", e);
105 private object RunNonAsyncTestMethod(TestExecutionContext context)
107 //return Reflect.InvokeMethod(testMethod.Method.MethodInfo, context.TestObject, arguments);
108 return testMethod.Method.Invoke(context.TestObject, arguments);