2004-06-10 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / nunit20 / core / Test.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
36         /// <summary>
37         ///             Test Class.
38         /// </summary>
39         public abstract class Test : LongLivingMarshalByRefObject, ITest, IComparable
40         {
41                 #region Private Fields
42
43                 /// <summary>
44                 /// Name of the test
45                 /// </summary>
46                 private string testName;
47
48                 /// <summary>
49                 /// Full Name of the test
50                 /// </summary>
51                 private string fullName;
52                 
53                 /// <summary>
54                 /// Int used to distinguish suites of the same
55                 /// name across multiple assemblies.
56                 /// </summary>
57                 private int assemblyKey;
58                 
59                 /// <summary>
60                 /// Whether or not the test should be run
61                 /// </summary>
62                 private bool shouldRun;
63                 
64                 /// <summary>
65                 /// Reason for not running the test, if applicable
66                 /// </summary>
67                 private string ignoreReason;
68                 
69                 /// <summary>
70                 /// Description for this test 
71                 /// </summary>
72                 private string description;
73                 
74                 /// <summary>
75                 /// Test suite containing this test, or null
76                 /// </summary>
77                 private TestSuite parent;
78                 
79                 /// <summary>
80                 /// List of categories applying to this test
81                 /// </summary>
82                 private IList categories;
83
84                 /// <summary>
85                 /// True if the test had the Explicit attribute
86                 /// </summary>
87                 private bool isExplicit;
88
89                 #endregion
90
91                 #region Constructors
92
93                 public Test( string name ) : this( name, 0 ) { }
94
95                 public Test( string name, int assemblyKey )
96                 {
97                         fullName = testName = name;
98                         this.assemblyKey = assemblyKey;
99                 }
100
101                 protected Test( string pathName, string testName ) 
102                         : this( pathName, testName, 0 ) { }
103
104                 protected Test( string pathName, string testName, int assemblyKey ) 
105                 { 
106                         fullName = pathName + "." + testName;
107                         this.testName = testName;
108                         this.assemblyKey = assemblyKey;
109                         shouldRun = true;
110                 }
111
112                 #endregion
113
114                 #region Properties
115
116                 public string Name
117                 {
118                         get { return testName; }
119                 }
120
121                 public string FullName 
122                 {
123                         get { return fullName; }
124                 }
125
126                 /// <summary>
127                 /// If the name is a path, this just returns the file part
128                 /// </summary>
129                 public string ShortName
130                 {
131                         get
132                         {
133                                 string name = Name;
134                                 int val = name.LastIndexOf("\\");
135                                 if(val != -1)
136                                         name = name.Substring(val+1);
137                                 return name;
138                         }
139                 }
140
141                 /// <summary>
142                 /// Int used to distinguish suites of the same
143                 /// name across multiple assemblies.
144                 /// </summary>
145                 public int AssemblyKey
146                 {
147                         get { return assemblyKey; }
148                         set { assemblyKey = value; }
149                 }
150
151                 /// <summary>
152                 /// Key used to look up a test in a hash table
153                 /// </summary>
154                 public string UniqueName
155                 {
156                         get { return string.Format( "[{0}]{1}", assemblyKey, fullName ); }
157                 }
158
159                 /// <summary>
160                 /// Whether or not the test should be run
161                 /// </summary>
162                 public virtual bool ShouldRun
163                 {
164                         get { return shouldRun; }
165                         set { shouldRun = value; }
166                 }
167
168                 /// <summary>
169                 /// Reason for not running the test, if applicable
170                 /// </summary>
171                 public string IgnoreReason
172                 {
173                         get { return ignoreReason; }
174                         set { ignoreReason = value; }
175                 }
176
177                 public TestSuite Parent 
178                 {
179                         get { return parent; }
180                         set { parent = value; }
181                 }
182
183                 public string TestPath 
184                 {
185                         get
186                         {
187                                 string testPath = "";
188                                 if (parent != null)
189                                         testPath = parent.TestPath;
190                                 return testPath + FullName;
191                         }
192                 }
193
194                 public IList Categories 
195                 {
196                         get { return categories; }
197                         set { categories = value; }
198                 }
199
200                 public bool HasCategory( string name )
201                 {
202                         return categories != null && categories.Contains( name );
203                 }
204
205                 public bool HasCategory( IList names )
206                 {
207                         if ( categories == null )
208                                 return false;
209
210                         foreach( string name in names )
211                                 if ( categories.Contains( name ) )
212                                         return true;
213                         
214                         return false;
215                 }
216
217                 public bool IsDescendant(Test test) 
218                 {
219                         if (parent != null) 
220                         {
221                                 return parent == test || parent.IsDescendant(test);
222                         }
223
224                         return false;
225                 }
226
227                 public String Description
228                 {
229                         get { return description; }
230                         set { description = value; }
231                 }
232
233                 public bool IsExplicit
234                 {
235                         get { return isExplicit; }
236                         set { isExplicit = value; }
237                 }
238
239                 #endregion
240
241                 #region Abstract Methods and Properties
242
243                 /// <summary>
244                 /// Count of the test cases ( 1 if this is a test case )
245                 /// </summary>
246                 public abstract int CountTestCases();
247                 public abstract int CountTestCases(IFilter filter);
248                 
249                 public abstract bool IsSuite { get; }
250                 public abstract bool IsFixture{ get; }
251                 public abstract bool IsTestCase{ get; }
252                 public abstract ArrayList Tests { get; }
253
254                 public abstract bool Filter(IFilter filter);
255
256                 public abstract TestResult Run( EventListener listener );
257                 public abstract TestResult Run(EventListener listener, IFilter filter);
258
259                 #endregion
260
261                 #region Protected Helper Methods
262
263                 protected MethodInfo FindMethodByAttribute(object fixture, Type type)
264                 {
265                         foreach(MethodInfo method in fixture.GetType().GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.NonPublic))
266                         {
267                                 if(method.IsDefined(type,true)) 
268                                 {
269                                         return method;
270                                 }
271                         }
272                         return null;
273                 }
274
275                 protected void InvokeMethod(MethodInfo method, object fixture) 
276                 {
277                         if(method != null)
278                         {
279                                 try
280                                 {
281                                         method.Invoke(fixture, null);
282                                 }
283                                 catch(TargetInvocationException e)
284                                 {
285                                         Exception inner = e.InnerException;
286                                         throw new NunitException("Rethrown",inner);
287                                 }
288                         }
289                 }
290
291                 #endregion
292
293                 #region IComparable Members
294
295                 public int CompareTo(object obj)
296                 {
297                         Test other = obj as Test;
298                         
299                         if ( other == null )
300                                 return -1;
301
302                         return this.FullName.CompareTo( other.FullName );
303                 }
304
305                 #endregion
306         }
307 }