2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / nunit20 / core / TemplateTestCase.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.Text;
34         using System.Reflection;
35
36         /// <summary>
37         /// Summary description for TestCase.
38         /// </summary>
39         public abstract class TemplateTestCase : TestCase
40         {
41                 private MethodInfo  method;
42
43                 public TemplateTestCase(Type fixtureType, MethodInfo method) : base(fixtureType.FullName, method.Name)
44                 {
45                         this.fixtureType = fixtureType;
46                         this.method = method;
47                 }
48
49                 public TemplateTestCase(object fixture, MethodInfo method) : base(fixture.GetType().FullName, method.Name)
50                 {
51                         this.Fixture = fixture;
52                         this.fixtureType = fixture.GetType();
53                         this.method = method;
54                 }
55
56                 public override void Run(TestCaseResult testResult)
57                 { 
58                         if ( ShouldRun )
59                         {
60                                 bool doParentSetUp = false;
61                                 if ( Parent != null )
62                                 {
63                                         doParentSetUp = !Parent.IsSetUp;
64                                         
65                                 }
66
67                                 try
68                                 {
69                                         if ( doParentSetUp )
70                                                 Parent.DoSetUp( testResult );
71
72                                         if ( Fixture == null && Parent != null)
73                                                 Fixture = Parent.Fixture;
74
75                                         if ( !testResult.IsFailure )
76                                                 doRun( testResult );
77                                 }
78                                 catch(Exception ex)
79                                 {
80                                         if ( ex is NunitException )
81                                                 ex = ex.InnerException;
82
83                                         if ( ex is NUnit.Framework.IgnoreException )
84                                                 testResult.NotRun( ex.Message );
85                                         else
86                                                 RecordException( ex, testResult );
87                                 }
88                                 finally
89                                 {
90                                         if ( doParentSetUp )
91                                                 Parent.DoTearDown( testResult );
92                                 }
93                         }
94                         else
95                         {
96                                 testResult.NotRun(this.IgnoreReason);
97                         }
98                 }
99
100                 /// <summary>
101                 /// The doRun method is used to run a test internally.
102                 /// It assumes that the caller is taking care of any 
103                 /// TestFixtureSetUp and TestFixtureTearDown needed.
104                 /// </summary>
105                 /// <param name="testResult">The result in which to record success or failure</param>
106                 public void doRun( TestCaseResult testResult )
107                 {
108                         DateTime start = DateTime.Now;
109
110                         try 
111                         {
112                                 Reflect.InvokeSetUp( this.Fixture );
113                                 doTestCase( testResult );
114                         }
115                         catch(Exception ex)
116                         {
117                                 if ( ex is NunitException )
118                                         ex = ex.InnerException;
119
120                                 if ( ex is NUnit.Framework.IgnoreException )
121                                         testResult.NotRun( ex.Message );
122                                 else
123                                         RecordException( ex, testResult );
124                         }
125                         finally 
126                         {
127                                 doTearDown( testResult );
128
129                                 DateTime stop = DateTime.Now;
130                                 TimeSpan span = stop.Subtract(start);
131                                 testResult.Time = (double)span.Ticks / (double)TimeSpan.TicksPerSecond;
132                         }
133                 }
134
135                 #region Invoke Methods by Reflection, Recording Errors
136
137                 private void doTearDown( TestCaseResult testResult )
138                 {
139                         try
140                         {
141                                 Reflect.InvokeTearDown( this.Fixture );
142                         }
143                         catch(Exception ex)
144                         {
145                                 if ( ex is NunitException )
146                                         ex = ex.InnerException;
147                                 RecordException(ex, testResult, true);
148                         }
149                 }
150
151                 private void doTestCase( TestCaseResult testResult )
152                 {
153                         try
154                         {
155                                 Reflect.InvokeMethod( this.method, this.Fixture );
156                                 ProcessNoException(testResult);
157                         }
158                         catch( Exception ex )
159                         {
160                                 if ( ex is NunitException )
161                                         ex = ex.InnerException;
162
163                                 if ( ex is NUnit.Framework.IgnoreException )
164                                         testResult.NotRun( ex.Message );
165                                 else
166                                         ProcessException(ex, testResult);
167                         }
168                 }
169
170                 #endregion
171
172                 #region Record Info About An Exception
173
174                 protected void RecordException( Exception exception, TestCaseResult testResult )
175                 {
176                         RecordException( exception, testResult, false );
177                 }
178
179                 protected void RecordException( Exception exception, TestCaseResult testResult, bool inTearDown )
180                 {
181                         StringBuilder msg = new StringBuilder();
182                         StringBuilder st = new StringBuilder();
183                         
184                         if ( inTearDown )
185                         {
186                                 msg.Append( testResult.Message );
187                                 msg.Append( Environment.NewLine );
188                                 msg.Append( "TearDown : " );
189                                 st.Append( testResult.StackTrace );
190                                 st.Append( Environment.NewLine );
191                                 st.Append( "--TearDown" );
192                                 st.Append( Environment.NewLine );
193                         }
194
195                         msg.Append( BuildMessage( exception ) );
196                         st.Append( BuildStackTrace( exception ) );
197                         testResult.Failure( msg.ToString(), st.ToString() );
198                 }
199
200                 private string BuildMessage(Exception exception)
201                 {
202                         StringBuilder sb = new StringBuilder();
203                         if ( exception is NUnit.Framework.AssertionException )
204                                 sb.Append( exception.Message );
205                         else
206                                 sb.AppendFormat( "{0} : {1}", exception.GetType().ToString(), exception.Message );
207
208                         Exception inner = exception.InnerException;
209                         while( inner != null )
210                         {
211                                 sb.Append( Environment.NewLine );
212                                 sb.AppendFormat( "  ----> {0} : {1}", inner.GetType().ToString(), inner.Message );
213                                 inner = inner.InnerException;
214                         }
215
216                         return sb.ToString();
217                 }
218                 
219                 private string BuildStackTrace(Exception exception)
220                 {
221                         if(exception.InnerException!=null)
222                                 return exception.StackTrace + Environment.NewLine + 
223                                         "--" + exception.GetType().Name + Environment.NewLine +
224                                         BuildStackTrace(exception.InnerException);
225                         else
226                                 return exception.StackTrace;
227                 }
228
229                 #endregion
230
231                 #region Abstract Methods
232
233                 protected internal abstract void ProcessNoException(TestCaseResult testResult);
234                 
235                 protected internal abstract void ProcessException(Exception exception, TestCaseResult testResult);
236
237                 #endregion
238         }
239 }