mirror of
https://github.com/Smaug123/unofficial-nunit-runner
synced 2025-10-06 09:48:40 +00:00
Rename from the rather bland "TestRunner" (#61)
This commit is contained in:
20
WoofWare.NUnitTestRunner.Lib/Array.fs
Normal file
20
WoofWare.NUnitTestRunner.Lib/Array.fs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Array =
|
||||
|
||||
let allOkOrError<'o, 'e> (a : Result<'o, 'e>[]) : Result<'o[], 'o[] * 'e[]> =
|
||||
let oks = ResizeArray ()
|
||||
let errors = ResizeArray ()
|
||||
|
||||
for i in a do
|
||||
match i with
|
||||
| Error e -> errors.Add e
|
||||
| Ok o -> oks.Add o
|
||||
|
||||
let oks = oks.ToArray ()
|
||||
|
||||
if errors.Count = 0 then
|
||||
Ok oks
|
||||
else
|
||||
Error (oks, errors.ToArray ())
|
7
WoofWare.NUnitTestRunner.Lib/AssemblyInfo.fs
Normal file
7
WoofWare.NUnitTestRunner.Lib/AssemblyInfo.fs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace WoofWare.NUnitTestRunner.AssemblyInfo
|
||||
|
||||
open System.Runtime.CompilerServices
|
||||
|
||||
[<assembly : InternalsVisibleTo("WoofWare.NUnitTestRunner.Test")>]
|
||||
|
||||
do ()
|
178
WoofWare.NUnitTestRunner.Lib/Domain.fs
Normal file
178
WoofWare.NUnitTestRunner.Lib/Domain.fs
Normal file
@@ -0,0 +1,178 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System.Reflection
|
||||
|
||||
/// A modifier on whether a given test should be run.
|
||||
[<RequireQualifiedAccess>]
|
||||
type Modifier =
|
||||
/// This test is Explicit: it can only be run by an explicit instruction to do so.
|
||||
/// (As of this writing, the console runner will never run such tests.)
|
||||
| Explicit of reason : string option
|
||||
/// This test is Ignored: it will never be run by the harness.
|
||||
| Ignored of reason : string option
|
||||
|
||||
/// Describes where data comes from, if any, to provide the args to this test.
|
||||
[<RequireQualifiedAccess>]
|
||||
type TestKind =
|
||||
/// This test takes no arguments.
|
||||
| Single
|
||||
/// This test has arguments supplied by TestCaseSource (i.e. we look for members with the given names, and
|
||||
/// populate the args from those).
|
||||
| Source of string list
|
||||
/// This test has arguments supplied by TestCase attributes.
|
||||
| Data of obj list list
|
||||
|
||||
/// Determines whether a set of `[<Value>]`s will be combined elementwise or Cartesian-product-wise.
|
||||
type Combinatorial =
|
||||
/// Combine `[<Value>]`s to produce every possible combination of args drawn from the respective sets.
|
||||
| Combinatorial
|
||||
/// Combine `[<Value>]`s such that one test is "the first Value from each", one test is "the second Value from
|
||||
/// each", and so on. Spare slots are filled with `Unchecked.defaultof<_>`.
|
||||
| Sequential
|
||||
|
||||
/// A single method or member which holds some tests. (Often such a member will represent only one test, but e.g.
|
||||
/// if it has [<TestCaseSource>] then it represents multiple tests.)
|
||||
type SingleTestMethod =
|
||||
{
|
||||
/// The method which we need to invoke, possibly some args, to run the test.
|
||||
Method : MethodInfo
|
||||
/// Where the data comes from to populate the args for this method.
|
||||
Kind : TestKind
|
||||
/// Any statements about whether the runner should run this test.
|
||||
/// (This does not include use of `--filter`s.)
|
||||
Modifiers : Modifier list
|
||||
/// `[<Category>]`s this test is in.
|
||||
Categories : string list
|
||||
/// Whether we should run this test repeatedly, and if so, how many times.
|
||||
Repeat : int option
|
||||
/// If this test has data supplied by `[<Value>]` annotations, specifies how those annotations are combined
|
||||
/// to produce the complete collection of args.
|
||||
Combinatorial : Combinatorial option
|
||||
}
|
||||
|
||||
/// Human-readable name of this test method.
|
||||
member this.Name = this.Method.Name
|
||||
|
||||
/// A test fixture (usually represented by the [<TestFixture>]` attribute), which may contain many tests,
|
||||
/// each of which may run many times.
|
||||
type TestFixture =
|
||||
{
|
||||
/// The assembly which contains this TestFixture, loaded into a separate context.
|
||||
ContainingAssembly : Assembly
|
||||
/// Fully-qualified name of this fixture (e.g. MyThing.Test.Foo for `[<TestFixture>] module Foo` in the
|
||||
/// `MyThing.Test` assembly).
|
||||
Name : string
|
||||
/// A method which is run once when this test fixture starts, before any other setup logic and before
|
||||
/// any tests run. If this method fails, no tests will run and no per-test setup/teardown logic will run,
|
||||
/// but OneTimeTearDown will run.
|
||||
OneTimeSetUp : MethodInfo option
|
||||
/// A method which is run once, after any other tear-down logic and after all tests run, even if everything
|
||||
/// else failed before this (i.e. even if OneTimeSetUp failed, even if all tests failed, etc).
|
||||
OneTimeTearDown : MethodInfo option
|
||||
/// Methods which are run in some arbitrary order before each individual test. If any of these fail, the test
|
||||
/// will not run, but the TearDown methods will still run, and OneTimeTearDown will still run at the end of
|
||||
/// the fixture. If the first SetUp we run fails, we don't define whether the other SetUps run before
|
||||
/// we proceed directly to running all the TearDowns.
|
||||
SetUp : MethodInfo list
|
||||
/// Methods which are run in some arbitrary order after each individual test, even if the test or its setup
|
||||
/// failed. If the first TearDown we run fails, we don't define whether the other TearDowns run.
|
||||
TearDown : MethodInfo list
|
||||
/// The individual test methods present within this fixture.
|
||||
Tests : SingleTestMethod list
|
||||
}
|
||||
|
||||
/// A test fixture about which we know nothing. No tests, no setup/teardown.
|
||||
static member Empty (containingAssembly : Assembly) (name : string) =
|
||||
{
|
||||
ContainingAssembly = containingAssembly
|
||||
Name = name
|
||||
OneTimeSetUp = None
|
||||
OneTimeTearDown = None
|
||||
SetUp = []
|
||||
TearDown = []
|
||||
Tests = []
|
||||
}
|
||||
|
||||
/// User code in the unit under test has failed somehow.
|
||||
[<RequireQualifiedAccess>]
|
||||
type UserMethodFailure =
|
||||
/// A method ran to completion and returned a value, when it was expected to return nothing.
|
||||
| ReturnedNonUnit of name : string * result : obj
|
||||
/// A method threw.
|
||||
| Threw of name : string * exn
|
||||
|
||||
/// Human-readable representation of the user failure.
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| UserMethodFailure.ReturnedNonUnit (method, ret) ->
|
||||
$"User-defined method '%s{method}' returned a non-unit: %O{ret}"
|
||||
| UserMethodFailure.Threw (method, exc) ->
|
||||
$"User-defined method '%s{method}' threw: %s{exc.Message}\n %s{exc.StackTrace}"
|
||||
|
||||
/// Name (not fully-qualified) of the method which failed.
|
||||
member this.Name =
|
||||
match this with
|
||||
| UserMethodFailure.Threw (name, _)
|
||||
| UserMethodFailure.ReturnedNonUnit (name, _) -> name
|
||||
|
||||
/// Represents the failure of a single run of one test. An error signalled this way is a user error: the unit under
|
||||
/// test has misbehaved.
|
||||
[<RequireQualifiedAccess>]
|
||||
type TestFailure =
|
||||
/// The test itself failed. (Setup must have succeeded if you get this.)
|
||||
| TestFailed of UserMethodFailure
|
||||
/// We failed to set up the test (e.g. its SetUp failed). If this happens, we won't proceed
|
||||
/// to running the test or running any TearDown for that test.
|
||||
| SetUpFailed of UserMethodFailure
|
||||
/// We failed to tear down the test (e.g. its TearDown failed). This can happen even if the test failed,
|
||||
/// because we always run tear-downs, even after failed tests.
|
||||
| TearDownFailed of UserMethodFailure
|
||||
|
||||
/// Name (not fully-qualified) of the method which failed.
|
||||
member this.Name =
|
||||
match this with
|
||||
| TestFailure.TestFailed f
|
||||
| TestFailure.SetUpFailed f
|
||||
| TestFailure.TearDownFailed f -> f.Name
|
||||
|
||||
/// Human-readable string representation.
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| TestFailure.TestFailed f -> $"execution: %O{f}"
|
||||
| TestFailure.SetUpFailed f -> $"Setup failed, and we did not attempt to run test: %O{f}"
|
||||
| TestFailure.TearDownFailed f -> $"Tear-down failed: %O{f}"
|
||||
|
||||
/// Represents the result of a test that didn't fail.
|
||||
[<RequireQualifiedAccess>]
|
||||
type TestMemberSuccess =
|
||||
/// The test passed.
|
||||
| Ok
|
||||
/// We didn't run the test, because it's [<Ignore>].
|
||||
| Ignored of reason : string option
|
||||
/// We didn't run the test, because it's [<Explicit>].
|
||||
| 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.
|
||||
[<RequireQualifiedAccess>]
|
||||
type TestMemberFailure =
|
||||
/// We couldn't run this test because it was somehow malformed in a way we detected up front.
|
||||
| Malformed of reasons : string list
|
||||
/// We tried to run the test, but it failed. (A single test can fail many times, e.g. if it failed and also
|
||||
/// the tear-down logic failed afterwards.)
|
||||
| Failed of TestFailure list
|
||||
|
||||
/// Human-readable string representation
|
||||
override this.ToString () : string =
|
||||
match this with
|
||||
| TestMemberFailure.Malformed reasons ->
|
||||
let reasons = reasons |> String.concat "; "
|
||||
$"Could not run test because it was malformed: %s{reasons}"
|
||||
| TestMemberFailure.Failed errors ->
|
||||
let errors =
|
||||
errors
|
||||
|> Seq.map (fun failure -> (failure : TestFailure).ToString ())
|
||||
|> String.concat "\n"
|
||||
|
||||
$"Test failed: %s{errors}"
|
300
WoofWare.NUnitTestRunner.Lib/Filter.fs
Normal file
300
WoofWare.NUnitTestRunner.Lib/Filter.fs
Normal file
@@ -0,0 +1,300 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open PrattParser
|
||||
|
||||
// Documentation:
|
||||
// https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=mstest
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type internal ParsedFilter =
|
||||
| FullyQualifiedName
|
||||
| Name
|
||||
| TestCategory
|
||||
| Not of ParsedFilter
|
||||
| Or of ParsedFilter * ParsedFilter
|
||||
| And of ParsedFilter * ParsedFilter
|
||||
| Equal of ParsedFilter * ParsedFilter
|
||||
| Contains of ParsedFilter * ParsedFilter
|
||||
| String of string
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type internal TokenType =
|
||||
| FullyQualifiedName
|
||||
| Name
|
||||
| TestCategory
|
||||
| OpenParen
|
||||
| CloseParen
|
||||
| And
|
||||
| Or
|
||||
| Not
|
||||
| Equal
|
||||
| NotEqual
|
||||
| Contains
|
||||
| NotContains
|
||||
| String
|
||||
| QuotedString
|
||||
|
||||
static member canTerminateUnquotedString (t : TokenType) : bool =
|
||||
// Here we essentially choose that unquoted strings can only appear on the RHS of an operation.
|
||||
match t with
|
||||
| TokenType.CloseParen
|
||||
| TokenType.And
|
||||
| TokenType.Or -> true
|
||||
| _ -> false
|
||||
|
||||
type internal Token =
|
||||
{
|
||||
Type : TokenType
|
||||
Trivia : int * int
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Token =
|
||||
let inline standalone (ty : TokenType) (charPos : int) : Token =
|
||||
{
|
||||
Type = ty
|
||||
Trivia = charPos, 1
|
||||
}
|
||||
|
||||
let inline single (ty : TokenType) (start : int) (len : int) : Token =
|
||||
{
|
||||
Type = ty
|
||||
Trivia = start, len
|
||||
}
|
||||
|
||||
let (|SingleChar|_|) (i : int, c : char) : Token option =
|
||||
match c with
|
||||
| '(' -> Some (standalone TokenType.OpenParen i)
|
||||
| ')' -> Some (standalone TokenType.CloseParen i)
|
||||
| '~' -> Some (standalone TokenType.Contains i)
|
||||
| '=' -> Some (standalone TokenType.Equal i)
|
||||
| '&' -> Some (standalone TokenType.And i)
|
||||
| '|' -> Some (standalone TokenType.Or i)
|
||||
| '!' -> Some (standalone TokenType.Not i)
|
||||
| _ -> None
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Lexer =
|
||||
type State =
|
||||
| UnquotedString of startPos : int
|
||||
| Awaiting
|
||||
| QuotedString of startPos : int
|
||||
|
||||
let lex (s : string) : Token seq =
|
||||
seq {
|
||||
let mutable i = 0
|
||||
let mutable state = State.Awaiting
|
||||
|
||||
while i < s.Length do
|
||||
match (i, s.[i]), state with
|
||||
| (endI, '"'), State.QuotedString startI ->
|
||||
yield Token.single TokenType.QuotedString startI (endI - startI)
|
||||
i <- i + 1
|
||||
state <- State.Awaiting
|
||||
| _, State.QuotedString _ -> i <- i + 1
|
||||
|
||||
// This one has to come before the check for prefix Not
|
||||
| (startI, '!'), State.Awaiting when i + 1 < s.Length ->
|
||||
i <- i + 1
|
||||
|
||||
match s.[i] with
|
||||
| '~' ->
|
||||
yield Token.single TokenType.NotContains startI 2
|
||||
i <- i + 1
|
||||
| '=' ->
|
||||
yield Token.single TokenType.NotEqual startI 2
|
||||
i <- i + 1
|
||||
| _ ->
|
||||
yield Token.single TokenType.Not startI 1
|
||||
i <- i + 1
|
||||
| Token.SingleChar token, State.Awaiting ->
|
||||
i <- i + 1
|
||||
yield token
|
||||
| Token.SingleChar t, State.UnquotedString stringStart ->
|
||||
if TokenType.canTerminateUnquotedString t.Type then
|
||||
yield Token.single TokenType.String stringStart (i - stringStart)
|
||||
// don't increment `i`, we'll just do the match again
|
||||
state <- State.Awaiting
|
||||
else
|
||||
i <- i + 1
|
||||
| (_, 'F'), State.Awaiting when
|
||||
i + 1 < s.Length
|
||||
&& s.[i + 1 ..].StartsWith ("ullyQualifiedName", StringComparison.Ordinal)
|
||||
->
|
||||
yield Token.single TokenType.FullyQualifiedName i "FullyQualifiedName".Length
|
||||
i <- i + "FullyQualifiedName".Length
|
||||
| (_, 'N'), State.Awaiting when
|
||||
i + 1 < s.Length && s.[i + 1 ..].StartsWith ("ame", StringComparison.Ordinal)
|
||||
->
|
||||
yield Token.single TokenType.Name i "Name".Length
|
||||
i <- i + "Name".Length
|
||||
| (_, 'T'), State.Awaiting when
|
||||
i + 1 < s.Length
|
||||
&& s.[i + 1 ..].StartsWith ("estCategory", StringComparison.Ordinal)
|
||||
->
|
||||
yield Token.single TokenType.TestCategory i "TestCategory".Length
|
||||
i <- i + "TestCategory".Length
|
||||
| (_, ' '), State.Awaiting -> i <- i + 1
|
||||
| (_, '"'), State.Awaiting ->
|
||||
state <- State.QuotedString i
|
||||
i <- i + 1
|
||||
| (_, _), State.Awaiting ->
|
||||
state <- State.UnquotedString i
|
||||
i <- i + 1
|
||||
| (_, _), State.UnquotedString _ -> i <- i + 1
|
||||
|
||||
match state with
|
||||
| State.Awaiting -> ()
|
||||
| State.UnquotedString start -> yield Token.single TokenType.String start (s.Length - start)
|
||||
| State.QuotedString i ->
|
||||
failwith $"Parse failed: we never closed the string which started at position %i{i}"
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal ParsedFilter =
|
||||
let private unescape (s : string) : string =
|
||||
System.Xml.XmlReader
|
||||
.Create(new StringReader ("<r>" + s + "</r>"))
|
||||
.ReadElementString ()
|
||||
|
||||
let private atom (inputString : string) (token : Token) : ParsedFilter option =
|
||||
let start, len = token.Trivia
|
||||
|
||||
match token.Type with
|
||||
| TokenType.QuotedString ->
|
||||
// +1 and -1, because the trivia contains the initial and terminal quote mark
|
||||
inputString.Substring (start + 1, len - 1)
|
||||
|> unescape
|
||||
|> ParsedFilter.String
|
||||
|> Some
|
||||
| TokenType.String -> Some (ParsedFilter.String (inputString.Substring (start, len)))
|
||||
| TokenType.FullyQualifiedName -> Some ParsedFilter.FullyQualifiedName
|
||||
| TokenType.Name -> Some ParsedFilter.Name
|
||||
| TokenType.TestCategory -> Some ParsedFilter.TestCategory
|
||||
| TokenType.OpenParen -> None
|
||||
| TokenType.CloseParen -> None
|
||||
| TokenType.And -> None
|
||||
| TokenType.Or -> None
|
||||
| TokenType.Not -> None
|
||||
| TokenType.NotEqual -> None
|
||||
| TokenType.Equal -> None
|
||||
| TokenType.NotContains -> None
|
||||
| TokenType.Contains -> None
|
||||
|
||||
let parser =
|
||||
Parser.make<_, Token, ParsedFilter> _.Type atom
|
||||
|> Parser.withInfix TokenType.And (10, 11) (fun a b -> ParsedFilter.And (a, b))
|
||||
|> Parser.withInfix TokenType.Equal (15, 16) (fun a b -> ParsedFilter.Equal (a, b))
|
||||
|> Parser.withInfix TokenType.NotEqual (15, 16) (fun a b -> ParsedFilter.Not (ParsedFilter.Equal (a, b)))
|
||||
|> Parser.withInfix TokenType.Contains (15, 16) (fun a b -> ParsedFilter.Contains (a, b))
|
||||
|> Parser.withInfix TokenType.NotContains (15, 16) (fun a b -> ParsedFilter.Not (ParsedFilter.Contains (a, b)))
|
||||
|> Parser.withInfix TokenType.Or (5, 6) (fun a b -> ParsedFilter.Or (a, b))
|
||||
|> Parser.withUnaryPrefix TokenType.Not ((), 13) ParsedFilter.Not
|
||||
|> Parser.withBracketLike
|
||||
TokenType.OpenParen
|
||||
{
|
||||
ConsumeBeforeInitialToken = false
|
||||
ConsumeAfterFinalToken = false
|
||||
BoundaryTokens = [ TokenType.CloseParen ]
|
||||
Construct = List.exactlyOne
|
||||
}
|
||||
|
||||
let parse (s : string) : ParsedFilter =
|
||||
let tokens = Lexer.lex s |> Seq.toList
|
||||
let parsed, remaining = Parser.execute parser s tokens
|
||||
|
||||
if not remaining.IsEmpty then
|
||||
failwith $"Leftover tokens: %O{remaining}"
|
||||
|
||||
match parsed with
|
||||
| ParsedFilter.String _ -> ParsedFilter.Contains (ParsedFilter.FullyQualifiedName, parsed)
|
||||
| _ -> parsed
|
||||
|
||||
/// The type of matching which this filter will perform.
|
||||
type Match =
|
||||
/// This filter will only match if its argument is exactly (case-sensitively) equal to this.
|
||||
| Exact of string
|
||||
/// This filter will match if its argument (case-sensitively) contains this substring.
|
||||
| Contains of string
|
||||
|
||||
/// A filter which is to be applied when running tests, to determine which tests to run.
|
||||
[<RequireQualifiedAccess>]
|
||||
type Filter =
|
||||
/// The fully qualified name of the test must match this.
|
||||
| FullyQualifiedName of Match
|
||||
/// The name (without its assembly prepended) of the test must match this.
|
||||
| Name of Match
|
||||
/// The test must be in a matching category.
|
||||
| TestCategory of Match
|
||||
/// The test must not match this filter.
|
||||
| Not of Filter
|
||||
/// The test must match at least one of these filters.
|
||||
| Or of Filter * Filter
|
||||
/// The test must match both of these filters.
|
||||
| And of Filter * Filter
|
||||
|
||||
/// Methods for manipulating filters.
|
||||
[<RequireQualifiedAccess>]
|
||||
module Filter =
|
||||
let rec internal makeParsed (fi : ParsedFilter) : Filter =
|
||||
match fi with
|
||||
| ParsedFilter.Not x -> Filter.Not (makeParsed x)
|
||||
| ParsedFilter.FullyQualifiedName -> failwith "malformed filter: found FullyQualifiedName with no operand"
|
||||
| ParsedFilter.Name -> failwith "malformed filter: found Name with no operand"
|
||||
| ParsedFilter.TestCategory -> failwith "malformed filter: found TestCategory with no operand"
|
||||
| ParsedFilter.Or (a, b) -> Filter.Or (makeParsed a, makeParsed b)
|
||||
| ParsedFilter.And (a, b) -> Filter.And (makeParsed a, makeParsed b)
|
||||
| ParsedFilter.Equal (key, value) ->
|
||||
let value =
|
||||
match value with
|
||||
| ParsedFilter.String s -> s
|
||||
| _ -> failwith $"malformed filter: found non-string operand on RHS of equality, '%O{value}'"
|
||||
|
||||
match key with
|
||||
| ParsedFilter.TestCategory -> Filter.TestCategory (Match.Exact value)
|
||||
| ParsedFilter.FullyQualifiedName -> Filter.FullyQualifiedName (Match.Exact value)
|
||||
| ParsedFilter.Name -> Filter.Name (Match.Exact value)
|
||||
| _ -> failwith $"Malformed filter: left-hand side of Equals clause must be e.g. TestCategory, was %O{key}"
|
||||
| ParsedFilter.Contains (key, value) ->
|
||||
let value =
|
||||
match value with
|
||||
| ParsedFilter.String s -> s
|
||||
| _ -> failwith $"malformed filter: found non-string operand on RHS of containment, '%O{value}'"
|
||||
|
||||
match key with
|
||||
| ParsedFilter.TestCategory -> Filter.TestCategory (Match.Contains value)
|
||||
| ParsedFilter.FullyQualifiedName -> Filter.FullyQualifiedName (Match.Contains value)
|
||||
| ParsedFilter.Name -> Filter.Name (Match.Contains value)
|
||||
| _ ->
|
||||
failwith $"Malformed filter: left-hand side of Contains clause must be e.g. TestCategory, was %O{key}"
|
||||
| ParsedFilter.String s -> failwith $"Malformed filter: got verbatim string %s{s} when expected an operation"
|
||||
|
||||
/// Parse the input string, e.g. the `foo` one might get from `dotnet test --filter foo`.
|
||||
/// Verbatim strings are assumed to be XML-escaped.
|
||||
let parse (s : string) : Filter = ParsedFilter.parse s |> makeParsed
|
||||
|
||||
/// Convert the representation of a test filter into a function that decides whether to run any given test.
|
||||
let rec shouldRun (filter : Filter) : TestFixture -> SingleTestMethod -> bool =
|
||||
match filter with
|
||||
| Filter.Not filter ->
|
||||
let inner = shouldRun filter
|
||||
fun a b -> not (inner a b)
|
||||
| Filter.And (a, b) ->
|
||||
let inner1 = shouldRun a
|
||||
let inner2 = shouldRun b
|
||||
fun a b -> inner1 a b && inner2 a b
|
||||
| Filter.Or (a, b) ->
|
||||
let inner1 = shouldRun a
|
||||
let inner2 = shouldRun b
|
||||
fun a b -> inner1 a b || inner2 a b
|
||||
| Filter.Name (Match.Exact m) -> fun _fixture method -> method.Method.Name = m
|
||||
| Filter.Name (Match.Contains m) -> fun _fixture method -> method.Method.Name.Contains m
|
||||
| Filter.FullyQualifiedName (Match.Exact m) ->
|
||||
fun _fixture method -> (method.Method.DeclaringType.FullName + "." + method.Method.Name) = m
|
||||
| Filter.FullyQualifiedName (Match.Contains m) ->
|
||||
fun _fixture method -> (method.Method.DeclaringType.FullName + "." + method.Method.Name).Contains m
|
||||
| Filter.TestCategory (Match.Contains m) ->
|
||||
fun _fixture method -> method.Categories |> List.exists (fun cat -> cat.Contains m)
|
||||
| Filter.TestCategory (Match.Exact m) -> fun _fixture method -> method.Categories |> List.contains m
|
15
WoofWare.NUnitTestRunner.Lib/List.fs
Normal file
15
WoofWare.NUnitTestRunner.Lib/List.fs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal List =
|
||||
|
||||
/// Given e.g. [[1,2],[4,5,6]], returns:
|
||||
/// [1;4] ; [1;5] ; [1;6] ; [2;4] ; [2;5] ; [2;6]
|
||||
/// in some order.
|
||||
/// This is like allPairs but more so.
|
||||
let rec combinations (s : 'a list list) : 'a list list =
|
||||
match s with
|
||||
| [] -> [ [] ]
|
||||
| head :: s ->
|
||||
let sub = combinations s
|
||||
head |> List.collect (fun head -> sub |> List.map (fun tail -> head :: tail))
|
30
WoofWare.NUnitTestRunner.Lib/Result.fs
Normal file
30
WoofWare.NUnitTestRunner.Lib/Result.fs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Result =
|
||||
|
||||
let inline getError<'r, 'e> (r : Result<'r, 'e>) : 'e option =
|
||||
match r with
|
||||
| Ok _ -> None
|
||||
| Error e -> Some e
|
||||
|
||||
let get<'r, 'e> (r : Result<'r, 'e>) : 'r option =
|
||||
match r with
|
||||
| Ok r -> Some r
|
||||
| Error _ -> None
|
||||
|
||||
let allOkOrError<'o, 'e> (a : Result<'o, 'e> list) : Result<'o list, 'o list * 'e list> =
|
||||
let oks = ResizeArray ()
|
||||
let errors = ResizeArray ()
|
||||
|
||||
for i in a do
|
||||
match i with
|
||||
| Error e -> errors.Add e
|
||||
| Ok o -> oks.Add o
|
||||
|
||||
let oks = oks |> Seq.toList
|
||||
|
||||
if errors.Count = 0 then
|
||||
Ok oks
|
||||
else
|
||||
Error (oks, Seq.toList errors)
|
123
WoofWare.NUnitTestRunner.Lib/SingleTestMethod.fs
Normal file
123
WoofWare.NUnitTestRunner.Lib/SingleTestMethod.fs
Normal file
@@ -0,0 +1,123 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System
|
||||
open System.Reflection
|
||||
|
||||
/// A single method or member which holds some tests. (Often such a member will represent only one test, but e.g.
|
||||
/// if it has [<TestCaseSource>] then it represents multiple tests.)
|
||||
[<RequireQualifiedAccess>]
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
||||
module SingleTestMethod =
|
||||
/// Extract a SingleTestMethod from the given MethodInfo that we think represents a test.
|
||||
/// You pass us the attributes you still haven't parsed from this MethodInfo, and we give you back the sub-list
|
||||
/// of attributes we were also unable to interpret.
|
||||
/// You also give us the list of categories with which the containing TestFixture is tagged.
|
||||
let parse
|
||||
(parentCategories : string list)
|
||||
(method : MethodInfo)
|
||||
(attrs : CustomAttributeData list)
|
||||
: SingleTestMethod option * CustomAttributeData list
|
||||
=
|
||||
let remaining, isTest, sources, hasData, modifiers, categories, repeat, comb =
|
||||
(([], false, [], None, [], [], None, None), attrs)
|
||||
||> List.fold (fun (remaining, isTest, sources, hasData, mods, cats, repeat, comb) attr ->
|
||||
match attr.AttributeType.FullName with
|
||||
| "NUnit.Framework.TestAttribute" ->
|
||||
if attr.ConstructorArguments.Count > 0 then
|
||||
failwith "Unexpectedly got arguments to the Test attribute"
|
||||
|
||||
(remaining, true, sources, hasData, mods, cats, repeat, comb)
|
||||
| "NUnit.Framework.TestCaseAttribute" ->
|
||||
let args = attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList
|
||||
|
||||
match hasData with
|
||||
| None -> (remaining, isTest, sources, Some [ List.ofSeq args ], mods, cats, repeat, comb)
|
||||
| Some existing ->
|
||||
(remaining, isTest, sources, Some ((List.ofSeq args) :: existing), mods, cats, repeat, comb)
|
||||
| "NUnit.Framework.TestCaseSourceAttribute" ->
|
||||
let arg = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
|
||||
|
||||
(remaining, isTest, arg :: sources, hasData, mods, cats, repeat, comb)
|
||||
| "NUnit.Framework.ExplicitAttribute" ->
|
||||
let reason =
|
||||
attr.ConstructorArguments
|
||||
|> Seq.tryHead
|
||||
|> Option.map (_.Value >> unbox<string>)
|
||||
|
||||
(remaining, isTest, sources, hasData, (Modifier.Explicit reason) :: mods, cats, repeat, comb)
|
||||
| "NUnit.Framework.IgnoreAttribute" ->
|
||||
let reason =
|
||||
attr.ConstructorArguments
|
||||
|> Seq.tryHead
|
||||
|> Option.map (_.Value >> unbox<string>)
|
||||
|
||||
(remaining, isTest, sources, hasData, (Modifier.Ignored reason) :: mods, cats, repeat, comb)
|
||||
| "NUnit.Framework.CategoryAttribute" ->
|
||||
let category =
|
||||
attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
|
||||
|
||||
(remaining, isTest, sources, hasData, mods, category :: cats, repeat, comb)
|
||||
| "NUnit.Framework.RepeatAttribute" ->
|
||||
match repeat with
|
||||
| Some _ -> failwith $"Got RepeatAttribute multiple times on %s{method.Name}"
|
||||
| None ->
|
||||
|
||||
let repeat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<int>
|
||||
(remaining, isTest, sources, hasData, mods, cats, Some repeat, comb)
|
||||
| "NUnit.Framework.CombinatorialAttribute" ->
|
||||
match comb with
|
||||
| Some _ ->
|
||||
failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}"
|
||||
| None ->
|
||||
(remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Combinatorial)
|
||||
| "NUnit.Framework.SequentialAttribute" ->
|
||||
match comb with
|
||||
| Some _ ->
|
||||
failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}"
|
||||
| None -> (remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Sequential)
|
||||
| s when s.StartsWith ("NUnit.Framework", StringComparison.Ordinal) ->
|
||||
failwith $"Unrecognised attribute on function %s{method.Name}: %s{attr.AttributeType.FullName}"
|
||||
| _ -> (attr :: remaining, isTest, sources, hasData, mods, cats, repeat, comb)
|
||||
)
|
||||
|
||||
let test =
|
||||
match isTest, sources, hasData, modifiers, categories, repeat, comb with
|
||||
| _, _ :: _, Some _, _, _, _, _ ->
|
||||
failwith
|
||||
$"Test '%s{method.Name}' unexpectedly has both TestData and TestCaseSource; not currently supported"
|
||||
| false, [], None, [], _, _, _ -> None
|
||||
| _, _ :: _, None, mods, categories, repeat, comb ->
|
||||
{
|
||||
Kind = TestKind.Source sources
|
||||
Method = method
|
||||
Modifiers = mods
|
||||
Categories = categories @ parentCategories
|
||||
Repeat = repeat
|
||||
Combinatorial = comb
|
||||
}
|
||||
|> Some
|
||||
| _, [], Some data, mods, categories, repeat, comb ->
|
||||
{
|
||||
Kind = TestKind.Data data
|
||||
Method = method
|
||||
Modifiers = mods
|
||||
Categories = categories @ parentCategories
|
||||
Repeat = repeat
|
||||
Combinatorial = comb
|
||||
}
|
||||
|> Some
|
||||
| true, [], None, mods, categories, repeat, comb ->
|
||||
{
|
||||
Kind = TestKind.Single
|
||||
Method = method
|
||||
Modifiers = mods
|
||||
Categories = categories @ parentCategories
|
||||
Repeat = repeat
|
||||
Combinatorial = comb
|
||||
}
|
||||
|> Some
|
||||
| false, [], None, _ :: _, _, _, _ ->
|
||||
failwith
|
||||
$"Unexpectedly got test modifiers but no test settings on '%s{method.Name}', which you probably didn't intend."
|
||||
|
||||
test, remaining
|
531
WoofWare.NUnitTestRunner.Lib/SurfaceBaseline.txt
Normal file
531
WoofWare.NUnitTestRunner.Lib/SurfaceBaseline.txt
Normal file
@@ -0,0 +1,531 @@
|
||||
WoofWare.NUnitTestRunner.Combinatorial inherit obj, implements WoofWare.NUnitTestRunner.Combinatorial System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.Combinatorial System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
|
||||
WoofWare.NUnitTestRunner.Combinatorial+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.Combinatorial+Tags.Combinatorial [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.Combinatorial+Tags.Sequential [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.Combinatorial.Combinatorial [static property]: [read-only] WoofWare.NUnitTestRunner.Combinatorial
|
||||
WoofWare.NUnitTestRunner.Combinatorial.get_Combinatorial [static method]: unit -> WoofWare.NUnitTestRunner.Combinatorial
|
||||
WoofWare.NUnitTestRunner.Combinatorial.get_IsCombinatorial [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Combinatorial.get_IsSequential [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Combinatorial.get_Sequential [static method]: unit -> WoofWare.NUnitTestRunner.Combinatorial
|
||||
WoofWare.NUnitTestRunner.Combinatorial.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.Combinatorial.IsCombinatorial [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Combinatorial.IsSequential [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Combinatorial.Sequential [static property]: [read-only] WoofWare.NUnitTestRunner.Combinatorial
|
||||
WoofWare.NUnitTestRunner.Combinatorial.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.Filter inherit obj, implements WoofWare.NUnitTestRunner.Filter System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.Filter System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 6 cases
|
||||
WoofWare.NUnitTestRunner.Filter+And inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+And.get_Item1 [method]: unit -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+And.get_Item2 [method]: unit -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+And.Item1 [property]: [read-only] WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+And.Item2 [property]: [read-only] WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+FullyQualifiedName inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+FullyQualifiedName.get_Item [method]: unit -> WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter+FullyQualifiedName.Item [property]: [read-only] WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter+Name inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Name.get_Item [method]: unit -> WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter+Name.Item [property]: [read-only] WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter+Not inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Not.get_Item [method]: unit -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Not.Item [property]: [read-only] WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Or inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Or.get_Item1 [method]: unit -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Or.get_Item2 [method]: unit -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Or.Item1 [property]: [read-only] WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Or.Item2 [property]: [read-only] WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.And [static field]: int = 5
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.FullyQualifiedName [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.Name [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.Not [static field]: int = 3
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.Or [static field]: int = 4
|
||||
WoofWare.NUnitTestRunner.Filter+Tags.TestCategory [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.Filter+TestCategory inherit WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter+TestCategory.get_Item [method]: unit -> WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter+TestCategory.Item [property]: [read-only] WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsAnd [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsFullyQualifiedName [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsName [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsNot [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsOr [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_IsTestCategory [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Filter.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.Filter.IsAnd [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.IsFullyQualifiedName [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.IsName [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.IsNot [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.IsOr [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.IsTestCategory [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Filter.NewAnd [static method]: (WoofWare.NUnitTestRunner.Filter, WoofWare.NUnitTestRunner.Filter) -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.NewFullyQualifiedName [static method]: WoofWare.NUnitTestRunner.Match -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.NewName [static method]: WoofWare.NUnitTestRunner.Match -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.NewNot [static method]: WoofWare.NUnitTestRunner.Filter -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.NewOr [static method]: (WoofWare.NUnitTestRunner.Filter, WoofWare.NUnitTestRunner.Filter) -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.NewTestCategory [static method]: WoofWare.NUnitTestRunner.Match -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.Filter.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.FilterModule inherit obj
|
||||
WoofWare.NUnitTestRunner.FilterModule.parse [static method]: string -> WoofWare.NUnitTestRunner.Filter
|
||||
WoofWare.NUnitTestRunner.FilterModule.shouldRun [static method]: WoofWare.NUnitTestRunner.Filter -> (WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.SingleTestMethod -> bool)
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults inherit obj, implements WoofWare.NUnitTestRunner.FixtureRunResults System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults..ctor [constructor]: ((WoofWare.NUnitTestRunner.TestMemberFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list, (WoofWare.NUnitTestRunner.SingleTestMethod * WoofWare.NUnitTestRunner.TestMemberSuccess * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list, (WoofWare.NUnitTestRunner.UserMethodFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list)
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.Failed [property]: [read-only] (WoofWare.NUnitTestRunner.TestMemberFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.get_Failed [method]: unit -> (WoofWare.NUnitTestRunner.TestMemberFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.get_IndividualTestRunMetadata [method]: unit -> (WoofWare.NUnitTestRunner.IndividualTestRunMetadata * Microsoft.FSharp.Core.FSharpChoice<WoofWare.NUnitTestRunner.TestMemberFailure, WoofWare.NUnitTestRunner.TestMemberSuccess, WoofWare.NUnitTestRunner.UserMethodFailure>) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.get_OtherFailures [method]: unit -> (WoofWare.NUnitTestRunner.UserMethodFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.get_Success [method]: unit -> (WoofWare.NUnitTestRunner.SingleTestMethod * WoofWare.NUnitTestRunner.TestMemberSuccess * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.IndividualTestRunMetadata [property]: [read-only] (WoofWare.NUnitTestRunner.IndividualTestRunMetadata * Microsoft.FSharp.Core.FSharpChoice<WoofWare.NUnitTestRunner.TestMemberFailure, WoofWare.NUnitTestRunner.TestMemberSuccess, WoofWare.NUnitTestRunner.UserMethodFailure>) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.OtherFailures [property]: [read-only] (WoofWare.NUnitTestRunner.UserMethodFailure * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.FixtureRunResults.Success [property]: [read-only] (WoofWare.NUnitTestRunner.SingleTestMethod * WoofWare.NUnitTestRunner.TestMemberSuccess * WoofWare.NUnitTestRunner.IndividualTestRunMetadata) list
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata inherit obj, implements WoofWare.NUnitTestRunner.IndividualTestRunMetadata System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.IndividualTestRunMetadata System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata..ctor [constructor]: (System.TimeSpan, System.DateTimeOffset, System.DateTimeOffset, string, System.Guid, System.Guid, string, string, string option, string option)
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.ClassName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.ComputerName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.End [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.ExecutionId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_ClassName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_ComputerName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_End [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_ExecutionId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_Start [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_StdErr [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_StdOut [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_TestId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_TestName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.get_Total [method]: unit -> System.TimeSpan
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.Start [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.StdErr [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.StdOut [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.Total [property]: [read-only] System.TimeSpan
|
||||
WoofWare.NUnitTestRunner.ITestProgress - interface with 5 member(s)
|
||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestFailed [method]: string -> WoofWare.NUnitTestRunner.TestMemberFailure -> unit
|
||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestFixtureStart [method]: string -> int -> unit
|
||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberFinished [method]: string -> unit
|
||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> unit
|
||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberStart [method]: string -> unit
|
||||
WoofWare.NUnitTestRunner.Match inherit obj, implements WoofWare.NUnitTestRunner.Match System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.Match System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
|
||||
WoofWare.NUnitTestRunner.Match+Contains inherit WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Match+Contains.get_Item [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.Match+Contains.Item [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.Match+Exact inherit WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Match+Exact.get_Item [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.Match+Exact.Item [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.Match+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.Match+Tags.Contains [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.Match+Tags.Exact [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.Match.get_IsContains [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Match.get_IsExact [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Match.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.Match.IsContains [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Match.IsExact [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Match.NewContains [static method]: string -> WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Match.NewExact [static method]: string -> WoofWare.NUnitTestRunner.Match
|
||||
WoofWare.NUnitTestRunner.Match.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.Modifier inherit obj, implements WoofWare.NUnitTestRunner.Modifier System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.Modifier System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
|
||||
WoofWare.NUnitTestRunner.Modifier+Explicit inherit WoofWare.NUnitTestRunner.Modifier
|
||||
WoofWare.NUnitTestRunner.Modifier+Explicit.get_reason [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.Modifier+Explicit.reason [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.Modifier+Ignored inherit WoofWare.NUnitTestRunner.Modifier
|
||||
WoofWare.NUnitTestRunner.Modifier+Ignored.get_reason [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.Modifier+Ignored.reason [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.Modifier+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.Modifier+Tags.Explicit [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.Modifier+Tags.Ignored [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.Modifier.get_IsExplicit [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Modifier.get_IsIgnored [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.Modifier.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.Modifier.IsExplicit [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Modifier.IsIgnored [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.Modifier.NewExplicit [static method]: string option -> WoofWare.NUnitTestRunner.Modifier
|
||||
WoofWare.NUnitTestRunner.Modifier.NewIgnored [static method]: string option -> WoofWare.NUnitTestRunner.Modifier
|
||||
WoofWare.NUnitTestRunner.Modifier.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod inherit obj, implements WoofWare.NUnitTestRunner.SingleTestMethod System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod..ctor [constructor]: (System.Reflection.MethodInfo, WoofWare.NUnitTestRunner.TestKind, WoofWare.NUnitTestRunner.Modifier list, string list, int option, WoofWare.NUnitTestRunner.Combinatorial option)
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Categories [property]: [read-only] string list
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Combinatorial [property]: [read-only] WoofWare.NUnitTestRunner.Combinatorial option
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Categories [method]: unit -> string list
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Combinatorial [method]: unit -> WoofWare.NUnitTestRunner.Combinatorial option
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Kind [method]: unit -> WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Method [method]: unit -> System.Reflection.MethodInfo
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Modifiers [method]: unit -> WoofWare.NUnitTestRunner.Modifier list
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.get_Repeat [method]: unit -> int option
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Kind [property]: [read-only] WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Method [property]: [read-only] System.Reflection.MethodInfo
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Modifiers [property]: [read-only] WoofWare.NUnitTestRunner.Modifier list
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.SingleTestMethod.Repeat [property]: [read-only] int option
|
||||
WoofWare.NUnitTestRunner.SingleTestMethodModule inherit obj
|
||||
WoofWare.NUnitTestRunner.SingleTestMethodModule.parse [static method]: string list -> System.Reflection.MethodInfo -> System.Reflection.CustomAttributeData list -> (WoofWare.NUnitTestRunner.SingleTestMethod option * System.Reflection.CustomAttributeData list)
|
||||
WoofWare.NUnitTestRunner.TestFailure inherit obj, implements WoofWare.NUnitTestRunner.TestFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
|
||||
WoofWare.NUnitTestRunner.TestFailure+SetUpFailed inherit WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+SetUpFailed.get_Item [method]: unit -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+SetUpFailed.Item [property]: [read-only] WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TestFailure+Tags.SetUpFailed [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TestFailure+Tags.TearDownFailed [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.TestFailure+Tags.TestFailed [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TestFailure+TearDownFailed inherit WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+TearDownFailed.get_Item [method]: unit -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+TearDownFailed.Item [property]: [read-only] WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+TestFailed inherit WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+TestFailed.get_Item [method]: unit -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure+TestFailed.Item [property]: [read-only] WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure.get_IsSetUpFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.get_IsTearDownFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.get_IsTestFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TestFailure.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TestFailure.IsSetUpFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.IsTearDownFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.IsTestFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestFailure.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TestFailure.NewSetUpFailed [static method]: WoofWare.NUnitTestRunner.UserMethodFailure -> WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure.NewTearDownFailed [static method]: WoofWare.NUnitTestRunner.UserMethodFailure -> WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure.NewTestFailed [static method]: WoofWare.NUnitTestRunner.UserMethodFailure -> WoofWare.NUnitTestRunner.TestFailure
|
||||
WoofWare.NUnitTestRunner.TestFailure.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TestFixture inherit obj, implements WoofWare.NUnitTestRunner.TestFixture System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TestFixture..ctor [constructor]: (System.Reflection.Assembly, string, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, WoofWare.NUnitTestRunner.SingleTestMethod list)
|
||||
WoofWare.NUnitTestRunner.TestFixture.ContainingAssembly [property]: [read-only] System.Reflection.Assembly
|
||||
WoofWare.NUnitTestRunner.TestFixture.Empty [static method]: System.Reflection.Assembly -> string -> WoofWare.NUnitTestRunner.TestFixture
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_ContainingAssembly [method]: unit -> System.Reflection.Assembly
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_OneTimeSetUp [method]: unit -> System.Reflection.MethodInfo option
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_OneTimeTearDown [method]: unit -> System.Reflection.MethodInfo option
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_SetUp [method]: unit -> System.Reflection.MethodInfo list
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_TearDown [method]: unit -> System.Reflection.MethodInfo list
|
||||
WoofWare.NUnitTestRunner.TestFixture.get_Tests [method]: unit -> WoofWare.NUnitTestRunner.SingleTestMethod list
|
||||
WoofWare.NUnitTestRunner.TestFixture.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TestFixture.OneTimeSetUp [property]: [read-only] System.Reflection.MethodInfo option
|
||||
WoofWare.NUnitTestRunner.TestFixture.OneTimeTearDown [property]: [read-only] System.Reflection.MethodInfo option
|
||||
WoofWare.NUnitTestRunner.TestFixture.SetUp [property]: [read-only] System.Reflection.MethodInfo list
|
||||
WoofWare.NUnitTestRunner.TestFixture.TearDown [property]: [read-only] System.Reflection.MethodInfo list
|
||||
WoofWare.NUnitTestRunner.TestFixture.Tests [property]: [read-only] WoofWare.NUnitTestRunner.SingleTestMethod list
|
||||
WoofWare.NUnitTestRunner.TestFixtureModule inherit obj
|
||||
WoofWare.NUnitTestRunner.TestFixtureModule.parse [static method]: System.Type -> WoofWare.NUnitTestRunner.TestFixture
|
||||
WoofWare.NUnitTestRunner.TestFixtureModule.run [static method]: WoofWare.NUnitTestRunner.ITestProgress -> (WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.SingleTestMethod -> bool) -> WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.FixtureRunResults
|
||||
WoofWare.NUnitTestRunner.TestKind inherit obj, implements WoofWare.NUnitTestRunner.TestKind System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
|
||||
WoofWare.NUnitTestRunner.TestKind+Data inherit WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind+Data.get_Item [method]: unit -> obj list list
|
||||
WoofWare.NUnitTestRunner.TestKind+Data.Item [property]: [read-only] obj list list
|
||||
WoofWare.NUnitTestRunner.TestKind+Source inherit WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind+Source.get_Item [method]: unit -> string list
|
||||
WoofWare.NUnitTestRunner.TestKind+Source.Item [property]: [read-only] string list
|
||||
WoofWare.NUnitTestRunner.TestKind+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TestKind+Tags.Data [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.TestKind+Tags.Single [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TestKind+Tags.Source [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TestKind.get_IsData [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestKind.get_IsSingle [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestKind.get_IsSource [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestKind.get_Single [static method]: unit -> WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TestKind.IsData [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestKind.IsSingle [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestKind.IsSource [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestKind.NewData [static method]: obj list list -> WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind.NewSource [static method]: string list -> WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind.Single [static property]: [read-only] WoofWare.NUnitTestRunner.TestKind
|
||||
WoofWare.NUnitTestRunner.TestKind.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure inherit obj, implements WoofWare.NUnitTestRunner.TestMemberFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Failed inherit WoofWare.NUnitTestRunner.TestMemberFailure
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Failed.get_Item [method]: unit -> WoofWare.NUnitTestRunner.TestFailure list
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Failed.Item [property]: [read-only] WoofWare.NUnitTestRunner.TestFailure list
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Malformed inherit WoofWare.NUnitTestRunner.TestMemberFailure
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Malformed.get_reasons [method]: unit -> string list
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Malformed.reasons [property]: [read-only] string list
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Tags.Failed [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure+Tags.Malformed [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.get_IsFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.get_IsMalformed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.IsFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.IsMalformed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.NewFailed [static method]: WoofWare.NUnitTestRunner.TestFailure list -> WoofWare.NUnitTestRunner.TestMemberFailure
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.NewMalformed [static method]: string list -> WoofWare.NUnitTestRunner.TestMemberFailure
|
||||
WoofWare.NUnitTestRunner.TestMemberFailure.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess inherit obj, implements WoofWare.NUnitTestRunner.TestMemberSuccess System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.TestMemberSuccess System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 4 cases
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Explicit inherit WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Explicit.get_reason [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Explicit.reason [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Ignored inherit WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Ignored.get_reason [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Ignored.reason [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Inconclusive inherit WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Inconclusive.get_reason [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Inconclusive.reason [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Tags.Explicit [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Tags.Ignored [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Tags.Inconclusive [static field]: int = 3
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess+Tags.Ok [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_IsExplicit [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_IsIgnored [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_IsInconclusive [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_IsOk [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_Ok [static method]: unit -> WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.IsExplicit [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.IsIgnored [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.IsInconclusive [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.IsOk [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.NewExplicit [static method]: string option -> WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.NewIgnored [static method]: string option -> WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.NewInconclusive [static method]: string option -> WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.Ok [static property]: [read-only] WoofWare.NUnitTestRunner.TestMemberSuccess
|
||||
WoofWare.NUnitTestRunner.TestMemberSuccess.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TestProgress inherit obj
|
||||
WoofWare.NUnitTestRunner.TestProgress.toStderr [static method]: unit -> WoofWare.NUnitTestRunner.ITestProgress
|
||||
WoofWare.NUnitTestRunner.TrxCounters inherit obj, implements WoofWare.NUnitTestRunner.TrxCounters System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxCounters..ctor [constructor]: (System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32)
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Aborted [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.AddFailed [method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxCounters.AddInconclusive [method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxCounters.AddNotExecuted [method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxCounters.AddPassed [method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Completed [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Disconnected [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Errors [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Executed [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Failed [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Aborted [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Completed [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Disconnected [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Errors [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Executed [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Failed [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Inconclusive [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_InProgress [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_NotExecuted [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_NotRunnable [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Passed [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_PassedButRunAborted [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Pending [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Timeout [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Total [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Warning [method]: unit -> System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.get_Zero [static method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Inconclusive [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.InProgress [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.NotExecuted [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.NotRunnable [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Passed [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.PassedButRunAborted [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Pending [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Timeout [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Total [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Warning [property]: [read-only] System.UInt32
|
||||
WoofWare.NUnitTestRunner.TrxCounters.Zero [static property]: [read-only] WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxDeployment inherit obj, implements WoofWare.NUnitTestRunner.TrxDeployment System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxDeployment..ctor [constructor]: string
|
||||
WoofWare.NUnitTestRunner.TrxDeployment.get_RunDeploymentRoot [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxDeployment.RunDeploymentRoot [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo inherit obj, implements WoofWare.NUnitTestRunner.TrxErrorInfo System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo..ctor [constructor]: (string option, string option)
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo.get_Message [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo.get_StackTrace [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo.Message [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TrxErrorInfo.StackTrace [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TrxExecution inherit obj, implements WoofWare.NUnitTestRunner.TrxExecution System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxExecution..ctor [constructor]: System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxExecution.get_Id [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxExecution.Id [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxOutcome inherit obj, implements WoofWare.NUnitTestRunner.TrxOutcome System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
|
||||
WoofWare.NUnitTestRunner.TrxOutcome+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TrxOutcome+Tags.Completed [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TrxOutcome+Tags.Failed [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.TrxOutcome+Tags.Warning [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.Completed [static property]: [read-only] WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.Failed [static property]: [read-only] WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_Completed [static method]: unit -> WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_Failed [static method]: unit -> WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_IsCompleted [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_IsFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_IsWarning [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.get_Warning [static method]: unit -> WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.IsCompleted [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.IsFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.IsWarning [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.Parse [static method]: string -> WoofWare.NUnitTestRunner.TrxOutcome option
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TrxOutcome.Warning [static property]: [read-only] WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxOutput inherit obj, implements WoofWare.NUnitTestRunner.TrxOutput System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxOutput..ctor [constructor]: (string option, WoofWare.NUnitTestRunner.TrxErrorInfo option)
|
||||
WoofWare.NUnitTestRunner.TrxOutput.ErrorInfo [property]: [read-only] WoofWare.NUnitTestRunner.TrxErrorInfo option
|
||||
WoofWare.NUnitTestRunner.TrxOutput.get_ErrorInfo [method]: unit -> WoofWare.NUnitTestRunner.TrxErrorInfo option
|
||||
WoofWare.NUnitTestRunner.TrxOutput.get_StdOut [method]: unit -> string option
|
||||
WoofWare.NUnitTestRunner.TrxOutput.StdOut [property]: [read-only] string option
|
||||
WoofWare.NUnitTestRunner.TrxReport inherit obj, implements WoofWare.NUnitTestRunner.TrxReport System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxReport..ctor [constructor]: (System.Guid, string, WoofWare.NUnitTestRunner.TrxReportTimes, WoofWare.NUnitTestRunner.TrxTestSettings, WoofWare.NUnitTestRunner.TrxUnitTestResult list, WoofWare.NUnitTestRunner.TrxUnitTest list, WoofWare.NUnitTestRunner.TrxTestEntry list, WoofWare.NUnitTestRunner.TrxTestListEntry list, WoofWare.NUnitTestRunner.TrxResultsSummary)
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_Id [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_Results [method]: unit -> WoofWare.NUnitTestRunner.TrxUnitTestResult list
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_ResultsSummary [method]: unit -> WoofWare.NUnitTestRunner.TrxResultsSummary
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_Settings [method]: unit -> WoofWare.NUnitTestRunner.TrxTestSettings
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_TestDefinitions [method]: unit -> WoofWare.NUnitTestRunner.TrxUnitTest list
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_TestEntries [method]: unit -> WoofWare.NUnitTestRunner.TrxTestEntry list
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_TestLists [method]: unit -> WoofWare.NUnitTestRunner.TrxTestListEntry list
|
||||
WoofWare.NUnitTestRunner.TrxReport.get_Times [method]: unit -> WoofWare.NUnitTestRunner.TrxReportTimes
|
||||
WoofWare.NUnitTestRunner.TrxReport.Id [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxReport.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxReport.Results [property]: [read-only] WoofWare.NUnitTestRunner.TrxUnitTestResult list
|
||||
WoofWare.NUnitTestRunner.TrxReport.ResultsSummary [property]: [read-only] WoofWare.NUnitTestRunner.TrxResultsSummary
|
||||
WoofWare.NUnitTestRunner.TrxReport.Settings [property]: [read-only] WoofWare.NUnitTestRunner.TrxTestSettings
|
||||
WoofWare.NUnitTestRunner.TrxReport.TestDefinitions [property]: [read-only] WoofWare.NUnitTestRunner.TrxUnitTest list
|
||||
WoofWare.NUnitTestRunner.TrxReport.TestEntries [property]: [read-only] WoofWare.NUnitTestRunner.TrxTestEntry list
|
||||
WoofWare.NUnitTestRunner.TrxReport.TestLists [property]: [read-only] WoofWare.NUnitTestRunner.TrxTestListEntry list
|
||||
WoofWare.NUnitTestRunner.TrxReport.Times [property]: [read-only] WoofWare.NUnitTestRunner.TrxReportTimes
|
||||
WoofWare.NUnitTestRunner.TrxReportModule inherit obj
|
||||
WoofWare.NUnitTestRunner.TrxReportModule.parse [static method]: string -> Microsoft.FSharp.Core.FSharpResult<WoofWare.NUnitTestRunner.TrxReport, string>
|
||||
WoofWare.NUnitTestRunner.TrxReportModule.toXml [static method]: WoofWare.NUnitTestRunner.TrxReport -> System.Xml.XmlDocument
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes inherit obj, implements WoofWare.NUnitTestRunner.TrxReportTimes System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes..ctor [constructor]: (System.DateTimeOffset, System.DateTimeOffset, System.DateTimeOffset, System.DateTimeOffset)
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.Creation [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.Finish [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.get_Creation [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.get_Finish [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.get_Queuing [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.get_Start [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.Queuing [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxReportTimes.Start [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary inherit obj, implements WoofWare.NUnitTestRunner.TrxResultsSummary System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary..ctor [constructor]: (WoofWare.NUnitTestRunner.TrxOutcome, WoofWare.NUnitTestRunner.TrxCounters, WoofWare.NUnitTestRunner.TrxOutput, WoofWare.NUnitTestRunner.TrxRunInfo list)
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.Counters [property]: [read-only] WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.get_Counters [method]: unit -> WoofWare.NUnitTestRunner.TrxCounters
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.get_Outcome [method]: unit -> WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.get_Output [method]: unit -> WoofWare.NUnitTestRunner.TrxOutput
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.get_RunInfos [method]: unit -> WoofWare.NUnitTestRunner.TrxRunInfo list
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.Outcome [property]: [read-only] WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.Output [property]: [read-only] WoofWare.NUnitTestRunner.TrxOutput
|
||||
WoofWare.NUnitTestRunner.TrxResultsSummary.RunInfos [property]: [read-only] WoofWare.NUnitTestRunner.TrxRunInfo list
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo inherit obj, implements WoofWare.NUnitTestRunner.TrxRunInfo System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo..ctor [constructor]: (string, WoofWare.NUnitTestRunner.TrxOutcome, System.DateTimeOffset, string)
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.ComputerName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.get_ComputerName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.get_Outcome [method]: unit -> WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.get_Text [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.get_Timestamp [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.Outcome [property]: [read-only] WoofWare.NUnitTestRunner.TrxOutcome
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.Text [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxRunInfo.Timestamp [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry inherit obj, implements WoofWare.NUnitTestRunner.TrxTestEntry System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry..ctor [constructor]: (System.Guid, System.Guid, System.Guid)
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.ExecutionId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.get_ExecutionId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.get_TestId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.get_TestListId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.TestId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestEntry.TestListId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry inherit obj, implements WoofWare.NUnitTestRunner.TrxTestListEntry System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry..ctor [constructor]: (string, System.Guid)
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry.get_Id [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry.Id [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestListEntry.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod inherit obj, implements WoofWare.NUnitTestRunner.TrxTestMethod System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod..ctor [constructor]: (string, System.Uri, string, string)
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.AdapterTypeName [property]: [read-only] System.Uri
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.ClassName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.CodeBase [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.get_AdapterTypeName [method]: unit -> System.Uri
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.get_ClassName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.get_CodeBase [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxTestMethod.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome inherit obj, implements WoofWare.NUnitTestRunner.TrxTestOutcome System.IEquatable, System.Collections.IStructuralEquatable - union type with 4 cases
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome+Tags.Failed [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome+Tags.Inconclusive [static field]: int = 3
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome+Tags.NotExecuted [static field]: int = 2
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome+Tags.Passed [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.Failed [static property]: [read-only] WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_Failed [static method]: unit -> WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_Inconclusive [static method]: unit -> WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_IsFailed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_IsInconclusive [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_IsNotExecuted [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_IsPassed [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_NotExecuted [static method]: unit -> WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_Passed [static method]: unit -> WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.Inconclusive [static property]: [read-only] WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.IsFailed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.IsInconclusive [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.IsNotExecuted [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.IsPassed [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.NotExecuted [static property]: [read-only] WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.Parse [static method]: string -> WoofWare.NUnitTestRunner.TrxTestOutcome option
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.Passed [static property]: [read-only] WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxTestOutcome.Tag [property]: [read-only] int
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings inherit obj, implements WoofWare.NUnitTestRunner.TrxTestSettings System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings..ctor [constructor]: (string, System.Guid, WoofWare.NUnitTestRunner.TrxDeployment)
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.Deployment [property]: [read-only] WoofWare.NUnitTestRunner.TrxDeployment
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.get_Deployment [method]: unit -> WoofWare.NUnitTestRunner.TrxDeployment
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.get_Id [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.Id [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxTestSettings.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest inherit obj, implements WoofWare.NUnitTestRunner.TrxUnitTest System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest..ctor [constructor]: (string, string, System.Guid, WoofWare.NUnitTestRunner.TrxExecution, WoofWare.NUnitTestRunner.TrxTestMethod)
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.Execution [property]: [read-only] WoofWare.NUnitTestRunner.TrxExecution
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.get_Execution [method]: unit -> WoofWare.NUnitTestRunner.TrxExecution
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.get_Id [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.get_Storage [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.get_TestMethod [method]: unit -> WoofWare.NUnitTestRunner.TrxTestMethod
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.Id [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.Storage [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTest.TestMethod [property]: [read-only] WoofWare.NUnitTestRunner.TrxTestMethod
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult inherit obj, implements WoofWare.NUnitTestRunner.TrxUnitTestResult System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult..ctor [constructor]: (System.Guid, System.Guid, string, string, System.TimeSpan, System.DateTimeOffset, System.DateTimeOffset, System.Guid, WoofWare.NUnitTestRunner.TrxTestOutcome, System.Guid, string, WoofWare.NUnitTestRunner.TrxOutput option)
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.ComputerName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.Duration [property]: [read-only] System.TimeSpan
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.EndTime [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.ExecutionId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_ComputerName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_Duration [method]: unit -> System.TimeSpan
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_EndTime [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_ExecutionId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_Outcome [method]: unit -> WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_Output [method]: unit -> WoofWare.NUnitTestRunner.TrxOutput option
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_RelativeResultsDirectory [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_StartTime [method]: unit -> System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_TestId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_TestListId [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_TestName [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.get_TestType [method]: unit -> System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.Outcome [property]: [read-only] WoofWare.NUnitTestRunner.TrxTestOutcome
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.Output [property]: [read-only] WoofWare.NUnitTestRunner.TrxOutput option
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.RelativeResultsDirectory [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.StartTime [property]: [read-only] System.DateTimeOffset
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestListId [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestName [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestType [property]: [read-only] System.Guid
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure inherit obj, implements WoofWare.NUnitTestRunner.UserMethodFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit inherit WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_result [method]: unit -> obj
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.result [property]: [read-only] obj
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Tags inherit obj
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Tags.ReturnedNonUnit [static field]: int = 0
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Tags.Threw [static field]: int = 1
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw inherit WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.get_Item2 [method]: unit -> System.Exception
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.get_name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.Item2 [property]: [read-only] System.Exception
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_IsReturnedNonUnit [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_IsThrew [method]: unit -> bool
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_Name [method]: unit -> string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_Tag [method]: unit -> int
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.IsReturnedNonUnit [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.IsThrew [property]: [read-only] bool
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.Name [property]: [read-only] string
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.NewReturnedNonUnit [static method]: (string, obj) -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.NewThrew [static method]: (string, System.Exception) -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||
WoofWare.NUnitTestRunner.UserMethodFailure.Tag [property]: [read-only] int
|
620
WoofWare.NUnitTestRunner.Lib/TestFixture.fs
Normal file
620
WoofWare.NUnitTestRunner.Lib/TestFixture.fs
Normal file
@@ -0,0 +1,620 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Reflection
|
||||
open System.Threading
|
||||
open Microsoft.FSharp.Core
|
||||
|
||||
type private StdoutSetter (newStdout : StreamWriter, newStderr : StreamWriter) =
|
||||
let oldStdout = Console.Out
|
||||
let oldStderr = Console.Error
|
||||
|
||||
do
|
||||
Console.SetOut newStdout
|
||||
Console.SetError newStderr
|
||||
|
||||
interface IDisposable with
|
||||
member _.Dispose () =
|
||||
Console.SetOut oldStdout
|
||||
Console.SetError oldStderr
|
||||
|
||||
/// Information about the circumstances of a run of a single test.
|
||||
type IndividualTestRunMetadata =
|
||||
{
|
||||
/// How long the test took.
|
||||
Total : TimeSpan
|
||||
/// When the test started.
|
||||
Start : DateTimeOffset
|
||||
/// When the test ended.
|
||||
End : DateTimeOffset
|
||||
/// The Environment.MachineName of the computer on which the run happened.
|
||||
ComputerName : string
|
||||
/// An identifier for this run of this test.
|
||||
ExecutionId : Guid
|
||||
/// An identifier for this test (possibly shared across repeats of this exact test with the same args).
|
||||
TestId : Guid
|
||||
/// Human-readable string representing this individual single test run, including any parameters.
|
||||
TestName : string
|
||||
/// Name of the class from which this test derived
|
||||
ClassName : string
|
||||
/// Anything that was printed to stdout while the test ran.
|
||||
StdOut : string option
|
||||
/// Anything that was printed to stderr while the test ran.
|
||||
StdErr : string option
|
||||
}
|
||||
|
||||
/// The results of running a single TestFixture.
|
||||
type FixtureRunResults =
|
||||
{
|
||||
/// These tests failed.
|
||||
/// TODO: domain is squiffy, the TestMemberFailure wants to be instead a TestFailure
|
||||
Failed : (TestMemberFailure * IndividualTestRunMetadata) list
|
||||
/// These tests succeeded.
|
||||
/// A given test method may appear many times in this list, if it represented many tests.
|
||||
Success : (SingleTestMethod * TestMemberSuccess * IndividualTestRunMetadata) list
|
||||
/// These failures occurred outside the context of a test - e.g. in setup or tear-down logic.
|
||||
OtherFailures : (UserMethodFailure * IndividualTestRunMetadata) list
|
||||
}
|
||||
|
||||
/// Another view on the data contained in this object, transposed.
|
||||
member this.IndividualTestRunMetadata
|
||||
: (IndividualTestRunMetadata * Choice<TestMemberFailure, TestMemberSuccess, UserMethodFailure>) list =
|
||||
[
|
||||
for a, d in this.Failed do
|
||||
yield d, Choice1Of3 a
|
||||
for _, a, d in this.Success do
|
||||
yield d, Choice2Of3 a
|
||||
for a, d in this.OtherFailures do
|
||||
yield d, Choice3Of3 a
|
||||
]
|
||||
|
||||
/// A test fixture (usually represented by the [<TestFixture>]` attribute), which may contain many tests,
|
||||
/// each of which may run many times.
|
||||
[<RequireQualifiedAccess>]
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
||||
module TestFixture =
|
||||
/// It's possible for multiple things to fail about a test: e.g. the test failed and also the tear-down failed.
|
||||
///
|
||||
/// This function does not throw.
|
||||
let private runOne
|
||||
(setUp : MethodInfo list)
|
||||
(tearDown : MethodInfo list)
|
||||
(testId : Guid)
|
||||
(test : MethodInfo)
|
||||
(containingObject : obj)
|
||||
(args : obj[])
|
||||
: Result<TestMemberSuccess, TestFailure list> * IndividualTestRunMetadata
|
||||
=
|
||||
let rec runMethods
|
||||
(wrap : UserMethodFailure -> TestFailure)
|
||||
(toRun : MethodInfo list)
|
||||
(args : obj[])
|
||||
: Result<unit, _>
|
||||
=
|
||||
match toRun with
|
||||
| [] -> Ok ()
|
||||
| head :: rest ->
|
||||
let result =
|
||||
try
|
||||
head.Invoke (containingObject, args) |> Ok
|
||||
with :? TargetInvocationException as e ->
|
||||
Error (UserMethodFailure.Threw (head.Name, e.InnerException))
|
||||
|
||||
match result with
|
||||
| Error e -> Error (wrap e)
|
||||
| Ok result ->
|
||||
match result with
|
||||
| :? unit -> runMethods wrap rest args
|
||||
| ret -> UserMethodFailure.ReturnedNonUnit (head.Name, ret) |> wrap |> Error
|
||||
|
||||
let start = DateTimeOffset.Now
|
||||
|
||||
use stdOutStream = new MemoryStream ()
|
||||
use stdErrStream = new MemoryStream ()
|
||||
use stdOut = new StreamWriter (stdOutStream)
|
||||
use stdErr = new StreamWriter (stdErrStream)
|
||||
|
||||
use _ = new StdoutSetter (stdOut, stdErr)
|
||||
|
||||
let sw = Stopwatch.StartNew ()
|
||||
|
||||
let metadata () =
|
||||
let name =
|
||||
if args.Length = 0 then
|
||||
test.Name
|
||||
else
|
||||
let argsStr = args |> Seq.map string<obj> |> String.concat ","
|
||||
$"%s{test.Name}(%s{argsStr})"
|
||||
|
||||
{
|
||||
End = DateTimeOffset.Now
|
||||
Start = start
|
||||
Total = sw.Elapsed
|
||||
ComputerName = Environment.MachineName
|
||||
ExecutionId = Guid.NewGuid ()
|
||||
TestId = testId
|
||||
TestName = name
|
||||
ClassName = test.DeclaringType.FullName
|
||||
StdOut =
|
||||
match stdOutStream.ToArray () with
|
||||
| [||] -> None
|
||||
| arr -> Console.OutputEncoding.GetString arr |> Some
|
||||
StdErr =
|
||||
match stdErrStream.ToArray () with
|
||||
| [||] -> None
|
||||
| arr -> Console.OutputEncoding.GetString arr |> Some
|
||||
}
|
||||
|
||||
let setUpResult = runMethods TestFailure.SetUpFailed setUp [||]
|
||||
sw.Stop ()
|
||||
|
||||
match setUpResult with
|
||||
| Error e -> Error [ e ], metadata ()
|
||||
| Ok () ->
|
||||
|
||||
sw.Start ()
|
||||
|
||||
let result =
|
||||
let result = runMethods TestFailure.TestFailed [ test ] args
|
||||
sw.Stop ()
|
||||
|
||||
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.
|
||||
sw.Start ()
|
||||
let tearDownResult = runMethods TestFailure.TearDownFailed tearDown [||]
|
||||
sw.Stop ()
|
||||
|
||||
let metadata = metadata ()
|
||||
|
||||
match result, tearDownResult with
|
||||
| Ok None, Ok () -> Ok TestMemberSuccess.Ok, metadata
|
||||
| Ok (Some s), Ok () -> Ok s, metadata
|
||||
| Error e, Ok ()
|
||||
| Ok _, Error e -> Error [ e ], metadata
|
||||
| Error e1, Error e2 -> Error [ e1 ; e2 ], metadata
|
||||
|
||||
let private getValues (test : SingleTestMethod) =
|
||||
let valuesAttrs =
|
||||
test.Method.GetParameters ()
|
||||
|> Array.map (fun i ->
|
||||
i.CustomAttributes
|
||||
|> Seq.choose (fun i ->
|
||||
if i.AttributeType.FullName = "NUnit.Framework.ValuesAttribute" then
|
||||
Some i.ConstructorArguments
|
||||
else
|
||||
None
|
||||
)
|
||||
|> Seq.toList
|
||||
|> function
|
||||
| [] -> Ok None
|
||||
| [ x ] -> Ok (Some x)
|
||||
| _ :: _ :: _ ->
|
||||
"Multiple Values attributes on a parameter. Exactly one per parameter please."
|
||||
|> Error
|
||||
)
|
||||
|> Array.allOkOrError
|
||||
|
||||
match valuesAttrs with
|
||||
| Error (_, e) -> Error (TestMemberFailure.Malformed (List.ofArray e))
|
||||
| Ok valuesAttrs ->
|
||||
|
||||
if valuesAttrs |> Array.exists (fun l -> l.IsSome) then
|
||||
if valuesAttrs |> Array.exists (fun l -> l.IsNone) then
|
||||
failwith
|
||||
$"Test '%s{test.Name}' has a parameter with the Values attribute and a parameter without. All parameters must have Values if any one does."
|
||||
|
||||
Some (valuesAttrs |> Array.map Option.get) |> Ok
|
||||
else
|
||||
Ok None
|
||||
|
||||
/// This method should never throw: it only throws if there's a critical logic error in the runner.
|
||||
/// Exceptions from the units under test are wrapped up and passed out.
|
||||
let private runTestsFromMember
|
||||
(setUp : MethodInfo list)
|
||||
(tearDown : MethodInfo list)
|
||||
(containingObject : obj)
|
||||
(test : SingleTestMethod)
|
||||
: (Result<TestMemberSuccess, TestMemberFailure> * IndividualTestRunMetadata) list
|
||||
=
|
||||
if test.Method.ContainsGenericParameters then
|
||||
let failureMetadata =
|
||||
{
|
||||
Total = TimeSpan.Zero
|
||||
Start = DateTimeOffset.Now
|
||||
End = DateTimeOffset.Now
|
||||
ComputerName = Environment.MachineName
|
||||
ExecutionId = Guid.NewGuid ()
|
||||
TestId = Guid.NewGuid ()
|
||||
TestName = test.Name
|
||||
ClassName = test.Method.DeclaringType.FullName
|
||||
StdErr = None
|
||||
StdOut = None
|
||||
}
|
||||
|
||||
let error =
|
||||
TestMemberFailure.Malformed [ "Test contained generic parameters; generics are not supported." ]
|
||||
|
||||
(Error error, failureMetadata) |> List.singleton
|
||||
else
|
||||
|
||||
let resultPreRun =
|
||||
(None, test.Modifiers)
|
||||
||> List.fold (fun _result modifier ->
|
||||
// TODO: would be nice not to throw away the accumulation,
|
||||
// and also when we get to being able to run Explicit tests we should discriminate exactly whether
|
||||
// there was an Ignore
|
||||
match modifier with
|
||||
| Modifier.Explicit reason ->
|
||||
// TODO: have a mode where we can run explicit tests
|
||||
Some (TestMemberSuccess.Explicit reason)
|
||||
| Modifier.Ignored reason -> Some (TestMemberSuccess.Ignored reason)
|
||||
)
|
||||
|
||||
let sw = Stopwatch.StartNew ()
|
||||
let startTime = DateTimeOffset.Now
|
||||
|
||||
match resultPreRun with
|
||||
| Some result ->
|
||||
sw.Stop ()
|
||||
|
||||
let failureMetadata =
|
||||
{
|
||||
Total = sw.Elapsed
|
||||
Start = startTime
|
||||
End = DateTimeOffset.Now
|
||||
ComputerName = Environment.MachineName
|
||||
ExecutionId = Guid.NewGuid ()
|
||||
// No need to keep these test GUIDs stable: no point trying to run an explicit test multiple times.
|
||||
TestId = Guid.NewGuid ()
|
||||
TestName = test.Name
|
||||
ClassName = test.Method.DeclaringType.FullName
|
||||
StdErr = None
|
||||
StdOut = None
|
||||
}
|
||||
|
||||
[ Ok result, failureMetadata ]
|
||||
| None ->
|
||||
|
||||
let individualTests =
|
||||
let values = getValues test
|
||||
|
||||
match values with
|
||||
| Error e -> Error e
|
||||
| Ok values ->
|
||||
match test.Kind, values with
|
||||
| TestKind.Data data, None -> data |> List.map (fun args -> Guid.NewGuid (), Array.ofList args) |> Ok
|
||||
| TestKind.Data _, Some _ ->
|
||||
[
|
||||
"Test has both the TestCase and Values attributes. Specify one or the other."
|
||||
]
|
||||
|> TestMemberFailure.Malformed
|
||||
|> Error
|
||||
| TestKind.Single, None -> (Guid.NewGuid (), [||]) |> List.singleton |> Ok
|
||||
| TestKind.Single, Some vals ->
|
||||
let combinatorial =
|
||||
Option.defaultValue Combinatorial.Combinatorial test.Combinatorial
|
||||
|
||||
match combinatorial with
|
||||
| Combinatorial.Combinatorial ->
|
||||
vals
|
||||
|> Seq.map (fun l -> l |> Seq.map (fun v -> v.Value) |> Seq.toList)
|
||||
|> Seq.toList
|
||||
|> List.combinations
|
||||
|> List.map (fun args -> Guid.NewGuid (), Array.ofList args)
|
||||
|> Ok
|
||||
| Combinatorial.Sequential ->
|
||||
let maxLength = vals |> Seq.map (fun i -> i.Count) |> Seq.max
|
||||
|
||||
List.init
|
||||
maxLength
|
||||
(fun i ->
|
||||
let args =
|
||||
vals
|
||||
|> Array.map (fun param -> if i >= param.Count then null else param.[i].Value)
|
||||
|
||||
Guid.NewGuid (), args
|
||||
)
|
||||
|> Ok
|
||||
| TestKind.Source _, Some _ ->
|
||||
[
|
||||
"Test has both the TestCaseSource and Values attributes. Specify one or the other."
|
||||
]
|
||||
|> TestMemberFailure.Malformed
|
||||
|> Error
|
||||
| TestKind.Source sources, None ->
|
||||
[
|
||||
for source in sources do
|
||||
let args =
|
||||
test.Method.DeclaringType.GetProperty (
|
||||
source,
|
||||
BindingFlags.Public
|
||||
||| BindingFlags.NonPublic
|
||||
||| BindingFlags.Instance
|
||||
||| BindingFlags.Static
|
||||
)
|
||||
|
||||
// Might not be an IEnumerable of a reference type.
|
||||
// Concretely, `FSharpList<HttpStatusCode> :> IEnumerable<obj>` fails.
|
||||
for arg in args.GetValue (null : obj) :?> System.Collections.IEnumerable do
|
||||
yield
|
||||
Guid.NewGuid (),
|
||||
match arg with
|
||||
| null -> [| (null : obj) |]
|
||||
| :? Tuple<obj, obj> as (a, b) -> [| a ; b |]
|
||||
| :? Tuple<obj, obj, obj> as (a, b, c) -> [| a ; b ; c |]
|
||||
| :? Tuple<obj, obj, obj, obj> as (a, b, c, d) -> [| a ; b ; c ; d |]
|
||||
| arg ->
|
||||
let argTy = arg.GetType ()
|
||||
|
||||
if argTy.FullName = "NUnit.Framework.TestCaseData" then
|
||||
let argsMem =
|
||||
argTy.GetMethod (
|
||||
"get_Arguments",
|
||||
BindingFlags.Public
|
||||
||| BindingFlags.Instance
|
||||
||| BindingFlags.FlattenHierarchy
|
||||
)
|
||||
|
||||
if isNull argsMem then
|
||||
failwith "Unexpectedly could not call `.Arguments` on TestCaseData"
|
||||
|
||||
(argsMem.Invoke (arg, [||]) |> unbox<obj[]>)
|
||||
else
|
||||
[| arg |]
|
||||
]
|
||||
|> Ok
|
||||
|
||||
sw.Stop ()
|
||||
|
||||
match individualTests with
|
||||
| Error e ->
|
||||
let failureMetadata =
|
||||
{
|
||||
Total = sw.Elapsed
|
||||
Start = startTime
|
||||
End = DateTimeOffset.Now
|
||||
ComputerName = Environment.MachineName
|
||||
ExecutionId = Guid.NewGuid ()
|
||||
// No need to keep these test GUIDs stable: we're not going to run them multiple times,
|
||||
// because we're not going to run anything at all.
|
||||
TestId = Guid.NewGuid ()
|
||||
TestName = test.Name
|
||||
ClassName = test.Method.DeclaringType.FullName
|
||||
StdErr = None
|
||||
StdOut = None
|
||||
}
|
||||
|
||||
[ Error e, failureMetadata ]
|
||||
| Ok individualTests ->
|
||||
|
||||
let count = test.Repeat |> Option.defaultValue 1
|
||||
|
||||
Seq.init count (fun _ -> individualTests)
|
||||
|> Seq.concat
|
||||
|> Seq.map (fun (testGuid, args) ->
|
||||
let results, summary =
|
||||
runOne setUp tearDown testGuid test.Method containingObject args
|
||||
|
||||
match results with
|
||||
| Ok results -> Ok results, summary
|
||||
| Error e -> Error (TestMemberFailure.Failed e), summary
|
||||
)
|
||||
|> Seq.toList
|
||||
|
||||
/// Run every test (except those which fail the `filter`) in this test fixture, as well as the
|
||||
/// appropriate setup and tear-down logic.
|
||||
let run
|
||||
(progress : ITestProgress)
|
||||
(filter : TestFixture -> SingleTestMethod -> bool)
|
||||
(tests : TestFixture)
|
||||
: FixtureRunResults
|
||||
=
|
||||
progress.OnTestFixtureStart tests.Name tests.Tests.Length
|
||||
|
||||
let containingObject =
|
||||
let methods =
|
||||
seq {
|
||||
match tests.OneTimeSetUp with
|
||||
| None -> ()
|
||||
| Some t -> yield t
|
||||
|
||||
match tests.OneTimeTearDown with
|
||||
| None -> ()
|
||||
| Some t -> yield t
|
||||
|
||||
yield! tests.Tests |> Seq.map (fun t -> t.Method)
|
||||
}
|
||||
|
||||
methods
|
||||
|> Seq.tryPick (fun mi ->
|
||||
if not mi.IsStatic then
|
||||
Some (Activator.CreateInstance mi.DeclaringType)
|
||||
else
|
||||
None
|
||||
)
|
||||
|> Option.toObj
|
||||
|
||||
let oldWorkDir = Environment.CurrentDirectory
|
||||
Environment.CurrentDirectory <- FileInfo(tests.ContainingAssembly.Location).Directory.FullName
|
||||
|
||||
let sw = Stopwatch.StartNew ()
|
||||
let startTime = DateTimeOffset.UtcNow
|
||||
|
||||
use stdOutStream = new MemoryStream ()
|
||||
use stdOut = new StreamWriter (stdOutStream)
|
||||
use stdErrStream = new MemoryStream ()
|
||||
use stdErr = new StreamWriter (stdErrStream)
|
||||
use _ = new StdoutSetter (stdOut, stdErr)
|
||||
|
||||
let endMetadata () =
|
||||
let stdOut = stdOutStream.ToArray () |> Console.OutputEncoding.GetString
|
||||
let stdErr = stdErrStream.ToArray () |> Console.OutputEncoding.GetString
|
||||
|
||||
{
|
||||
Total = sw.Elapsed
|
||||
Start = startTime
|
||||
End = DateTimeOffset.UtcNow
|
||||
ComputerName = Environment.MachineName
|
||||
ExecutionId = Guid.NewGuid ()
|
||||
TestId = Guid.NewGuid ()
|
||||
// This one is a bit dubious, because we don't actually have a test name at all
|
||||
TestName = tests.Name
|
||||
ClassName = tests.Name
|
||||
StdOut = if String.IsNullOrEmpty stdOut then None else Some stdOut
|
||||
StdErr = if String.IsNullOrEmpty stdErr then None else Some stdErr
|
||||
}
|
||||
|
||||
let setupResult =
|
||||
match tests.OneTimeSetUp with
|
||||
| Some su ->
|
||||
try
|
||||
match su.Invoke (containingObject, [||]) with
|
||||
| :? unit -> None
|
||||
| ret -> Some (UserMethodFailure.ReturnedNonUnit (su.Name, ret), endMetadata ())
|
||||
with :? TargetInvocationException as e ->
|
||||
Some (UserMethodFailure.Threw (su.Name, e.InnerException), endMetadata ())
|
||||
| _ -> None
|
||||
|
||||
let testFailures = ResizeArray<TestMemberFailure * IndividualTestRunMetadata> ()
|
||||
|
||||
let successes =
|
||||
ResizeArray<SingleTestMethod * TestMemberSuccess * IndividualTestRunMetadata> ()
|
||||
|
||||
match setupResult with
|
||||
| Some _ ->
|
||||
// Don't run any tests if setup failed.
|
||||
()
|
||||
| None ->
|
||||
for test in tests.Tests do
|
||||
if filter tests test then
|
||||
progress.OnTestMemberStart test.Name
|
||||
let testSuccess = ref 0
|
||||
|
||||
let results = runTestsFromMember tests.SetUp tests.TearDown containingObject test
|
||||
|
||||
for result, report in results do
|
||||
match result with
|
||||
| Error failure ->
|
||||
testFailures.Add (failure, report)
|
||||
progress.OnTestFailed test.Name failure
|
||||
| Ok result ->
|
||||
Interlocked.Increment testSuccess |> ignore<int>
|
||||
lock successes (fun () -> successes.Add (test, result, report))
|
||||
|
||||
progress.OnTestMemberFinished test.Name
|
||||
else
|
||||
progress.OnTestMemberSkipped test.Name
|
||||
|
||||
// Unconditionally run OneTimeTearDown if it exists.
|
||||
let tearDownError =
|
||||
match tests.OneTimeTearDown with
|
||||
| Some td ->
|
||||
try
|
||||
match td.Invoke (containingObject, [||]) with
|
||||
| null -> None
|
||||
| ret -> Some (UserMethodFailure.ReturnedNonUnit (td.Name, ret), endMetadata ())
|
||||
with :? TargetInvocationException as e ->
|
||||
Some (UserMethodFailure.Threw (td.Name, e), endMetadata ())
|
||||
| _ -> None
|
||||
|
||||
Environment.CurrentDirectory <- oldWorkDir
|
||||
|
||||
{
|
||||
Failed = testFailures |> Seq.toList
|
||||
Success = successes |> Seq.toList
|
||||
OtherFailures = [ tearDownError ; setupResult ] |> List.choose id
|
||||
}
|
||||
|
||||
/// Interpret this type as a [<TestFixture>], extracting the test members from it and annotating them with all
|
||||
/// relevant information about how we should run them.
|
||||
let parse (parentType : Type) : TestFixture =
|
||||
let categories =
|
||||
parentType.CustomAttributes
|
||||
|> Seq.filter (fun attr -> attr.AttributeType.FullName = "NUnit.Framework.CategoryAttribute")
|
||||
|> Seq.map (fun attr -> attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>)
|
||||
|> Seq.toList
|
||||
|
||||
(TestFixture.Empty parentType.Assembly parentType.Name, parentType.GetRuntimeMethods ())
|
||||
||> Seq.fold (fun state mi ->
|
||||
((state, []), mi.CustomAttributes)
|
||||
||> Seq.fold (fun (state, unrecognisedAttrs) attr ->
|
||||
match attr.AttributeType.FullName with
|
||||
| "NUnit.Framework.OneTimeSetUpAttribute" ->
|
||||
match state.OneTimeSetUp with
|
||||
| Some _existing -> failwith "Multiple OneTimeSetUp methods found"
|
||||
| None ->
|
||||
{ state with
|
||||
OneTimeSetUp = Some mi
|
||||
},
|
||||
unrecognisedAttrs
|
||||
| "NUnit.Framework.OneTimeTearDownAttribute" ->
|
||||
match state.OneTimeTearDown with
|
||||
| Some _existing -> failwith "Multiple OneTimeTearDown methods found"
|
||||
| None ->
|
||||
{ state with
|
||||
OneTimeTearDown = Some mi
|
||||
},
|
||||
unrecognisedAttrs
|
||||
| "NUnit.Framework.TearDownAttribute" ->
|
||||
{ state with
|
||||
TearDown = mi :: state.TearDown
|
||||
},
|
||||
unrecognisedAttrs
|
||||
| "NUnit.Framework.SetUpAttribute" ->
|
||||
{ state with
|
||||
SetUp = mi :: state.SetUp
|
||||
},
|
||||
unrecognisedAttrs
|
||||
| "NUnit.Framework.TestFixtureSetUpAttribute" ->
|
||||
failwith "TestFixtureSetUp is not supported (upstream has deprecated it; use OneTimeSetUp)"
|
||||
| "NUnit.Framework.TestFixtureTearDownAttribute" ->
|
||||
failwith "TestFixtureTearDown is not supported (upstream has deprecated it; use OneTimeTearDown)"
|
||||
| "NUnit.Framework.RetryAttribute" ->
|
||||
failwith "RetryAttribute is not supported. Don't write flaky tests."
|
||||
| "NUnit.Framework.RandomAttribute" ->
|
||||
failwith "RandomAttribute is not supported. Use a property-based testing framework like FsCheck."
|
||||
| "NUnit.Framework.AuthorAttribute"
|
||||
| "NUnit.Framework.CultureAttribute"
|
||||
| "NUnit.Framework.DescriptionAttribute" ->
|
||||
// ignoring for now: metadata only
|
||||
state, unrecognisedAttrs
|
||||
| _ -> state, attr :: unrecognisedAttrs
|
||||
)
|
||||
|> fun (state, unrecognised) ->
|
||||
let state, unrecognised =
|
||||
match SingleTestMethod.parse categories mi unrecognised with
|
||||
| Some test, unrecognised ->
|
||||
{ state with
|
||||
Tests = test :: state.Tests
|
||||
},
|
||||
unrecognised
|
||||
| None, unrecognised -> state, unrecognised
|
||||
|
||||
unrecognised
|
||||
|> List.filter (fun attr ->
|
||||
attr.AttributeType.FullName.StartsWith ("NUnit.Framework.", StringComparison.Ordinal)
|
||||
)
|
||||
|> function
|
||||
| [] -> ()
|
||||
| unrecognised ->
|
||||
unrecognised
|
||||
|> Seq.map (fun x -> x.AttributeType.FullName)
|
||||
|> String.concat ", "
|
||||
|> failwithf "Unrecognised attributes: %s"
|
||||
|
||||
state
|
||||
)
|
45
WoofWare.NUnitTestRunner.Lib/TestProgress.fs
Normal file
45
WoofWare.NUnitTestRunner.Lib/TestProgress.fs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System
|
||||
|
||||
/// Represents something which knows how to report progress through a test suite.
|
||||
/// Note that we don't guarantee anything about parallelism; you must make sure
|
||||
/// all implementations are safe to run concurrently.
|
||||
type ITestProgress =
|
||||
/// Called just before we start executing the setup logic for the given test fixture.
|
||||
/// We tell you how many test methods there are in the fixture.
|
||||
abstract OnTestFixtureStart : name : string -> testCount : int -> unit
|
||||
/// Called just before we start executing the test(s) indicated by a particular method.
|
||||
abstract OnTestMemberStart : name : string -> unit
|
||||
/// Called when a test fails. (This may be called repeatedly with the same `name`, e.g. if the test
|
||||
/// is run multiple times with different combinations of test data.)
|
||||
abstract OnTestFailed : name : string -> failure : TestMemberFailure -> unit
|
||||
/// Called when we've finished every test indicated by a particular method. (The test may have been run
|
||||
/// multiple times, e.g. with different combinations of test data.)
|
||||
abstract OnTestMemberFinished : name : string -> unit
|
||||
/// Called when we decide not to run the test(s) indicated by a particular method (e.g. because it's
|
||||
/// marked [<Explicit>]).
|
||||
abstract OnTestMemberSkipped : name : string -> unit
|
||||
|
||||
/// Methods for constructing specific ITestProgress objects.
|
||||
[<RequireQualifiedAccess>]
|
||||
module TestProgress =
|
||||
/// An ITestProgress which logs to stderr.
|
||||
let toStderr () : ITestProgress =
|
||||
{ new ITestProgress with
|
||||
member _.OnTestFixtureStart name testCount =
|
||||
let plural = if testCount = 1 then "" else "s"
|
||||
Console.Error.WriteLine $"Running test fixture: %s{name} (%i{testCount} test%s{plural} to run)"
|
||||
|
||||
member _.OnTestMemberStart name =
|
||||
Console.Error.WriteLine $"Running test: %s{name}"
|
||||
|
||||
member _.OnTestFailed name failure =
|
||||
Console.Error.WriteLine $"Test failed: %O{failure}"
|
||||
|
||||
member _.OnTestMemberFinished name =
|
||||
Console.Error.WriteLine $"Finished test %s{name}"
|
||||
|
||||
member _.OnTestMemberSkipped name =
|
||||
Console.Error.WriteLine $"Skipping test due to filter: %s{name}"
|
||||
}
|
1773
WoofWare.NUnitTestRunner.Lib/TrxReport.fs
Normal file
1773
WoofWare.NUnitTestRunner.Lib/TrxReport.fs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<Authors>Patrick Stevens</Authors>
|
||||
<Copyright>Copyright (c) Patrick Stevens 2024</Copyright>
|
||||
<Description>Library with primitives to allow you to run NUnit tests.</Description>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/Smaug123/unofficial-nunit-runner</RepositoryUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>nunit;test;runner</PackageTags>
|
||||
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarnOn>FS3559</WarnOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.fs" />
|
||||
<Compile Include="Array.fs" />
|
||||
<Compile Include="List.fs" />
|
||||
<Compile Include="Result.fs" />
|
||||
<Compile Include="Domain.fs" />
|
||||
<Compile Include="Filter.fs" />
|
||||
<Compile Include="SingleTestMethod.fs" />
|
||||
<Compile Include="TestProgress.fs" />
|
||||
<Compile Include="TestFixture.fs" />
|
||||
<Compile Include="Xml.fs" />
|
||||
<Compile Include="TrxReport.fs" />
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<EmbeddedResource Include="SurfaceBaseline.txt" />
|
||||
<EmbeddedResource Include="version.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WoofWare.PrattParser" Version="0.1.2" />
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
47
WoofWare.NUnitTestRunner.Lib/Xml.fs
Normal file
47
WoofWare.NUnitTestRunner.Lib/Xml.fs
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace WoofWare.NUnitTestRunner
|
||||
|
||||
open System.Xml
|
||||
|
||||
[<AutoOpen>]
|
||||
module internal XmlPatterns =
|
||||
[<return : Struct>]
|
||||
let (|NodeWithChildren|_|) (expectedName : string) (node : XmlNode) : unit voption =
|
||||
if node.Name = expectedName && node.HasChildNodes then
|
||||
ValueSome ()
|
||||
else
|
||||
ValueNone
|
||||
|
||||
let (|NodeWithNamedChild|_|) (childName : string) (node : XmlNode) : XmlNode option =
|
||||
if node.HasChildNodes then
|
||||
node.ChildNodes
|
||||
|> Seq.cast<XmlNode>
|
||||
|> Seq.tryFind (fun n -> n.Name = childName)
|
||||
else
|
||||
None
|
||||
|
||||
let (|OneChildNode|_|) (expectedName : string) (node : XmlNode) : XmlNode option =
|
||||
if node.Name = expectedName && node.HasChildNodes && node.ChildNodes.Count = 1 then
|
||||
Some node.FirstChild
|
||||
else
|
||||
None
|
||||
|
||||
let (|NoChildrenNode|_|) (node : XmlNode) : string option =
|
||||
if node.HasChildNodes then None else Some node.Value
|
||||
|
||||
[<return : Struct>]
|
||||
let (|NamedNoChildren|_|) (name : string) (node : XmlNode) : unit voption =
|
||||
if node.HasChildNodes then ValueNone
|
||||
elif node.Name = name then ValueSome ()
|
||||
else ValueNone
|
||||
|
||||
[<return : Struct>]
|
||||
let (|Int64|_|) (s : string) : int64 voption =
|
||||
match System.Int64.TryParse s with
|
||||
| false, _ -> ValueNone
|
||||
| true, v -> ValueSome v
|
||||
|
||||
[<return : Struct>]
|
||||
let (|Int|_|) (s : string) : int voption =
|
||||
match System.Int32.TryParse s with
|
||||
| false, _ -> ValueNone
|
||||
| true, v -> ValueSome v
|
11
WoofWare.NUnitTestRunner.Lib/version.json
Normal file
11
WoofWare.NUnitTestRunner.Lib/version.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.8",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/main$"
|
||||
],
|
||||
"pathFilters": [
|
||||
"./",
|
||||
":/Directory.Build.props",
|
||||
":/README.md"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user