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-2003 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
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 © 2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright © 2000-2003 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 '***********************************************************************************/
30 namespace NUnit
.Console
33 using System
.Collections
;
34 using System
.Collections
.Specialized
;
36 using System
.Reflection
;
39 using System
.Xml
.XPath
;
40 using System
.Resources
;
42 using System
.Text
.RegularExpressions
;
43 using System
.Diagnostics
;
49 /// Summary description for ConsoleUi.
51 public class ConsoleUi
54 public static int Main(string[] args
)
56 ConsoleOptions options
= new ConsoleOptions(args
);
68 Console
.Error
.WriteLine("fatal error: no inputs specified");
73 if(!options
.Validate())
75 Console
.Error
.WriteLine("fatal error: invalid arguments");
82 ConsoleUi consoleUi
= new ConsoleUi();
83 return consoleUi
.Execute( options
);
85 catch( FileNotFoundException ex
)
87 Console
.WriteLine( ex
.Message
);
90 catch( BadImageFormatException ex
)
92 Console
.WriteLine( ex
.Message
);
97 Console
.WriteLine( "Unhandled Exception:\n{0}", ex
.ToString() );
104 Console
.Out
.WriteLine("\nHit <enter> key to continue");
110 private static XmlTextReader
GetTransformReader(ConsoleOptions parser
)
112 XmlTextReader reader
= null;
113 if(!parser
.IsTransform
)
115 Assembly assembly
= Assembly
.GetAssembly(typeof(XmlResultVisitor
));
116 ResourceManager resourceManager
= new ResourceManager("NUnit.Util.Transform",assembly
);
117 string xmlData
= (string)resourceManager
.GetObject("Summary.xslt");
119 reader
= new XmlTextReader(new StringReader(xmlData
));
123 FileInfo xsltInfo
= new FileInfo(parser
.transform
);
126 Console
.Error
.WriteLine("Transform file: {0} does not exist", xsltInfo
.FullName
);
131 reader
= new XmlTextReader(xsltInfo
.FullName
);
138 private static void WriteCopyright()
140 Assembly executingAssembly
= Assembly
.GetExecutingAssembly();
141 System
.Version version
= executingAssembly
.GetName().Version
;
143 object[] objectAttrs
= executingAssembly
.GetCustomAttributes(typeof(AssemblyProductAttribute
), false);
144 AssemblyProductAttribute productAttr
= (AssemblyProductAttribute
)objectAttrs
[0];
146 objectAttrs
= executingAssembly
.GetCustomAttributes(typeof(AssemblyCopyrightAttribute
), false);
147 AssemblyCopyrightAttribute copyrightAttr
= (AssemblyCopyrightAttribute
)objectAttrs
[0];
149 Console
.WriteLine(String
.Format("{0} version {1}", productAttr
.Product
, version
.ToString(3)));
150 Console
.WriteLine(copyrightAttr
.Copyright
);
153 string clrPlatform
= Type
.GetType("Mono.Runtime", false) == null ? ".NET" : "Mono";
154 Console
.WriteLine( string.Format("OS Version: {0} {1} Version: {2}",
155 Environment
.OSVersion
, clrPlatform
, Environment
.Version
) );
159 private static Test
MakeTestFromCommandLine(TestDomain testDomain
, ConsoleOptions parser
)
161 NUnitProject project
;
163 if ( parser
.IsTestProject
)
165 project
= NUnitProject
.LoadProject( (string)parser
.Parameters
[0] );
166 string configName
= (string) parser
.config
;
167 if ( configName
!= null )
168 project
.SetActiveConfig( configName
);
171 project
= NUnitProject
.FromAssemblies( (string[])parser
.Parameters
.ToArray( typeof( string ) ) );
173 return testDomain
.Load( project
, parser
.fixture
);
180 public int Execute( ConsoleOptions options
)
182 XmlTextReader transformReader
= GetTransformReader(options
);
183 if(transformReader
== null) return 3;
185 ConsoleWriter outStream
= options
.isOut
186 ? new ConsoleWriter( new StreamWriter( options
.output
) )
187 : new ConsoleWriter(Console
.Out
);
189 ConsoleWriter errorStream
= options
.isErr
190 ? new ConsoleWriter( new StreamWriter( options
.err
) )
191 : new ConsoleWriter(Console
.Error
);
193 TestDomain testDomain
= new TestDomain(outStream
, errorStream
);
194 if ( options
.noshadow
) testDomain
.ShadowCopyFiles
= false;
196 Test test
= MakeTestFromCommandLine(testDomain
, options
);
200 Console
.Error
.WriteLine("Unable to locate fixture {0}", options
.fixture
);
204 Directory
.SetCurrentDirectory(new FileInfo((string)options
.Parameters
[0]).DirectoryName
);
206 EventListener collector
= new EventCollector( options
, outStream
);
208 string savedDirectory
= Environment
.CurrentDirectory
;
210 if (options
.HasInclude
)
212 Console
.WriteLine( "Included categories: " + options
.include
);
213 testDomain
.SetFilter( new CategoryFilter( options
.IncludedCategories
) );
215 else if ( options
.HasExclude
)
217 Console
.WriteLine( "Excluded categories: " + options
.exclude
);
218 testDomain
.SetFilter( new CategoryFilter( options
.ExcludedCategories
, true ) );
221 TestResult result
= null;
222 if ( options
.thread
)
224 testDomain
.RunTest( collector
);
226 result
= testDomain
.Result
;
230 result
= testDomain
.Run( collector
);
233 Directory
.SetCurrentDirectory( savedDirectory
);
237 string xmlOutput
= CreateXmlOutput( result
);
239 if (options
.xmlConsole
)
240 Console
.WriteLine(xmlOutput
);
242 CreateSummaryDocument(xmlOutput
, transformReader
);
244 // Write xml output here
245 string xmlResultFile
= options
.IsXml
? options
.xml
: "TestResult.xml";
247 using ( StreamWriter writer
= new StreamWriter( xmlResultFile
) )
249 writer
.Write(xmlOutput
);
252 if ( testDomain
!= null )
255 return result
.IsFailure
? 1 : 0;
258 private string CreateXmlOutput( TestResult result
)
260 StringBuilder builder
= new StringBuilder();
261 XmlResultVisitor resultVisitor
= new XmlResultVisitor(new StringWriter( builder
), result
);
262 result
.Accept(resultVisitor
);
263 resultVisitor
.Write();
265 return builder
.ToString();
268 private void CreateSummaryDocument(string xmlOutput
, XmlTextReader transformReader
)
270 XPathDocument originalXPathDocument
= new XPathDocument(new StringReader(xmlOutput
));
271 XslTransform summaryXslTransform
= new XslTransform();
273 // Using obsolete form for now, remove warning suppression from project after changing
274 summaryXslTransform
.Load(transformReader
);
276 // Using obsolete form for now, remove warning suppression from project after changing
277 summaryXslTransform
.Transform(originalXPathDocument
,null,Console
.Out
);
280 #region Nested Class to Handle Events
282 private class EventCollector
: LongLivingMarshalByRefObject
, EventListener
284 private int testRunCount
;
285 private int testIgnoreCount
;
286 private int failureCount
;
289 private ConsoleOptions options
;
290 private ConsoleWriter writer
;
292 StringCollection messages
;
294 private bool debugger
= false;
295 private string currentTestName
;
297 public EventCollector( ConsoleOptions options
, ConsoleWriter writer
)
299 debugger
= Debugger
.IsAttached
;
301 this.options
= options
;
302 this.writer
= writer
;
303 this.currentTestName
= string.Empty
;
306 public void RunStarted(Test
[] tests
)
310 public void RunFinished(TestResult
[] results
)
314 public void RunFinished(Exception exception
)
318 public void TestFinished(TestCaseResult testResult
)
320 if ( !options
.xmlConsole
&& !options
.labels
)
322 if(testResult
.Executed
)
326 if(testResult
.IsFailure
)
332 messages
.Add( string.Format( "{0}) {1} :", failureCount
, testResult
.Test
.FullName
) );
333 messages
.Add( testResult
.Message
.Trim( Environment
.NewLine
.ToCharArray() ) );
335 string stackTrace
= StackTraceFilter
.Filter( testResult
.StackTrace
);
336 string[] trace
= stackTrace
.Split( System
.Environment
.NewLine
.ToCharArray() );
337 foreach( string s
in trace
)
339 if ( s
!= string.Empty
)
341 string link
= Regex
.Replace( s
.Trim(), @".* in (.*):line (.*)", "$1($2)");
342 messages
.Add( string.Format( "at\n{0}", link
) );
355 currentTestName
= string.Empty
;
358 public void TestStarted(TestCase testCase
)
360 currentTestName
= testCase
.FullName
;
362 if ( options
.labels
)
363 writer
.WriteLine("***** {0}", testCase
.FullName
);
364 else if ( !options
.xmlConsole
)
368 public void SuiteStarted(TestSuite suite
)
370 if ( debugger
&& level
++ == 0 )
372 messages
= new StringCollection();
376 Trace
.WriteLine( "################################ UNIT TESTS ################################" );
377 Trace
.WriteLine( "Running tests in '" + suite
.FullName
+ "'..." );
381 public void SuiteFinished(TestSuiteResult suiteResult
)
383 if ( debugger
&& --level
== 0)
385 Trace
.WriteLine( "############################################################################" );
387 if (messages
.Count
== 0)
389 Trace
.WriteLine( "############## S U C C E S S #################" );
393 Trace
.WriteLine( "############## F A I L U R E S #################" );
395 foreach ( string s
in messages
)
401 Trace
.WriteLine( "############################################################################" );
402 Trace
.WriteLine( "Executed tests : " + testRunCount
);
403 Trace
.WriteLine( "Ignored tests : " + testIgnoreCount
);
404 Trace
.WriteLine( "Failed tests : " + failureCount
);
405 Trace
.WriteLine( "Total time : " + suiteResult
.Time
+ " seconds" );
406 Trace
.WriteLine( "############################################################################");
410 public void UnhandledException( Exception exception
)
412 string msg
= string.Format( "##### Unhandled Exception while running {0}", currentTestName
);
414 // If we do labels, we already have a newline
415 if ( !options
.labels
) writer
.WriteLine();
416 writer
.WriteLine( msg
);
417 writer
.WriteLine( exception
.ToString() );
421 Trace
.WriteLine( msg
);
422 Trace
.WriteLine( exception
.ToString() );