1 // ***********************************************************************
2 // Copyright (c) 2009 Charlie Poole
3 //
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:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
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 // ***********************************************************************
23 
24 using System;
25 using System.Reflection;
26 using NUnit.Framework;
27 using NUnit.Framework.Api;
28 using NUnit.Framework.Builders;
29 using NUnit.Framework.Internal;
30 using NUnit.Framework.Internal.Commands;
31 using NUnit.Framework.Extensibility;
32 using NUnit.Framework.Internal.WorkItems;
33 using System.Threading;
34 
35 namespace NUnit.TestUtilities
36 {
37     /// <summary>
38     /// Utility Class used to build NUnit tests for use as test data
39     /// </summary>
40     public class TestBuilder
41     {
42         private static NUnitTestFixtureBuilder fixtureBuilder = new NUnitTestFixtureBuilder();
43         private static NUnitTestCaseBuilder testBuilder = new NUnitTestCaseBuilder();
44 
45 #if !NUNITLITE
TestBuilder()46         static TestBuilder()
47         {
48             if (!CoreExtensions.Host.Initialized)
49                 CoreExtensions.Host.Initialize();
50         }
51 #endif
52 
MakeFixture(Type type)53         public static TestSuite MakeFixture(Type type)
54         {
55             return (TestSuite)fixtureBuilder.BuildFrom(type);
56         }
57 
MakeFixture(object fixture)58         public static TestSuite MakeFixture(object fixture)
59         {
60             return (TestSuite)fixtureBuilder.BuildFrom(fixture.GetType());
61         }
62 
MakeParameterizedMethodSuite(Type type, string methodName)63         public static TestSuite MakeParameterizedMethodSuite(Type type, string methodName)
64         {
65             return (TestSuite)MakeTestCase(type, methodName);
66         }
67 
MakeTestCase(Type type, string methodName)68         public static Test MakeTestCase(Type type, string methodName)
69         {
70             MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
71             if (method == null)
72                 Assert.Fail("Unable to find method {0} in type {1}", methodName, type.FullName);
73             return testBuilder.BuildFrom(method);
74         }
75 
MakeTestCase(object fixture, string methodName)76         public static Test MakeTestCase(object fixture, string methodName)
77         {
78             return MakeTestCase(fixture.GetType(), methodName);
79         }
80 
RunTestFixture(Type type)81         public static TestResult RunTestFixture(Type type)
82         {
83             TestSuite suite = MakeFixture(type);
84 
85             TestExecutionContext context = new TestExecutionContext();
86             context.TestObject = null;
87 
88             CompositeWorkItem work = new CompositeWorkItem(suite, TestFilter.Empty);
89             return ExecuteAndWaitForResult(work, context);
90         }
91 
RunTestFixture(object fixture)92         public static TestResult RunTestFixture(object fixture)
93         {
94             TestSuite suite = MakeFixture(fixture);
95 
96             TestExecutionContext context = new TestExecutionContext();
97             context.TestObject = fixture;
98 
99             WorkItem work = suite.CreateWorkItem(TestFilter.Empty);
100             return ExecuteAndWaitForResult(work, context);
101         }
102 
RunTestCase(Type type, string methodName)103         public static ITestResult RunTestCase(Type type, string methodName)
104         {
105             Test test = MakeTestCase(type, methodName);
106 
107             object testObject = null;
108             if (!IsStaticClass(type))
109                 testObject = Activator.CreateInstance(type);
110 
111             return RunTest(test, testObject);
112         }
113 
RunTestCase(object fixture, string methodName)114         public static ITestResult RunTestCase(object fixture, string methodName)
115         {
116             Test test = MakeTestCase(fixture, methodName);
117             return RunTest(test, fixture);
118         }
119 
RunTestCaseAsync(object fixture, string methodName)120         public static WorkItem RunTestCaseAsync(object fixture, string methodName)
121         {
122             Test test = MakeTestCase(fixture, methodName);
123             return RunTestAsync(test, fixture);
124         }
125 
RunTest(Test test)126         public static ITestResult RunTest(Test test)
127         {
128             return RunTest(test, null);
129         }
130 
RunTestAsync(Test test)131         public static WorkItem RunTestAsync(Test test)
132         {
133             return RunTestAsync(test, (object)null);
134         }
135 
RunTestAsync(Test test, object testObject)136         public static WorkItem RunTestAsync(Test test, object testObject)
137         {
138             TestExecutionContext context = new TestExecutionContext();
139             context.TestObject = testObject;
140 
141             WorkItem work = test.CreateWorkItem(TestFilter.Empty);
142             work.Execute(context);
143 
144             return work;
145         }
146 
RunTest(Test test, object testObject)147         public static ITestResult RunTest(Test test, object testObject)
148         {
149             TestExecutionContext context = new TestExecutionContext();
150             context.TestObject = testObject;
151 
152             WorkItem work = test.CreateWorkItem(TestFilter.Empty);
153             return ExecuteAndWaitForResult(work, context);
154         }
155 
ExecuteAndWaitForResult(WorkItem work, TestExecutionContext context)156         private static TestResult ExecuteAndWaitForResult(WorkItem work, TestExecutionContext context)
157         {
158             work.Execute(context);
159 
160             // TODO: Replace with an event
161             while (work.State != WorkItemState.Complete)
162                 Thread.Sleep(1);
163 
164             return work.Result;
165         }
166 
IsStaticClass(Type type)167         private static bool IsStaticClass(Type type)
168         {
169             return type.IsAbstract && type.IsSealed;
170         }
171 
TestBuilder()172         private TestBuilder() { }
173     }
174 }
175