ff2229a5ec68d451a96d66649bd389172146c167
[mono.git] / mcs / nunit20 / util / UITestNode.cs
1 #region Copyright (c) 2002, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Philip A. Craig
2 /************************************************************************************
3 '
4 ' Copyright © 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
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 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov 
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 : TestInfo
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                 /// True if the test should be run
57                 /// </summary>
58                 private bool shouldRun;
59
60                 /// <summary>
61                 /// Reason for not running the test
62                 /// </summary>
63                 private string ignoreReason;
64
65                 /// <summary>
66                 /// Number of test cases in this test or suite
67                 /// </summary>
68                 private int testCaseCount;
69
70                 /// <summary>
71                 /// For a test suite, the child tests or suites
72                 /// Null if this is not a test suite
73                 /// </summary>
74                 private ArrayList tests;
75
76                 /// <summary>
77                 /// True if this is a suite
78                 /// </summary>
79                 private bool isSuite;
80
81                 /// <summary>
82                 /// Interface of the test suite from which this 
83                 /// object was constructed. Used for deferred 
84                 /// population of the object.
85                 /// </summary>
86                 private TestInfo testSuite;
87
88                 #endregion
89
90                 #region Construction and Conversion
91
92                 /// <summary>
93                 /// Construct from a TestInfo interface, which might be
94                 /// a Test or another UITestNode. Optionally, populate
95                 /// the array of child tests.
96                 /// </summary>
97                 /// <param name="test">TestInfo interface from which a UITestNode is to be constructed</param>
98                 /// <param name="populate">True if child array is to be populated</param>
99                 public UITestNode ( TestInfo test, bool populate )
100                 {
101                         fullName = test.FullName;
102                         testName = test.Name;
103                         shouldRun = test.ShouldRun;
104                         ignoreReason = test.IgnoreReason;
105                         
106                         if ( test.IsSuite )
107                         {
108                                 testCaseCount = 0;
109                                 testSuite = test;
110                                 isSuite = true;
111
112                                 tests = new ArrayList();
113
114                                 if ( populate ) PopulateTests();
115                         }
116                         else
117                         {
118                                 testCaseCount = 1;
119                                 isSuite = false;
120                         }
121                 }
122
123                 /// <summary>
124                 /// Default construction uses lazy population approach
125                 /// </summary>
126                 /// <param name="test"></param>
127                 public UITestNode ( TestInfo test ) : this( test, false ) { }
128
129                 /// <summary>
130                 /// Populate the arraylist of child Tests recursively.
131                 /// If already populated, it has no effect.
132                 /// </summary>
133                 public void PopulateTests()
134                 {
135                         if ( !Populated )
136                         {
137                                 foreach( Test test in testSuite.Tests )
138                                 {
139                                         UITestNode node = new UITestNode( test, true );
140                                         tests.Add( node );
141                                         testCaseCount += node.CountTestCases;
142                                 }
143
144                                 testSuite = null;
145                         }
146                 }
147
148                 /// <summary>
149                 /// Allow implicit conversion of a Test to a TestInfo
150                 /// </summary>
151                 /// <param name="test"></param>
152                 /// <returns></returns>
153                 public static implicit operator UITestNode( Test test )
154                 {
155                         return new UITestNode( test );
156                 }
157
158                 #endregion
159
160                 #region Properties
161
162                 /// <summary>
163                 /// The reason for ignoring a test
164                 /// </summary>
165                 public string IgnoreReason
166                 {
167                         get { return ignoreReason; }
168                         set { ignoreReason = value; }
169                 }
170
171                 /// <summary>
172                 /// True if the test should be run
173                 /// </summary>
174                 public bool ShouldRun
175                 {
176                         get { return shouldRun; }
177                         set { shouldRun = value; }
178                 }
179
180                 /// <summary>
181                 /// Full name of the test
182                 /// </summary>
183                 public string FullName 
184                 {
185                         get { return fullName; }
186                 }
187
188                 /// <summary>
189                 /// Name of the test
190                 /// </summary>
191                 public string Name
192                 {
193                         get { return testName; }
194                 }
195
196                 /// <summary>
197                 /// If the name is a path, this just returns the file part
198                 /// </summary>
199                 public string ShortName
200                 {
201                         get
202                         {
203                                 string name = Name;
204                                 int val = name.LastIndexOf("\\");
205                                 if(val != -1)
206                                         name = name.Substring(val+1);
207                                 return name;
208                         }
209                 }
210
211                 /// <summary>
212                 /// Count of test cases in this test. If the suite
213                 /// has never been populated, it will be done now.
214                 /// </summary>
215                 public int CountTestCases
216                 { 
217                         get 
218                         { 
219                                 if ( !Populated )
220                                         PopulateTests();
221
222                                 return testCaseCount; 
223                         }
224                 }
225
226                 /// <summary>
227                 /// Array of child tests, null if this is a test case.
228                 /// The array is populated on access if necessary.
229                 /// </summary>
230                 public ArrayList Tests 
231                 {
232                         get 
233                         {
234                                 if ( !Populated )
235                                         PopulateTests();
236
237                                 return tests;
238                         }
239                 }
240
241                 /// <summary>
242                 /// True if this is a suite, false if a test case
243                 /// </summary>
244                 public bool IsSuite
245                 {
246                         get { return isSuite; }
247                 }
248
249                 /// <summary>
250                 /// True if this is a test case, false if a suite
251                 /// </summary>
252                 public bool IsTestCase
253                 {
254                         get { return !isSuite; }
255                 }
256
257                 /// <summary>
258                 /// True if this is a fixture. May populate the test's
259                 /// children as a side effect.
260                 /// TODO: An easier way to tell this?
261                 /// </summary>
262                 public bool IsFixture
263                 {
264                         get
265                         {
266                                 // A test case is obviously not a fixture
267                                 if ( IsTestCase ) return false;
268
269                                 // We have no way of constructing an empty suite unless it's a fixture
270                                 if ( Tests.Count == 0 ) return true;
271                                 
272                                 // Any suite with children is a fixture if the children are test cases
273                                 UITestNode firstChild = (UITestNode)Tests[0];
274                                 return !firstChild.IsSuite;
275                         }
276                 }
277
278                 /// <summary>
279                 /// False for suites that have not yet been populated
280                 /// with their children, otherwise true - used for testing.
281                 /// </summary>
282                 public bool Populated
283                 {
284                         get { return testSuite == null; }
285                 }
286
287                 public TestResult Run( EventListener listener )
288                 {
289                         throw new InvalidOperationException( "Cannot use Run on a local copy of Test data" );
290                 }
291
292                 #endregion
293         }
294 }