2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[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                 private ArrayList categories = new ArrayList();
99
100                 private bool isExplicit;
101
102                 #endregion
103
104                 #region Construction and Conversion
105
106                 /// <summary>
107                 /// Construct from a TestInfo interface, which might be
108                 /// a Test or another UITestNode. Optionally, populate
109                 /// the array of child tests.
110                 /// </summary>
111                 /// <param name="test">TestInfo interface from which a UITestNode is to be constructed</param>
112                 /// <param name="populate">True if child array is to be populated</param>
113                 public UITestNode ( ITest test, bool populate )
114                 {
115                         fullName = test.FullName;
116                         testName = test.Name;
117                         assemblyKey = test.AssemblyKey;
118                         shouldRun = test.ShouldRun;
119                         ignoreReason = test.IgnoreReason;
120                         description = test.Description;
121                         isExplicit = test.IsExplicit;
122
123                         if (test.Categories != null) 
124                         {
125                                 categories.AddRange(test.Categories);
126                         }
127
128                         if ( test is UITestNode )
129                                 testCaseCount = 0;
130                         
131                         if ( test.IsSuite )
132                         {
133                                 testCaseCount = 0;
134                                 testSuite = test;
135                                 isSuite = true;
136
137                                 tests = new ArrayList();
138
139                                 if ( populate ) PopulateTests();
140                         }
141                         else
142                         {
143                                 testCaseCount = 1;
144                                 isSuite = false;
145                         }
146                 }
147
148                 /// <summary>
149                 /// Default construction uses lazy population approach
150                 /// </summary>
151                 /// <param name="test"></param>
152                 public UITestNode ( ITest test ) : this( test, false ) { }
153
154                 public UITestNode ( string pathName, string testName )
155                         : this( pathName, testName, 0 ) { }
156
157                 public UITestNode ( string pathName, string testName, int assemblyKey )
158                 {
159                         this.fullName = pathName + "." + testName;
160                         this.testName = testName;
161                         this.assemblyKey = assemblyKey;
162                         this.shouldRun = true;
163                         this.isSuite = false;
164                         this.testCaseCount = 1;
165                 }
166
167                 /// <summary>
168                 /// Populate the arraylist of child Tests recursively.
169                 /// If already populated, it has no effect.
170                 /// </summary>
171                 public void PopulateTests()
172                 {
173                         if ( !Populated )
174                         {
175                                 foreach( ITest test in testSuite.Tests )
176                                 {
177                                         UITestNode node = new UITestNode( test, true );
178                                         tests.Add( node );
179                                         testCaseCount += node.CountTestCases();
180                                 }
181
182                                 testSuite = null;
183                         }
184                 }
185
186                 /// <summary>
187                 /// Allow implicit conversion of a Test to a TestInfo
188                 /// </summary>
189                 /// <param name="test"></param>
190                 /// <returns></returns>
191                 public static implicit operator UITestNode( Test test )
192                 {
193                         return new UITestNode( test );
194                 }
195
196                 #endregion
197
198                 #region Properties
199
200                 /// <summary>
201                 /// The test description 
202                 /// </summary>
203                 public string Description
204                 {
205                         get { return description; }
206                         set { description = value; }
207                 }
208
209                 /// <summary>
210                 /// The reason for ignoring a test
211                 /// </summary>
212                 public string IgnoreReason
213                 {
214                         get { return ignoreReason; }
215                         set { ignoreReason = value; }
216                 }
217
218                 /// <summary>
219                 /// True if the test should be run
220                 /// </summary>
221                 public bool ShouldRun
222                 {
223                         get { return shouldRun; }
224                         set { shouldRun = value; }
225                 }
226
227                 /// <summary>
228                 /// Full name of the test
229                 /// </summary>
230                 public string FullName 
231                 {
232                         get { return fullName; }
233                 }
234
235                 /// <summary>
236                 /// Name of the test
237                 /// </summary>
238                 public string Name
239                 {
240                         get { return testName; }
241                 }
242
243                 /// <summary>
244                 /// Identifier for assembly containing this test
245                 /// </summary>
246                 public int AssemblyKey
247                 {
248                         get { return assemblyKey; }
249                         set { assemblyKey = value; }
250                 }
251
252                 public string UniqueName
253                 {
254                         get{ return string.Format( "[{0}]{1}", assemblyKey, fullName ); }
255                 }
256
257                 /// <summary>
258                 /// If the name is a path, this just returns the file part
259                 /// </summary>
260                 public string ShortName
261                 {
262                         get
263                         {
264                                 string name = Name;
265                                 int val = name.LastIndexOf("\\");
266                                 if(val != -1)
267                                         name = name.Substring(val+1);
268                                 return name;
269                         }
270                 }
271
272                 public bool IsExplicit
273                 {
274                         get { return isExplicit; }
275                         set { isExplicit = value; }
276                 }
277
278                 public IList Categories 
279                 {
280                         get { return categories; }
281                 }
282
283                 public bool HasCategory( string name )
284                 {
285                         return categories != null && categories.Contains( name );
286                 }
287
288                 public bool HasCategory( IList names )
289                 {
290                         if ( categories == null )
291                                 return false;
292
293                         foreach( string name in names )
294                                 if ( categories.Contains( name ) )
295                                         return true;
296
297                         return false;
298                 }
299
300                 /// <summary>
301                 /// Count of test cases in this test. If the suite
302                 /// has never been populated, it will be done now.
303                 /// </summary>
304                 public int CountTestCases()
305                 { 
306                         if ( !Populated )
307                                 PopulateTests();
308
309                         return testCaseCount; 
310                 }
311
312                 /// <summary>
313                 /// Array of child tests, null if this is a test case.
314                 /// The array is populated on access if necessary.
315                 /// </summary>
316                 public ArrayList Tests 
317                 {
318                         get 
319                         {
320                                 if ( !Populated )
321                                         PopulateTests();
322
323                                 return tests;
324                         }
325                 }
326
327                 /// <summary>
328                 /// True if this is a suite, false if a test case
329                 /// </summary>
330                 public bool IsSuite
331                 {
332                         get { return isSuite; }
333                 }
334
335                 /// <summary>
336                 /// True if this is a test case, false if a suite
337                 /// </summary>
338                 public bool IsTestCase
339                 {
340                         get { return !isSuite; }
341                 }
342
343                 /// <summary>
344                 /// True if this is a fixture. May populate the test's
345                 /// children as a side effect.
346                 /// TODO: An easier way to tell this?
347                 /// </summary>
348                 public bool IsFixture
349                 {
350                         get
351                         {
352                                 // A test case is obviously not a fixture
353                                 if ( IsTestCase ) return false;
354
355                                 // We have no way of constructing an empty suite unless it's a fixture
356                                 if ( Tests.Count == 0 ) return true;
357                                 
358                                 // Any suite with children is a fixture if the children are test cases
359                                 UITestNode firstChild = (UITestNode)Tests[0];
360                                 return !firstChild.IsSuite;
361                         }
362                 }
363
364                 /// <summary>
365                 /// False for suites that have not yet been populated
366                 /// with their children, otherwise true - used for testing.
367                 /// </summary>
368                 public bool Populated
369                 {
370                         get { return testSuite == null; }
371                 }
372
373                 public TestResult Run( EventListener listener )
374                 {
375                         throw new InvalidOperationException( "Cannot use Run on a local copy of Test data" );
376                 }
377
378                 #endregion
379         }
380 }