From 705964dddd0d42f223a2f0f0c409ba5c547b92f4 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 14 May 2020 16:26:34 +0200 Subject: [PATCH] [Touch.Client] Add a client that uses MonoTouch.Dialog and NUnitLite from NuGet. (#63) * [TouchRunner] Add an extension method to get a result's duration. * [TouchRunner] A TestSuite's name can't be empty in recent versions of NUnit. * [TouchRunner] Use usings. * [Touch.Client] Add a client that uses MonoTouch.Dialog and NUnitLite from NuGet. --- .../TouchRunner/NUnitOutputTextWriter.cs | 4 + NUnitLite/TouchRunner/TestCaseElement.cs | 10 +- NUnitLite/TouchRunner/TestElement.cs | 4 + NUnitLite/TouchRunner/TestRocks.cs | 24 +++ NUnitLite/TouchRunner/TestSuiteElement.cs | 2 +- NUnitLite/TouchRunner/TouchRunner.cs | 146 ++++++++++++++++-- Touch.Client/Touch.Client.csproj | 102 ++++++++++++ Touch.Unit.sln | 18 +++ 8 files changed, 297 insertions(+), 13 deletions(-) create mode 100644 Touch.Client/Touch.Client.csproj diff --git a/NUnitLite/TouchRunner/NUnitOutputTextWriter.cs b/NUnitLite/TouchRunner/NUnitOutputTextWriter.cs index 1352d44..b625c81 100644 --- a/NUnitLite/TouchRunner/NUnitOutputTextWriter.cs +++ b/NUnitLite/TouchRunner/NUnitOutputTextWriter.cs @@ -22,7 +22,11 @@ using System.IO; using System.Text; +#if NUNITLITE_NUGET +using NUnitLite; +#else using NUnitLite.Runner; +#endif using MonoTouch.NUnit.UI; namespace MonoTouch.NUnit { diff --git a/NUnitLite/TouchRunner/TestCaseElement.cs b/NUnitLite/TouchRunner/TestCaseElement.cs index eebfa60..ddc4b7e 100644 --- a/NUnitLite/TouchRunner/TestCaseElement.cs +++ b/NUnitLite/TouchRunner/TestCaseElement.cs @@ -27,7 +27,11 @@ using NUnit.Framework; using NUnit.Framework.Internal; +#if NUNITLITE_NUGET +using NUnit.Framework.Interfaces; +#else using NUnit.Framework.Api; +#endif namespace MonoTouch.NUnit.UI { @@ -43,12 +47,16 @@ public TestCaseElement (TestMethod testCase, TouchRunner runner) return; var suite = (testCase.Parent as TestSuite); +#if NUNITLITE_NUGET + Run (); +#else var context = TestExecutionContext.CurrentContext; context.TestObject = Reflect.Construct (testCase.Method.ReflectedType, null); suite.GetOneTimeSetUpCommand ().Execute (context); Run (); suite.GetOneTimeTearDownCommand ().Execute (context); +#endif Runner.CloseWriter (); // display more details on (any) failure (but not when ignored) @@ -87,7 +95,7 @@ public override void Update () int counter = Result.AssertCount; Value = String.Format ("{0} {1} ms for {2} assertion{3}", Result.IsInconclusive () ? "Inconclusive." : "Success!", - Result.Duration.TotalMilliseconds, counter, + Result.GetDuration ().TotalMilliseconds, counter, counter == 1 ? String.Empty : "s"); DetailColor = DarkGreen; } else if (Result.IsFailure ()) { diff --git a/NUnitLite/TouchRunner/TestElement.cs b/NUnitLite/TouchRunner/TestElement.cs index 2fd7624..054e083 100644 --- a/NUnitLite/TouchRunner/TestElement.cs +++ b/NUnitLite/TouchRunner/TestElement.cs @@ -25,7 +25,11 @@ using MonoTouch.Dialog; using NUnit.Framework.Internal; +#if NUNITLITE_NUGET +using NUnit.Framework.Interfaces; +#else using NUnit.Framework.Api; +#endif namespace MonoTouch.NUnit.UI { diff --git a/NUnitLite/TouchRunner/TestRocks.cs b/NUnitLite/TouchRunner/TestRocks.cs index 9c420f6..1694c0b 100644 --- a/NUnitLite/TouchRunner/TestRocks.cs +++ b/NUnitLite/TouchRunner/TestRocks.cs @@ -18,9 +18,17 @@ // limitations under the License. // +using System; +using System.IO; + using NUnit.Framework; using NUnit.Framework.Internal; +#if NUNITLITE_NUGET +using NUnitLite; +using NUnit.Framework.Interfaces; +#else using NUnit.Framework.Api; +#endif namespace MonoTouch.NUnit { @@ -58,5 +66,21 @@ static public string GetMessage (this TestResult result) return m; return m.Substring (m.IndexOf (" : ") + 3); } + + static public TimeSpan GetDuration (this TestResult result) + { +#if NUNITLITE_NUGET + return TimeSpan.FromSeconds (result.Duration); +#else + return result.Duration; +#endif + } + +#if NUNITLITE_NUGET + static public void WriteResultFile (this NUnitLite.OutputWriter @this, ITestResult result, TextWriter writer) + { + @this.WriteResultFile (result, writer, null, null); + } +#endif } } \ No newline at end of file diff --git a/NUnitLite/TouchRunner/TestSuiteElement.cs b/NUnitLite/TouchRunner/TestSuiteElement.cs index 1b9d87c..b9a3952 100644 --- a/NUnitLite/TouchRunner/TestSuiteElement.cs +++ b/NUnitLite/TouchRunner/TestSuiteElement.cs @@ -67,7 +67,7 @@ public override void Update () StringBuilder sb = new StringBuilder (); if (failure == 0) { DetailColor = DarkGreen; - sb.Append ("Success! ").Append (Result.Duration.TotalMilliseconds).Append (" ms for ").Append (positive).Append (" test"); + sb.Append ("Success! ").Append (Result.GetDuration ().TotalMilliseconds).Append (" ms for ").Append (positive).Append (" test"); if (positive > 1) sb.Append ('s'); } else { diff --git a/NUnitLite/TouchRunner/TouchRunner.cs b/NUnitLite/TouchRunner/TouchRunner.cs index e20e3a7..ddc741d 100644 --- a/NUnitLite/TouchRunner/TouchRunner.cs +++ b/NUnitLite/TouchRunner/TouchRunner.cs @@ -40,11 +40,24 @@ using NUnit.Framework.Api; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; +#if NUNITLITE_NUGET +using NUnitLite; +using NUnit.Framework.Interfaces; +using NUnit.Framework.Internal.Execution; +#else +using NUnitLite.Runner; using NUnit.Framework.Internal.WorkItems; +#endif + +#if NUNITLITE_NUGET +using SettingsDictionary = System.Collections.Generic.IDictionary; +#else +using SettingsDictionary = System.Collections.IDictionary; +#endif namespace MonoTouch.NUnit.UI { public abstract class BaseTouchRunner : ITestListener { - TestSuite suite = new TestSuite (String.Empty); + TestSuite suite = new TestSuite ("TestSuite"); ITestFilter filter = TestFilter.Empty; bool connection_failure; @@ -119,7 +132,7 @@ protected virtual void ExecuteOnMainThread (Action action) public void LoadSync () { foreach (Assembly assembly in assemblies) - Load (assembly, fixtures == null ? null : new Dictionary> () { { "LOAD", fixtures } }); + Load (assembly); assemblies.Clear (); } @@ -275,13 +288,21 @@ public bool OpenWriter (string message) break; } if (options.EnableXml) { - NUnitLite.Runner.OutputWriter formatter; + OutputWriter formatter; switch (options.XmlVersion) { case XmlVersion.NUnitV3: - formatter = new NUnitLite.Runner.NUnit3XmlOutputWriter (DateTime.UtcNow); +#if NUNITLITE_NUGET + formatter = new NUnit3XmlOutputWriter (); +#else + formatter = new NUnit3XmlOutputWriter (DateTime.UtcNow); +#endif break; default: - formatter = new NUnitLite.Runner.NUnit2XmlOutputWriter (DateTime.UtcNow); +#if NUNITLITE_NUGET + formatter = new NUnit2XmlOutputWriter (); +#else + formatter = new NUnit2XmlOutputWriter (DateTime.UtcNow); +#endif break; } Writer = new NUnitOutputTextWriter ( @@ -388,7 +409,7 @@ public virtual void TestFinished (ITestResult r) string name = result.Test.Name; if (!String.IsNullOrEmpty (name)) - Writer.WriteLine ("{0} : {1} ms", name, result.Duration.TotalMilliseconds); + Writer.WriteLine ("{0} : {1} ms", name, result.GetDuration ().TotalMilliseconds); } else { if (result.IsSuccess ()) { Writer.Write ("\t[PASS] "); @@ -405,7 +426,11 @@ public virtual void TestFinished (ITestResult r) } else { Writer.Write ("\t[INFO] "); } +#if NUNITLITE_NUGET + Writer.Write (result.Test.FullName); +#else Writer.Write (result.Test.FixtureType.Name); +#endif Writer.Write ("."); Writer.Write (result.Test.Name); @@ -424,18 +449,55 @@ public virtual void TestFinished (ITestResult r) } } + Dictionary default_settings = new Dictionary () { +#if NUNITLITE_NUGET + { "RunOnMainThread", true }, +#endif + }; + + SettingsDictionary CreateSettings (SettingsDictionary settings) + { + if (fixtures == null && (settings == null || settings.Count == 0)) + return default_settings; + + var dict = new Dictionary (default_settings); + + if (settings != null) { + foreach (var key in settings.Keys) + dict [key?.ToString ()] = settings [key]; + } + + if (fixtures != null) + dict ["LOAD"] = fixtures; + + return dict; + } + +#if NUNITLITE_NUGET + NUnitTestAssemblyRunner runner = new NUnitTestAssemblyRunner (new DefaultTestAssemblyBuilder ()); + + public bool Load (string assemblyName, IDictionary settings = null) + { + return AddSuite ((TestSuite) runner.Load (assemblyName, CreateSettings (settings))); + } + + public bool Load (Assembly assembly, IDictionary settings = null) + { + return AddSuite ((TestSuite) runner.Load (assembly, CreateSettings (settings))); + } +#else NUnitLiteTestAssemblyBuilder builder = new NUnitLiteTestAssemblyBuilder (); - Dictionary empty = new Dictionary (); - public bool Load (string assemblyName, IDictionary settings) + public bool Load (string assemblyName, SettingsDictionary settings = null) { - return AddSuite (builder.Build (assemblyName, settings ?? empty)); + return AddSuite (builder.Build (assemblyName, CreateSettings (settings))); } - public bool Load (Assembly assembly, IDictionary settings) + public bool Load (Assembly assembly, SettingsDictionary settings = null) { - return AddSuite (builder.Build (assembly, settings ?? empty)); + return AddSuite (builder.Build (assembly, CreateSettings (settings))); } +#endif bool AddSuite (TestSuite ts) { @@ -453,12 +515,34 @@ public TestResult Run (Test test) InconclusiveCount = 0; Result = null; + +#if NUNITLITE_NUGET + runner.Run (this, new MatchTestFilter { MatchTest = test }); + + // The TestResult we get back from the runner is for the top-most test suite, + // which isn't necessarily the test that we ran. So look for the TestResult + // for the test we ran. + ITestResult find_result (ITestResult tr) + { + if (tr.Test == test) + return tr; + foreach (var child in tr.Children) { + var r = find_result (child); + if (r != null) + return r; + } + return null; + } + + Result = (TestResult) (find_result (runner.Result) ?? runner.Result); +#else TestExecutionContext current = TestExecutionContext.CurrentContext; current.WorkDirectory = Environment.CurrentDirectory; current.Listener = this; WorkItem wi = test.CreateWorkItem (filter, new FinallyDelegate ()); wi.Execute (current); Result = wi.Result; +#endif return Result; } @@ -471,6 +555,13 @@ public ITest LoadedTest { public void TestOutput (TestOutput testOutput) { } + +#if NUNITLITE_NUGET + public void SendMessage (TestMessage message) + { + Writer.WriteLine (message.ToString ()); + } +#endif } #if __WATCHOS__ @@ -696,4 +787,37 @@ protected override void ExecuteOnMainThread (Action action) } } #endif + + // A filter that matches a specific test + class MatchTestFilter : TestFilter { + public ITest MatchTest; + +#if NUNITLITE_NUGET + public override TNode AddToXml (TNode parentNode, bool recursive) + { + throw new NotImplementedException (); + } +#endif + + public override bool Match (ITest test) + { + return IsMatch (test, MatchTest); + } + + static bool IsMatch (ITest test, ITest match) + { + if (test == match) + return true; + + if (match.HasChildren) { + foreach (var child in match.Tests) { + if (IsMatch (test, child)) + return true; + } + } + + return false; + + } + } } diff --git a/Touch.Client/Touch.Client.csproj b/Touch.Client/Touch.Client.csproj new file mode 100644 index 0000000..01cca79 --- /dev/null +++ b/Touch.Client/Touch.Client.csproj @@ -0,0 +1,102 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {F611ED96-54B5-4975-99BB-12F50AF95936} + {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {a52b8a63-bc84-4b47-910d-692533484892} + Library + Touch.Client + Resources + Touch.Client + PackageReference + + + true + full + false + bin\Debug + DEBUG;NUNITLITE_NUGET + prompt + 4 + + + full + true + bin\Release + prompt + 4 + + + + + + + + + + + + + + HttpTextWriter.cs + + + NUnitOutputTextWriter.cs + + + Options.cs + + + TcpTextWriter.cs + + + TestCaseElement.cs + + + TestElement.cs + + + TestResultElement.cs + + + TestRocks.cs + + + TestSuiteElement.cs + + + TouchOptions.cs + + + TouchRunner.cs + + + TouchViewController.cs + + + + + 3.12.0 + + + 2.0.0-pre1 + all + true + + + 3.6.0 + + + + + + + + + + + \ No newline at end of file diff --git a/Touch.Unit.sln b/Touch.Unit.sln index 300476f..150390b 100644 --- a/Touch.Unit.sln +++ b/Touch.Unit.sln @@ -8,6 +8,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "monotouch.tests", "monotouc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Touch.Server", "Touch.Server\Touch.Server.csproj", "{A1303AE1-2693-4DF7-A17B-20C2ABA1E2ED}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Touch.Client", "Touch.Client\Touch.Client.csproj", "{F611ED96-54B5-4975-99BB-12F50AF95936}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|iPhoneSimulator = Debug|iPhoneSimulator @@ -84,6 +86,22 @@ Global {A1303AE1-2693-4DF7-A17B-20C2ABA1E2ED}.Release|iPhone.Build.0 = Release|iPhone {A1303AE1-2693-4DF7-A17B-20C2ABA1E2ED}.Release|iPhoneSimulator.ActiveCfg = Release|iPhone {A1303AE1-2693-4DF7-A17B-20C2ABA1E2ED}.Release|iPhoneSimulator.Build.0 = Release|iPhone + {F611ED96-54B5-4975-99BB-12F50AF95936}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Debug|iPhone.Build.0 = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Release|iPhone.ActiveCfg = Release|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.Release|iPhone.Build.0 = Release|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AdHoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AdHoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AdHoc|iPhone.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AdHoc|iPhone.Build.0 = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {F611ED96-54B5-4975-99BB-12F50AF95936}.AppStore|iPhone.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Touch.Unit.csproj