Compare commits

...

3 Commits

Author SHA1 Message Date
dependabot[bot]
6583b9e025 Bump FSharp.Core and WoofWare.Myriad.Plugins (#247)
* Bump fsharp-analyzers from 0.29.1 to 0.30.0

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.29.1 to 0.30.0.
- [Release notes](https://github.com/ionide/FSharp.Analyzers.SDK/releases)
- [Changelog](https://github.com/ionide/FSharp.Analyzers.SDK/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ionide/FSharp.Analyzers.SDK/compare/v0.29.1...v0.30.0)

---
updated-dependencies:
- dependency-name: fsharp-analyzers
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump FSharp.Core and WoofWare.Myriad.Plugins

Bumps [FSharp.Core](https://github.com/dotnet/fsharp) and [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad). These dependencies needed to be updated together.

Updates `FSharp.Core` from 6.0.1 to 6.0.1
- [Release notes](https://github.com/dotnet/fsharp/releases)
- [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md)
- [Commits](https://github.com/dotnet/fsharp/commits)

Updates `WoofWare.Myriad.Plugins` from 4.0.13 to 4.0.14
- [Release notes](https://github.com/Smaug123/WoofWare.Myriad/releases)
- [Changelog](https://github.com/Smaug123/WoofWare.Myriad/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Smaug123/WoofWare.Myriad/compare/WoofWare.Myriad.Plugins.4.0.13...WoofWare.Myriad.Plugins.4.0.14)

---
updated-dependencies:
- dependency-name: FSharp.Core
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: WoofWare.Myriad.Plugins
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Deps

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2025-04-01 09:22:52 +01:00
patrick-conscriptus[bot]
48f7302391 Automated commit (#245)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-03-30 00:46:20 +00:00
Patrick Stevens
d1fa66a2e8 Fix behaviour of Explicit test fixtures (#244) 2025-03-25 21:49:50 +00:00
13 changed files with 112 additions and 31 deletions

View File

@@ -9,7 +9,7 @@
]
},
"fsharp-analyzers": {
"version": "0.29.1",
"version": "0.30.0",
"commands": [
"fsharp-analyzers"
]

View File

@@ -10,6 +10,7 @@
<Compile Include="NoAttribute.fs" />
<Compile Include="Inconclusive.fs" />
<Compile Include="RunSubProcess.fs" />
<Compile Include="TestExplicit.fs" />
<Compile Include="TestNonParallel.fs" />
<Compile Include="TestParallel.fs" />
<Compile Include="TestParallelIndividualTest.fs" />

24
Consumer/TestExplicit.fs Normal file
View File

@@ -0,0 +1,24 @@
namespace Consumer
open NUnit.Framework
[<TestFixture>]
module TestExplicitIndividual =
[<Explicit>]
[<Test>]
let ``This test should not be run`` () = failwith<unit> "should not call"
[<Explicit>]
[<TestFixture>]
module TestExplicitModule =
[<OneTimeSetUp>]
let setUp () = failwith<unit> "should not call: setup"
[<OneTimeTearDown>]
let tearDown () =
failwith<unit> "should not call: teardown"
[<Test>]
let ``This test should not be run because its module is explicit`` () = failwith<unit> "should not call: test"

View File

@@ -138,10 +138,17 @@ type TestFixture =
Tests : SingleTestMethod list
/// If this fixture has declared a parallelisability, that goes here.
Parallelize : Parallelizable<ClassParallelScope> option
/// It is possible to mark a fixture as "Explicit" or "Ignored", for example.
Modifiers : Modifier list
}
/// A test fixture about which we know nothing. No tests, no setup/teardown.
static member Empty (ty : Type) (par : Parallelizable<ClassParallelScope> option) (args : obj list list) =
static member Empty
(ty : Type)
(par : Parallelizable<ClassParallelScope> option)
(modifiers : Modifier list)
(args : obj list list)
=
{
ContainingAssembly = ty.Assembly
Type = ty
@@ -153,6 +160,7 @@ type TestFixture =
Parameters = args
Tests = []
Parallelize = par
Modifiers = modifiers
}
/// User code in the unit under test has failed somehow.

View File

@@ -170,8 +170,9 @@ WoofWare.NUnitTestRunner.IndividualTestRunMetadata.StdOut [property]: [read-only
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 - interface with 6 member(s)
WoofWare.NUnitTestRunner.ITestProgress.OnTestFailed [method]: string -> WoofWare.NUnitTestRunner.TestMemberFailure -> unit
WoofWare.NUnitTestRunner.ITestProgress.OnTestFixtureSkipped [method]: string -> string -> unit
WoofWare.NUnitTestRunner.ITestProgress.OnTestFixtureStart [method]: string -> int -> unit
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberFinished [method]: string -> unit
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> unit
@@ -346,11 +347,12 @@ WoofWare.NUnitTestRunner.TestFailure.NewTearDownFailed [static method]: WoofWare
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.Type, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, obj list list, WoofWare.NUnitTestRunner.SingleTestMethod list, WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option)
WoofWare.NUnitTestRunner.TestFixture..ctor [constructor]: (System.Reflection.Assembly, string, System.Type, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, obj list list, WoofWare.NUnitTestRunner.SingleTestMethod list, WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option, WoofWare.NUnitTestRunner.Modifier list)
WoofWare.NUnitTestRunner.TestFixture.ContainingAssembly [property]: [read-only] System.Reflection.Assembly
WoofWare.NUnitTestRunner.TestFixture.Empty [static method]: System.Type -> WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option -> obj list list -> WoofWare.NUnitTestRunner.TestFixture
WoofWare.NUnitTestRunner.TestFixture.Empty [static method]: System.Type -> WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option -> WoofWare.NUnitTestRunner.Modifier list -> obj list list -> WoofWare.NUnitTestRunner.TestFixture
WoofWare.NUnitTestRunner.TestFixture.Equals [method]: (WoofWare.NUnitTestRunner.TestFixture, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.TestFixture.get_ContainingAssembly [method]: unit -> System.Reflection.Assembly
WoofWare.NUnitTestRunner.TestFixture.get_Modifiers [method]: unit -> WoofWare.NUnitTestRunner.Modifier list
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
@@ -360,6 +362,7 @@ WoofWare.NUnitTestRunner.TestFixture.get_SetUp [method]: unit -> System.Reflecti
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.get_Type [method]: unit -> System.Type
WoofWare.NUnitTestRunner.TestFixture.Modifiers [property]: [read-only] WoofWare.NUnitTestRunner.Modifier 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

View File

@@ -597,15 +597,15 @@ module TestFixture =
/// 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, args, par =
(([], [], None), parentType.CustomAttributes)
||> Seq.fold (fun (categories, args, par) attr ->
let categories, args, mods, par =
(([], [], [], None), parentType.CustomAttributes)
||> Seq.fold (fun (categories, args, mods, par) attr ->
match attr.AttributeType.FullName with
| "NUnit.Framework.SetUpFixtureAttribute" ->
failwith "This test runner does not support SetUpFixture. Please shout if you want this."
| "NUnit.Framework.CategoryAttribute" ->
let cat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
cat :: categories, args, par
cat :: categories, args, mods, par
| "NUnit.Framework.TestFixtureAttribute" ->
let newArgs =
match attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList with
@@ -613,38 +613,52 @@ module TestFixture =
x |> Seq.cast<CustomAttributeTypedArgument> |> Seq.map _.Value |> Seq.toList
| xs -> xs
categories, newArgs :: args, par
categories, newArgs :: args, mods, par
| "NUnit.Framework.NonParallelizableAttribute" ->
match par with
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
| None -> categories, args, Some Parallelizable.No
| None -> categories, args, mods, Some Parallelizable.No
| "NUnit.Framework.ParallelizableAttribute" ->
match par with
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
| None ->
match attr.ConstructorArguments |> Seq.toList with
| [] -> categories, args, Some (Parallelizable.Yes ClassParallelScope.Self)
| [] -> categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Self)
| [ v ] ->
match v.Value with
| :? int as v ->
match ParallelScope.ofInt v with
| ParallelScope.Fixtures ->
categories, args, Some (Parallelizable.Yes ClassParallelScope.Fixtures)
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Fixtures)
| ParallelScope.Children ->
categories, args, Some (Parallelizable.Yes ClassParallelScope.Children)
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Children)
| ParallelScope.All ->
categories, args, Some (Parallelizable.Yes ClassParallelScope.All)
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.All)
| ParallelScope.Self ->
categories, args, Some (Parallelizable.Yes ClassParallelScope.Self)
| ParallelScope.None -> categories, args, Some Parallelizable.No
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Self)
| ParallelScope.None -> categories, args, mods, Some Parallelizable.No
| v ->
failwith
$"Unexpectedly non-int value %O{v} of parallel scope in %s{parentType.FullName}"
| _ -> failwith $"unexpectedly got multiple args to Parallelizable on %s{parentType.FullName}"
| _ -> categories, args, par
| "NUnit.Framework.ExplicitAttribute" ->
let reason =
attr.ConstructorArguments
|> Seq.tryHead
|> Option.map (_.Value >> unbox<string>)
categories, args, Modifier.Explicit reason :: mods, par
| "NUnit.Framework.IgnoreAttribute" ->
let reason =
attr.ConstructorArguments
|> Seq.tryHead
|> Option.map (_.Value >> unbox<string>)
categories, args, Modifier.Ignored reason :: mods, par
| _ -> categories, args, mods, par
)
(TestFixture.Empty parentType par args, parentType.GetRuntimeMethods ())
(TestFixture.Empty parentType par mods args, parentType.GetRuntimeMethods ())
||> Seq.fold (fun state mi ->
((state, []), mi.CustomAttributes)
||> Seq.fold (fun (state, unrecognisedAttrs) attr ->
@@ -717,6 +731,8 @@ module TestFixture =
/// Run every test (except those which fail the `filter`) in this test fixture, as well as the
/// appropriate setup and tear-down logic.
///
/// If the TestFixture has modifiers that specify no tests should be run, we don't run any tests.
let run
(contexts : TestContexts)
(par : ParallelQueue)
@@ -725,6 +741,26 @@ module TestFixture =
(tests : TestFixture)
: FixtureRunResults list Task
=
match
tests.Modifiers
|> List.tryFind (
function
| Modifier.Explicit _
| Modifier.Ignored _ -> true
)
with
| Some modifier ->
let reason =
match modifier with
| Modifier.Explicit (Some reason) -> reason
| Modifier.Ignored (Some reason) -> reason
| Modifier.Ignored None -> "test fixture marked Ignore"
| Modifier.Explicit None -> "test fixture marked Explicit"
progress.OnTestFixtureSkipped tests.Name reason
Task.FromResult []
| None ->
match tests.Parameters with
| [] -> [ null ]
| args -> args |> List.map List.toArray

View File

@@ -10,6 +10,8 @@ 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 when skipping the test fixture with the given name, e.g. because it's `[<Explicit>]`.
abstract OnTestFixtureSkipped : name : string -> reason : string -> 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
@@ -32,6 +34,9 @@ module TestProgress =
let plural = if testCount = 1 then "" else "s"
writer.WriteLine $"Running test fixture: %s{name} (%i{testCount} test%s{plural} to run)"
member _.OnTestFixtureSkipped name reason =
writer.WriteLine $"Skipping test fixture (%s{reason}): %s{name}"
member _.OnTestMemberStart name =
writer.WriteLine $"Running test: %s{name}"

View File

@@ -14,7 +14,7 @@
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarnOn>FS3559</WarnOn>
<WoofWareMyriadPluginVersion>4.0.13</WoofWareMyriadPluginVersion>
<WoofWareMyriadPluginVersion>4.0.14</WoofWareMyriadPluginVersion>
</PropertyGroup>
<ItemGroup>

View File

@@ -1,5 +1,5 @@
{
"version": "0.20",
"version": "0.21",
"publicReleaseRefSpec": [
"^refs/heads/main$"
],

View File

@@ -13,6 +13,10 @@ module Progress =
member _.OnTestFixtureStart name testCount =
console.MarkupLine $"[white]Running tests: %s{Markup.Escape name}[/]"
member _.OnTestFixtureSkipped name reason =
console.MarkupLine
$"[yellow]Skipping test fixture (%s{Markup.Escape reason}): %s{Markup.Escape name}[/]"
member _.OnTestMemberFinished name =
console.MarkupLine $"[gray]Finished test: %s{Markup.Escape name}[/]"

View File

@@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.13.0]" />
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.14.0]" />
</ItemGroup>
</Project>

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1742578646,
"narHash": "sha256-GiQ40ndXRnmmbDZvuv762vS+gew1uDpFwOfgJ8tLiEs=",
"lastModified": 1743076231,
"narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "94c4dbe77c0740ebba36c173672ca15a7926c993",
"rev": "6c5963357f3c1c840201eda129a99d455074db04",
"type": "github"
},
"original": {

View File

@@ -26,8 +26,8 @@
},
{
"pname": "fsharp-analyzers",
"version": "0.29.1",
"hash": "sha256-wfZbODwGDcPINaMy/uOLPN9aztDfJg5JXy0t+bGyy1k="
"version": "0.30.0",
"hash": "sha256-7oaSwpHAU1opzpz4szLU/gDaJC/ww9eiFkPu0nr4Mj4="
},
{
"pname": "FSharp.Core",
@@ -361,8 +361,8 @@
},
{
"pname": "WoofWare.Myriad.Plugins",
"version": "4.0.13",
"hash": "sha256-ak0YjK+b8ruLLVgwkR2h2O8wmJkdtNZGQTM3j3BxVgk="
"version": "4.0.14",
"hash": "sha256-WxgGXH4YVyFDEyNAxFIbB5MwKc3gF5ktYvzOeMdV418="
},
{
"pname": "WoofWare.Myriad.Plugins.Attributes",
@@ -376,7 +376,7 @@
},
{
"pname": "WoofWare.Whippet.Fantomas",
"version": "0.3.1",
"hash": "sha256-i5oiqcrxzM90Ocuq5MIu2Ha5lV0aYu5nCvuwmFqp6NA="
"version": "0.3.2",
"hash": "sha256-dhzp/ASz1dlROJAfLYRKOCRlmjLBoS00KYeWEkSVtMA="
}
]