Files
linux-packaging-mono/external/nunit-lite/NUnitLite-1.0.0/src/framework/Runner/TextUI.cs
Xamarin Public Jenkins (auto-signing) ef583813eb Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
2019-07-26 19:53:28 +00:00

469 lines
18 KiB
C#

// ***********************************************************************
// Copyright (c) 2007 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using NUnit.Framework.Api;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Filters;
using System.Diagnostics;
namespace NUnitLite.Runner
{
/// <summary>
/// TextUI is a general purpose class that runs tests and
/// outputs to a TextWriter.
///
/// Call it from your Main like this:
/// new TextUI(textWriter).Execute(args);
/// OR
/// new TextUI().Execute(args);
/// The provided TextWriter is used by default, unless the
/// arguments to Execute override it using -out. The second
/// form uses the Console, provided it exists on the platform.
///
/// NOTE: When running on a platform without a Console, such
/// as Windows Phone, the results will simply not appear if
/// you fail to specify a file in the call itself or as an option.
/// </summary>
public class TextUI : ITestListener
{
private CommandLineOptions commandLineOptions;
private NUnit.ObjectList assemblies = new NUnit.ObjectList();
private TextWriter writer;
private ITestListener listener;
private ITestAssemblyRunner runner;
private FinallyDelegate finallyDelegate = new FinallyDelegate();
public bool Failure;
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="TextUI"/> class.
/// </summary>
public TextUI() : this(ConsoleWriter.Out, TestListener.NULL) { }
/// <summary>
/// Initializes a new instance of the <see cref="TextUI"/> class.
/// </summary>
/// <param name="writer">The TextWriter to use.</param>
public TextUI(TextWriter writer) : this(writer, TestListener.NULL) { }
/// <summary>
/// Initializes a new instance of the <see cref="TextUI"/> class.
/// </summary>
/// <param name="writer">The TextWriter to use.</param>
/// <param name="listener">The Test listener to use.</param>
public TextUI(TextWriter writer, ITestListener listener)
{
// Set the default writer - may be overridden by the args specified
this.writer = writer;
this.listener = listener;
}
void TopLevelHandler(object sender, UnhandledExceptionEventArgs e)
{
// Make sure that the test harness knows this exception was thrown
this.finallyDelegate.HandleUnhandledExc(e.ExceptionObject as Exception);
}
ITestAssemblyRunner DefaultRunner ()
{
return new NUnitLiteTestAssemblyRunner(new NUnitLiteTestAssemblyBuilder(), this.finallyDelegate);;
}
#if MONODROID_TOOLS
ITestAssemblyRunner AndroidRunner (string app)
{
return new Xamarin.AndroidTestAssemblyRunner(app);
}
#elif MONOTOUCH_TOOLS
ITestAssemblyRunner iOSRunner (string app)
{
throw new NotImplementedException ();
}
#elif WASM_TOOLS
ITestAssemblyRunner WebAssemblyRunner (string app)
{
throw new NotImplementedException ();
}
#endif
#endregion
#region Public Methods
/// <summary>
/// Execute a test run based on the aruments passed
/// from Main.
/// </summary>
/// <param name="args">An array of arguments</param>
public void Execute(string[] args)
{
this.commandLineOptions = new CommandLineOptions();
commandLineOptions.Parse(args);
if (runner == null) {
#if MONODROID_TOOLS
if (!string.IsNullOrEmpty (commandLineOptions.Android)) {
runner = AndroidRunner (commandLineOptions.Android);
} else if (!string.IsNullOrEmpty (commandLineOptions.Remote) && commandLineOptions.Remote.StartsWith ("android:")) {
Xamarin.AndroidRemoteRunner.App = commandLineOptions.Remote.Substring (8);
runner = DefaultRunner ();
} else
#elif MONOTOUCH_TOOLS
if (!string.IsNullOrEmpty (commandLineOptions.iOS)) {
runner = iOSRunner (commandLineOptions.iOS);
} else if (!string.IsNullOrEmpty (commandLineOptions.Remote) && commandLineOptions.Remote.StartsWith ("ios:")) {
// Xamarin.iOSRemoteRunner.App = commandLineOptions.Remote.Substring (4);
// runner = DefaultRunner ();
throw new NotImplementedException ();
} else
#elif WASM_TOOLS
if (!string.IsNullOrEmpty (commandLineOptions.WebAssembly)) {
runner = WebAssemblyRunner (commandLineOptions.WebAssembly);
} else if (!string.IsNullOrEmpty (commandLineOptions.Remote) && commandLineOptions.Remote.StartsWith ("wasm:")) {
// Xamarin.WebAssemblyRemoteRunner.App = commandLineOptions.Remote.Substring (5);
// runner = DefaultRunner ();
throw new NotImplementedException ();
} else
#endif
{
runner = DefaultRunner ();
}
}
if (commandLineOptions.OutFile != null)
this.writer = new StreamWriter(commandLineOptions.OutFile);
if (!commandLineOptions.NoHeader)
WriteHeader(this.writer);
if (commandLineOptions.ShowHelp)
writer.Write(commandLineOptions.HelpText);
else if (commandLineOptions.Error)
{
writer.WriteLine(commandLineOptions.ErrorMessage);
writer.WriteLine(commandLineOptions.HelpText);
}
else
{
WriteRuntimeEnvironment(this.writer);
if (commandLineOptions.Wait && commandLineOptions.OutFile != null)
writer.WriteLine("Ignoring /wait option - only valid for Console");
#if SILVERLIGHT
IDictionary loadOptions = new System.Collections.Generic.Dictionary<string, string>();
#else
IDictionary loadOptions = new Hashtable();
#endif
//if (options.Load.Count > 0)
// loadOptions["LOAD"] = options.Load;
//IDictionary runOptions = new Hashtable();
//if (commandLineOptions.TestCount > 0)
// runOptions["RUN"] = commandLineOptions.Tests;
ITestFilter filter = commandLineOptions.TestCount > 0
? new SimpleNameFilter(commandLineOptions.Tests)
: TestFilter.Empty;
try
{
foreach (string name in commandLineOptions.Parameters) {
try {
assemblies.Add(Assembly.LoadFrom(name));
}
catch (FileNotFoundException/* e*/) {
assemblies.Add(Assembly.Load(name));
}
}
if (assemblies.Count == 0) {
// NOTE: Execute must be directly called from the
// test assembly in order for the mechanism to work.
Assembly callingAssembly = Assembly.GetCallingAssembly();
assemblies.Add(callingAssembly);
}
// TODO: For now, ignore all but first assembly
Assembly assembly = assemblies[0] as Assembly;
Randomizer.InitialSeed = commandLineOptions.InitialSeed;
if (!runner.Load(assembly, loadOptions))
{
AssemblyName assemblyName = AssemblyHelper.GetAssemblyName(assembly);
Console.WriteLine("No tests found in assembly {0}", assemblyName.Name);
return;
}
if (commandLineOptions.Explore)
ExploreTests();
else
{
if (commandLineOptions.Include != null && commandLineOptions.Include != string.Empty)
{
TestFilter includeFilter = new SimpleCategoryExpression(commandLineOptions.Include).Filter;
if (filter.IsEmpty)
filter = includeFilter;
else
filter = new AndFilter(filter, includeFilter);
}
if (commandLineOptions.Exclude != null && commandLineOptions.Exclude != string.Empty)
{
TestFilter excludeFilter = new NotFilter(new SimpleCategoryExpression(commandLineOptions.Exclude).Filter);
if (filter.IsEmpty)
filter = excludeFilter;
else if (filter is AndFilter)
((AndFilter)filter).Add(excludeFilter);
else
filter = new AndFilter(filter, excludeFilter);
}
#if MONO
filter = Xamarin.BabysitterSupport.AddBabysitterFilter(filter);
#endif
RunTests(filter);
}
}
catch (FileNotFoundException ex)
{
Failure = true;
writer.WriteLine(ex.Message);
}
catch (Exception ex)
{
Failure = true;
writer.WriteLine(ex.ToString());
}
finally
{
if (commandLineOptions.OutFile == null)
{
if (commandLineOptions.Wait)
{
Console.WriteLine("Press Enter key to continue . . .");
Console.ReadLine();
}
}
else
{
writer.Close();
}
}
}
}
/// <summary>
/// Write the standard header information to a TextWriter.
/// </summary>
/// <param name="writer">The TextWriter to use</param>
public static void WriteHeader(TextWriter writer)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
#if NUNITLITE
string title = "NUnitLite";
#else
string title = "NUNit Framework";
#endif
AssemblyName assemblyName = AssemblyHelper.GetAssemblyName(executingAssembly);
System.Version version = assemblyName.Version;
string copyright = "Copyright (C) 2012, Charlie Poole";
string build = "";
object[] attrs = executingAssembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attrs.Length > 0)
{
AssemblyTitleAttribute titleAttr = (AssemblyTitleAttribute)attrs[0];
title = titleAttr.Title;
}
attrs = executingAssembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attrs.Length > 0)
{
AssemblyCopyrightAttribute copyrightAttr = (AssemblyCopyrightAttribute)attrs[0];
copyright = copyrightAttr.Copyright;
}
attrs = executingAssembly.GetCustomAttributes(typeof(AssemblyConfigurationAttribute), false);
if (attrs.Length > 0)
{
AssemblyConfigurationAttribute configAttr = (AssemblyConfigurationAttribute)attrs[0];
if (configAttr.Configuration.Length > 0)
build = string.Format("({0})", configAttr.Configuration);
}
writer.WriteLine(String.Format("{0} {1} {2}", title, version.ToString(3), build));
writer.WriteLine(copyright);
writer.WriteLine();
}
/// <summary>
/// Write information about the current runtime environment
/// </summary>
/// <param name="writer">The TextWriter to be used</param>
public static void WriteRuntimeEnvironment(TextWriter writer)
{
string clrPlatform = Type.GetType("Mono.Runtime", false) == null ? ".NET" : "Mono";
writer.WriteLine("Runtime Environment -");
writer.WriteLine(" OS Version: {0}", Environment.OSVersion);
writer.WriteLine(" {0} Version: {1}", clrPlatform, Environment.Version);
writer.WriteLine();
}
#endregion
#region Helper Methods
private void RunTests(ITestFilter filter)
{
DateTime startTime = DateTime.Now;
var crashHandler = new UnhandledExceptionEventHandler(TopLevelHandler);
AppDomain.CurrentDomain.UnhandledException += crashHandler;
ITestResult result = runner.Run(this, filter);
new ResultReporter(result, writer).ReportResults();
string resultFile = commandLineOptions.ResultFile;
string resultFormat = commandLineOptions.ResultFormat;
this.Failure = (result.ResultState.Equals(ResultState.Failure) || result.ResultState.Equals(ResultState.Error));
if (resultFile != null || commandLineOptions.ResultFormat != null)
{
if (resultFile == null)
resultFile = "TestResult.xml";
if (resultFormat == "nunit2")
new NUnit2XmlOutputWriter(startTime).WriteResultFile(result, resultFile);
else if (resultFormat == "nunit3")
new NUnit3XmlOutputWriter(startTime).WriteResultFile(result, resultFile);
#if MONO
else if (resultFormat == "xunit")
new XunitXmlOutputWriter(startTime).WriteResultFile(result, resultFile);
#endif
else
throw new Exception("Unknown resultFormat.");
Console.WriteLine();
Console.WriteLine("Results saved as {0}.", resultFile);
}
AppDomain.CurrentDomain.UnhandledException -= crashHandler;
}
private void ExploreTests()
{
XmlNode testNode = runner.LoadedTest.ToXml(true);
string listFile = commandLineOptions.ExploreFile;
TextWriter textWriter = listFile != null && listFile.Length > 0
? new StreamWriter(listFile)
: Console.Out;
#if CLR_2_0 || CLR_4_0
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
settings.Indent = true;
settings.Encoding = System.Text.Encoding.UTF8;
System.Xml.XmlWriter testWriter = System.Xml.XmlWriter.Create(textWriter, settings);
#else
System.Xml.XmlTextWriter testWriter = new System.Xml.XmlTextWriter(textWriter);
testWriter.Formatting = System.Xml.Formatting.Indented;
#endif
testNode.WriteTo(testWriter);
testWriter.Close();
Console.WriteLine();
Console.WriteLine("Test info saved as {0}.", listFile);
}
#endregion
#region ITestListener Members
/// <summary>
/// A test has just started
/// </summary>
/// <param name="test">The test</param>
public void TestStarted(ITest test)
{
#if MONO
if (!test.IsSuite)
Xamarin.BabysitterSupport.RecordEnterTest(test.FullName);
if (commandLineOptions.LabelTestsInOutput)
writer.WriteLine("***** {0}", test.FullName);
else
writer.Write(".");
#else
if (commandLineOptions.LabelTestsInOutput)
writer.WriteLine("***** {0}", test.Name);
#endif
}
/// <summary>
/// A test has just finished
/// </summary>
/// <param name="result">The result of the test</param>
public void TestFinished(ITestResult result)
{
#if MONO
if (!result.Test.IsSuite) {
Xamarin.BabysitterSupport.RecordLeaveTest (result.Test.FullName);
if (result.ResultState.Status == TestStatus.Failed)
{
Xamarin.BabysitterSupport.RecordFailedTest (result.Test.FullName);
if (!commandLineOptions.LabelTestsInOutput)
writer.Write("F");
}
}
#endif
}
/// <summary>
/// A test has produced some text output
/// </summary>
/// <param name="testOutput">A TestOutput object holding the text that was written</param>
public void TestOutput(TestOutput testOutput)
{
}
#endregion
}
}