2003-10-12 Todd Berman <tberman@gentoo.org>
[mono.git] / mcs / nunit20 / util / UITestNode.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-2002 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  2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright  2000-2002 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.Util
31 {
32         using System;
33         using System.Collections;
34         using NUnit.Core;
35
36         /// <summary>
37         /// UITestNode holds common info needed about a test
38         /// in the UI, avoiding the remoting issues associated
39         /// with holding an actual Test object.
40         /// </summary>
41         public class UITestNode : ITest
42         {
43                 #region Instance Variables
44
45                 /// <summary>
46                 /// The full name of the test, including the assembly and namespaces
47                 /// </summary>
48                 private string fullName;
49
50                 /// <summary>
51                 /// The test name
52                 /// </summary>
53                 private string testName;
54
55                 /// <summary>
56                 /// Used to distinguish tests in multiple assemblies;
57                 /// </summary>
58                 private int assemblyKey;
59
60                 /// <summary>
61                 /// True if the test should be run
62                 /// </summary>
63                 private bool shouldRun;
64
65                 /// <summary>
66                 /// Reason for not running the test
67                 /// </summary>
68                 private string ignoreReason;
69
70                 /// <summary>
71                 /// Number of test cases in this test or suite
72                 /// </summary>
73                 private int testCaseCount;
74
75                 /// <summary>
76                 /// For a test suite, the child tests or suites
77                 /// Null if this is not a test suite
78                 /// </summary>
79                 private ArrayList tests;
80
81                 /// <summary>
82                 /// True if this is a suite
83                 /// </summary>
84                 private bool isSuite;
85
86                 /// <summary>
87                 /// Interface of the test suite from which this 
88                 /// object was constructed. Used for deferred 
89                 /// population of the object.
90                 /// </summary>
91                 private ITest testSuite;
92
93                 /// <summary>
94                 /// The test description
95                 /// </summary>
96                 private string description;
97
98                 #endregion
99
100                 #region Construction and Conversion
101
102                 public UITestNode( string suiteName ) : this( suiteName, 0 ) { }
103
104                 public UITestNode( string suiteName, int assemblyKey )
105                 {
106                         this.fullName = this.testName = suiteName;
107                         this.assemblyKey = assemblyKey;
108                         this.shouldRun = true;
109                         this.isSuite = true;
110                         this.testCaseCount = 0;
111                         this.tests = new ArrayList();
112                 }
113
114                 public UITestNode( string pathName, string testName ) 
115                         : this( pathName, testName, 0 ) { }
116
117                 public UITestNode( string pathName, string testName, int assemblyKey ) 
118                 { 
119                         this.fullName = pathName + "." + testName;
120                         this.testName = testName;
121                         this.assemblyKey = assemblyKey;
122                         this.shouldRun = true;
123                         this.isSuite = false;
124                         this.testCaseCount = 1;
125                 }
126
127                 /// <summary>
128                 /// Construct from a TestInfo interface, which might be
129                 /// a Test or another UITestNode. Optionally, populate
130                 /// the array of child tests.
131                 /// </summary>
132                 /// <param name="test">TestInfo interface from which a UITestNode is to be constructed</param>
133                 /// <param name="populate">True if child array is to be populated</param>
134                 public UITestNode ( ITest test, bool populate )
135                 {
136                         fullName = test.FullName;
137                         testName = test.Name;
138                         assemblyKey = test.AssemblyKey;
139                         shouldRun = test.ShouldRun;
140                         ignoreReason = test.IgnoreReason;
141                         description = test.Description;
142                         
143                         if ( test.IsSuite )
144                         {
145                                 testCaseCount = 0;
146                                 testSuite = test;
147                                 isSuite = true;
148
149                                 tests = new ArrayList();
150
151                                 if ( populate ) PopulateTests();
152                         }
153                         else
154                         {
155                                 testCaseCount = 1;
156                                 isSuite = false;
157                         }
158                 }
159
160                 /// <summary>
161                 /// Default construction uses lazy population approach
162                 /// </summary>
163                 /// <param name="test"></param>
164                 public UITestNode ( ITest test ) : this( test, false ) { }
165
166                 /// <summary>
167                 /// Populate the arraylist of child Tests recursively.
168                 /// If already populated, it has no effect.
169                 /// </summary>
170                 public void PopulateTests()
171                 {
172                         if ( !Populated )
173                         {
174                                 foreach( Test test in testSuite.Tests )
175                                 {
176                                         UITestNode node = new UITestNode( test, true );
177                                         tests.Add( node );
178                                         testCaseCount += node.CountTestCases;
179                                 }
180
181                                 testSuite = null;
182                         }
183                 }
184
185                 /// <summary>
186                 /// Allow implicit conversion of a Test to a TestInfo
187                 /// </summary>
188                 /// <param name="test"></param>
189                 /// <returns></returns>
190                 public static implicit operator UITestNode( Test test )
191                 {
192                         return new UITestNode( test );
193                 }
194
195                 #endregion
196
197                 #region Properties
198
199                 /// <summary>
200                 /// The test description 
201                 /// </summary>
202                 public string Description
203                 {
204                         get { return description; }
205                         set { description = value; }
206                 }
207
208                 /// <summary>
209                 /// The reason for ignoring a test
210                 /// </summary>
211                 public string IgnoreReason
212                 {
213                         get { return ignoreReason; }
214                         set { ignoreReason = value; }
215                 }
216
217                 /// <summary>
218                 /// True if the test should be run
219                 /// </summary>
220                 public bool ShouldRun
221                 {
222                         get { return shouldRun; }
223                         set { shouldRun = value; }
224                 }
225
226                 /// <summary>
227                 /// Full name of the test
228                 /// </summary>
229                 public string FullName 
230                 {
231                         get { return fullName; }
232                 }
233
234                 /// <summary>
235                 /// Name of the test
236                 /// </summary>
237                 public string Name
238                 {
239                         get { return testName; }
240                 }
241
242                 /// <summary>
243                 /// Identifier for assembly containing this test
244                 /// </summary>
245                 public int AssemblyKey
246                 {
247                         get { return assemblyKey; }
248                         set { assemblyKey = value; }
249                 }
250
251                 public string UniqueName
252                 {
253                         get{ return string.Format( "[{0}]{1}", assemblyKey, fullName ); }
254                 }
255
256                 /// <summary>
257                 /// If the name is a path, this just returns the file part
258                 /// </summary>
259                 public string ShortName
260                 {
261                         get
262                         {
263                                 string name = Name;
264                                 int val = name.LastIndexOf("\\");
265                                 if(val != -1)
266                                         name = name.Substring(val+1);
267                                 return name;
268                         }
269                 }
270
271                 /// <summary>
272                 /// Count of test cases in this test. If the suite
273                 /// has never been populated, it will be done now.
274                 /// </summary>
275                 public int CountTestCases
276                 { 
277                         get 
278                         { 
279                                 if ( !Populated )
280                                         PopulateTests();
281
282                                 return testCaseCount; 
283                         }
284                 }
285
286                 /// <summary>
287                 /// Array of child tests, null if this is a test case.
288                 /// The array is populated on access if necessary.
289                 /// </summary>
290                 public ArrayList Tests 
291                 {
292                         get 
293                         {
294                                 if ( !Populated )
295                                         PopulateTests();
296
297                                 return tests;
298                         }
299                 }
300
301                 /// <summary>
302                 /// True if this is a suite, false if a test case
303                 /// </summary>
304                 public bool IsSuite
305                 {
306                         get { return isSuite; }
307                 }
308
309                 /// <summary>
310                 /// True if this is a test case, false if a suite
311                 /// </summary>
312                 public bool IsTestCase
313                 {
314                         get { return !isSuite; }
315                 }
316
317                 /// <summary>
318                 /// True if this is a fixture. May populate the test's
319                 /// children as a side effect.
320                 /// TODO: An easier way to tell this?
321                 /// </summary>
322                 public bool IsFixture
323                 {
324                         get
325                         {
326                                 // A test case is obviously not a fixture
327                                 if ( IsTestCase ) return false;
328
329                                 // We have no way of constructing an empty suite unless it's a fixture
330                                 if ( Tests.Count == 0 ) return true;
331                                 
332                                 // Any suite with children is a fixture if the children are test cases
333                                 UITestNode firstChild = (UITestNode)Tests[0];
334                                 return !firstChild.IsSuite;
335                         }
336                 }
337
338                 /// <summary>
339                 /// False for suites that have not yet been populated
340                 /// with their children, otherwise true - used for testing.
341                 /// </summary>
342                 public bool Populated
343                 {
344                         get { return testSuite == null; }
345                 }
346
347                 public TestResult Run( EventListener listener )
348                 {
349                         throw new InvalidOperationException( "Cannot use Run on a local copy of Test data" );
350                 }
351
352                 #endregion
353         }
354 }