namespace NUnit.Runner { using System; using System.Collections; using System.Collections.Specialized; using System.IO; using System.IO.IsolatedStorage; using System.Reflection; using NUnit.Framework; /// /// Base class for all test runners. /// /// /// /// public abstract class BaseTestRunner: MarshalByRefObject, ITestListener { /// /// /// [Obsolete("Shoud be handled by a loader")] public static string SUITE_PROPERTYNAME="Suite"; private static NameValueCollection fPreferences = new NameValueCollection(); private static int fgMaxMessageLength = 500; private static bool fgFilterStack = true; private bool fLoading = true; /// /// /// public BaseTestRunner() { fPreferences = new NameValueCollection(); fPreferences.Add("loading", "true"); fPreferences.Add("filterstack", "true"); ReadPreferences(); fgMaxMessageLength = GetPreference("maxmessage", fgMaxMessageLength); } #region ITestListener Methods /// /// /// /// /// public abstract void AddError(ITest test, Exception t); /// /// /// /// /// public abstract void AddFailure(ITest test, AssertionFailedError t); /// /// /// /// public abstract void EndTest(ITest test); #endregion #if false /// /// Clears the status message. /// protected virtual void ClearStatus() { // Belongs in the GUI TestRunner class. } #endif /// /// Returns the formatted string of the elapsed time. /// public static string ElapsedTimeAsString(long runTime) { return ((double)runTime/1000).ToString(); } /// /// Extract the class name from a string in VA/Java style /// public static string ExtractClassName(string className) { if(className.StartsWith("Default package for")) return className.Substring(className.LastIndexOf(".")+1); return className; } static bool FilterLine(string line) { string[] patterns = new string[] { "NUnit.Framework.TestCase", "NUnit.Framework.TestResult", "NUnit.Framework.TestSuite", "NUnit.Framework.Assertion." // don't filter AssertionFailure }; for (int i = 0; i < patterns.Length; i++) { if (line.IndexOf(patterns[i]) > 0) return true; } return false; } /// /// Filters stack frames from internal NUnit classes /// public static string FilterStack(string stack) { string pref = GetPreference("filterstack"); if (((pref != null) && !GetPreference("filterstack").Equals("true")) || fgFilterStack == false) return stack; StringWriter sw = new StringWriter(); StringReader sr = new StringReader(stack); try { string line; while ((line = sr.ReadLine()) != null) { if (!FilterLine(line)) sw.WriteLine(line); } } catch (Exception) { return stack; // return the stack unfiltered } return sw.ToString(); } /// /// /// /// /// public static string GetFilteredTrace(Exception t) { return BaseTestRunner.FilterStack(t.StackTrace); } /// /// /// /// /// public static string GetPreference(string key) { return fPreferences.Get(key); } private static int GetPreference(String key, int dflt) { String value= GetPreference(key); int intValue= dflt; if (value != null) { try { intValue= int.Parse(value); } catch (FormatException) {} } return intValue; } private static FileStream GetPreferencesFile() { return new IsolatedStorageFileStream("NUnit.Prefs", FileMode.OpenOrCreate); } /// /// /// /// public virtual ITestLoader GetLoader() { if (UseReloadingTestSuiteLoader()) return new UnloadingLoader(); return new StandardLoader(); } /// /// Returns the ITest corresponding to the given suite. This is /// a template method, subclasses override RunFailed(), ClearStatus(). /// public ITest GetTest(string suiteClassName) { ITest test = null; try { test = LoadSuiteClass(suiteClassName); } catch (TypeLoadException e) { RunFailed(e.Message); return null; } catch (Exception e) { RunFailed("Error: " + e.ToString()); return null; } //ClearStatus(); return test; } /// /// Returns the loaded Class for a suite name. /// protected ITest LoadSuiteClass(string suiteClassName) { return GetLoader().LoadTest(suiteClassName); } private static void ReadPreferences() { FileStream fs= null; try { fs= GetPreferencesFile(); fPreferences= new NameValueCollection(fPreferences); ReadPrefsFromFile(ref fPreferences, fs); } catch (IOException) { try { if (fs != null) fs.Close(); } catch (IOException) { } } } /// /// Real method reads name/value pairs, populates, or maybe just /// deserializes... /// /// /// private static void ReadPrefsFromFile(ref NameValueCollection prefs, FileStream fs) { } /// /// Override to define how to handle a failed loading of a test suite. /// protected abstract void RunFailed(string message); /// /// Truncates a String to the maximum length. /// /// /// public static string Truncate(string message) { if (fgMaxMessageLength != -1 && message.Length > fgMaxMessageLength) message = message.Substring(0, fgMaxMessageLength)+"..."; return message; } /// /// /// /// public abstract void StartTest(ITest test); /// /// /// /// /// /// protected string ProcessArguments(string[] args, ref bool wait) { string suiteName=""; wait = false; foreach (string arg in args) { if (arg.Equals("/noloading")) SetLoading(false); else if (arg.Equals("/nofilterstack")) fgFilterStack = false; else if (arg.Equals("/wait")) wait = true; else if (arg.Equals("/c")) suiteName= ExtractClassName(arg); else if (arg.Equals("/v")) { Console.Error.WriteLine("NUnit "+NUnit.Runner.Version.id() + " by Philip Craig"); Console.Error.WriteLine("ported from JUnit 3.6 by Kent Beck" + " and Erich Gamma"); } else suiteName = arg; } return suiteName; } /// /// Sets the loading behaviour of the test runner /// protected void SetLoading(bool enable) { fLoading = enable; } /// /// /// /// protected bool UseReloadingTestSuiteLoader() { return bool.TrueString.Equals( GetPreference("loading")) && fLoading; } } }