From 9a0eb1d8fcf986c83f151c1b2e1b1c1ae1c6e046 Mon Sep 17 00:00:00 2001 From: Patrick Stevens <3138005+Smaug123@users.noreply.github.com> Date: Thu, 6 Jun 2024 21:23:47 +0100 Subject: [PATCH] Special NUnit exception types (#38) --- Consumer/Consumer.fsproj | 1 + Consumer/Inconclusive.fs | 19 +++++++++++++++++++ TestRunner.Lib/Domain.fs | 2 ++ TestRunner.Lib/SurfaceBaseline.txt | 9 ++++++++- TestRunner.Lib/TestFixture.fs | 27 +++++++++++++++++++++------ TestRunner.Lib/version.json | 2 +- 6 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 Consumer/Inconclusive.fs diff --git a/Consumer/Consumer.fsproj b/Consumer/Consumer.fsproj index 4caa70d..3db48ea 100644 --- a/Consumer/Consumer.fsproj +++ b/Consumer/Consumer.fsproj @@ -9,6 +9,7 @@ + diff --git a/Consumer/Inconclusive.fs b/Consumer/Inconclusive.fs new file mode 100644 index 0000000..0c1b29a --- /dev/null +++ b/Consumer/Inconclusive.fs @@ -0,0 +1,19 @@ +namespace Consumer + +open NUnit.Framework + +[] +module Inconclusive = + + [] + let ``Inconclusive test`` () = + Assert.Inconclusive "I was inconclusive" + + [] + let ``Ignore test`` () = Assert.Ignore "I am ignored" + + [] + let ``Pass test`` () = Assert.Pass "ohhhh yeaahhhh" + + [] + let ``Warning`` () = Assert.Warn "warning" diff --git a/TestRunner.Lib/Domain.fs b/TestRunner.Lib/Domain.fs index 04295a2..ee5806d 100644 --- a/TestRunner.Lib/Domain.fs +++ b/TestRunner.Lib/Domain.fs @@ -151,6 +151,8 @@ type TestMemberSuccess = | Ignored of reason : string option /// We didn't run the test, because it's []. | Explicit of reason : string option + /// We ran the test, and it performed Assert.Inconclusive. + | Inconclusive of reason : string option /// Represents the failure of a test. [] diff --git a/TestRunner.Lib/SurfaceBaseline.txt b/TestRunner.Lib/SurfaceBaseline.txt index 5bde67e..e339479 100644 --- a/TestRunner.Lib/SurfaceBaseline.txt +++ b/TestRunner.Lib/SurfaceBaseline.txt @@ -221,27 +221,34 @@ TestRunner.TestMemberFailure.IsMalformed [property]: [read-only] bool TestRunner.TestMemberFailure.NewFailed [static method]: TestRunner.TestFailure list -> TestRunner.TestMemberFailure TestRunner.TestMemberFailure.NewMalformed [static method]: string list -> TestRunner.TestMemberFailure TestRunner.TestMemberFailure.Tag [property]: [read-only] int -TestRunner.TestMemberSuccess inherit obj, implements TestRunner.TestMemberSuccess System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.TestMemberSuccess System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 3 cases +TestRunner.TestMemberSuccess inherit obj, implements TestRunner.TestMemberSuccess System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.TestMemberSuccess System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 4 cases TestRunner.TestMemberSuccess+Explicit inherit TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess+Explicit.get_reason [method]: unit -> string option TestRunner.TestMemberSuccess+Explicit.reason [property]: [read-only] string option TestRunner.TestMemberSuccess+Ignored inherit TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess+Ignored.get_reason [method]: unit -> string option TestRunner.TestMemberSuccess+Ignored.reason [property]: [read-only] string option +TestRunner.TestMemberSuccess+Inconclusive inherit TestRunner.TestMemberSuccess +TestRunner.TestMemberSuccess+Inconclusive.get_reason [method]: unit -> string option +TestRunner.TestMemberSuccess+Inconclusive.reason [property]: [read-only] string option TestRunner.TestMemberSuccess+Tags inherit obj TestRunner.TestMemberSuccess+Tags.Explicit [static field]: int = 2 TestRunner.TestMemberSuccess+Tags.Ignored [static field]: int = 1 +TestRunner.TestMemberSuccess+Tags.Inconclusive [static field]: int = 3 TestRunner.TestMemberSuccess+Tags.Ok [static field]: int = 0 TestRunner.TestMemberSuccess.get_IsExplicit [method]: unit -> bool TestRunner.TestMemberSuccess.get_IsIgnored [method]: unit -> bool +TestRunner.TestMemberSuccess.get_IsInconclusive [method]: unit -> bool TestRunner.TestMemberSuccess.get_IsOk [method]: unit -> bool TestRunner.TestMemberSuccess.get_Ok [static method]: unit -> TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess.get_Tag [method]: unit -> int TestRunner.TestMemberSuccess.IsExplicit [property]: [read-only] bool TestRunner.TestMemberSuccess.IsIgnored [property]: [read-only] bool +TestRunner.TestMemberSuccess.IsInconclusive [property]: [read-only] bool TestRunner.TestMemberSuccess.IsOk [property]: [read-only] bool TestRunner.TestMemberSuccess.NewExplicit [static method]: string option -> TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess.NewIgnored [static method]: string option -> TestRunner.TestMemberSuccess +TestRunner.TestMemberSuccess.NewInconclusive [static method]: string option -> TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess.Ok [static property]: [read-only] TestRunner.TestMemberSuccess TestRunner.TestMemberSuccess.Tag [property]: [read-only] int TestRunner.TestProgress inherit obj diff --git a/TestRunner.Lib/TestFixture.fs b/TestRunner.Lib/TestFixture.fs index c97403e..441f630 100644 --- a/TestRunner.Lib/TestFixture.fs +++ b/TestRunner.Lib/TestFixture.fs @@ -31,7 +31,7 @@ module TestFixture = (test : MethodInfo) (containingObject : obj) (args : obj[]) - : Result + : Result = let rec runMethods (wrap : UserMethodFailure -> TestFailure) @@ -59,15 +59,30 @@ module TestFixture = | Error e -> Error [ e ] | Ok () -> - let result = runMethods TestFailure.TestFailed [ test ] args + let result = + let result = runMethods TestFailure.TestFailed [ test ] args + + match result with + | Ok () -> Ok None + | Error (TestFailure.TestFailed (UserMethodFailure.Threw (_, exc)) as orig) -> + match exc.GetType().FullName with + | "NUnit.Framework.SuccessException" -> Ok None + | "NUnit.Framework.IgnoreException" -> Ok (Some (TestMemberSuccess.Ignored (Option.ofObj exc.Message))) + | "NUnit.Framework.InconclusiveException" -> + Ok (Some (TestMemberSuccess.Inconclusive (Option.ofObj exc.Message))) + | s when s.StartsWith ("NUnit.Framework.", StringComparison.Ordinal) -> + failwith $"Unrecognised special exception: %s{s}" + | _ -> Error orig + | Error orig -> Error orig // Unconditionally run TearDown after tests, even if tests failed. let tearDownResult = runMethods TestFailure.TearDownFailed tearDown [||] match result, tearDownResult with - | Ok (), Ok () -> Ok () + | Ok None, Ok () -> Ok TestMemberSuccess.Ok + | Ok (Some s), Ok () -> Ok s | Error e, Ok () - | Ok (), Error e -> Error [ e ] + | Ok _, Error e -> Error [ e ] | Error e1, Error e2 -> Error [ e1 ; e2 ] let private getValues (test : SingleTestMethod) = @@ -140,11 +155,11 @@ module TestFixture = | Ok values -> let inline normaliseError - (e : Result) + (e : Result) : Result = match e with - | Ok () -> Ok TestMemberSuccess.Ok + | Ok s -> Ok s | Error e -> Error (e |> TestMemberFailure.Failed) match test.Kind, values with diff --git a/TestRunner.Lib/version.json b/TestRunner.Lib/version.json index b8c4ffc..df56be9 100644 --- a/TestRunner.Lib/version.json +++ b/TestRunner.Lib/version.json @@ -1,5 +1,5 @@ { - "version": "0.3", + "version": "0.4", "publicReleaseRefSpec": null, "pathFilters": [ "./",