**** Merged from MCS ****
[mono-project.git] / mcs / nunit20 / util / UITestNode.cs
blob2448fc7e01d5c9c5abab6fbddeb31e6c3daacece
1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
4 ' Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright 2000-2002 Philip A. Craig
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.
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:
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.
19 ' Portions Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright 2000-2002 Philip A. Craig
22 ' 2. Altered source versions must be plainly marked as such, and must not be
23 ' misrepresented as being the original software.
25 ' 3. This notice may not be removed or altered from any source distribution.
27 '***********************************************************************************/
28 #endregion
30 namespace NUnit.Util
32 using System;
33 using System.Collections;
34 using NUnit.Core;
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
43 #region Instance Variables
45 /// <summary>
46 /// The full name of the test, including the assembly and namespaces
47 /// </summary>
48 private string fullName;
50 /// <summary>
51 /// The test name
52 /// </summary>
53 private string testName;
55 /// <summary>
56 /// Used to distinguish tests in multiple assemblies;
57 /// </summary>
58 private int assemblyKey;
60 /// <summary>
61 /// True if the test should be run
62 /// </summary>
63 private bool shouldRun;
65 /// <summary>
66 /// Reason for not running the test
67 /// </summary>
68 private string ignoreReason;
70 /// <summary>
71 /// Number of test cases in this test or suite
72 /// </summary>
73 private int testCaseCount;
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;
81 /// <summary>
82 /// True if this is a suite
83 /// </summary>
84 private bool isSuite;
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;
93 /// <summary>
94 /// The test description
95 /// </summary>
96 private string description;
98 private ArrayList categories = new ArrayList();
100 private bool isExplicit;
102 #endregion
104 #region Construction and Conversion
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 )
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;
123 if (test.Categories != null)
125 categories.AddRange(test.Categories);
128 if ( test is UITestNode )
129 testCaseCount = 0;
131 if ( test.IsSuite )
133 testCaseCount = 0;
134 testSuite = test;
135 isSuite = true;
137 tests = new ArrayList();
139 if ( populate ) PopulateTests();
141 else
143 testCaseCount = 1;
144 isSuite = false;
148 /// <summary>
149 /// Default construction uses lazy population approach
150 /// </summary>
151 /// <param name="test"></param>
152 public UITestNode ( ITest test ) : this( test, false ) { }
154 public UITestNode ( string pathName, string testName )
155 : this( pathName, testName, 0 ) { }
157 public UITestNode ( string pathName, string testName, int assemblyKey )
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;
167 /// <summary>
168 /// Populate the arraylist of child Tests recursively.
169 /// If already populated, it has no effect.
170 /// </summary>
171 public void PopulateTests()
173 if ( !Populated )
175 foreach( ITest test in testSuite.Tests )
177 UITestNode node = new UITestNode( test, true );
178 tests.Add( node );
179 testCaseCount += node.CountTestCases();
182 testSuite = null;
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 )
193 return new UITestNode( test );
196 #endregion
198 #region Properties
200 /// <summary>
201 /// The test description
202 /// </summary>
203 public string Description
205 get { return description; }
206 set { description = value; }
209 /// <summary>
210 /// The reason for ignoring a test
211 /// </summary>
212 public string IgnoreReason
214 get { return ignoreReason; }
215 set { ignoreReason = value; }
218 /// <summary>
219 /// True if the test should be run
220 /// </summary>
221 public bool ShouldRun
223 get { return shouldRun; }
224 set { shouldRun = value; }
227 /// <summary>
228 /// Full name of the test
229 /// </summary>
230 public string FullName
232 get { return fullName; }
235 /// <summary>
236 /// Name of the test
237 /// </summary>
238 public string Name
240 get { return testName; }
243 /// <summary>
244 /// Identifier for assembly containing this test
245 /// </summary>
246 public int AssemblyKey
248 get { return assemblyKey; }
249 set { assemblyKey = value; }
252 public string UniqueName
254 get{ return string.Format( "[{0}]{1}", assemblyKey, fullName ); }
257 /// <summary>
258 /// If the name is a path, this just returns the file part
259 /// </summary>
260 public string ShortName
264 string name = Name;
265 int val = name.LastIndexOf("\\");
266 if(val != -1)
267 name = name.Substring(val+1);
268 return name;
272 public bool IsExplicit
274 get { return isExplicit; }
275 set { isExplicit = value; }
278 public IList Categories
280 get { return categories; }
283 public bool HasCategory( string name )
285 return categories != null && categories.Contains( name );
288 public bool HasCategory( IList names )
290 if ( categories == null )
291 return false;
293 foreach( string name in names )
294 if ( categories.Contains( name ) )
295 return true;
297 return false;
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()
306 if ( !Populated )
307 PopulateTests();
309 return testCaseCount;
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
318 get
320 if ( !Populated )
321 PopulateTests();
323 return tests;
327 /// <summary>
328 /// True if this is a suite, false if a test case
329 /// </summary>
330 public bool IsSuite
332 get { return isSuite; }
335 /// <summary>
336 /// True if this is a test case, false if a suite
337 /// </summary>
338 public bool IsTestCase
340 get { return !isSuite; }
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
352 // A test case is obviously not a fixture
353 if ( IsTestCase ) return false;
355 // We have no way of constructing an empty suite unless it's a fixture
356 if ( Tests.Count == 0 ) return true;
358 // Any suite with children is a fixture if the children are test cases
359 UITestNode firstChild = (UITestNode)Tests[0];
360 return !firstChild.IsSuite;
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
370 get { return testSuite == null; }
373 public TestResult Run( EventListener listener )
375 throw new InvalidOperationException( "Cannot use Run on a local copy of Test data" );
378 #endregion