2006-02-14 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / nunit20 / core / TestSuite.cs
1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
3 '
4 ' Copyright © 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright © 2000-2003 Philip A. Craig
6 '
7 ' This software is provided 'as-is', without any express or implied warranty. In no 
8 ' event will the authors be held liable for any damages arising from the use of this 
9 ' software.
10
11 ' Permission is granted to anyone to use this software for any purpose, including 
12 ' commercial applications, and to alter it and redistribute it freely, subject to the 
13 ' following restrictions:
14 '
15 ' 1. The origin of this software must not be misrepresented; you must not claim that 
16 ' you wrote the original software. If you use this software in a product, an 
17 ' acknowledgment (see the following) in the product documentation is required.
18 '
19 ' Portions Copyright © 2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright © 2000-2003 Philip A. Craig
21 '
22 ' 2. Altered source versions must be plainly marked as such, and must not be 
23 ' misrepresented as being the original software.
24 '
25 ' 3. This notice may not be removed or altered from any source distribution.
26 '
27 '***********************************************************************************/
28 #endregion
29
30 namespace NUnit.Core
31 {
32         using System;
33         using System.Collections;
34         using System.Reflection;
35         using System.Text;
36
37         /// <summary>
38         /// Summary description for TestSuite.
39         /// </summary>
40         /// 
41         [Serializable]
42         public class TestSuite : Test
43         {
44                 private static readonly string EXPLICIT_SELECTION_REQUIRED = "Explicit selection required";
45                 
46                 #region Fields
47
48                 /// <summary>
49                 /// Our collection of child tests
50                 /// </summary>
51                 private ArrayList tests = new ArrayList();
52
53                 /// <summary>
54                 /// The fixture setup method for this suite
55                 /// </summary>
56                 protected MethodInfo fixtureSetUp;
57
58                 /// <summary>
59                 /// The fixture teardown method for this suite
60                 /// </summary>
61                 protected MethodInfo fixtureTearDown;
62
63                 /// <summary>
64                 /// True if the fixture has been set up
65                 /// </summary>
66                 private bool isSetUp;
67
68                 #endregion
69
70                 #region Constructors
71
72                 public TestSuite( string name ) : this( name, 0 ) { }
73
74                 public TestSuite( string name, int assemblyKey ) 
75                         : base( name, assemblyKey )
76                 {
77                         ShouldRun = true;
78                 }
79
80                 public TestSuite( string parentSuiteName, string name ) 
81                         : this( parentSuiteName, name, 0 ) { }
82
83                 public TestSuite( string parentSuiteName, string name, int assemblyKey ) 
84                         : base( parentSuiteName, name, assemblyKey )
85                 {
86                         ShouldRun = true;
87                 }
88
89                 public TestSuite( Type fixtureType ) : base( fixtureType, 0 ) { }
90
91                 public TestSuite( Type fixtureType, int assemblyKey ) : base( fixtureType, assemblyKey ) { }
92
93                 protected TestSuite( object fixture ) : base( fixture, 0 ) { }
94
95                 protected TestSuite( object fixture, int assemblyKey ) : base( fixture, assemblyKey ) { }
96
97                 #endregion
98
99                 public void Sort()
100                 {
101                         this.Tests.Sort();
102
103                         foreach( Test test in Tests )
104                         {
105                                 TestSuite suite = test as TestSuite;
106                                 if ( suite != null )
107                                         suite.Sort();
108                         }               
109                 }
110
111                 public void Add( Test test ) 
112                 {
113                         if(test.ShouldRun)
114                         {
115                                 test.ShouldRun = ShouldRun;
116                                 test.IgnoreReason = IgnoreReason;
117                         }
118                         test.Parent = this;
119                         tests.Add(test);
120                 }
121
122                 //Keep this in for testing for the time being
123                 public void Add( object fixture )
124                 {
125                         Add( new TestFixture( fixture ) );
126                 }
127
128                 #region Properties
129
130                 public override ArrayList Tests 
131                 {
132                         get { return tests; }
133                 }
134
135                 public override bool IsSuite
136                 {
137                         get { return true; }
138                 }
139
140                 public override bool IsTestCase
141                 {
142                         get { return false; }
143                 }
144
145                 public bool IsSetUp
146                 {
147                         get { return isSetUp; }
148                         set { isSetUp = value; }
149                 }
150
151                 #endregion
152
153                 /// <summary>
154                 /// True if this is a fixture. May populate the test's
155                 /// children as a side effect.
156                 /// TODO: An easier way to tell this?
157                 /// </summary>
158                 public override bool IsFixture
159                 {
160                         get
161                         {
162                                 // We have no way of constructing an empty suite unless it's a fixture
163                                 if ( Tests.Count == 0 ) return true;
164                                 
165                                 // Any suite with children is a fixture if the children are test cases
166                                 Test firstChild = (Test)Tests[0];
167                                 return !firstChild.IsSuite;
168                         }
169                 }
170
171                 public override int CountTestCases()
172                 {
173                         int count = 0;
174
175                         foreach(Test test in Tests)
176                         {
177                                 count += test.CountTestCases();
178                         }
179                         return count;
180                 }
181
182                 public override int CountTestCases(IFilter filter)
183                 {
184                         int count = 0;
185
186                         if(this.Filter(filter)) 
187                         {
188                                 foreach(Test test in Tests)
189                                 {
190                                         count += test.CountTestCases(filter);
191                                 }
192                         }
193                         return count;
194                 }
195
196                 public override TestResult Run(EventListener listener)
197                 {
198                         return Run( listener, null );
199                 }
200                         
201                 public override TestResult Run(EventListener listener, IFilter filter)
202                 {
203                         TestSuiteResult suiteResult = new TestSuiteResult(this, Name);
204
205                         listener.SuiteStarted(this);
206                         long startTime = DateTime.Now.Ticks;
207
208                         if ( ShouldRun )
209                         {
210                                 suiteResult.Executed = true;    
211                                 DoSetUp( suiteResult );
212
213                                 RunAllTests( suiteResult, listener, filter );
214
215                                 DoTearDown( suiteResult );
216                         }
217                         else
218                                 suiteResult.NotRun(this.IgnoreReason);
219
220                         long stopTime = DateTime.Now.Ticks;
221                         double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond;
222                         suiteResult.Time = time;
223
224                         listener.SuiteFinished(suiteResult);
225                         return suiteResult;
226                 }
227
228                 public virtual void DoSetUp( TestResult suiteResult )
229                 {
230                 }
231
232                 public virtual void DoTearDown( TestResult suiteResult )
233                 {
234                 }
235
236                 protected virtual void RunAllTests(
237                         TestSuiteResult suiteResult, EventListener listener, IFilter filter )
238                 {
239                         foreach(Test test in ArrayList.Synchronized(Tests))
240                         {
241                                 bool saveShouldRun = test.ShouldRun;
242
243                                 if (test.ShouldRun)
244                                 {
245                                         if (this.ShouldRun == false)
246                                         {
247                                                 test.ShouldRun = false;
248                                                 test.IgnoreReason = this.IgnoreReason;
249                                         }
250                                         else if ( test.IsExplicit && filter == null )
251                                         {
252                                                 test.ShouldRun = false;
253                                                 test.IgnoreReason = EXPLICIT_SELECTION_REQUIRED;
254                                         }
255                                 }
256                                         
257                                 if ( filter == null || test.Filter( filter ) )
258                                 {
259                                         suiteResult.AddResult( test.Run( listener, filter ) );
260                                 }
261                                 
262                                 if ( saveShouldRun && !test.ShouldRun ) 
263                                 {
264                                         test.ShouldRun = true;
265                                         test.IgnoreReason = null;
266                                 }
267                         }
268                 }
269
270                 public override bool Filter(IFilter filter) 
271                 {
272                         return filter.Pass(this);
273                 }
274         }
275 }