1 // ***********************************************************************
2 // Copyright (c) 2014 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
29 using NUnit.Framework.TUnit;
31 using System.Collections.Generic;
32 using System.Reflection;
33 using System.Threading;
35 namespace NUnit.Framework.Internal.Commands
38 /// SetUpTearDownItem holds the setup and teardown methods
39 /// for a single level of the inheritance hierarchy.
41 public class SetUpTearDownItem
43 public IList<MethodInfo> _setUpMethods;
44 public IList<MethodInfo> _tearDownMethods;
45 public bool _setUpWasRun;
48 /// Construct a SetUpTearDownNode
50 /// <param name="setUpMethods">A list of setup methods for this level</param>
51 /// <param name="tearDownMethods">A list teardown methods for this level</param>
52 public SetUpTearDownItem(IList<MethodInfo> setUpMethods, IList<MethodInfo> tearDownMethods)
54 _setUpMethods = setUpMethods;
55 _tearDownMethods = tearDownMethods;
59 /// Returns true if this level has any methods at all.
60 /// This flag is used to discard levels that do nothing.
62 public bool HasMethods
64 get { return _setUpMethods.Count > 0 || _tearDownMethods.Count > 0; }
68 /// Run SetUp on this level.
70 /// <param name="context">The execution context to use for running.</param>
71 public void RunSetUp(TestExecutionContext context)
74 foreach (MethodInfo setUpMethod in _setUpMethods)
75 RunSetUpOrTearDownMethod(context, setUpMethod);
78 #region add by nguyen.vtan , method use for run setup of TC on main thread
79 public void RunSetupForTC(TestExecutionContext context)
82 TAsyncThreadMgr asyncThreadMgr = TAsyncThreadMgr.GetInstance();
83 asyncThreadMgr.SetData(this);
87 /// Run TearDown for this level.
89 /// <param name="context"></param>
90 public void RunTearDown(TestExecutionContext context)
92 // As of NUnit 3.0, we will only run teardown at a given
93 // inheritance level if we actually ran setup at that level.
97 // Even though we are only running one level at a time, we
98 // run the teardowns in reverse order to provide consistency.
99 int index = _tearDownMethods.Count;
102 RunSetUpOrTearDownMethod(context, _tearDownMethods[index]);
107 context.CurrentResult.RecordTearDownException(ex);
111 #region add by nguyen.vtan , method use for run teardown of TC on main thread
112 public void RunTearDownForTC(TestExecutionContext context)
117 // Even though we are only running one level at a time, we
118 // run the teardowns in reverse order to provide consistency.
119 TAsyncThreadMgr asyncThreadMgr = TAsyncThreadMgr.GetInstance();
120 asyncThreadMgr.SetTearDownData(this);
125 context.CurrentResult.RecordTearDownException(ex);
129 public void RunSetUpOrTearDownMethod(TestExecutionContext context, MethodInfo method)
131 #if NET_4_0 || NET_4_5 || PORTABLE
132 if (AsyncInvocationRegion.IsAsyncOperation(method))
133 RunAsyncMethod(method, context);
136 RunNonAsyncMethod(method, context);
139 #if NET_4_0 || NET_4_5 || PORTABLE
140 private void RunAsyncMethod(MethodInfo method, TestExecutionContext context)
142 using (AsyncInvocationRegion region = AsyncInvocationRegion.Create(method))
143 region.WaitForPendingOperationsToComplete(RunNonAsyncMethod(method, context));
146 private object RunNonAsyncMethod(MethodInfo method, TestExecutionContext context)
148 return Reflect.InvokeMethod(method, method.IsStatic ? null : context.TestObject);