Compare commits

...

184 Commits

Author SHA1 Message Date
Patrick Stevens
81aa6832d5 Switch to trusted publishing (#301) 2025-10-03 09:37:51 +00:00
dependabot[bot]
a20f32de02 Bump WoofWare.Myriad.Plugins from 8.0.5 to 8.1.1 (#297)
* Bump WoofWare.Myriad.Plugins from 8.0.5 to 8.1.1

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins
  dependency-version: 8.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* 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-09-30 22:55:29 +01:00
dependabot[bot]
1e53e72d4a Bump ApiSurface from 5.0.1 to 5.0.2 (#299)
* Bump ApiSurface from 5.0.1 to 5.0.2

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-version: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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-09-30 22:49:22 +01:00
dependabot[bot]
b38a3fcc02 Upgrade to net9, bump Nerdbank.GitVersioning from 3.8.38-alpha to 3.8.118 (#300)
* Bump Nerdbank.GitVersioning from 3.8.38-alpha to 3.8.118

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-version: 3.8.118
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Deps

* Try upgrading to net9

* Bump tests

* Upgrade pipeline

* Bump version

---------

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-09-30 07:21:29 +00:00
patrick-conscriptus[bot]
73dc21e11f Automated commit (#296)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-09-21 00:46:53 +00:00
patrick-conscriptus[bot]
5b54bb256e Automated commit (#295)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-09-14 00:45:51 +00:00
Patrick Stevens
b56e1b1542 Bump ApiSurface (#294) 2025-09-08 20:38:52 +00:00
dependabot[bot]
ba46b1edb6 Bump Spectre.Console from 0.50.0 to 0.51.1 (#293)
* Bump Spectre.Console from 0.50.0 to 0.51.1

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.51.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* 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-09-08 17:41:56 +00:00
patrick-conscriptus[bot]
72674e1711 Automated commit (#292)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-09-07 00:46:50 +00:00
dependabot[bot]
c4b862bdd8 Bump actions/attest-build-provenance from 2.4.0 to 3.0.0 (#291) 2025-09-02 07:29:12 +01:00
patrick-conscriptus[bot]
4c629b1d64 Automated commit (#290)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-08-31 00:47:27 +00:00
dependabot[bot]
e67820c56d Bump FsCheck from 3.3.0 to 3.3.1 (#289)
* Bump FsCheck from 3.3.0 to 3.3.1

---
updated-dependencies:
- dependency-name: FsCheck
  dependency-version: 3.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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-08-27 08:59:47 +00:00
patrick-conscriptus[bot]
31bff4cb03 Automated commit (#288)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-08-24 00:50:07 +00:00
patrick-conscriptus[bot]
d081cfaafb Automated commit (#287)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-08-17 00:52:15 +00:00
dependabot[bot]
c237df3885 Bump actions/checkout from 4 to 5 (#286) 2025-08-12 07:31:15 +01:00
dependabot[bot]
3b9b9eb4c8 Bump actions/download-artifact from 4 to 5 (#285) 2025-08-11 23:30:06 +01:00
patrick-conscriptus[bot]
12e3fc0e4f Automated commit (#284)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-08-10 00:55:19 +00:00
dependabot[bot]
208b809096 Bump fsharp-analyzers from 0.32.0 to 0.32.1 (#282)
* Bump fsharp-analyzers from 0.32.0 to 0.32.1

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

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

* 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-08-05 19:07:01 +00:00
dependabot[bot]
b4e5baddcf Bump NasAmin/trx-parser from 0.6.0 to 0.7.0 (#283)
* Bump NasAmin/trx-parser from 0.6.0 to 0.7.0

Bumps [NasAmin/trx-parser](https://github.com/nasamin/trx-parser) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/nasamin/trx-parser/releases)
- [Changelog](https://github.com/NasAmin/trx-parser/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nasamin/trx-parser/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: NasAmin/trx-parser
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Don't run external dependency on main

---------

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-08-05 19:59:56 +01:00
patrick-conscriptus[bot]
5597b3f2f8 Automated commit (#281)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-08-03 00:57:08 +00:00
Patrick Stevens
fcfdcef6cf Async tests (#280) 2025-07-29 23:07:12 +00:00
Patrick Stevens
eeada219f6 Permit async ParallelQueue (#279) 2025-07-29 22:24:58 +01:00
Patrick Stevens
99e0fdff08 Make ParallelQueue surface its errors, correctly flow ExecutionContext (#278) 2025-07-29 22:04:45 +01:00
dependabot[bot]
fda4e7ba60 Bump WoofWare.Myriad.Plugins from 8.0.4 to 8.0.5 (#277)
* Bump WoofWare.Myriad.Plugins from 8.0.4 to 8.0.5

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

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

* 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-07-28 20:42:53 +01:00
patrick-conscriptus[bot]
dfdfa84733 Automated commit (#276)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-07-27 00:56:11 +00:00
patrick-conscriptus[bot]
c218110749 Automated commit (#275)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-07-20 00:55:52 +00:00
dependabot[bot]
309968721c Bump ApiSurface from 4.1.21 to 4.1.22 (#274)
* Bump ApiSurface from 4.1.21 to 4.1.22

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-version: 4.1.22
  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-07-14 21:03:17 +00:00
patrick-conscriptus[bot]
876ca9e625 Automated commit (#273)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-07-13 00:54:57 +00:00
patrick-conscriptus[bot]
59f9789cdc Automated commit (#271)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-07-06 00:53:02 +00:00
dependabot[bot]
c8c28b9a32 Bump FsUnit to 7.1.1 (#270)
* Bump FsUnit to 7.1.1

---
updated-dependencies:
- dependency-name: FsUnit
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: FsUnit
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: FsUnit
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* 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-06-30 20:56:14 +00:00
patrick-conscriptus[bot]
6d87610017 Automated commit (#269)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-06-29 00:53:55 +00:00
dependabot[bot]
9f28334b7f Bump WoofWare.Myriad.Plugins from 7.0.7 to 8.0.4 (#268)
* Bump WoofWare.Myriad.Plugins from 7.0.7 to 8.0.4

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins
  dependency-version: 8.0.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* Bump 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-06-23 23:00:17 +00:00
patrick-conscriptus[bot]
5cf2261d7f Automated commit (#267)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-06-22 00:52:35 +00:00
dependabot[bot]
c3589820c3 Bump ApiSurface from 4.1.20 to 4.1.21 (#265)
* Bump ApiSurface from 4.1.20 to 4.1.21

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-version: 4.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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-06-16 18:39:50 +00:00
dependabot[bot]
5d0c205f21 Bump actions/attest-build-provenance from 2.3.0 to 2.4.0 (#266) 2025-06-16 17:59:44 +00:00
patrick-conscriptus[bot]
16135fbd56 Automated commit (#264)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-06-15 00:52:57 +00:00
dependabot[bot]
cbc51cde14 Bump FsCheck and Microsoft.NET.Test.Sdk (#263)
* Bump FsCheck and Microsoft.NET.Test.Sdk

Bumps FsCheck from 3.2.0 to 3.3.0
Bumps Microsoft.NET.Test.Sdk to 17.14.1, 17.14.1, 17.14.1

---
updated-dependencies:
- dependency-name: FsCheck
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 17.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 17.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 17.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Deps

* Bump

---------

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-06-13 22:28:06 +01:00
patrick-conscriptus[bot]
6a4b900aa9 Automated commit (#262)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-06-08 00:51:50 +00:00
patrick-conscriptus[bot]
4169289ded Automated commit (#261)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-06-01 00:57:26 +00:00
patrick-conscriptus[bot]
7df58d5309 Automated commit (#260)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-05-25 00:50:30 +00:00
patrick-conscriptus[bot]
ac4c8c245e Automated commit (#259)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-05-18 00:48:51 +00:00
patrick-conscriptus[bot]
3e79e79978 Automated commit (#258)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-05-11 00:48:12 +00:00
patrick-conscriptus[bot]
c16e7dd1ee Automated commit (#257)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-05-04 00:49:25 +00:00
dependabot[bot]
cd66617ce7 Bump FSharp.Core and WoofWare.Myriad.Plugins (#256)
* 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.14 to 7.0.7
- [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.14...WoofWare.Myriad.Plugins.7.0.7)

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

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

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrick Stevens <3138005+Smaug123@users.noreply.github.com>
2025-04-29 22:05:29 +01:00
dependabot[bot]
144f71a417 Bump actions/attest-build-provenance from 2.2.3 to 2.3.0 (#255)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2.2.3 to 2.3.0.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](c074443f1a...db473fddc0)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 23:20:49 +01:00
patrick-conscriptus[bot]
3673fc56ee Automated commit (#254)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-04-27 00:47:27 +00:00
patrick-conscriptus[bot]
5f74b41825 Automated commit (#253)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-04-20 00:47:23 +00:00
dependabot[bot]
2068007da0 Bump Spectre.Console from 0.49.1 to 0.50.0 (#251) 2025-04-14 18:56:23 +01:00
patrick-conscriptus[bot]
6fd824c065 Automated commit (#250)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-04-13 02:10:19 +00:00
dependabot[bot]
0480d5c151 Bump actions/create-github-app-token from 1 to 2 (#249)
Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 1 to 2.
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Commits](https://github.com/actions/create-github-app-token/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/create-github-app-token
  dependency-version: '2'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 18:50:59 +01:00
patrick-conscriptus[bot]
9107b1b502 Automated commit (#248)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-04-06 00:45:50 +00:00
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
dependabot[bot]
e75c584a43 Bump WoofWare.PrattParser and other deps (#241)
* 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.12 to 4.0.13
- [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.12...WoofWare.Myriad.Plugins.4.0.13)

---
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>

* Bump FSharp.Core and WoofWare.PrattParser

Bumps [FSharp.Core](https://github.com/Microsoft/visualfsharp) and [WoofWare.PrattParser](https://github.com/Smaug123/fsharp-prattparser). These dependencies needed to be updated together.

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

Updates `WoofWare.PrattParser` from 0.2.3 to 0.2.4
- [Release notes](https://github.com/Smaug123/fsharp-prattparser/releases)
- [Commits](https://github.com/Smaug123/fsharp-prattparser/compare/WoofWare.PrattParser.0.2.3...WoofWare.PrattParser.0.2.4)

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

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

* Bump ApiSurface and FSharp.Core

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) and [FSharp.Core](https://github.com/Microsoft/visualfsharp). These dependencies needed to be updated together.

Updates `ApiSurface` from 4.1.17 to 4.1.20
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.17...ApiSurface.4.1.20)

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

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: FSharp.Core
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* Bump WoofWare.DotnetRuntimeLocator from 0.1.11 to 0.1.12

Bumps [WoofWare.DotnetRuntimeLocator](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator) from 0.1.11 to 0.1.12.
- [Release notes](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/releases)
- [Commits](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/compare/WoofWare.DotnetRuntimeLocator.0.1.11...WoofWare.DotnetRuntimeLocator.0.1.12)

---
updated-dependencies:
- dependency-name: WoofWare.DotnetRuntimeLocator
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Rem unused dep

* Restore dep

---------

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-03-24 19:17:59 +00:00
patrick-conscriptus[bot]
d7bdd38253 Automated commit (#239)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-03-23 00:45:27 +00:00
Patrick Stevens
b7d87459d9 Bump NBGV (#238) 2025-03-21 14:32:08 +00:00
dependabot[bot]
992679d8ca Bump fsharp-analyzers from 0.29.0 to 0.29.1 (#237)
* Bump fsharp-analyzers from 0.29.0 to 0.29.1

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.29.0 to 0.29.1.
- [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.0...v0.29.1)

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

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

* 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-03-10 22:08:14 +00:00
dependabot[bot]
011a5129cc Bump cachix/install-nix-action from 30 to 31 (#236) 2025-03-10 17:36:58 +00:00
dependabot[bot]
46a13d1583 Bump actions/attest-build-provenance from 2.2.2 to 2.2.3 (#235) 2025-03-10 17:34:31 +00:00
patrick-conscriptus[bot]
1a291a2ac7 Automated commit (#234)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-03-09 00:37:20 +00:00
dependabot[bot]
fd34215461 Bump actions/attest-build-provenance from 2.2.0 to 2.2.2 (#233)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2.2.0 to 2.2.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](520d128f16...bd77c07785)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-03 19:29:30 +00:00
patrick-conscriptus[bot]
eda120332a Automated commit (#232)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-03-02 00:44:02 +00:00
dependabot[bot]
799e5c8c3a Bump fantomas from 7.0.0 to 7.0.1 (#231)
* Bump fantomas from 7.0.0 to 7.0.1

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v7.0.0...v7.0.1)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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-02-25 00:25:02 +00:00
patrick-conscriptus[bot]
172865b2a1 Automated commit (#230)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-02-23 00:43:32 +00:00
dependabot[bot]
f264fca446 Bump fsharp-analyzers from 0.28.0 to 0.29.0 (#227) 2025-02-20 10:29:35 +00:00
patrick-conscriptus[bot]
8dd18603d6 Automated commit (#226)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-02-16 00:43:31 +00:00
dependabot[bot]
012b4a6e03 Bump Microsoft.NET.Test.Sdk from 17.12.0 to 17.13.0 (#224)
* Bump Microsoft.NET.Test.Sdk from 17.12.0 to 17.13.0

Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.12.0 to 17.13.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.12.0...v17.13.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Bump NUnit3TestAdapter from 4.6.0 to 5.0.0

Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.6.0 to 5.0.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.6.0...V5.0.0)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* 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-02-10 20:03:32 +00:00
patrick-conscriptus[bot]
51918f6d35 Automated commit (#223)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-02-09 00:42:06 +00:00
dependabot[bot]
225b2645b0 Bump FsCheck from 3.0.1 to 3.1.0 (#222)
* Bump FsCheck from 3.0.1 to 3.1.0

Bumps [FsCheck](https://github.com/Fscheck/fscheck) from 3.0.1 to 3.1.0.
- [Release notes](https://github.com/Fscheck/fscheck/releases)
- [Changelog](https://github.com/fscheck/FsCheck/blob/master/FsCheck%20Release%20Notes.md)
- [Commits](https://github.com/Fscheck/fscheck/compare/3.0.1...3.1.0)

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

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

* 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-02-03 17:28:25 +00:00
patrick-conscriptus[bot]
5c05d29917 Automated commit (#221)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-02-02 00:41:25 +00:00
dependabot[bot]
33aa337598 Bump FsCheck from 3.0.0 to 3.0.1 (#220)
* Bump FsCheck from 3.0.0 to 3.0.1

Bumps [FsCheck](https://github.com/Fscheck/fscheck) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/Fscheck/fscheck/releases)
- [Changelog](https://github.com/fscheck/FsCheck/blob/master/FsCheck%20Release%20Notes.md)
- [Commits](https://github.com/Fscheck/fscheck/compare/3.0.0...3.0.1)

---
updated-dependencies:
- dependency-name: FsCheck
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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-01-29 00:47:07 +00:00
dependabot[bot]
daa53a84a5 Bump actions/attest-build-provenance from 2.1.0 to 2.2.0 (#219) 2025-01-27 16:59:11 +00:00
patrick-conscriptus[bot]
4c9568819a Automated commit (#218)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-01-26 00:40:21 +00:00
dependabot[bot]
6ab8316b2b Bump FSharp.Core and WoofWare.Myriad.Plugins (#217)
* 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.9 to 4.0.11
- [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.9...WoofWare.Myriad.Plugins.4.0.11)

---
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

---------

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-01-20 18:24:06 +00:00
patrick-conscriptus[bot]
600772a81f Automated commit (#215)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-01-19 00:42:01 +00:00
dependabot[bot]
c6b735816e Bump fantomas from 6.3.16 to 7.0.0 (#214)
* Bump ApiSurface from 4.1.15 to 4.1.16

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.15 to 4.1.16.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.15...ApiSurface.4.1.16)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump Nerdbank.GitVersioning from 3.7.112 to 3.7.115

Bumps [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) from 3.7.112 to 3.7.115.
- [Release notes](https://github.com/dotnet/Nerdbank.GitVersioning/releases)
- [Commits](https://github.com/dotnet/Nerdbank.GitVersioning/commits)

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump FsCheck from 3.0.0-rc3 to 3.0.0

Bumps [FsCheck](https://github.com/Fscheck/fscheck) from 3.0.0-rc3 to 3.0.0.
- [Release notes](https://github.com/Fscheck/fscheck/releases)
- [Changelog](https://github.com/fscheck/FsCheck/blob/master/FsCheck%20Release%20Notes.md)
- [Commits](https://github.com/Fscheck/fscheck/compare/3.0.0-rc3...3.0.0)

---
updated-dependencies:
- dependency-name: FsCheck
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fantomas from 6.3.16 to 7.0.0

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.16 to 7.0.0.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.16...v7.0.0)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

* deps

* Reformat

---------

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-01-14 01:05:45 +00:00
Patrick Stevens
29c3c17bc0 Bump GR action (#210) 2025-01-13 08:59:42 +00:00
patrick-conscriptus[bot]
512b41d7c1 Automated commit (#209)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-01-12 00:44:23 +00:00
Patrick Stevens
f920e597bd Bump flake (#208) 2025-01-10 14:35:47 +00:00
Patrick Stevens
226da02b1b Fix release tag again (#207) 2025-01-10 14:28:40 +00:00
Patrick Stevens
e9b9366b90 Fix release tag (#206) 2025-01-10 13:54:24 +00:00
Patrick Stevens
e7c31b5366 Use GR's release action (#205) 2025-01-10 13:45:56 +00:00
dependabot[bot]
9d26610384 Bump FsUnit (#204)
* Bump FsUnit and NUnit

Bumps [FsUnit](https://github.com/fsprojects/FsUnit) and [NUnit](https://github.com/nunit/nunit). These dependencies needed to be updated together.

Updates `FsUnit` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/fsprojects/FsUnit/releases)
- [Changelog](https://github.com/fsprojects/FsUnit/blob/master/RELEASE_NOTES.md)
- [Commits](https://github.com/fsprojects/FsUnit/compare/7.0.0...7.0.1)

Updates `NUnit` from 4.3.2 to 4.0.1
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/4.3.2...v4.0.1)

---
updated-dependencies:
- dependency-name: FsUnit
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* 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-01-06 18:30:49 +00:00
patrick-conscriptus[bot]
61fbb5f55b Automated commit (#203)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2025-01-05 00:43:52 +00:00
dependabot[bot]
d9938d96a3 Bump NUnit from 4.3.0 to 4.3.2 (#202)
* Bump NUnit from 4.3.0 to 4.3.2

Bumps [NUnit](https://github.com/nunit/nunit) from 4.3.0 to 4.3.2.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/4.3.0...4.3.2)

---
updated-dependencies:
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Fix

---------

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>
2024-12-30 22:43:23 +00:00
patrick-conscriptus[bot]
874a367ce3 Automated commit (#201)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-12-29 00:43:54 +00:00
Patrick Stevens
4300fbe6b8 Use nondeprecated nixpkgs methods (#200) 2024-12-24 19:52:45 +00:00
dependabot[bot]
402b98f85c Bump FsUnit and NUnit (#199)
* Bump FsUnit and NUnit

Bumps [FsUnit](https://github.com/fsprojects/FsUnit) and [NUnit](https://github.com/nunit/nunit). These dependencies needed to be updated together.

Updates `FsUnit` from 6.0.1 to 7.0.0
- [Release notes](https://github.com/fsprojects/FsUnit/releases)
- [Changelog](https://github.com/fsprojects/FsUnit/blob/master/RELEASE_NOTES.md)
- [Commits](https://github.com/fsprojects/FsUnit/compare/6.0.1...7.0.0)

Updates `NUnit` from 4.3.0 to 4.0.1
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/4.3.0...v4.0.1)

---
updated-dependencies:
- dependency-name: FsUnit
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* 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>
2024-12-23 16:26:01 +00:00
patrick-conscriptus[bot]
a795d6222c Automated commit (#197)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-12-22 00:43:20 +00:00
dependabot[bot]
cf482b677b Bump ApiSurface from 4.1.12 to 4.1.15 (#195)
* Bump FSharp.Core, WoofWare.Myriad.Plugins and WoofWare.Myriad.Plugins.Attributes

Bumps [FSharp.Core](https://github.com/dotnet/fsharp), [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) and [WoofWare.Myriad.Plugins.Attributes](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.7 to 4.0.9
- [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.7...WoofWare.Myriad.Plugins.4.0.9)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.6.4 to 3.6.6
- [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.Attributes.3.6.4...WoofWare.Myriad.Plugins.Attributes.3.6.6)

---
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
- dependency-name: WoofWare.Myriad.Plugins.Attributes
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump Nerdbank.GitVersioning from 3.6.146 to 3.7.112

Bumps [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) from 3.6.146 to 3.7.112.
- [Release notes](https://github.com/dotnet/Nerdbank.GitVersioning/releases)
- [Commits](https://github.com/dotnet/Nerdbank.GitVersioning/compare/v3.6.146...v3.7.112)

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Bump FSharp.Core and WoofWare.PrattParser

Bumps [FSharp.Core](https://github.com/Microsoft/visualfsharp) and [WoofWare.PrattParser](https://github.com/Smaug123/fsharp-prattparser). These dependencies needed to be updated together.

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

Updates `WoofWare.PrattParser` from 0.2.2 to 0.2.3
- [Release notes](https://github.com/Smaug123/fsharp-prattparser/releases)
- [Commits](https://github.com/Smaug123/fsharp-prattparser/compare/WoofWare.PrattParser.0.2.2...WoofWare.PrattParser.0.2.3)

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

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

* Bump ApiSurface from 4.1.12 to 4.1.15

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.12 to 4.1.15.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.12...ApiSurface.4.1.15)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump NUnit from 4.2.2 to 4.3.0

Bumps [NUnit](https://github.com/nunit/nunit) from 4.2.2 to 4.3.0.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/4.2.2...4.3.0)

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

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

* 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>
2024-12-16 17:48:20 +00:00
dependabot[bot]
db27a7acc8 Bump actions/attest-build-provenance from 2.0.1 to 2.1.0 (#191) 2024-12-16 16:30:42 +00:00
patrick-conscriptus[bot]
99826df864 Automated commit (#189)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-12-15 00:46:53 +00:00
dependabot[bot]
1c93b2c4b2 Bump actions/attest-build-provenance from 1.4.4 to 2.0.1 (#188) 2024-12-09 17:58:03 +00:00
patrick-conscriptus[bot]
4369b35dd1 Automated commit (#186)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-12-08 00:47:43 +00:00
Patrick Stevens
a183455f55 Rem net6 selftest (#185) 2024-12-01 09:34:46 +00:00
patrick-conscriptus[bot]
de5f5a64ef Upgrade Nix flake and deps (#184)
* Automated commit

* Rem net6

* NoEquality

---------

Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-12-01 09:30:19 +00:00
dependabot[bot]
fdddbf828b Bump ApiSurface from 4.1.11 to 4.1.12 (#181)
* Bump Microsoft.NET.Test.Sdk from 17.11.1 to 17.12.0

Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.11.1 to 17.12.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.11.1...v17.12.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Bump ApiSurface from 4.1.11 to 4.1.12

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.11 to 4.1.12.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.11...ApiSurface.4.1.12)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump WoofWare.DotnetRuntimeLocator from 0.1.9 to 0.1.11

Bumps [WoofWare.DotnetRuntimeLocator](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator) from 0.1.9 to 0.1.11.
- [Release notes](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/releases)
- [Commits](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/compare/WoofWare.DotnetRuntimeLocator.0.1.9...WoofWare.DotnetRuntimeLocator.0.1.11)

---
updated-dependencies:
- dependency-name: WoofWare.DotnetRuntimeLocator
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fsharp-analyzers from 0.27.0 to 0.28.0

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.27.0 to 0.28.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.27.0...v0.28.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>

* Fix flake

* Fix analysers

* 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>
2024-11-25 17:35:05 +00:00
patrick-conscriptus[bot]
67d9d71100 Automated commit (#179)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-11-24 00:46:09 +00:00
dependabot[bot]
c39745280b Bump ApiSurface from 4.1.8 to 4.1.11 (#178)
* Bump ApiSurface from 4.1.8 to 4.1.11

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.8 to 4.1.11.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.8...ApiSurface.4.1.11)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-11-18 20:04:32 +00:00
patrick-conscriptus[bot]
26c29d63bc Automated commit (#177)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-11-17 00:44:12 +00:00
dependabot[bot]
78f7f76074 Bump actions/attest-build-provenance from 1.4.3 to 1.4.4 (#176) 2024-11-11 16:34:01 +00:00
patrick-conscriptus[bot]
c2401207c4 Automated commit (#175)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-11-10 00:41:59 +00:00
dependabot[bot]
46e097a02e Bump FSharp.Core, WoofWare.Myriad.Plugins and WoofWare.Myriad.Plugins.Attributes (#173)
* Bump FSharp.Core, WoofWare.Myriad.Plugins and WoofWare.Myriad.Plugins.Attributes

Bumps [FSharp.Core](https://github.com/dotnet/fsharp), [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) and [WoofWare.Myriad.Plugins.Attributes](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.6 to 4.0.7
- [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.6...WoofWare.Myriad.Plugins.4.0.7)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.6.4 to 3.6.4
- [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.Attributes.3.6.4...WoofWare.Myriad.Plugins.Attributes.3.6.4)

---
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
- dependency-name: WoofWare.Myriad.Plugins.Attributes
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fantomas from 6.3.15 to 6.3.16

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.15 to 6.3.16.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.15...v6.3.16)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-11-04 17:42:21 +00:00
patrick-conscriptus[bot]
7c23c3bb1c Automated commit (#172)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-11-03 00:42:52 +00:00
Patrick Stevens
ace1417de6 Hang when argument not supplied (#171) 2024-10-30 19:33:28 +00:00
Patrick Stevens
a694637958 Implement ParallelScope.None (#169) 2024-10-29 17:17:39 +00:00
dependabot[bot]
8626cc1252 Bump WoofWare.Myriad.Plugins.Attributes from 3.6.3 to 3.6.4 (#167)
* Bump WoofWare.Myriad.Plugins.Attributes from 3.6.3 to 3.6.4

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.6.3 to 3.6.4.
- [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.Attributes.3.6.3...WoofWare.Myriad.Plugins.Attributes.3.6.4)

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

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

* 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>
2024-10-28 19:00:43 +00:00
patrick-conscriptus[bot]
0287a6b7eb Automated commit (#166)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-10-27 00:46:47 +00:00
dependabot[bot]
8579ee8f8b Bump ApiSurface from 4.1.7 to 4.1.8 (#163)
* Bump ApiSurface from 4.1.7 to 4.1.8

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.7 to 4.1.8.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.7...ApiSurface.4.1.8)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump Nerdbank.GitVersioning from 3.6.143 to 3.6.146

Bumps [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) from 3.6.143 to 3.6.146.
- [Release notes](https://github.com/dotnet/Nerdbank.GitVersioning/releases)
- [Commits](https://github.com/dotnet/Nerdbank.GitVersioning/commits)

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-10-21 19:29:34 +01:00
patrick-conscriptus[bot]
debda1a557 Automated commit (#162)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-10-20 00:43:04 +00:00
dependabot[bot]
bf7d846f61 Bump WoofWare.Myriad.Plugins from 4.0.5 to 4.0.6 (#161)
* Bump ApiSurface from 4.1.6 to 4.1.7

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.6 to 4.1.7.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.6...ApiSurface.4.1.7)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump WoofWare.Myriad.Plugins from 4.0.5 to 4.0.6

Bumps [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) from 4.0.5 to 4.0.6.
- [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.5...WoofWare.Myriad.Plugins.4.0.6)

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

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

* 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>
2024-10-14 22:53:56 +00:00
patrick-conscriptus[bot]
4690bf23ad Automated commit (#159)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-10-13 00:42:04 +00:00
dependabot[bot]
04283ee961 Bump WoofWareMyriadPluginVersion from 3.1.1 to 4.0.5 (#156)
* Bump WoofWareMyriadPluginVersion from 3.1.1 to 4.0.4

Bumps `WoofWareMyriadPluginVersion` from 3.1.1 to 4.0.4.

Updates `WoofWare.Myriad.Plugins` from 3.1.1 to 4.0.4
- [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.3.1.1...WoofWare.Myriad.Plugins.4.0.4)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.6.2 to 3.6.3
- [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.Attributes.3.6.2...WoofWare.Myriad.Plugins.Attributes.3.6.3)

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

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

* Bump ApiSurface from 4.1.5 to 4.1.6

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.1.5 to 4.1.6.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.1.5...ApiSurface.4.1.6)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* deps

* Bump again

---------

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>
2024-10-07 21:01:54 +01:00
dependabot[bot]
6c61c2cbf1 Bump cachix/install-nix-action from 29 to 30 (#158)
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 29 to 30.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Commits](https://github.com/cachix/install-nix-action/compare/v29...v30)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 18:04:00 +01:00
patrick-conscriptus[bot]
2a0cabd3a9 Automated commit (#155)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-10-06 00:42:04 +00:00
dependabot[bot]
111e019a83 Bump cachix/install-nix-action from V28 to 29 (#154) 2024-09-30 18:08:42 +01:00
patrick-conscriptus[bot]
16d353e8df Automated commit (#153)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-09-29 00:43:01 +00:00
dependabot[bot]
8528da77aa Bump WoofWareMyriadPluginVersion from 3.0.1 to 3.1.1 (#152)
* Bump WoofWareMyriadPluginVersion from 3.0.1 to 3.1.1

Bumps `WoofWareMyriadPluginVersion` from 3.0.1 to 3.1.1.

Updates `WoofWare.Myriad.Plugins` from 3.0.1 to 3.1.1
- [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.3.0.1...WoofWare.Myriad.Plugins.3.1.1)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.6.1 to 3.6.2
- [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.Attributes.3.6.1...WoofWare.Myriad.Plugins.Attributes.3.6.2)

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

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

* 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>
2024-09-23 18:50:21 +01:00
patrick-conscriptus[bot]
b74ae980d7 Automated commit (#151)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-09-22 00:42:29 +00:00
Patrick Stevens
318ba70608 Bump nixpkgs (#150) 2024-09-20 18:51:57 +00:00
dependabot[bot]
1ee38136a1 Bump FsUnit from 6.0.0 to 6.0.1 (#147)
* Bump FsUnit from 6.0.0 to 6.0.1

Bumps [FsUnit](https://github.com/fsprojects/FsUnit) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/fsprojects/FsUnit/releases)
- [Changelog](https://github.com/fsprojects/FsUnit/blob/master/RELEASE_NOTES.md)
- [Commits](https://github.com/fsprojects/FsUnit/compare/6.0.0...6.0.1)

---
updated-dependencies:
- dependency-name: FsUnit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fantomas from 6.3.12 to 6.3.15

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.12 to 6.3.15.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.12...v6.3.15)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump WoofWare.Myriad.Plugins.Attributes from 3.4.1 to 3.6.1

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.4.1 to 3.6.1.
- [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.Attributes.3.4.1...WoofWare.Myriad.Plugins.Attributes.3.6.1)

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins.Attributes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Deps

* And WoofWare

* And WoofWare

---------

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>
2024-09-16 17:14:11 +00:00
dependabot[bot]
3d8bb8d0ca Bump cachix/install-nix-action from V27 to 28 (#146) 2024-09-16 16:43:01 +00:00
dependabot[bot]
2f64191348 Bump Microsoft.NET.Test.Sdk from 17.11.0 to 17.11.1 (#143)
* Bump WoofWare.Myriad.Plugins.Attributes from 3.2.1 to 3.4.1

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.2.1 to 3.4.1.
- [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.Attributes.3.2.1...WoofWare.Myriad.Plugins.Attributes.3.4.1)

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins.Attributes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Bump Microsoft.NET.Test.Sdk from 17.11.0 to 17.11.1

Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.11.0 to 17.11.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.11.0...v17.11.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fantomas from 6.3.11 to 6.3.12

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.11 to 6.3.12.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.11...v6.3.12)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-09-09 19:30:29 +00:00
dependabot[bot]
86b8c0ec64 Bump actions/attest-build-provenance from 1.4.2 to 1.4.3 (#145) 2024-09-09 19:15:36 +01:00
patrick-conscriptus[bot]
e088d2b420 Automated commit (#141)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-09-08 00:41:57 +00:00
dependabot[bot]
3ea9d94861 Bump Nerdbank.GitVersioning from 3.6.141 to 3.6.143 (#139) 2024-09-02 20:02:06 +01:00
patrick-conscriptus[bot]
e003ef0934 Automated commit (#136)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-09-01 00:44:42 +00:00
Patrick Stevens
50948e629c Bump to net8.0.401 (#135) 2024-08-28 17:07:54 +00:00
Patrick Stevens
b14e5ede40 Switch to centrally managed actions (#134) 2024-08-28 16:53:29 +00:00
dependabot[bot]
f256eb7b29 Bump fsharp-analyzers from 0.26.1 to 0.27.0 (#133)
* Bump NUnit from 4.1.0 to 4.2.1

Bumps [NUnit](https://github.com/nunit/nunit) from 4.1.0 to 4.2.1.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/4.1.0...4.2.1)

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

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

* Bump WoofWareMyriadPluginVersion from 2.1.57 to 2.2.1

Bumps `WoofWareMyriadPluginVersion` from 2.1.57 to 2.2.1.

Updates `WoofWare.Myriad.Plugins` from 2.1.57 to 2.2.1
- [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.2.1.57...WoofWare.Myriad.Plugins.2.2.1)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.1.12 to 3.2.1
- [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.Attributes.3.1.12...WoofWare.Myriad.Plugins.Attributes.3.2.1)

Updates `FSharp.Core` from 6.0.0 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)

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

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

* Bump ApiSurface from 4.0.44 to 4.1.2

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.44 to 4.1.2.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.44...ApiSurface.4.1.2)

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

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

* Bump fantomas from 6.3.10 to 6.3.11

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.10 to 6.3.11.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.10...v6.3.11)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fsharp-analyzers from 0.26.1 to 0.27.0

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.26.1 to 0.27.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.26.1...v0.27.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 analysers

* 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>
2024-08-26 18:17:57 +01:00
dependabot[bot]
ec7d9187c5 Bump actions/attest-build-provenance from 1.4.1 to 1.4.2 (#128)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](310b0a4a3b...6149ea5740)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 16:24:24 +00:00
patrick-conscriptus[bot]
62eb3c5a66 Automated commit (#127)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-25 00:39:45 +00:00
dependabot[bot]
97e7a87e6a Bump WoofWare.Myriad.Plugins from 2.1.56 to 2.1.57 (#125)
* Bump WoofWare.Myriad.Plugins from 2.1.56 to 2.1.57

Bumps [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) from 2.1.56 to 2.1.57.
- [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.2.1.56...WoofWare.Myriad.Plugins.2.1.57)

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

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

* Bump ApiSurface from 4.0.43 to 4.0.44

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.43 to 4.0.44.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.43...ApiSurface.4.0.44)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-08-20 07:58:29 +00:00
patrick-conscriptus[bot]
14d91840b2 Automated commit (#123)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-18 00:39:09 +00:00
dependabot[bot]
2859a5f6e6 Bump Nerdbank.GitVersioning from 3.6.139 to 3.6.141 (#121)
* Bump fsharp-analyzers from 0.26.0 to 0.26.1

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.26.0 to 0.26.1.
- [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.26.0...v0.26.1)

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

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

* Bump WoofWareMyriadPluginVersion from 2.1.53 to 2.1.56

Bumps `WoofWareMyriadPluginVersion` from 2.1.53 to 2.1.56.

Updates `WoofWare.Myriad.Plugins` from 2.1.53 to 2.1.56
- [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.2.1.53...WoofWare.Myriad.Plugins.2.1.56)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.1.11 to 3.1.12
- [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.Attributes.3.1.11...WoofWare.Myriad.Plugins.Attributes.3.1.12)

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

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

* Bump Nerdbank.GitVersioning from 3.6.139 to 3.6.141

Bumps [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) from 3.6.139 to 3.6.141.
- [Release notes](https://github.com/dotnet/Nerdbank.GitVersioning/releases)
- [Commits](https://github.com/dotnet/Nerdbank.GitVersioning/compare/v3.6.139...v3.6.141)

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump WoofWare.Myriad.Plugins.Attributes from 3.1.11 to 3.1.12

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.1.11 to 3.1.12.
- [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.Attributes.3.1.11...WoofWare.Myriad.Plugins.Attributes.3.1.12)

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

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

* 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>
2024-08-12 17:59:16 +01:00
dependabot[bot]
64649b76ce Bump actions/attest-build-provenance from 1.4.0 to 1.4.1 (#118)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](210c191353...310b0a4a3b)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 16:18:49 +00:00
patrick-conscriptus[bot]
c9f013891b Automated commit (#117)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-11 00:39:47 +00:00
dependabot[bot]
a7660d1c38 Bump WoofWare.Myriad.Plugins.Attributes from 3.1.9 to 3.1.11 (#116)
* Bump WoofWare.Myriad.Plugins.Attributes from 3.1.9 to 3.1.11

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.1.9 to 3.1.11.
- [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.Attributes.3.1.9...WoofWare.Myriad.Plugins.Attributes.3.1.11)

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

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

---------

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>
2024-08-05 22:57:49 +00:00
dependabot[bot]
d49d36206e Bump actions/attest-build-provenance from 1.3.3 to 1.4.0 (#115)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.3.3 to 1.4.0.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](5e9cb68e95...210c191353)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 17:46:45 +01:00
Patrick Stevens
881d5227e7 Properly exclude test project (#114) 2024-08-04 19:42:26 +01:00
dependabot[bot]
6564835ee4 Bump NUnit3TestAdapter from 4.5.0 to 4.6.0 (#112)
* Bump NUnit3TestAdapter from 4.5.0 to 4.6.0

Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.5.0 to 4.6.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.5.0...V4.6.0)

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

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

---------

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>
2024-08-04 19:06:14 +01:00
patrick-conscriptus[bot]
db2ecdfa43 Automated commit (#113)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-04 00:38:57 +00:00
patrick-conscriptus[bot]
5b376cc592 Automated commit (#111)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-07-28 00:38:17 +00:00
dependabot[bot]
4d34382cd3 Bump WoofWare.Myriad.Plugins from 2.1.52 to 2.1.53 (#110)
* Bump WoofWare.Myriad.Plugins from 2.1.52 to 2.1.53

Bumps [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) from 2.1.52 to 2.1.53.
- [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.2.1.52...WoofWare.Myriad.Plugins.2.1.53)

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

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

* Dep

---------

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>
2024-07-22 19:30:40 +01:00
patrick-conscriptus[bot]
c26e4f085d Automated commit (#109)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-07-21 00:37:52 +00:00
dependabot[bot]
b002be5d72 Bump fantomas from 6.3.9 to 6.3.10 (#108)
* Bump WoofWare.Myriad.Plugins.Attributes from 3.1.8 to 3.1.9

Bumps WoofWare.Myriad.Plugins.Attributes from 3.1.8 to 3.1.9.

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

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

* Bump fantomas from 6.3.9 to 6.3.10

Bumps fantomas from 6.3.9 to 6.3.10.

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Update lockfile

---------

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>
2024-07-15 17:44:32 +00:00
dependabot[bot]
5483184edc Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 (#106)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.3.2 to 1.3.3.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](bdd51370e0...5e9cb68e95)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 18:34:00 +01:00
patrick-conscriptus[bot]
3596b8a3a8 Upgrade Nix flake and deps (#105)
* Automated commit

* Fix flake

---------

Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-14 07:50:39 +00:00
Patrick Stevens
68326d7628 Add flake update workflow (#103) 2024-07-12 21:52:28 +00:00
Patrick Stevens
f4b0a5457b Abstract away the required-checks feature (#104) 2024-07-12 21:58:01 +01:00
Patrick Stevens
c4b67304a1 Fix required checks (#102) 2024-07-12 17:24:12 +01:00
Patrick Stevens
337a0635d2 Add reproducibility check (#101) 2024-07-11 00:36:13 +01:00
dependabot[bot]
e8e302db2d Bump ApiSurface from 4.0.42 to 4.0.43 (#100)
* Bump ApiSurface from 4.0.42 to 4.0.43

Bumps ApiSurface from 4.0.42 to 4.0.43.

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-07-08 18:57:55 +01:00
dependabot[bot]
1522e3cc9c Bump WoofWareMyriadPluginVersion from 2.1.51 to 2.1.52 (#99)
* Bump WoofWareMyriadPluginVersion from 2.1.51 to 2.1.52

Bumps `WoofWareMyriadPluginVersion` from 2.1.51 to 2.1.52.

Updates `WoofWare.Myriad.Plugins` from 2.1.51 to 2.1.52
- [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.2.1.51...WoofWare.Myriad.Plugins.2.1.52)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.1.7 to 3.1.8
- [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.Attributes.3.1.7...WoofWare.Myriad.Plugins.Attributes.3.1.8)

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

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

* 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>
2024-07-01 19:05:43 +01:00
dependabot[bot]
81c6b584a4 Bump ApiSurface from 4.0.41 to 4.0.42, WoofWare.Myriad.Plugins from 2.1.45 to 2.1.51 (#98)
* Bump WoofWare.Myriad.Plugins from 2.1.45 to 2.1.49

Bumps [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) from 2.1.45 to 2.1.49.
- [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.2.1.45...WoofWare.Myriad.Plugins.2.1.49)

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

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

* Bump ApiSurface from 4.0.41 to 4.0.42

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.41 to 4.0.42.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.41...ApiSurface.4.0.42)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-07-01 18:44:01 +01:00
dependabot[bot]
40824e06e7 Bump actions/attest-build-provenance from 1.0.0 to 1.3.2 (#96)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.0.0 to 1.3.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](897ed5eab6...bdd51370e0)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-24 18:54:49 +01:00
Patrick Stevens
fb945c04ac Use DOTNET_STARTUP_HOOK to have the target run the tests (#91) 2024-06-23 17:25:24 +01:00
Patrick Stevens
85cd116d52 Delete unused file (#94) 2024-06-23 15:30:46 +01:00
Patrick Stevens
8e7c54cc83 Split out AppContext and Args to lib (#93) 2024-06-23 15:26:35 +01:00
Patrick Stevens
378a0169f8 Formatting (#92) 2024-06-23 15:13:40 +01:00
Patrick Stevens
870804d6ef Multi-framework Consumer test (#89) 2024-06-23 11:50:58 +01:00
Patrick Stevens
9f5f22c644 Pull report generation into lib (#90) 2024-06-23 11:44:53 +01:00
Patrick Stevens
296f230616 Bump deps (#88) 2024-06-17 23:51:00 +01:00
Patrick Stevens
56ac203570 Attest contents of NuGet packages (#87) 2024-06-17 23:37:53 +01:00
Patrick Stevens
e17e769d5a Direnv (#84) 2024-06-16 23:29:01 +01:00
Patrick Stevens
57c34e0c4c Permit self-contained test fixtures (#83) 2024-06-16 21:26:31 +01:00
Patrick Stevens
7f9464b826 Args (#82) 2024-06-16 19:28:16 +01:00
Patrick Stevens
3d04199c56 More runtimes (#81) 2024-06-16 16:13:58 +01:00
Patrick Stevens
9d4b893e02 Run tests in parallel (#79) 2024-06-16 15:43:07 +01:00
Patrick Stevens
55e9645316 Rewrite tests to allow being run in parallel (#80) 2024-06-16 15:20:07 +01:00
Patrick Stevens
e9dc768449 Parallelize (#69) 2024-06-16 11:55:10 +01:00
Patrick Stevens
e0b2d52812 Generalise Spectre to arbitrary console (#78) 2024-06-15 23:57:48 +01:00
Patrick Stevens
2ed4a04f70 Add test for stdout/stderr redirection (#77) 2024-06-15 23:32:31 +01:00
Patrick Stevens
2e066a1a9a Recognise parallelism attributes (#76) 2024-06-15 23:26:19 +01:00
Patrick Stevens
6468a301b9 Capture stderr too (#75) 2024-06-15 23:06:11 +01:00
Patrick Stevens
13f636df3d Promote runtime stuff to lib (#74) 2024-06-15 22:55:30 +01:00
Patrick Stevens
eed076cad5 Cap runtime of test (#73) 2024-06-15 22:50:15 +01:00
Patrick Stevens
df64e46079 Cope with parameterised fixtures (#70) 2024-06-11 23:28:13 +01:00
Patrick Stevens
b3bc0aa4c0 Fix param count error with TestCase (#68) 2024-06-11 22:41:43 +01:00
Patrick Stevens
d3f9ee6b02 Throw on SetUpFixture (#63) 2024-06-10 23:45:03 +01:00
Patrick Stevens
3e6fff27d6 Stop throwing on unrecognised exceptions (#62) 2024-06-10 23:28:49 +01:00
Patrick Stevens
ebcf0ed589 Rename from the rather bland "TestRunner" (#61) 2024-06-10 23:25:33 +01:00
dependabot[bot]
181063afcd Bump fantomas from 6.3.7 to 6.3.9 (#58)
* Bump WoofWare.Myriad.Plugins.Attributes from 3.1.4 to 3.1.6

Bumps [WoofWare.Myriad.Plugins.Attributes](https://github.com/Smaug123/WoofWare.Myriad) from 3.1.4 to 3.1.6.
- [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.Attributes.3.1.4...WoofWare.Myriad.Plugins.Attributes.3.1.6)

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

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

* Bump ApiSurface from 4.0.40 to 4.0.41

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.40 to 4.0.41.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.40...ApiSurface.4.0.41)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump fantomas from 6.3.7 to 6.3.9

Bumps [fantomas](https://github.com/fsprojects/fantomas) from 6.3.7 to 6.3.9.
- [Release notes](https://github.com/fsprojects/fantomas/releases)
- [Changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fsprojects/fantomas/compare/v6.3.7...v6.3.9)

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump WoofWare.DotnetRuntimeLocator from 0.1.3 to 0.1.4

Bumps [WoofWare.DotnetRuntimeLocator](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/releases)
- [Commits](https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/compare/WoofWare.DotnetRuntimeLocator.0.1.3...WoofWare.DotnetRuntimeLocator.0.1.4)

---
updated-dependencies:
- dependency-name: WoofWare.DotnetRuntimeLocator
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* 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>
2024-06-10 18:42:15 +01:00
78 changed files with 4780 additions and 2012 deletions

View File

@@ -3,13 +3,13 @@
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"fantomas": { "fantomas": {
"version": "6.3.7", "version": "7.0.3",
"commands": [ "commands": [
"fantomas" "fantomas"
] ]
}, },
"fsharp-analyzers": { "fsharp-analyzers": {
"version": "0.26.0", "version": "0.32.1",
"commands": [ "commands": [
"fsharp-analyzers" "fsharp-analyzers"
] ]

View File

@@ -1,40 +1,40 @@
root=true root = true
[*] [*]
charset=utf-8 charset = utf-8
trim_trailing_whitespace=true trim_trailing_whitespace = true
insert_final_newline=true insert_final_newline = true
indent_style=space indent_style = space
indent_size=4 indent_size = 4
# ReSharper properties # ReSharper properties
resharper_xml_indent_size=2 resharper_xml_indent_size = 2
resharper_xml_max_line_length=100 resharper_xml_max_line_length = 100
resharper_xml_tab_width=2 resharper_xml_tab_width = 2
[*.{csproj,fsproj,sqlproj,targets,props,ts,tsx,css,json}] [*.{csproj,fsproj,sqlproj,targets,props,ts,tsx,css,json}]
indent_style=space indent_style = space
indent_size=2 indent_size = 2
[*.{fs,fsi}] [*.{fs,fsi}]
fsharp_bar_before_discriminated_union_declaration=true fsharp_bar_before_discriminated_union_declaration = true
fsharp_space_before_uppercase_invocation=true fsharp_space_before_uppercase_invocation = true
fsharp_space_before_class_constructor=true fsharp_space_before_class_constructor = true
fsharp_space_before_member=true fsharp_space_before_member = true
fsharp_space_before_colon=true fsharp_space_before_colon = true
fsharp_space_before_semicolon=true fsharp_space_before_semicolon = true
fsharp_multiline_bracket_style=aligned fsharp_multiline_bracket_style = aligned
fsharp_newline_between_type_definition_and_members=true fsharp_newline_between_type_definition_and_members = true
fsharp_align_function_signature_to_indentation=true fsharp_align_function_signature_to_indentation = true
fsharp_alternative_long_member_definitions=true fsharp_alternative_long_member_definitions = true
fsharp_multi_line_lambda_closing_newline=true fsharp_multi_line_lambda_closing_newline = true
fsharp_experimental_keep_indent_in_branch=true fsharp_experimental_keep_indent_in_branch = true
fsharp_max_value_binding_width=80 fsharp_max_value_binding_width = 80
fsharp_max_record_width=0 fsharp_max_record_width = 0
max_line_length=120 max_line_length = 120
end_of_line=lf end_of_line = lf
[*.{appxmanifest,build,dtd,nuspec,xaml,xamlx,xoml,xsd}] [*.{appxmanifest,build,dtd,nuspec,xaml,xamlx,xoml,xsd}]
indent_style=space indent_style = space
indent_size=2 indent_size = 2
tab_width=2 tab_width = 2

23
.envrc Normal file
View File

@@ -0,0 +1,23 @@
use flake
DOTNET_PATH=$(readlink "$(which dotnet)")
SETTINGS_FILE=$(find . -maxdepth 1 -type f -name '*.sln.DotSettings.user')
MSBUILD=$(realpath "$(find "$(dirname "$DOTNET_PATH")/../share/dotnet/sdk" -maxdepth 2 -type f -name MSBuild.dll)")
if [ -f "$SETTINGS_FILE" ] ; then
xmlstarlet ed --inplace \
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
-N s="clr-namespace:System;assembly=mscorlib" \
-N ss="urn:shemas-jetbrains-com:settings-storage-xaml" \
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue']" \
--value "$(realpath "$(dirname "$DOTNET_PATH")/../share/dotnet/dotnet")" \
"$SETTINGS_FILE"
xmlstarlet ed --inplace \
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
-N s="clr-namespace:System;assembly=mscorlib" \
-N ss="urn:shemas-jetbrains-com:settings-storage-xaml" \
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue']" \
--value "$MSBUILD" \
"$SETTINGS_FILE"
fi

1
.fantomasignore Normal file
View File

@@ -0,0 +1 @@
.direnv/

View File

@@ -25,11 +25,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -38,7 +38,30 @@ jobs:
- name: Build - name: Build
run: 'nix develop --command dotnet build --no-restore --configuration ${{matrix.config}}' run: 'nix develop --command dotnet build --no-restore --configuration ${{matrix.config}}'
- name: Test - name: Test
run: 'nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}}' run: |
nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}} --filter 'FullyQualifiedName !~ FailingConsumer'
selftest-intended-failures:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Restore dependencies
run: nix develop --command dotnet restore
- name: Build
run: 'nix develop --command dotnet build --no-restore --configuration Release'
- name: Test using self
run: 'nix develop --command dotnet exec ./WoofWare.NUnitTestRunner/bin/Release/net9.0/WoofWare.NUnitTestRunner.dll ./FailingConsumer/bin/Release/net9.0/FailingConsumer.dll --trx TrxOut/out.trx || true'
- name: Munge output
run: 'nix develop --command xmlstarlet sel -N x="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" -t -m "//x:UnitTestResult" -v "@testName" -o ": " -v ".//x:ErrorInfo/x:Message" -n TrxOut/out.trx > snapshot.txt'
- name: Check output matches expected
run: 'actual=$(cat snapshot.txt | sort) expected=$(cat FailingConsumer/expected.txt | sort) [ "$expected" == "$actual" ]'
selftest: selftest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -58,11 +81,11 @@ jobs:
statuses: read statuses: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -71,10 +94,10 @@ jobs:
- name: Build - name: Build
run: 'nix develop --command dotnet build --no-restore --configuration Release' run: 'nix develop --command dotnet build --no-restore --configuration Release'
- name: Test using self - name: Test using self
run: 'nix develop --command dotnet exec ./TestRunner/bin/Release/net8.0/TestRunner.dll ./Consumer/bin/Release/net8.0/Consumer.dll --trx TrxOut/out.trx' run: 'nix develop --command dotnet exec ./WoofWare.NUnitTestRunner/bin/Release/net9.0/WoofWare.NUnitTestRunner.dll ./Consumer/bin/Release/net9.0/Consumer.dll --trx TrxOut/out.trx'
- name: Parse Trx files - name: Parse Trx files
uses: NasAmin/trx-parser@v0.6.0 uses: NasAmin/trx-parser@v0.7.0
if: always() if: always() && github.ref_name != 'main'
id: trx-parser id: trx-parser
with: with:
TRX_PATH: ${{ github.workspace }}/TrxOut TRX_PATH: ${{ github.workspace }}/TrxOut
@@ -86,41 +109,43 @@ jobs:
security-events: write security-events: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Prepare analyzers - name: Prepare analyzers
run: nix develop --command dotnet restore analyzers/analyzers.fsproj run: nix develop --command dotnet restore analyzers/analyzers.fsproj
- name: Build project - name: Build project
run: nix develop --command dotnet build ./TestRunner/TestRunner.fsproj run: nix develop --command dotnet build ./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.fsproj
- name: Run analyzers - name: Run analyzers
run: nix run .#fsharp-analyzers -- --project ./TestRunner/TestRunner.fsproj --analyzers-path ./.analyzerpackages/g-research.fsharp.analyzers/*/ --verbosity detailed --report ./analysis.sarif --treat-as-error GRA-STRING-001 GRA-STRING-002 GRA-STRING-003 GRA-UNIONCASE-001 GRA-INTERPOLATED-001 GRA-TYPE-ANNOTATE-001 GRA-VIRTUALCALL-001 GRA-IMMUTABLECOLLECTIONEQUALITY-001 GRA-JSONOPTS-001 GRA-LOGARGFUNCFULLAPP-001 GRA-DISPBEFOREASYNC-001 --exclude-analyzers PartialAppAnalyzer run: nix run .#fsharp-analyzers -- --project ./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.fsproj --analyzers-path ./.analyzerpackages/g-research.fsharp.analyzers/*/ --verbosity detailed --report ./analysis.sarif --treat-as-error GRA-STRING-001 GRA-STRING-002 GRA-STRING-003 GRA-UNIONCASE-001 GRA-INTERPOLATED-001 GRA-TYPE-ANNOTATE-001 GRA-VIRTUALCALL-001 GRA-IMMUTABLECOLLECTIONEQUALITY-001 GRA-JSONOPTS-001 GRA-LOGARGFUNCFULLAPP-001 GRA-DISPBEFOREASYNC-001 --exclude-analyzers PartialAppAnalyzer
build-nix: build-nix:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build - name: Build
run: nix build run: nix build
- name: Reproducibility check
run: nix build --rebuild
check-dotnet-format: check-dotnet-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -131,9 +156,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -146,7 +171,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -159,7 +184,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -169,11 +194,11 @@ jobs:
nuget-pack: nuget-pack:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
@@ -187,19 +212,19 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nuget-package-lib name: nuget-package-lib
path: TestRunner.Lib/bin/Release/WoofWare.NUnitTestRunner.Lib.*.nupkg path: WoofWare.NUnitTestRunner.Lib/bin/Release/WoofWare.NUnitTestRunner.Lib.*.nupkg
- name: Upload NuGet artifact (tool) - name: Upload NuGet artifact (tool)
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nuget-package-tool name: nuget-package-tool
path: TestRunner/bin/Release/WoofWare.NUnitTestRunner.*.nupkg path: WoofWare.NUnitTestRunner/bin/Release/WoofWare.NUnitTestRunner.*.nupkg
expected-pack: expected-pack:
needs: [nuget-pack] needs: [nuget-pack]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download NuGet artifact (lib) - name: Download NuGet artifact (lib)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v5
with: with:
name: nuget-package-lib name: nuget-package-lib
path: packed-lib path: packed-lib
@@ -207,7 +232,7 @@ jobs:
# Verify that there is exactly one nupkg in the artifact that would be NuGet published # Verify that there is exactly one nupkg in the artifact that would be NuGet published
run: if [[ $(find packed-lib -maxdepth 1 -name 'WoofWare.NUnitTestRunner.Lib.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi run: if [[ $(find packed-lib -maxdepth 1 -name 'WoofWare.NUnitTestRunner.Lib.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi
- name: Download NuGet artifact (tool) - name: Download NuGet artifact (tool)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v5
with: with:
name: nuget-package-tool name: nuget-package-tool
path: packed-tool path: packed-tool
@@ -215,59 +240,165 @@ jobs:
# Verify that there is exactly one nupkg in the artifact that would be NuGet published # Verify that there is exactly one nupkg in the artifact that would be NuGet published
run: if [[ $(find packed-tool -maxdepth 1 -name 'WoofWare.NUnitTestRunner.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi run: if [[ $(find packed-tool -maxdepth 1 -name 'WoofWare.NUnitTestRunner.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi
github-release-tool-dry-run: all-required-checks-complete:
needs: [nuget-pack] if: ${{ always() }}
needs: [github-release-dry-run, check-dotnet-format, check-nix-format, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, selftest-intended-failures, selftest]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: G-Research/common-actions/check-required-lite@2b7dc49cb14f3344fbe6019c14a31165e258c059
- name: Download NuGet artifact (lib) with:
uses: actions/download-artifact@v4 needs-context: ${{ toJSON(needs) }}
attestation-lib:
runs-on: ubuntu-latest
needs: [all-required-checks-complete]
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
permissions:
id-token: write
attestations: write
contents: read
steps:
- name: Download NuGet artifact
uses: actions/download-artifact@v5
with: with:
name: nuget-package-lib name: nuget-package-lib
- name: Download NuGet artifact (tool) path: packed
uses: actions/download-artifact@v4 - name: Attest Build Provenance
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-path: "packed/*.nupkg"
attestation-tool:
runs-on: ubuntu-latest
needs: [all-required-checks-complete]
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
permissions:
id-token: write
attestations: write
contents: read
steps:
- name: Download NuGet artifact
uses: actions/download-artifact@v5
with: with:
name: nuget-package-tool name: nuget-package-tool
- name: Tag and release tool path: packed
env: - name: Attest Build Provenance
DRY_RUN: 1 uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
GITHUB_TOKEN: mock-token with:
run: sh .github/workflows/tag.sh subject-path: "packed/*.nupkg"
all-required-checks-complete: nuget-publish-lib:
needs: [check-dotnet-format, check-nix-format, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-tool-dry-run]
runs-on: ubuntu-latest
steps:
- run: echo "All required checks complete."
nuget-publish:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }} if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
needs: [all-required-checks-complete] needs: [all-required-checks-complete]
environment: main-deploy environment: main-deploy
permissions:
id-token: write
attestations: write
contents: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@V27 uses: cachix/install-nix-action@v31
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Download NuGet artifact (lib) - name: Download NuGet artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v5
with: with:
name: nuget-package-lib name: nuget-package-lib
path: packed-lib path: packed
- name: Publish to NuGet (lib) - name: Identify .NET
run: nix develop --command dotnet nuget push "packed-lib/WoofWare.NUnitTestRunner.Lib.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate id: identify-dotnet
- name: Download NuGet artifact (tool) run: nix develop --command bash -c "echo dotnet=$(which dotnet) >> $GITHUB_OUTPUT"
uses: actions/download-artifact@v4 - name: Obtain NuGet key
uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544
id: login
with:
user: ${{ secrets.NUGET_USER }}
- name: Publish NuGet package
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
with:
package-name: WoofWare.NUnitTestRunner.Lib
nuget-key: ${{ steps.login.outputs.NUGET_API_KEY }}
nupkg-dir: packed/
dotnet: ${{ steps.identify-dotnet.outputs.dotnet }}
nuget-publish-tool:
runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
needs: [all-required-checks-complete]
environment: main-deploy
permissions:
id-token: write
attestations: write
contents: read
steps:
- uses: actions/checkout@v5
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Download NuGet artifact
uses: actions/download-artifact@v5
with: with:
name: nuget-package-tool name: nuget-package-tool
path: packed-tool path: packed
- name: Publish to NuGet (tool) - name: Identify .NET
run: nix develop --command dotnet nuget push "packed-tool/WoofWare.NUnitTestRunner.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate id: identify-dotnet
run: nix develop --command bash -c "echo dotnet=$(which dotnet) >> $GITHUB_OUTPUT"
- name: Obtain NuGet key
uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544
id: login
with:
user: ${{ secrets.NUGET_USER }}
- name: Publish NuGet package
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
with:
package-name: WoofWare.NUnitTestRunner
nuget-key: ${{ steps.login.outputs.NUGET_API_KEY }}
nupkg-dir: packed/
dotnet: ${{ steps.identify-dotnet.outputs.dotnet }}
github-release-tool: github-release-dry-run:
strategy:
matrix:
artifact:
- nuget-package-tool
- nuget-package-lib
runs-on: ubuntu-latest
needs: [nuget-pack]
steps:
- uses: actions/checkout@v5
- name: Download NuGet artifact (tool)
uses: actions/download-artifact@v5
with:
name: ${{ matrix.artifact }}
- name: Compute package path
id: compute-path
run: |
find . -maxdepth 1 -type f -name 'WoofWare.NUnitTestRunner.*.nupkg' -exec sh -c 'echo "output=$(basename "$1")" >> $GITHUB_OUTPUT' shell {} \;
- name: Compute tag name
id: compute-tag
env:
NUPKG_PATH: ${{ steps.compute-path.outputs.output }}
run: echo "output=$(basename "$NUPKG_PATH" .nupkg)" >> $GITHUB_OUTPUT
- name: Tag and release
uses: G-Research/common-actions/github-release@19d7281a0f9f83e13c78f99a610dbc80fc59ba3b
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
target-commitish: ${{ github.sha }}
tag: ${{ steps.compute-tag.outputs.output }}
binary-contents: ${{ steps.compute-path.outputs.output }}
dry-run: true
github-release:
strategy:
matrix:
artifact:
- nuget-package-tool
- nuget-package-lib
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }} if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
needs: [all-required-checks-complete] needs: [all-required-checks-complete]
@@ -275,16 +406,24 @@ jobs:
permissions: permissions:
contents: write contents: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Download NuGet artifact (tool) - name: Download NuGet artifact (tool)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v5
with: with:
name: nuget-package-tool name: ${{ matrix.artifact }}
- name: Download NuGet artifact (lib) - name: Compute package path
uses: actions/download-artifact@v4 id: compute-path
with: run: |
name: nuget-package-lib find . -maxdepth 1 -type f -name 'WoofWare.NUnitTestRunner.*.nupkg' -exec sh -c 'echo "output=$(basename "$1")" >> $GITHUB_OUTPUT' shell {} \;
- name: Tag and release plugin - name: Compute tag name
id: compute-tag
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NUPKG_PATH: ${{ steps.compute-path.outputs.output }}
run: sh .github/workflows/tag.sh run: echo "output=$(basename "$NUPKG_PATH" .nupkg)" >> $GITHUB_OUTPUT
- name: Tag and release
uses: G-Research/common-actions/github-release@19d7281a0f9f83e13c78f99a610dbc80fc59ba3b
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
target-commitish: ${{ github.sha }}
tag: ${{ steps.compute-tag.outputs.output }}
binary-contents: ${{ steps.compute-path.outputs.output }}

54
.github/workflows/flake_update.yaml vendored Normal file
View File

@@ -0,0 +1,54 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/github-workflow.json
name: Weekly Nix Flake Update
on:
schedule:
- cron: '0 0 * * 0' # Runs at 00:00 every Sunday
workflow_dispatch: # Allows manual triggering
jobs:
update-nix-flake:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Update Nix flake
run: 'nix flake update'
- name: Build fetch-deps
run: 'nix build ".#default.fetch-deps"'
- name: Run fetch-deps
run: ./result nix/deps.json
- name: Format
run: 'nix develop --command alejandra .'
- name: Create token
id: generate-token
uses: actions/create-github-app-token@v2
with:
# https://github.com/actions/create-github-app-token/issues/136
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Raise pull request
uses: Smaug123/commit-action@cc25e6d80a796c49669dda4a0aa36c54c573983d
id: cpr
with:
bearer-token: ${{ steps.generate-token.outputs.token }}
pr-title: "Upgrade Nix flake and deps"
- name: Enable Pull Request Automerge
if: ${{ steps.cpr.outputs.pull-request-number }}
uses: peter-evans/enable-pull-request-automerge@v3
with:
token: ${{ steps.generate-token.outputs.token }}
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
merge-method: squash

View File

@@ -1,124 +0,0 @@
#!/bin/bash
echo "Dry-run? $DRY_RUN!"
find . -maxdepth 1 -type f ! -name "$(printf "*\n*")" -name '*.nupkg' | while IFS= read -r file
do
tag=$(basename "$file" .nupkg)
git tag "$tag"
${DRY_RUN:+echo} git push origin "$tag"
done
export TAG
TAG=$(find . -maxdepth 1 -type f -name 'WoofWare.NUnitTestRunner.*.nupkg' -exec sh -c 'basename "$1" .nupkg' shell {} \; | grep -v Lib)
case "$TAG" in
*"
"*)
echo "Error: TAG contains a newline; multiple tools found."
exit 1
;;
esac
# target_commitish empty indicates the repo default branch
IS_PRERELEASE="false"
if [ "${TAG#*prerelease}" != "$TAG" ]; then
IS_PRERELEASE="true"
fi
curl_body='{"tag_name":"'"$TAG"'","target_commitish":"","name":"'"$TAG"'","draft":false,"prerelease":'"$IS_PRERELEASE"',"generate_release_notes":false}'
echo "cURL body: $curl_body"
failed_output=$(cat <<'EOF'
{
"message": "Validation Failed",
"errors": [
{
"resource": "Release",
"code": "already_exists",
"field": "tag_name"
}
],
"documentation_url": "https://docs.github.com/rest/releases/releases#create-a-release"
}
EOF
)
success_output=$(cat <<'EOF'
{
"url": "https://api.github.com/repos/Smaug123/unofficial-nunit-runner/releases/158152116",
"assets_url": "https://api.github.com/repos/Smaug123/unofficial-nunit-runner/releases/158152116/assets",
"upload_url": "https://uploads.github.com/repos/Smaug123/unofficial-nunit-runner/releases/158152116/assets{?name,label}",
"html_url": "https://github.com/Smaug123/unofficial-nunit-runner/releases/tag/WoofWare.NUnitTestRunner.2.1.30",
"id": 158152116,
"author": {
"login": "github-actions[bot]",
"id": 41898282,
"node_id": "MDM6Qm90NDE4OTgyODI=",
"avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/github-actions%5Bbot%5D",
"html_url": "https://github.com/apps/github-actions",
"followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers",
"following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}",
"gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}",
"starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions",
"organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs",
"repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos",
"events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}",
"received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events",
"type": "Bot",
"site_admin": false
},
"node_id": "RE_kwDOJfksgc4JbTW0",
"tag_name": "WoofWare.NUnitTestRunner.2.1.30",
"target_commitish": "main",
"name": "WoofWare.NUnitTestRunner.2.1.30",
"draft": false,
"prerelease": false,
"created_at": "2024-05-30T11:00:55Z",
"published_at": "2024-05-30T11:03:02Z",
"assets": [
],
"tarball_url": "https://api.github.com/repos/Smaug123/unofficial-nunit-runner/tarball/WoofWare.NUnitTestRunner.2.1.30",
"zipball_url": "https://api.github.com/repos/Smaug123/unofficial-nunit-runner/zipball/WoofWare.NUnitTestRunner.2.1.30",
"body": null
}
EOF
)
HANDLE_OUTPUT=''
handle_error() {
ERROR_OUTPUT="$1"
exit_message=$(echo "$ERROR_OUTPUT" | jq -r --exit-status 'if .errors | length == 1 then .errors[0].code else null end')
if [ "$exit_message" = "already_exists" ] ; then
HANDLE_OUTPUT="Did not create GitHub release because it already exists at this version."
else
echo "Unexpected error output from curl: $(cat curl_output.json)"
echo "JQ output: $(exit_message)"
exit 2
fi
}
run_tests() {
handle_error "$failed_output"
if [ "$HANDLE_OUTPUT" != "Did not create GitHub release because it already exists at this version." ]; then
echo "Bad output from handler: $HANDLE_OUTPUT"
exit 3
fi
HANDLE_OUTPUT=''
echo "Tests passed."
}
run_tests
if [ "$DRY_RUN" != 1 ] ; then
if curl --fail-with-body -L -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/Smaug123/unofficial-nunit-runner/releases -d "$curl_body" > curl_output.json; then
echo "Curl succeeded."
else
handle_error "$(cat curl_output.json)"
echo "$HANDLE_OUTPUT"
fi
fi

View File

@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFrameworks>net9.0</TargetFrameworks>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject> <IsTestProject>true</IsTestProject>
</PropertyGroup> </PropertyGroup>
@@ -10,6 +9,14 @@
<ItemGroup> <ItemGroup>
<Compile Include="NoAttribute.fs" /> <Compile Include="NoAttribute.fs" />
<Compile Include="Inconclusive.fs" /> <Compile Include="Inconclusive.fs" />
<Compile Include="RunSubProcess.fs" />
<Compile Include="TestAsync.fs" />
<Compile Include="TestExplicit.fs" />
<Compile Include="TestNonParallel.fs" />
<Compile Include="TestParallel.fs" />
<Compile Include="TestParallelIndividualTest.fs" />
<Compile Include="TestStdout.fs" />
<Compile Include="TestParameterisedFixture.fs" />
<Compile Include="TestSetUp.fs" /> <Compile Include="TestSetUp.fs" />
<Compile Include="TestValues.fs" /> <Compile Include="TestValues.fs" />
<None Include="some-config.json"> <None Include="some-config.json">
@@ -21,10 +28,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FsUnit" Version="6.0.0" /> <PackageReference Include="FsUnit" Version="7.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="NUnit" Version="4.1.0"/> <PackageReference Include="NUnit" Version="4.3.2"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/> <PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
</ItemGroup> </ItemGroup>
</Project> </Project>

45
Consumer/RunSubProcess.fs Normal file
View File

@@ -0,0 +1,45 @@
namespace Consumer
open System
open System.Diagnostics
open System.IO
open System.IO.Compression
open System.Text
open NUnit.Framework
open FsUnitTyped
[<TestFixture>]
module RunSubProcess =
[<Test>]
let ``Run a subprocess`` () =
let exe = "/bin/bash"
let args = [ "-c" ; "echo hi >&2 && echo bye" ]
let workingDir = None
let psi =
ProcessStartInfo (
exe,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Option.toObj workingDir
)
for arg in args do
psi.ArgumentList.Add arg
psi.EnvironmentVariables.Add ("THING", Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "hi"))
let stderr = StringBuilder ()
use proc = new Process (StartInfo = psi)
proc.OutputDataReceived.Add (fun e -> printfn $"%s{e.Data}")
proc.ErrorDataReceived.Add (fun e ->
eprintfn $"%s{e.Data}"
stderr.AppendLine e.Data |> ignore
)
proc.Start () |> shouldEqual true
proc.BeginOutputReadLine ()
proc.BeginErrorReadLine ()
proc.WaitForExit ()

23
Consumer/TestAsync.fs Normal file
View File

@@ -0,0 +1,23 @@
namespace Consumer
open System
open System.Threading.Tasks
open FsUnitTyped
open NUnit.Framework
[<TestFixture>]
module TestAsync =
[<Test>]
let ``an async test`` () =
async {
do! Async.Sleep (TimeSpan.FromMilliseconds 20.0)
1 |> shouldEqual 1
}
[<Test>]
let ``an async test, task-based`` () =
task {
do! Task.Delay (TimeSpan.FromMilliseconds 20.0)
1 |> shouldEqual 1
}

View File

@@ -35,6 +35,13 @@ module TestCaseData =
[<TestCaseSource(nameof optionalRaw)>] [<TestCaseSource(nameof optionalRaw)>]
let ``Consume options, raw`` (s : string option) : unit = s |> shouldEqual s let ``Consume options, raw`` (s : string option) : unit = s |> shouldEqual s
[<TestCase(30, 15, 44, false)>]
let bug66 (i : int, j : int, k : int, l : bool) =
i |> shouldEqual 30
j |> shouldEqual 15
k |> shouldEqual 44
l |> shouldEqual false
[<OneTimeTearDown>] [<OneTimeTearDown>]
let tearDown () = let tearDown () =
testCasesSeen testCasesSeen

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

@@ -0,0 +1,19 @@
namespace Consumer
open System
open System.Threading
open NUnit.Framework
open FsUnitTyped
[<TestFixture>]
[<NonParallelizable>]
module TestNonParallel =
let defaults = List.init 40 id
let lock = ref 0
[<TestCaseSource(nameof defaults)>]
let ``Default thing, but not parallel`` (i : int) =
Interlocked.Increment lock |> shouldEqual 1
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
lock.Value <- 0
i |> shouldEqual i

66
Consumer/TestParallel.fs Normal file
View File

@@ -0,0 +1,66 @@
namespace Consumer
open System
open System.Threading
open NUnit.Framework
open FsUnitTyped
[<TestFixture>]
[<Parallelizable>]
module TestParallelDefault =
let defaults = List.init 60 id
[<TestCaseSource(nameof defaults)>]
let ``Default thing, no scope`` (i : int) =
Console.WriteLine i
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
i |> shouldEqual i
[<TestFixture>]
[<Parallelizable(ParallelScope.All)>]
module TestParallelAllScope =
let defaults = List.init 60 id
[<TestCaseSource(nameof defaults)>]
let ``Thing, all scope`` (i : int) =
Console.WriteLine i
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
i |> shouldEqual i
[<TestFixture>]
[<Parallelizable(ParallelScope.Self)>]
module TestParallelSelfScope =
let defaults = List.init 60 id
[<TestCaseSource(nameof defaults)>]
let ``Thing, self scope`` (i : int) =
Console.WriteLine i
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
i |> shouldEqual i
[<TestFixture>]
[<Parallelizable(ParallelScope.Children)>]
module TestParallelChildrenScope =
let defaults = List.init 60 id
[<TestCaseSource(nameof defaults)>]
let ``Thing, children scope`` (i : int) =
Console.WriteLine i
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
i |> shouldEqual i
[<TestFixture>]
[<Parallelizable(ParallelScope.Fixtures)>]
module TestParallelFixturesScope =
let defaults = List.init 60 id
[<TestCaseSource(nameof defaults)>]
let ``Thing, fixtures scope`` (i : int) =
Console.WriteLine i
Thread.Sleep (TimeSpan.FromMilliseconds (float i))
i |> shouldEqual i

View File

@@ -0,0 +1,59 @@
namespace Consumer
open System
open System.Collections.Concurrent
open System.Threading
open NUnit.Framework
open FsUnitTyped
// These tests are flaky if the bug https://github.com/Smaug123/unofficial-nunit-runner/issues/168 is unfixed.
[<TestFixture>]
module TestParallelIndividualTest =
type private Transitions =
| Started of int
| LockAcquired of int
| Exited of int
let locker = obj ()
let private sequence = ConcurrentQueue<Transitions> ()
[<Test>]
[<Parallelizable(ParallelScope.None)>]
let ``does not run in parallel`` () =
sequence.Enqueue (Transitions.Started 0)
let entered = Monitor.TryEnter (locker, TimeSpan.Zero)
if entered then
sequence.Enqueue (Transitions.LockAcquired 0)
Monitor.Exit locker
sequence.Enqueue (Transitions.Exited 0)
else
sequence.Enqueue (Transitions.Exited 0)
failwith "failed to acquire the lock"
[<Test>]
let ``unrestricted parallelism`` () =
sequence.Enqueue (Transitions.Started 1)
let entered = Monitor.TryEnter (locker, TimeSpan.Zero)
if entered then
sequence.Enqueue (Transitions.LockAcquired 1)
Monitor.Exit locker
sequence.Enqueue (Transitions.Exited 1)
else
sequence.Enqueue (Transitions.Exited 1)
failwith "failed to acquire the lock"
[<OneTimeTearDown>]
let ``It worked`` () =
let sequence = sequence |> Seq.toList
let allowed n =
[ Transitions.Started n ; Transitions.LockAcquired n ; Transitions.Exited n ]
if sequence <> allowed 0 @ allowed 1 && sequence <> allowed 1 @ allowed 0 then
let s = sequence |> Seq.map string<Transitions> |> String.concat "\n"
failwith $"Unexpected sequence!\n%s{s}"
()

View File

@@ -0,0 +1,18 @@
namespace Consumer
open NUnit.Framework
open FsUnitTyped
[<TestFixture true>]
[<TestFixture false>]
type TestParameterisedFixture (v : bool) =
[<Test>]
member _.Thing () = v |> shouldEqual v
[<TestFixture(3, true)>]
[<TestFixture(6, false)>]
type TestParameterisedFixtureMultiple (i : int, v : bool) =
[<Test>]
member _.Thing () =
v |> shouldEqual v
i |> shouldEqual i

View File

@@ -1,5 +1,6 @@
namespace Consumer namespace Consumer
open System
open FsUnitTyped open FsUnitTyped
open System.Threading open System.Threading
open NUnit.Framework open NUnit.Framework
@@ -11,6 +12,8 @@ module TestSetUp =
[<OneTimeSetUp>] [<OneTimeSetUp>]
let oneTimeSetUp () = let oneTimeSetUp () =
Console.WriteLine "I'm being set up for the first time!"
if Interlocked.Increment haveOneTimeSetUp <> 1 then if Interlocked.Increment haveOneTimeSetUp <> 1 then
failwith "one time setup happened more than once" failwith "one time setup happened more than once"
@@ -22,12 +25,14 @@ module TestSetUp =
[<SetUp>] [<SetUp>]
let setUp () = let setUp () =
Console.WriteLine "It's a set-up!"
haveOneTimeSetUp.Value |> shouldEqual 1 haveOneTimeSetUp.Value |> shouldEqual 1
let newId = Interlocked.Increment setUpTimes let newId = Interlocked.Increment setUpTimes
lock setUpTimesSeen (fun () -> setUpTimesSeen.Add newId) lock setUpTimesSeen (fun () -> setUpTimesSeen.Add newId)
[<TearDown>] [<TearDown>]
let tearDown () = let tearDown () =
Console.WriteLine "I'm a tear-down!"
let newId = Interlocked.Increment tearDownTimes let newId = Interlocked.Increment tearDownTimes
lock tearDownTimesSeen (fun () -> tearDownTimesSeen.Add newId) lock tearDownTimesSeen (fun () -> tearDownTimesSeen.Add newId)
@@ -35,19 +40,23 @@ module TestSetUp =
[<OneTimeTearDown>] [<OneTimeTearDown>]
let oneTimeTearDown () = let oneTimeTearDown () =
Console.WriteLine "I'm being torn down, finally!"
if Interlocked.Increment haveOneTimeTearDown <> 1 then if Interlocked.Increment haveOneTimeTearDown <> 1 then
failwith "one time tear down happened more than once" failwith "one time tear down happened more than once"
setUpTimesSeen setUpTimesSeen
|> Seq.toList |> Seq.toList
|> List.sort
// Six tests: one for Test, two for the TestCase, three for the Repeat. // Six tests: one for Test, two for the TestCase, three for the Repeat.
|> shouldEqual [ 1..6 ] |> shouldEqual [ 1..6 ]
tearDownTimesSeen |> Seq.toList |> shouldEqual [ 1..6 ] tearDownTimesSeen |> Seq.toList |> List.sort |> shouldEqual [ 1..6 ]
[<Test>] [<Test>]
let ``Test 1`` () = let ``Test 1`` () =
haveOneTimeTearDown.Value |> shouldEqual 0 haveOneTimeTearDown.Value |> shouldEqual 0
Console.WriteLine "By the way, I'm test 1"
1 |> shouldEqual 1 1 |> shouldEqual 1
[<TestCase "h">] [<TestCase "h">]

13
Consumer/TestStdout.fs Normal file
View File

@@ -0,0 +1,13 @@
namespace Consumer
open System
open NUnit.Framework
[<TestFixture>]
module TestStdout =
[<Test>]
let ``Stdout is redirected`` () =
Console.Out.WriteLine "Hi!"
Console.WriteLine "Hi! part 2"
Console.Error.WriteLine "Bye!"

View File

@@ -86,14 +86,42 @@ module TestValues =
[<OneTimeTearDown>] [<OneTimeTearDown>]
let ``Values are all OK`` () = let ``Values are all OK`` () =
seen1 |> Seq.toList |> shouldEqual [ true ; false ] seen1 |> Seq.toList |> List.sort |> shouldEqual [ false ; true ]
seen2 |> Seq.toList |> shouldEqual [ (true, false) ; (false, true) ]
seen3 |> Seq.toList |> shouldEqual [ (88, box 29) ; (31, box 0) ] seen2
seen4 |> Seq.toList |> shouldEqual [ ("hi", box "ohh") ; ("bye", null) ] |> Seq.toList
seen5 |> Seq.toList |> shouldEqual [ (88, box 29) ; (31, box 29) ] |> List.sort
seen6 |> Seq.toList |> shouldEqual [ ("hi", box "ohh") ; ("bye", box "ohh") ] |> shouldEqual [ (false, true) ; (true, false) ]
seen7 |> Seq.toList |> shouldEqual [ (88, box 29) ; (31, box 29) ]
seen8 |> Seq.toList |> shouldEqual [ ("hi", box "ohh") ; ("bye", box "ohh") ] seen3
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ (31, box 0) ; (88, box 29) ]
seen4
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ ("bye", null) ; ("hi", box "ohh") ]
seen5
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ (31, box 29) ; (88, box 29) ]
seen6
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ ("bye", box "ohh") ; ("hi", box "ohh") ]
seen7
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ (31, box 29) ; (88, box 29) ]
seen8
|> Seq.toList
|> List.sortBy fst
|> shouldEqual [ ("bye", box "ohh") ; ("hi", box "ohh") ]
seen9 seen9
|> Seq.toList |> Seq.toList

View File

@@ -10,7 +10,7 @@
<WarnOn>FS3388,FS3559</WarnOn> <WarnOn>FS3388,FS3559</WarnOn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.139" PrivateAssets="all"/> <PackageReference Include="Nerdbank.GitVersioning" Version="3.8.118" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<PropertyGroup Condition="'$(GITHUB_ACTION)' != ''"> <PropertyGroup Condition="'$(GITHUB_ACTION)' != ''">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild> <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<Compile Include="TestInsufficientArgs.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FsUnit" Version="7.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="NUnit" Version="4.3.2"/>
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,9 @@
namespace FailingConsumer
open NUnit.Framework
[<TestFixture>]
module TestInsufficientArgs =
[<Test>]
let foo (_ : int) = ()

View File

@@ -0,0 +1 @@
foo: had parameter count mismatch: expected 1, actual 0

View File

@@ -8,3 +8,12 @@ To supply special characters in a string, XML-encode them and `"quote"` the stri
We support at least the [documented `dotnet test` examples](https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests). We support at least the [documented `dotnet test` examples](https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests).
However, we would recommend phrasing some of them differently, for maximum peace of mind: However, we would recommend phrasing some of them differently, for maximum peace of mind:
* `FullyQualifiedName=MyNamespace.MyTestsClass<ParameterType1%2CParameterType2>.MyTestMethod`. This would be better phrased with quotes and escaping as `FullyQualifiedName="MyNamespace.MyTestsClass&lt;ParameterType1%2CParameterType2&gt;.MyTestMethod"` * `FullyQualifiedName=MyNamespace.MyTestsClass<ParameterType1%2CParameterType2>.MyTestMethod`. This would be better phrased with quotes and escaping as `FullyQualifiedName="MyNamespace.MyTestsClass&lt;ParameterType1%2CParameterType2&gt;.MyTestMethod"`
## Parallelism
WoofWare.NUnitTestRunner has *limited* support for parallelism.
By default, we run tests in parallel, taking half the available processors; we may or may not respect the NUnit parallelism attributes to any given extent that they tell us to be *more* parallel (but we will never incorrectly run tests in parallel).
# Licence
WoofWare.NUnitTestRunner is licensed to you under the MIT licence, a copy of which can be found at [LICENSE](./LICENSE).

View File

@@ -1,7 +0,0 @@
namespace TestRunner.AssemblyInfo
open System.Runtime.CompilerServices
[<assembly : InternalsVisibleTo("TestRunner.Test")>]
do ()

View File

@@ -1,531 +0,0 @@
TestRunner.Combinatorial inherit obj, implements TestRunner.Combinatorial System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.Combinatorial System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
TestRunner.Combinatorial+Tags inherit obj
TestRunner.Combinatorial+Tags.Combinatorial [static field]: int = 0
TestRunner.Combinatorial+Tags.Sequential [static field]: int = 1
TestRunner.Combinatorial.Combinatorial [static property]: [read-only] TestRunner.Combinatorial
TestRunner.Combinatorial.get_Combinatorial [static method]: unit -> TestRunner.Combinatorial
TestRunner.Combinatorial.get_IsCombinatorial [method]: unit -> bool
TestRunner.Combinatorial.get_IsSequential [method]: unit -> bool
TestRunner.Combinatorial.get_Sequential [static method]: unit -> TestRunner.Combinatorial
TestRunner.Combinatorial.get_Tag [method]: unit -> int
TestRunner.Combinatorial.IsCombinatorial [property]: [read-only] bool
TestRunner.Combinatorial.IsSequential [property]: [read-only] bool
TestRunner.Combinatorial.Sequential [static property]: [read-only] TestRunner.Combinatorial
TestRunner.Combinatorial.Tag [property]: [read-only] int
TestRunner.Filter inherit obj, implements TestRunner.Filter System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.Filter System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 6 cases
TestRunner.Filter+And inherit TestRunner.Filter
TestRunner.Filter+And.get_Item1 [method]: unit -> TestRunner.Filter
TestRunner.Filter+And.get_Item2 [method]: unit -> TestRunner.Filter
TestRunner.Filter+And.Item1 [property]: [read-only] TestRunner.Filter
TestRunner.Filter+And.Item2 [property]: [read-only] TestRunner.Filter
TestRunner.Filter+FullyQualifiedName inherit TestRunner.Filter
TestRunner.Filter+FullyQualifiedName.get_Item [method]: unit -> TestRunner.Match
TestRunner.Filter+FullyQualifiedName.Item [property]: [read-only] TestRunner.Match
TestRunner.Filter+Name inherit TestRunner.Filter
TestRunner.Filter+Name.get_Item [method]: unit -> TestRunner.Match
TestRunner.Filter+Name.Item [property]: [read-only] TestRunner.Match
TestRunner.Filter+Not inherit TestRunner.Filter
TestRunner.Filter+Not.get_Item [method]: unit -> TestRunner.Filter
TestRunner.Filter+Not.Item [property]: [read-only] TestRunner.Filter
TestRunner.Filter+Or inherit TestRunner.Filter
TestRunner.Filter+Or.get_Item1 [method]: unit -> TestRunner.Filter
TestRunner.Filter+Or.get_Item2 [method]: unit -> TestRunner.Filter
TestRunner.Filter+Or.Item1 [property]: [read-only] TestRunner.Filter
TestRunner.Filter+Or.Item2 [property]: [read-only] TestRunner.Filter
TestRunner.Filter+Tags inherit obj
TestRunner.Filter+Tags.And [static field]: int = 5
TestRunner.Filter+Tags.FullyQualifiedName [static field]: int = 0
TestRunner.Filter+Tags.Name [static field]: int = 1
TestRunner.Filter+Tags.Not [static field]: int = 3
TestRunner.Filter+Tags.Or [static field]: int = 4
TestRunner.Filter+Tags.TestCategory [static field]: int = 2
TestRunner.Filter+TestCategory inherit TestRunner.Filter
TestRunner.Filter+TestCategory.get_Item [method]: unit -> TestRunner.Match
TestRunner.Filter+TestCategory.Item [property]: [read-only] TestRunner.Match
TestRunner.Filter.get_IsAnd [method]: unit -> bool
TestRunner.Filter.get_IsFullyQualifiedName [method]: unit -> bool
TestRunner.Filter.get_IsName [method]: unit -> bool
TestRunner.Filter.get_IsNot [method]: unit -> bool
TestRunner.Filter.get_IsOr [method]: unit -> bool
TestRunner.Filter.get_IsTestCategory [method]: unit -> bool
TestRunner.Filter.get_Tag [method]: unit -> int
TestRunner.Filter.IsAnd [property]: [read-only] bool
TestRunner.Filter.IsFullyQualifiedName [property]: [read-only] bool
TestRunner.Filter.IsName [property]: [read-only] bool
TestRunner.Filter.IsNot [property]: [read-only] bool
TestRunner.Filter.IsOr [property]: [read-only] bool
TestRunner.Filter.IsTestCategory [property]: [read-only] bool
TestRunner.Filter.NewAnd [static method]: (TestRunner.Filter, TestRunner.Filter) -> TestRunner.Filter
TestRunner.Filter.NewFullyQualifiedName [static method]: TestRunner.Match -> TestRunner.Filter
TestRunner.Filter.NewName [static method]: TestRunner.Match -> TestRunner.Filter
TestRunner.Filter.NewNot [static method]: TestRunner.Filter -> TestRunner.Filter
TestRunner.Filter.NewOr [static method]: (TestRunner.Filter, TestRunner.Filter) -> TestRunner.Filter
TestRunner.Filter.NewTestCategory [static method]: TestRunner.Match -> TestRunner.Filter
TestRunner.Filter.Tag [property]: [read-only] int
TestRunner.FilterModule inherit obj
TestRunner.FilterModule.parse [static method]: string -> TestRunner.Filter
TestRunner.FilterModule.shouldRun [static method]: TestRunner.Filter -> (TestRunner.TestFixture -> TestRunner.SingleTestMethod -> bool)
TestRunner.FixtureRunResults inherit obj, implements TestRunner.FixtureRunResults System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.FixtureRunResults..ctor [constructor]: ((TestRunner.TestMemberFailure * TestRunner.IndividualTestRunMetadata) list, (TestRunner.SingleTestMethod * TestRunner.TestMemberSuccess * TestRunner.IndividualTestRunMetadata) list, (TestRunner.UserMethodFailure * TestRunner.IndividualTestRunMetadata) list)
TestRunner.FixtureRunResults.Failed [property]: [read-only] (TestRunner.TestMemberFailure * TestRunner.IndividualTestRunMetadata) list
TestRunner.FixtureRunResults.get_Failed [method]: unit -> (TestRunner.TestMemberFailure * TestRunner.IndividualTestRunMetadata) list
TestRunner.FixtureRunResults.get_IndividualTestRunMetadata [method]: unit -> (TestRunner.IndividualTestRunMetadata * Microsoft.FSharp.Core.FSharpChoice<TestRunner.TestMemberFailure, TestRunner.TestMemberSuccess, TestRunner.UserMethodFailure>) list
TestRunner.FixtureRunResults.get_OtherFailures [method]: unit -> (TestRunner.UserMethodFailure * TestRunner.IndividualTestRunMetadata) list
TestRunner.FixtureRunResults.get_Success [method]: unit -> (TestRunner.SingleTestMethod * TestRunner.TestMemberSuccess * TestRunner.IndividualTestRunMetadata) list
TestRunner.FixtureRunResults.IndividualTestRunMetadata [property]: [read-only] (TestRunner.IndividualTestRunMetadata * Microsoft.FSharp.Core.FSharpChoice<TestRunner.TestMemberFailure, TestRunner.TestMemberSuccess, TestRunner.UserMethodFailure>) list
TestRunner.FixtureRunResults.OtherFailures [property]: [read-only] (TestRunner.UserMethodFailure * TestRunner.IndividualTestRunMetadata) list
TestRunner.FixtureRunResults.Success [property]: [read-only] (TestRunner.SingleTestMethod * TestRunner.TestMemberSuccess * TestRunner.IndividualTestRunMetadata) list
TestRunner.IndividualTestRunMetadata inherit obj, implements TestRunner.IndividualTestRunMetadata System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.IndividualTestRunMetadata System.IComparable, System.IComparable, System.Collections.IStructuralComparable
TestRunner.IndividualTestRunMetadata..ctor [constructor]: (System.TimeSpan, System.DateTimeOffset, System.DateTimeOffset, string, System.Guid, System.Guid, string, string, string option, string option)
TestRunner.IndividualTestRunMetadata.ClassName [property]: [read-only] string
TestRunner.IndividualTestRunMetadata.ComputerName [property]: [read-only] string
TestRunner.IndividualTestRunMetadata.End [property]: [read-only] System.DateTimeOffset
TestRunner.IndividualTestRunMetadata.ExecutionId [property]: [read-only] System.Guid
TestRunner.IndividualTestRunMetadata.get_ClassName [method]: unit -> string
TestRunner.IndividualTestRunMetadata.get_ComputerName [method]: unit -> string
TestRunner.IndividualTestRunMetadata.get_End [method]: unit -> System.DateTimeOffset
TestRunner.IndividualTestRunMetadata.get_ExecutionId [method]: unit -> System.Guid
TestRunner.IndividualTestRunMetadata.get_Start [method]: unit -> System.DateTimeOffset
TestRunner.IndividualTestRunMetadata.get_StdErr [method]: unit -> string option
TestRunner.IndividualTestRunMetadata.get_StdOut [method]: unit -> string option
TestRunner.IndividualTestRunMetadata.get_TestId [method]: unit -> System.Guid
TestRunner.IndividualTestRunMetadata.get_TestName [method]: unit -> string
TestRunner.IndividualTestRunMetadata.get_Total [method]: unit -> System.TimeSpan
TestRunner.IndividualTestRunMetadata.Start [property]: [read-only] System.DateTimeOffset
TestRunner.IndividualTestRunMetadata.StdErr [property]: [read-only] string option
TestRunner.IndividualTestRunMetadata.StdOut [property]: [read-only] string option
TestRunner.IndividualTestRunMetadata.TestId [property]: [read-only] System.Guid
TestRunner.IndividualTestRunMetadata.TestName [property]: [read-only] string
TestRunner.IndividualTestRunMetadata.Total [property]: [read-only] System.TimeSpan
TestRunner.ITestProgress - interface with 5 member(s)
TestRunner.ITestProgress.OnTestFailed [method]: string -> TestRunner.TestMemberFailure -> unit
TestRunner.ITestProgress.OnTestFixtureStart [method]: string -> int -> unit
TestRunner.ITestProgress.OnTestMemberFinished [method]: string -> unit
TestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> unit
TestRunner.ITestProgress.OnTestMemberStart [method]: string -> unit
TestRunner.Match inherit obj, implements TestRunner.Match System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.Match System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
TestRunner.Match+Contains inherit TestRunner.Match
TestRunner.Match+Contains.get_Item [method]: unit -> string
TestRunner.Match+Contains.Item [property]: [read-only] string
TestRunner.Match+Exact inherit TestRunner.Match
TestRunner.Match+Exact.get_Item [method]: unit -> string
TestRunner.Match+Exact.Item [property]: [read-only] string
TestRunner.Match+Tags inherit obj
TestRunner.Match+Tags.Contains [static field]: int = 1
TestRunner.Match+Tags.Exact [static field]: int = 0
TestRunner.Match.get_IsContains [method]: unit -> bool
TestRunner.Match.get_IsExact [method]: unit -> bool
TestRunner.Match.get_Tag [method]: unit -> int
TestRunner.Match.IsContains [property]: [read-only] bool
TestRunner.Match.IsExact [property]: [read-only] bool
TestRunner.Match.NewContains [static method]: string -> TestRunner.Match
TestRunner.Match.NewExact [static method]: string -> TestRunner.Match
TestRunner.Match.Tag [property]: [read-only] int
TestRunner.Modifier inherit obj, implements TestRunner.Modifier System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.Modifier System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
TestRunner.Modifier+Explicit inherit TestRunner.Modifier
TestRunner.Modifier+Explicit.get_reason [method]: unit -> string option
TestRunner.Modifier+Explicit.reason [property]: [read-only] string option
TestRunner.Modifier+Ignored inherit TestRunner.Modifier
TestRunner.Modifier+Ignored.get_reason [method]: unit -> string option
TestRunner.Modifier+Ignored.reason [property]: [read-only] string option
TestRunner.Modifier+Tags inherit obj
TestRunner.Modifier+Tags.Explicit [static field]: int = 0
TestRunner.Modifier+Tags.Ignored [static field]: int = 1
TestRunner.Modifier.get_IsExplicit [method]: unit -> bool
TestRunner.Modifier.get_IsIgnored [method]: unit -> bool
TestRunner.Modifier.get_Tag [method]: unit -> int
TestRunner.Modifier.IsExplicit [property]: [read-only] bool
TestRunner.Modifier.IsIgnored [property]: [read-only] bool
TestRunner.Modifier.NewExplicit [static method]: string option -> TestRunner.Modifier
TestRunner.Modifier.NewIgnored [static method]: string option -> TestRunner.Modifier
TestRunner.Modifier.Tag [property]: [read-only] int
TestRunner.SingleTestMethod inherit obj, implements TestRunner.SingleTestMethod System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.SingleTestMethod..ctor [constructor]: (System.Reflection.MethodInfo, TestRunner.TestKind, TestRunner.Modifier list, string list, int option, TestRunner.Combinatorial option)
TestRunner.SingleTestMethod.Categories [property]: [read-only] string list
TestRunner.SingleTestMethod.Combinatorial [property]: [read-only] TestRunner.Combinatorial option
TestRunner.SingleTestMethod.get_Categories [method]: unit -> string list
TestRunner.SingleTestMethod.get_Combinatorial [method]: unit -> TestRunner.Combinatorial option
TestRunner.SingleTestMethod.get_Kind [method]: unit -> TestRunner.TestKind
TestRunner.SingleTestMethod.get_Method [method]: unit -> System.Reflection.MethodInfo
TestRunner.SingleTestMethod.get_Modifiers [method]: unit -> TestRunner.Modifier list
TestRunner.SingleTestMethod.get_Name [method]: unit -> string
TestRunner.SingleTestMethod.get_Repeat [method]: unit -> int option
TestRunner.SingleTestMethod.Kind [property]: [read-only] TestRunner.TestKind
TestRunner.SingleTestMethod.Method [property]: [read-only] System.Reflection.MethodInfo
TestRunner.SingleTestMethod.Modifiers [property]: [read-only] TestRunner.Modifier list
TestRunner.SingleTestMethod.Name [property]: [read-only] string
TestRunner.SingleTestMethod.Repeat [property]: [read-only] int option
TestRunner.SingleTestMethodModule inherit obj
TestRunner.SingleTestMethodModule.parse [static method]: string list -> System.Reflection.MethodInfo -> System.Reflection.CustomAttributeData list -> (TestRunner.SingleTestMethod option * System.Reflection.CustomAttributeData list)
TestRunner.TestFailure inherit obj, implements TestRunner.TestFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
TestRunner.TestFailure+SetUpFailed inherit TestRunner.TestFailure
TestRunner.TestFailure+SetUpFailed.get_Item [method]: unit -> TestRunner.UserMethodFailure
TestRunner.TestFailure+SetUpFailed.Item [property]: [read-only] TestRunner.UserMethodFailure
TestRunner.TestFailure+Tags inherit obj
TestRunner.TestFailure+Tags.SetUpFailed [static field]: int = 1
TestRunner.TestFailure+Tags.TearDownFailed [static field]: int = 2
TestRunner.TestFailure+Tags.TestFailed [static field]: int = 0
TestRunner.TestFailure+TearDownFailed inherit TestRunner.TestFailure
TestRunner.TestFailure+TearDownFailed.get_Item [method]: unit -> TestRunner.UserMethodFailure
TestRunner.TestFailure+TearDownFailed.Item [property]: [read-only] TestRunner.UserMethodFailure
TestRunner.TestFailure+TestFailed inherit TestRunner.TestFailure
TestRunner.TestFailure+TestFailed.get_Item [method]: unit -> TestRunner.UserMethodFailure
TestRunner.TestFailure+TestFailed.Item [property]: [read-only] TestRunner.UserMethodFailure
TestRunner.TestFailure.get_IsSetUpFailed [method]: unit -> bool
TestRunner.TestFailure.get_IsTearDownFailed [method]: unit -> bool
TestRunner.TestFailure.get_IsTestFailed [method]: unit -> bool
TestRunner.TestFailure.get_Name [method]: unit -> string
TestRunner.TestFailure.get_Tag [method]: unit -> int
TestRunner.TestFailure.IsSetUpFailed [property]: [read-only] bool
TestRunner.TestFailure.IsTearDownFailed [property]: [read-only] bool
TestRunner.TestFailure.IsTestFailed [property]: [read-only] bool
TestRunner.TestFailure.Name [property]: [read-only] string
TestRunner.TestFailure.NewSetUpFailed [static method]: TestRunner.UserMethodFailure -> TestRunner.TestFailure
TestRunner.TestFailure.NewTearDownFailed [static method]: TestRunner.UserMethodFailure -> TestRunner.TestFailure
TestRunner.TestFailure.NewTestFailed [static method]: TestRunner.UserMethodFailure -> TestRunner.TestFailure
TestRunner.TestFailure.Tag [property]: [read-only] int
TestRunner.TestFixture inherit obj, implements TestRunner.TestFixture System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TestFixture..ctor [constructor]: (System.Reflection.Assembly, string, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, TestRunner.SingleTestMethod list)
TestRunner.TestFixture.ContainingAssembly [property]: [read-only] System.Reflection.Assembly
TestRunner.TestFixture.Empty [static method]: System.Reflection.Assembly -> string -> TestRunner.TestFixture
TestRunner.TestFixture.get_ContainingAssembly [method]: unit -> System.Reflection.Assembly
TestRunner.TestFixture.get_Name [method]: unit -> string
TestRunner.TestFixture.get_OneTimeSetUp [method]: unit -> System.Reflection.MethodInfo option
TestRunner.TestFixture.get_OneTimeTearDown [method]: unit -> System.Reflection.MethodInfo option
TestRunner.TestFixture.get_SetUp [method]: unit -> System.Reflection.MethodInfo list
TestRunner.TestFixture.get_TearDown [method]: unit -> System.Reflection.MethodInfo list
TestRunner.TestFixture.get_Tests [method]: unit -> TestRunner.SingleTestMethod list
TestRunner.TestFixture.Name [property]: [read-only] string
TestRunner.TestFixture.OneTimeSetUp [property]: [read-only] System.Reflection.MethodInfo option
TestRunner.TestFixture.OneTimeTearDown [property]: [read-only] System.Reflection.MethodInfo option
TestRunner.TestFixture.SetUp [property]: [read-only] System.Reflection.MethodInfo list
TestRunner.TestFixture.TearDown [property]: [read-only] System.Reflection.MethodInfo list
TestRunner.TestFixture.Tests [property]: [read-only] TestRunner.SingleTestMethod list
TestRunner.TestFixtureModule inherit obj
TestRunner.TestFixtureModule.parse [static method]: System.Type -> TestRunner.TestFixture
TestRunner.TestFixtureModule.run [static method]: TestRunner.ITestProgress -> (TestRunner.TestFixture -> TestRunner.SingleTestMethod -> bool) -> TestRunner.TestFixture -> TestRunner.FixtureRunResults
TestRunner.TestKind inherit obj, implements TestRunner.TestKind System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
TestRunner.TestKind+Data inherit TestRunner.TestKind
TestRunner.TestKind+Data.get_Item [method]: unit -> obj list list
TestRunner.TestKind+Data.Item [property]: [read-only] obj list list
TestRunner.TestKind+Source inherit TestRunner.TestKind
TestRunner.TestKind+Source.get_Item [method]: unit -> string list
TestRunner.TestKind+Source.Item [property]: [read-only] string list
TestRunner.TestKind+Tags inherit obj
TestRunner.TestKind+Tags.Data [static field]: int = 2
TestRunner.TestKind+Tags.Single [static field]: int = 0
TestRunner.TestKind+Tags.Source [static field]: int = 1
TestRunner.TestKind.get_IsData [method]: unit -> bool
TestRunner.TestKind.get_IsSingle [method]: unit -> bool
TestRunner.TestKind.get_IsSource [method]: unit -> bool
TestRunner.TestKind.get_Single [static method]: unit -> TestRunner.TestKind
TestRunner.TestKind.get_Tag [method]: unit -> int
TestRunner.TestKind.IsData [property]: [read-only] bool
TestRunner.TestKind.IsSingle [property]: [read-only] bool
TestRunner.TestKind.IsSource [property]: [read-only] bool
TestRunner.TestKind.NewData [static method]: obj list list -> TestRunner.TestKind
TestRunner.TestKind.NewSource [static method]: string list -> TestRunner.TestKind
TestRunner.TestKind.Single [static property]: [read-only] TestRunner.TestKind
TestRunner.TestKind.Tag [property]: [read-only] int
TestRunner.TestMemberFailure inherit obj, implements TestRunner.TestMemberFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
TestRunner.TestMemberFailure+Failed inherit TestRunner.TestMemberFailure
TestRunner.TestMemberFailure+Failed.get_Item [method]: unit -> TestRunner.TestFailure list
TestRunner.TestMemberFailure+Failed.Item [property]: [read-only] TestRunner.TestFailure list
TestRunner.TestMemberFailure+Malformed inherit TestRunner.TestMemberFailure
TestRunner.TestMemberFailure+Malformed.get_reasons [method]: unit -> string list
TestRunner.TestMemberFailure+Malformed.reasons [property]: [read-only] string list
TestRunner.TestMemberFailure+Tags inherit obj
TestRunner.TestMemberFailure+Tags.Failed [static field]: int = 1
TestRunner.TestMemberFailure+Tags.Malformed [static field]: int = 0
TestRunner.TestMemberFailure.get_IsFailed [method]: unit -> bool
TestRunner.TestMemberFailure.get_IsMalformed [method]: unit -> bool
TestRunner.TestMemberFailure.get_Tag [method]: unit -> int
TestRunner.TestMemberFailure.IsFailed [property]: [read-only] bool
TestRunner.TestMemberFailure.IsMalformed [property]: [read-only] bool
TestRunner.TestMemberFailure.NewFailed [static method]: TestRunner.TestFailure list -> TestRunner.TestMemberFailure
TestRunner.TestMemberFailure.NewMalformed [static method]: string list -> TestRunner.TestMemberFailure
TestRunner.TestMemberFailure.Tag [property]: [read-only] int
TestRunner.TestMemberSuccess inherit obj, implements TestRunner.TestMemberSuccess System.IEquatable, System.Collections.IStructuralEquatable, TestRunner.TestMemberSuccess System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 4 cases
TestRunner.TestMemberSuccess+Explicit inherit TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess+Explicit.get_reason [method]: unit -> string option
TestRunner.TestMemberSuccess+Explicit.reason [property]: [read-only] string option
TestRunner.TestMemberSuccess+Ignored inherit TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess+Ignored.get_reason [method]: unit -> string option
TestRunner.TestMemberSuccess+Ignored.reason [property]: [read-only] string option
TestRunner.TestMemberSuccess+Inconclusive inherit TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess+Inconclusive.get_reason [method]: unit -> string option
TestRunner.TestMemberSuccess+Inconclusive.reason [property]: [read-only] string option
TestRunner.TestMemberSuccess+Tags inherit obj
TestRunner.TestMemberSuccess+Tags.Explicit [static field]: int = 2
TestRunner.TestMemberSuccess+Tags.Ignored [static field]: int = 1
TestRunner.TestMemberSuccess+Tags.Inconclusive [static field]: int = 3
TestRunner.TestMemberSuccess+Tags.Ok [static field]: int = 0
TestRunner.TestMemberSuccess.get_IsExplicit [method]: unit -> bool
TestRunner.TestMemberSuccess.get_IsIgnored [method]: unit -> bool
TestRunner.TestMemberSuccess.get_IsInconclusive [method]: unit -> bool
TestRunner.TestMemberSuccess.get_IsOk [method]: unit -> bool
TestRunner.TestMemberSuccess.get_Ok [static method]: unit -> TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess.get_Tag [method]: unit -> int
TestRunner.TestMemberSuccess.IsExplicit [property]: [read-only] bool
TestRunner.TestMemberSuccess.IsIgnored [property]: [read-only] bool
TestRunner.TestMemberSuccess.IsInconclusive [property]: [read-only] bool
TestRunner.TestMemberSuccess.IsOk [property]: [read-only] bool
TestRunner.TestMemberSuccess.NewExplicit [static method]: string option -> TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess.NewIgnored [static method]: string option -> TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess.NewInconclusive [static method]: string option -> TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess.Ok [static property]: [read-only] TestRunner.TestMemberSuccess
TestRunner.TestMemberSuccess.Tag [property]: [read-only] int
TestRunner.TestProgress inherit obj
TestRunner.TestProgress.toStderr [static method]: unit -> TestRunner.ITestProgress
TestRunner.TrxCounters inherit obj, implements TestRunner.TrxCounters System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.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)
TestRunner.TrxCounters.Aborted [property]: [read-only] System.UInt32
TestRunner.TrxCounters.AddFailed [method]: unit -> TestRunner.TrxCounters
TestRunner.TrxCounters.AddInconclusive [method]: unit -> TestRunner.TrxCounters
TestRunner.TrxCounters.AddNotExecuted [method]: unit -> TestRunner.TrxCounters
TestRunner.TrxCounters.AddPassed [method]: unit -> TestRunner.TrxCounters
TestRunner.TrxCounters.Completed [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Disconnected [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Errors [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Executed [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Failed [property]: [read-only] System.UInt32
TestRunner.TrxCounters.get_Aborted [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Completed [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Disconnected [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Errors [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Executed [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Failed [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Inconclusive [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_InProgress [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_NotExecuted [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_NotRunnable [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Passed [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_PassedButRunAborted [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Pending [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Timeout [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Total [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Warning [method]: unit -> System.UInt32
TestRunner.TrxCounters.get_Zero [static method]: unit -> TestRunner.TrxCounters
TestRunner.TrxCounters.Inconclusive [property]: [read-only] System.UInt32
TestRunner.TrxCounters.InProgress [property]: [read-only] System.UInt32
TestRunner.TrxCounters.NotExecuted [property]: [read-only] System.UInt32
TestRunner.TrxCounters.NotRunnable [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Passed [property]: [read-only] System.UInt32
TestRunner.TrxCounters.PassedButRunAborted [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Pending [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Timeout [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Total [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Warning [property]: [read-only] System.UInt32
TestRunner.TrxCounters.Zero [static property]: [read-only] TestRunner.TrxCounters
TestRunner.TrxDeployment inherit obj, implements TestRunner.TrxDeployment System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxDeployment..ctor [constructor]: string
TestRunner.TrxDeployment.get_RunDeploymentRoot [method]: unit -> string
TestRunner.TrxDeployment.RunDeploymentRoot [property]: [read-only] string
TestRunner.TrxErrorInfo inherit obj, implements TestRunner.TrxErrorInfo System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxErrorInfo..ctor [constructor]: (string option, string option)
TestRunner.TrxErrorInfo.get_Message [method]: unit -> string option
TestRunner.TrxErrorInfo.get_StackTrace [method]: unit -> string option
TestRunner.TrxErrorInfo.Message [property]: [read-only] string option
TestRunner.TrxErrorInfo.StackTrace [property]: [read-only] string option
TestRunner.TrxExecution inherit obj, implements TestRunner.TrxExecution System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxExecution..ctor [constructor]: System.Guid
TestRunner.TrxExecution.get_Id [method]: unit -> System.Guid
TestRunner.TrxExecution.Id [property]: [read-only] System.Guid
TestRunner.TrxOutcome inherit obj, implements TestRunner.TrxOutcome System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
TestRunner.TrxOutcome+Tags inherit obj
TestRunner.TrxOutcome+Tags.Completed [static field]: int = 0
TestRunner.TrxOutcome+Tags.Failed [static field]: int = 2
TestRunner.TrxOutcome+Tags.Warning [static field]: int = 1
TestRunner.TrxOutcome.Completed [static property]: [read-only] TestRunner.TrxOutcome
TestRunner.TrxOutcome.Failed [static property]: [read-only] TestRunner.TrxOutcome
TestRunner.TrxOutcome.get_Completed [static method]: unit -> TestRunner.TrxOutcome
TestRunner.TrxOutcome.get_Failed [static method]: unit -> TestRunner.TrxOutcome
TestRunner.TrxOutcome.get_IsCompleted [method]: unit -> bool
TestRunner.TrxOutcome.get_IsFailed [method]: unit -> bool
TestRunner.TrxOutcome.get_IsWarning [method]: unit -> bool
TestRunner.TrxOutcome.get_Tag [method]: unit -> int
TestRunner.TrxOutcome.get_Warning [static method]: unit -> TestRunner.TrxOutcome
TestRunner.TrxOutcome.IsCompleted [property]: [read-only] bool
TestRunner.TrxOutcome.IsFailed [property]: [read-only] bool
TestRunner.TrxOutcome.IsWarning [property]: [read-only] bool
TestRunner.TrxOutcome.Parse [static method]: string -> TestRunner.TrxOutcome option
TestRunner.TrxOutcome.Tag [property]: [read-only] int
TestRunner.TrxOutcome.Warning [static property]: [read-only] TestRunner.TrxOutcome
TestRunner.TrxOutput inherit obj, implements TestRunner.TrxOutput System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxOutput..ctor [constructor]: (string option, TestRunner.TrxErrorInfo option)
TestRunner.TrxOutput.ErrorInfo [property]: [read-only] TestRunner.TrxErrorInfo option
TestRunner.TrxOutput.get_ErrorInfo [method]: unit -> TestRunner.TrxErrorInfo option
TestRunner.TrxOutput.get_StdOut [method]: unit -> string option
TestRunner.TrxOutput.StdOut [property]: [read-only] string option
TestRunner.TrxReport inherit obj, implements TestRunner.TrxReport System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxReport..ctor [constructor]: (System.Guid, string, TestRunner.TrxReportTimes, TestRunner.TrxTestSettings, TestRunner.TrxUnitTestResult list, TestRunner.TrxUnitTest list, TestRunner.TrxTestEntry list, TestRunner.TrxTestListEntry list, TestRunner.TrxResultsSummary)
TestRunner.TrxReport.get_Id [method]: unit -> System.Guid
TestRunner.TrxReport.get_Name [method]: unit -> string
TestRunner.TrxReport.get_Results [method]: unit -> TestRunner.TrxUnitTestResult list
TestRunner.TrxReport.get_ResultsSummary [method]: unit -> TestRunner.TrxResultsSummary
TestRunner.TrxReport.get_Settings [method]: unit -> TestRunner.TrxTestSettings
TestRunner.TrxReport.get_TestDefinitions [method]: unit -> TestRunner.TrxUnitTest list
TestRunner.TrxReport.get_TestEntries [method]: unit -> TestRunner.TrxTestEntry list
TestRunner.TrxReport.get_TestLists [method]: unit -> TestRunner.TrxTestListEntry list
TestRunner.TrxReport.get_Times [method]: unit -> TestRunner.TrxReportTimes
TestRunner.TrxReport.Id [property]: [read-only] System.Guid
TestRunner.TrxReport.Name [property]: [read-only] string
TestRunner.TrxReport.Results [property]: [read-only] TestRunner.TrxUnitTestResult list
TestRunner.TrxReport.ResultsSummary [property]: [read-only] TestRunner.TrxResultsSummary
TestRunner.TrxReport.Settings [property]: [read-only] TestRunner.TrxTestSettings
TestRunner.TrxReport.TestDefinitions [property]: [read-only] TestRunner.TrxUnitTest list
TestRunner.TrxReport.TestEntries [property]: [read-only] TestRunner.TrxTestEntry list
TestRunner.TrxReport.TestLists [property]: [read-only] TestRunner.TrxTestListEntry list
TestRunner.TrxReport.Times [property]: [read-only] TestRunner.TrxReportTimes
TestRunner.TrxReportModule inherit obj
TestRunner.TrxReportModule.parse [static method]: string -> Microsoft.FSharp.Core.FSharpResult<TestRunner.TrxReport, string>
TestRunner.TrxReportModule.toXml [static method]: TestRunner.TrxReport -> System.Xml.XmlDocument
TestRunner.TrxReportTimes inherit obj, implements TestRunner.TrxReportTimes System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxReportTimes..ctor [constructor]: (System.DateTimeOffset, System.DateTimeOffset, System.DateTimeOffset, System.DateTimeOffset)
TestRunner.TrxReportTimes.Creation [property]: [read-only] System.DateTimeOffset
TestRunner.TrxReportTimes.Finish [property]: [read-only] System.DateTimeOffset
TestRunner.TrxReportTimes.get_Creation [method]: unit -> System.DateTimeOffset
TestRunner.TrxReportTimes.get_Finish [method]: unit -> System.DateTimeOffset
TestRunner.TrxReportTimes.get_Queuing [method]: unit -> System.DateTimeOffset
TestRunner.TrxReportTimes.get_Start [method]: unit -> System.DateTimeOffset
TestRunner.TrxReportTimes.Queuing [property]: [read-only] System.DateTimeOffset
TestRunner.TrxReportTimes.Start [property]: [read-only] System.DateTimeOffset
TestRunner.TrxResultsSummary inherit obj, implements TestRunner.TrxResultsSummary System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxResultsSummary..ctor [constructor]: (TestRunner.TrxOutcome, TestRunner.TrxCounters, TestRunner.TrxOutput, TestRunner.TrxRunInfo list)
TestRunner.TrxResultsSummary.Counters [property]: [read-only] TestRunner.TrxCounters
TestRunner.TrxResultsSummary.get_Counters [method]: unit -> TestRunner.TrxCounters
TestRunner.TrxResultsSummary.get_Outcome [method]: unit -> TestRunner.TrxOutcome
TestRunner.TrxResultsSummary.get_Output [method]: unit -> TestRunner.TrxOutput
TestRunner.TrxResultsSummary.get_RunInfos [method]: unit -> TestRunner.TrxRunInfo list
TestRunner.TrxResultsSummary.Outcome [property]: [read-only] TestRunner.TrxOutcome
TestRunner.TrxResultsSummary.Output [property]: [read-only] TestRunner.TrxOutput
TestRunner.TrxResultsSummary.RunInfos [property]: [read-only] TestRunner.TrxRunInfo list
TestRunner.TrxRunInfo inherit obj, implements TestRunner.TrxRunInfo System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxRunInfo..ctor [constructor]: (string, TestRunner.TrxOutcome, System.DateTimeOffset, string)
TestRunner.TrxRunInfo.ComputerName [property]: [read-only] string
TestRunner.TrxRunInfo.get_ComputerName [method]: unit -> string
TestRunner.TrxRunInfo.get_Outcome [method]: unit -> TestRunner.TrxOutcome
TestRunner.TrxRunInfo.get_Text [method]: unit -> string
TestRunner.TrxRunInfo.get_Timestamp [method]: unit -> System.DateTimeOffset
TestRunner.TrxRunInfo.Outcome [property]: [read-only] TestRunner.TrxOutcome
TestRunner.TrxRunInfo.Text [property]: [read-only] string
TestRunner.TrxRunInfo.Timestamp [property]: [read-only] System.DateTimeOffset
TestRunner.TrxTestEntry inherit obj, implements TestRunner.TrxTestEntry System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxTestEntry..ctor [constructor]: (System.Guid, System.Guid, System.Guid)
TestRunner.TrxTestEntry.ExecutionId [property]: [read-only] System.Guid
TestRunner.TrxTestEntry.get_ExecutionId [method]: unit -> System.Guid
TestRunner.TrxTestEntry.get_TestId [method]: unit -> System.Guid
TestRunner.TrxTestEntry.get_TestListId [method]: unit -> System.Guid
TestRunner.TrxTestEntry.TestId [property]: [read-only] System.Guid
TestRunner.TrxTestEntry.TestListId [property]: [read-only] System.Guid
TestRunner.TrxTestListEntry inherit obj, implements TestRunner.TrxTestListEntry System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxTestListEntry..ctor [constructor]: (string, System.Guid)
TestRunner.TrxTestListEntry.get_Id [method]: unit -> System.Guid
TestRunner.TrxTestListEntry.get_Name [method]: unit -> string
TestRunner.TrxTestListEntry.Id [property]: [read-only] System.Guid
TestRunner.TrxTestListEntry.Name [property]: [read-only] string
TestRunner.TrxTestMethod inherit obj, implements TestRunner.TrxTestMethod System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxTestMethod..ctor [constructor]: (string, System.Uri, string, string)
TestRunner.TrxTestMethod.AdapterTypeName [property]: [read-only] System.Uri
TestRunner.TrxTestMethod.ClassName [property]: [read-only] string
TestRunner.TrxTestMethod.CodeBase [property]: [read-only] string
TestRunner.TrxTestMethod.get_AdapterTypeName [method]: unit -> System.Uri
TestRunner.TrxTestMethod.get_ClassName [method]: unit -> string
TestRunner.TrxTestMethod.get_CodeBase [method]: unit -> string
TestRunner.TrxTestMethod.get_Name [method]: unit -> string
TestRunner.TrxTestMethod.Name [property]: [read-only] string
TestRunner.TrxTestOutcome inherit obj, implements TestRunner.TrxTestOutcome System.IEquatable, System.Collections.IStructuralEquatable - union type with 4 cases
TestRunner.TrxTestOutcome+Tags inherit obj
TestRunner.TrxTestOutcome+Tags.Failed [static field]: int = 1
TestRunner.TrxTestOutcome+Tags.Inconclusive [static field]: int = 3
TestRunner.TrxTestOutcome+Tags.NotExecuted [static field]: int = 2
TestRunner.TrxTestOutcome+Tags.Passed [static field]: int = 0
TestRunner.TrxTestOutcome.Failed [static property]: [read-only] TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.get_Failed [static method]: unit -> TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.get_Inconclusive [static method]: unit -> TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.get_IsFailed [method]: unit -> bool
TestRunner.TrxTestOutcome.get_IsInconclusive [method]: unit -> bool
TestRunner.TrxTestOutcome.get_IsNotExecuted [method]: unit -> bool
TestRunner.TrxTestOutcome.get_IsPassed [method]: unit -> bool
TestRunner.TrxTestOutcome.get_NotExecuted [static method]: unit -> TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.get_Passed [static method]: unit -> TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.get_Tag [method]: unit -> int
TestRunner.TrxTestOutcome.Inconclusive [static property]: [read-only] TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.IsFailed [property]: [read-only] bool
TestRunner.TrxTestOutcome.IsInconclusive [property]: [read-only] bool
TestRunner.TrxTestOutcome.IsNotExecuted [property]: [read-only] bool
TestRunner.TrxTestOutcome.IsPassed [property]: [read-only] bool
TestRunner.TrxTestOutcome.NotExecuted [static property]: [read-only] TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.Parse [static method]: string -> TestRunner.TrxTestOutcome option
TestRunner.TrxTestOutcome.Passed [static property]: [read-only] TestRunner.TrxTestOutcome
TestRunner.TrxTestOutcome.Tag [property]: [read-only] int
TestRunner.TrxTestSettings inherit obj, implements TestRunner.TrxTestSettings System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxTestSettings..ctor [constructor]: (string, System.Guid, TestRunner.TrxDeployment)
TestRunner.TrxTestSettings.Deployment [property]: [read-only] TestRunner.TrxDeployment
TestRunner.TrxTestSettings.get_Deployment [method]: unit -> TestRunner.TrxDeployment
TestRunner.TrxTestSettings.get_Id [method]: unit -> System.Guid
TestRunner.TrxTestSettings.get_Name [method]: unit -> string
TestRunner.TrxTestSettings.Id [property]: [read-only] System.Guid
TestRunner.TrxTestSettings.Name [property]: [read-only] string
TestRunner.TrxUnitTest inherit obj, implements TestRunner.TrxUnitTest System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxUnitTest..ctor [constructor]: (string, string, System.Guid, TestRunner.TrxExecution, TestRunner.TrxTestMethod)
TestRunner.TrxUnitTest.Execution [property]: [read-only] TestRunner.TrxExecution
TestRunner.TrxUnitTest.get_Execution [method]: unit -> TestRunner.TrxExecution
TestRunner.TrxUnitTest.get_Id [method]: unit -> System.Guid
TestRunner.TrxUnitTest.get_Name [method]: unit -> string
TestRunner.TrxUnitTest.get_Storage [method]: unit -> string
TestRunner.TrxUnitTest.get_TestMethod [method]: unit -> TestRunner.TrxTestMethod
TestRunner.TrxUnitTest.Id [property]: [read-only] System.Guid
TestRunner.TrxUnitTest.Name [property]: [read-only] string
TestRunner.TrxUnitTest.Storage [property]: [read-only] string
TestRunner.TrxUnitTest.TestMethod [property]: [read-only] TestRunner.TrxTestMethod
TestRunner.TrxUnitTestResult inherit obj, implements TestRunner.TrxUnitTestResult System.IEquatable, System.Collections.IStructuralEquatable
TestRunner.TrxUnitTestResult..ctor [constructor]: (System.Guid, System.Guid, string, string, System.TimeSpan, System.DateTimeOffset, System.DateTimeOffset, System.Guid, TestRunner.TrxTestOutcome, System.Guid, string, TestRunner.TrxOutput option)
TestRunner.TrxUnitTestResult.ComputerName [property]: [read-only] string
TestRunner.TrxUnitTestResult.Duration [property]: [read-only] System.TimeSpan
TestRunner.TrxUnitTestResult.EndTime [property]: [read-only] System.DateTimeOffset
TestRunner.TrxUnitTestResult.ExecutionId [property]: [read-only] System.Guid
TestRunner.TrxUnitTestResult.get_ComputerName [method]: unit -> string
TestRunner.TrxUnitTestResult.get_Duration [method]: unit -> System.TimeSpan
TestRunner.TrxUnitTestResult.get_EndTime [method]: unit -> System.DateTimeOffset
TestRunner.TrxUnitTestResult.get_ExecutionId [method]: unit -> System.Guid
TestRunner.TrxUnitTestResult.get_Outcome [method]: unit -> TestRunner.TrxTestOutcome
TestRunner.TrxUnitTestResult.get_Output [method]: unit -> TestRunner.TrxOutput option
TestRunner.TrxUnitTestResult.get_RelativeResultsDirectory [method]: unit -> string
TestRunner.TrxUnitTestResult.get_StartTime [method]: unit -> System.DateTimeOffset
TestRunner.TrxUnitTestResult.get_TestId [method]: unit -> System.Guid
TestRunner.TrxUnitTestResult.get_TestListId [method]: unit -> System.Guid
TestRunner.TrxUnitTestResult.get_TestName [method]: unit -> string
TestRunner.TrxUnitTestResult.get_TestType [method]: unit -> System.Guid
TestRunner.TrxUnitTestResult.Outcome [property]: [read-only] TestRunner.TrxTestOutcome
TestRunner.TrxUnitTestResult.Output [property]: [read-only] TestRunner.TrxOutput option
TestRunner.TrxUnitTestResult.RelativeResultsDirectory [property]: [read-only] string
TestRunner.TrxUnitTestResult.StartTime [property]: [read-only] System.DateTimeOffset
TestRunner.TrxUnitTestResult.TestId [property]: [read-only] System.Guid
TestRunner.TrxUnitTestResult.TestListId [property]: [read-only] System.Guid
TestRunner.TrxUnitTestResult.TestName [property]: [read-only] string
TestRunner.TrxUnitTestResult.TestType [property]: [read-only] System.Guid
TestRunner.UserMethodFailure inherit obj, implements TestRunner.UserMethodFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
TestRunner.UserMethodFailure+ReturnedNonUnit inherit TestRunner.UserMethodFailure
TestRunner.UserMethodFailure+ReturnedNonUnit.get_name [method]: unit -> string
TestRunner.UserMethodFailure+ReturnedNonUnit.get_result [method]: unit -> obj
TestRunner.UserMethodFailure+ReturnedNonUnit.name [property]: [read-only] string
TestRunner.UserMethodFailure+ReturnedNonUnit.result [property]: [read-only] obj
TestRunner.UserMethodFailure+Tags inherit obj
TestRunner.UserMethodFailure+Tags.ReturnedNonUnit [static field]: int = 0
TestRunner.UserMethodFailure+Tags.Threw [static field]: int = 1
TestRunner.UserMethodFailure+Threw inherit TestRunner.UserMethodFailure
TestRunner.UserMethodFailure+Threw.get_Item2 [method]: unit -> System.Exception
TestRunner.UserMethodFailure+Threw.get_name [method]: unit -> string
TestRunner.UserMethodFailure+Threw.Item2 [property]: [read-only] System.Exception
TestRunner.UserMethodFailure+Threw.name [property]: [read-only] string
TestRunner.UserMethodFailure.get_IsReturnedNonUnit [method]: unit -> bool
TestRunner.UserMethodFailure.get_IsThrew [method]: unit -> bool
TestRunner.UserMethodFailure.get_Name [method]: unit -> string
TestRunner.UserMethodFailure.get_Tag [method]: unit -> int
TestRunner.UserMethodFailure.IsReturnedNonUnit [property]: [read-only] bool
TestRunner.UserMethodFailure.IsThrew [property]: [read-only] bool
TestRunner.UserMethodFailure.Name [property]: [read-only] string
TestRunner.UserMethodFailure.NewReturnedNonUnit [static method]: (string, obj) -> TestRunner.UserMethodFailure
TestRunner.UserMethodFailure.NewThrew [static method]: (string, System.Exception) -> TestRunner.UserMethodFailure
TestRunner.UserMethodFailure.Tag [property]: [read-only] int

View File

@@ -1,620 +0,0 @@
namespace TestRunner
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
)

View File

@@ -1,34 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestRunner", "TestRunner\TestRunner.fsproj", "{D4CAE716-79EB-4174-B58C-54E66CF16536}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestRunner.Test", "TestRunner\TestRunner.Test\TestRunner.Test.fsproj", "{E776AC80-CD07-4A3E-9F85-1AEFBB56309D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Consumer", "Consumer\Consumer.fsproj", "{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestRunner.Lib", "TestRunner.Lib\TestRunner.Lib.fsproj", "{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Release|Any CPU.Build.0 = Release|Any CPU
{E776AC80-CD07-4A3E-9F85-1AEFBB56309D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E776AC80-CD07-4A3E-9F85-1AEFBB56309D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E776AC80-CD07-4A3E-9F85-1AEFBB56309D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E776AC80-CD07-4A3E-9F85-1AEFBB56309D}.Release|Any CPU.Build.0 = Release|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Release|Any CPU.Build.0 = Release|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -1,24 +0,0 @@
namespace TestRunner
open Spectre.Console
[<RequireQualifiedAccess>]
module Progress =
let spectre () : ITestProgress =
{ new ITestProgress with
member _.OnTestFailed name failure =
AnsiConsole.Console.MarkupLine
$"[red]Test '%s{Markup.Escape name}' failed: %s{Markup.Escape (failure.ToString ())}[/]"
member _.OnTestFixtureStart name testCount =
AnsiConsole.Console.MarkupLine $"[white]Running tests: %s{Markup.Escape name}[/]"
member _.OnTestMemberFinished name =
AnsiConsole.Console.MarkupLine $"[gray]Finished test: %s{Markup.Escape name}[/]"
member _.OnTestMemberSkipped name =
AnsiConsole.Console.MarkupLine $"[yellow]Skipping test due to filter: %s{Markup.Escape name}[/]"
member _.OnTestMemberStart name =
AnsiConsole.Console.MarkupLine $"[white]Running test: %s{Markup.Escape name}[/]"
}

View File

@@ -1,22 +0,0 @@
namespace TestRunner
[<RequireQualifiedAccess>]
module internal Seq =
let tryMinBy (f : 'a -> 'b) (s : 'a seq) : 'a option =
use enum = s.GetEnumerator ()
if not (enum.MoveNext ()) then
None
else
let mutable answer = enum.Current
let mutable fAnswer = f enum.Current
while enum.MoveNext () do
let fNext = f enum.Current
if fNext < fAnswer then
answer <- enum.Current
Some answer

View File

@@ -1,11 +0,0 @@
{
"version": "0.1-prerelease",
"publicReleaseRefSpec": ["^refs/heads/main$"],
"pathFilters": [
"./",
"^TestRunner.Test/",
"../TestRunner.Lib",
":/Directory.Build.props",
":/README.md"
]
}

View File

@@ -0,0 +1,99 @@
namespace WoofWare.NUnitTestRunner
open System
open System.IO
[<AutoOpen>]
module internal Patterns =
let (|Key|_|) (start : string) (s : string) : string option =
if s.StartsWith (start + "=", StringComparison.Ordinal) then
s.Substring (start.Length + 1) |> Some
else
None
/// Represents how verbose the test runner's logging should be.
[<RequireQualifiedAccess>]
type LogLevel =
/// Don't log any information about the test run.
| Nothing
/// Log as much information as is available about the test run.
| Verbose
/// Arguments controlling the test runner itself (not the tests therein).
type Args =
{
/// The DLL containing the tests we'll reflectively discover and invoke.
Dll : FileInfo
/// If set, the output file into which we will write a TRX report. (We'll create parent directories as necessary.)
Trx : FileInfo option
/// Also contains the original string which specified the filter.
Filter : (string * Filter) option
/// How verbose to be with the test runner's own logging.
Logging : LogLevel
/// Maximum number of tests which can run concurrently. This setting overrides any LevelOfParallelism reflectively
/// extracted from the assembly under test.
LevelOfParallelism : int option
/// Abort if the test runner is running for longer than this timeout.
Timeout : TimeSpan option
}
/// Parse `argv` into a structured Args.
static member Parse (args : string list) : Args =
match args with
| [] -> failwith "The first arg must be a positional arg, the DLL to test."
| dll :: args ->
let rec go
(trx : FileInfo option)
(filter : (string * Filter) option)
(logging : LogLevel option)
(par : int option)
(timeout : TimeSpan option)
(args : string list)
=
match args with
| [] ->
{
Dll = FileInfo dll
Trx = trx
Filter = filter
Logging = logging |> Option.defaultValue LogLevel.Nothing
LevelOfParallelism = par
Timeout = timeout
}
| Key "--filter" filterStr :: rest
| "--filter" :: filterStr :: rest ->
match filter with
| Some _ -> failwith "Two conflicting filters; you can only specify --filter once"
| None -> go trx (Some (filterStr, Filter.parse filterStr)) logging par timeout rest
| Key "--trx" trxStr :: rest
| "--trx" :: trxStr :: rest ->
match trx with
| Some _ -> failwith "Two conflicting TRX outputs; you can only specify --trx once"
| None -> go (Some (FileInfo trxStr)) filter logging par timeout rest
| Key "--verbose" verboseStr :: rest
| "--verbose" :: verboseStr :: rest ->
match logging with
| Some _ -> failwith "Two conflicting --verbose outputs; you can only specify --verbose once"
| None ->
let verbose =
if Boolean.Parse verboseStr then
LogLevel.Verbose
else
LogLevel.Nothing
go trx filter (Some verbose) par timeout rest
| Key "--parallelism" parStr :: rest
| "--parallelism" :: parStr :: rest ->
match par with
| Some _ -> failwith "Two conflicting --parallelism outputs; you can only specify --parallelism once"
| None -> go trx filter logging (Some (Int32.Parse parStr)) timeout rest
| Key "--timeout-seconds" timeoutStr :: rest
| "--timeout-seconds" :: timeoutStr :: rest ->
match timeout with
| Some _ ->
failwith "Two conflicting --timeout-seconds outputs; you can only specify --timeout-seconds once"
| None -> go trx filter logging par (Some (TimeSpan.FromSeconds (Int32.Parse timeoutStr |> float))) rest
| k :: _rest -> failwith $"Unrecognised arg %s{k}"
go None None None None None args

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal Array = module internal Array =

View File

@@ -0,0 +1,7 @@
namespace WoofWare.NUnitTestRunner.AssemblyInfo
open System.Runtime.CompilerServices
[<assembly : InternalsVisibleTo("WoofWare.NUnitTestRunner.Test")>]
do ()

View File

@@ -0,0 +1,62 @@
namespace WoofWare.NUnitTestRunner
open System.Reflection
/// Attributes at the assembly level which control the behaviour of NUnit.
type AssemblyLevelAttributes =
{
/// How many tests can be running at once, if anything's running in parallel.
Parallelism : int option
/// Whether the tests in this assembly can be parallelised at all.
Parallelizable : Parallelizable<AssemblyParallelScope> option
}
[<RequireQualifiedAccess>]
module AssemblyLevelAttributes =
/// Reflectively obtain the values of any relevant assembly attributes.
let get (assy : Assembly) : AssemblyLevelAttributes =
((None, None), assy.CustomAttributes)
||> Seq.fold (fun (levelPar, par) attr ->
match attr.AttributeType.FullName with
| "NUnit.Framework.LevelOfParallelismAttribute" ->
let arg = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<int>
match levelPar with
| None -> (Some arg, par)
| Some existing ->
failwith $"Assembly %s{assy.Location} declares parallelism %i{arg} and also %i{existing}"
| "NUnit.Framework.NonParallelizableAttribute" ->
match levelPar with
| None -> (Some 1, par)
| Some existing ->
failwith
$"Assembly %s{assy.Location} declares non-parallelizable and also parallelism %i{existing}"
| "NUnit.Framework.ParallelizableAttribute" ->
match par with
| Some _ -> failwith "Got multiple Parallelize attributes in assembly"
| None ->
match attr.ConstructorArguments |> Seq.toList with
| [] -> levelPar, Some (Parallelizable.Yes AssemblyParallelScope.Fixtures)
| [ v ] ->
match v.Value with
| :? int as v ->
match ParallelScope.ofInt v with
| ParallelScope.Fixtures ->
levelPar, Some (Parallelizable.Yes AssemblyParallelScope.Fixtures)
| ParallelScope.Children ->
levelPar, Some (Parallelizable.Yes AssemblyParallelScope.Children)
| ParallelScope.None -> levelPar, Some Parallelizable.No
| ParallelScope.All ->
failwith "ParallelScope.All is invalid on assemblies; only Fixtures or Children"
| ParallelScope.Self ->
failwith "ParallelScope.Self is invalid on assemblies; only Fixtures or Children"
| v -> failwith $"Unexpectedly non-int value %O{v} of parallel scope on assembly"
| _ -> failwith "unexpectedly got multiple args to Parallelizable on assembly"
| _ -> levelPar, par
)
|> fun (par, canPar) ->
{
Parallelizable = canPar
Parallelism = par
}

View File

@@ -0,0 +1,173 @@
namespace WoofWare.NUnitTestRunner
open System
open System.Collections.Generic
open System.IO
open System.Reflection
open System.Runtime.Loader
open System.Text
open System.Threading
type internal OutputStreamId = | OutputStreamId of Guid
type private ThreadAwareWriter (local : AsyncLocal<OutputStreamId>, underlying : Dictionary<OutputStreamId, TextWriter>)
=
inherit TextWriter ()
override _.get_Encoding () = Encoding.Default
override this.Write (v : char) : unit =
lock
underlying
(fun () ->
match underlying.TryGetValue local.Value with
| true, output -> output.Write v
| false, _ ->
let wanted =
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
failwith $"no such context: %O{local.Value}\nwanted:\n{wanted}"
)
override this.WriteLine (v : string) : unit =
lock
underlying
(fun () ->
match underlying.TryGetValue local.Value with
| true, output -> output.WriteLine v
| false, _ ->
let wanted =
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
failwith $"no such context: %O{local.Value}\nwanted:\n{wanted}"
)
/// Wraps up the necessary context to intercept global state.
[<NoEquality ; NoComparison>]
type TestContexts =
internal
{
/// Accesses to this must be locked on StdOutWriters.
StdOuts : Dictionary<OutputStreamId, MemoryStream>
/// Accesses to this must be locked on StdErrWriters.
StdErrs : Dictionary<OutputStreamId, MemoryStream>
StdOutWriters : Dictionary<OutputStreamId, TextWriter>
StdErrWriters : Dictionary<OutputStreamId, TextWriter>
StdOutWriter : TextWriter
StdErrWriter : TextWriter
AsyncLocal : AsyncLocal<OutputStreamId>
}
/// Call this exactly once.
static member Empty () =
let stdouts = Dictionary ()
let stderrs = Dictionary ()
let stdoutWriters = Dictionary ()
let stderrWriters = Dictionary ()
let local = AsyncLocal ()
let stdoutWriter = new ThreadAwareWriter (local, stdoutWriters)
let stderrWriter = new ThreadAwareWriter (local, stderrWriters)
{
StdOuts = stdouts
StdErrs = stderrs
StdOutWriter = stdoutWriter
StdErrWriter = stderrWriter
StdOutWriters = stdoutWriters
StdErrWriters = stderrWriters
AsyncLocal = local
}
/// An output stream which will identify the ExecutionContext it's being written to from,
/// and will separate that output into its own stream internally.
member this.Stdout : TextWriter = this.StdOutWriter
/// An output stream which will identify the ExecutionContext it's being written to from,
/// and will separate that output into its own stream internally.
member this.Stderr : TextWriter = this.StdErrWriter
member internal this.DumpStdout (id : OutputStreamId) : string =
lock
this.StdOutWriters
(fun () ->
this.StdOutWriters.[id].Flush ()
this.StdOuts.[id].ToArray ()
)
|> Encoding.Default.GetString
member internal this.DumpStderr (id : OutputStreamId) : string =
lock
this.StdErrWriters
(fun () ->
this.StdErrWriters.[id].Flush ()
this.StdErrs.[id].ToArray ()
)
|> Encoding.Default.GetString
member internal this.NewOutputs () =
let id = Guid.NewGuid () |> OutputStreamId
let msOut = new MemoryStream ()
let wrOut = new StreamWriter (msOut)
let msErr = new MemoryStream ()
let wrErr = new StreamWriter (msErr)
lock
this.StdOutWriters
(fun () ->
this.StdOutWriters.Add (id, wrOut)
this.StdOuts.Add (id, msOut)
)
lock
this.StdErrWriters
(fun () ->
this.StdErrWriters.Add (id, wrErr)
this.StdErrs.Add (id, msErr)
)
id
interface IDisposable with
member this.Dispose () =
// TODO: dispose the streams
()
/// A separate AssemblyLoadContext within which you can run the tests in the given DLL.
/// Supply places to find the .NET runtimes.
type LoadContext (dll : FileInfo, runtimes : DirectoryInfo list, contexts : TestContexts) =
inherit AssemblyLoadContext ()
/// Load the assembly with the given name into this assembly context.
/// This additionally monkey-patches System.Console: it performs SetOut and SetError on them
/// so that they redirect their outputs into the given `TestContexts`.
override this.Load (target : AssemblyName) : Assembly =
let path = Path.Combine (dll.Directory.FullName, $"%s{target.Name}.dll")
let assy =
if File.Exists path then
this.LoadFromAssemblyPath path
else
runtimes
|> List.tryPick (fun di ->
let path = Path.Combine (di.FullName, $"%s{target.Name}.dll")
if File.Exists path then
this.LoadFromAssemblyPath path |> Some
else
None
)
|> Option.defaultValue null
if target.Name = "System.Console" then
if isNull assy then
failwith "could not monkey-patch System.Console"
else
let consoleType = assy.GetType "System.Console"
let setOut = consoleType.GetMethod "SetOut"
setOut.Invoke ((null : obj), [| contexts.Stdout |]) |> unbox<unit>
let setErr = consoleType.GetMethod "SetError"
setErr.Invoke ((null : obj), [| contexts.Stderr |]) |> unbox<unit>
assy
else
assy

View File

@@ -1,174 +1,20 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open WoofWare.DotnetRuntimeLocator
open System.IO
open System.Reflection open System.Reflection
open System.Runtime.Loader
// Fix for https://github.com/Smaug123/unofficial-nunit-runner/issues/8 /// Methods for constructing TRX reports.
// Set AppContext.BaseDirectory to where the test DLL is. [<RequireQualifiedAccess>]
// (This tells the DLL loader to look next to the test DLL for dependencies.) module BuildTrxReport =
type SetBaseDir (testDll : FileInfo) =
let oldBaseDir = AppContext.BaseDirectory
do AppContext.SetData ("APP_CONTEXT_BASE_DIRECTORY", testDll.Directory.FullName)
interface IDisposable with /// Build a TRX report from the given results.
member _.Dispose () = let build
AppContext.SetData ("APP_CONTEXT_BASE_DIRECTORY", oldBaseDir) (assy : Assembly)
(creationTime : DateTimeOffset)
(startTime : DateTimeOffset)
type Ctx (dll : FileInfo, runtimes : DirectoryInfo list) = (results : FixtureRunResults list)
inherit AssemblyLoadContext () : TrxReport
override this.Load (target : AssemblyName) : Assembly =
let path = Path.Combine (dll.Directory.FullName, $"%s{target.Name}.dll")
if File.Exists path then
this.LoadFromAssemblyPath path
else
runtimes
|> List.tryPick (fun di ->
let path = Path.Combine (di.FullName, $"%s{target.Name}.dll")
if File.Exists path then
this.LoadFromAssemblyPath path |> Some
else
None
)
|> Option.defaultValue null
module Program =
let selectRuntime
(config : RuntimeOptions)
(f : DotnetEnvironmentInfo)
: Choice<DotnetEnvironmentFrameworkInfo, DotnetEnvironmentSdkInfo> option
= =
let rollForward =
match Environment.GetEnvironmentVariable "DOTNET_ROLL_FORWARD" with
| null ->
config.RollForward
|> Option.map RollForward.Parse
|> Option.defaultValue RollForward.Minor
| s -> RollForward.Parse s
let desiredVersions =
match config.Framework with
| Some f -> [ Version f.Version, f.Name ]
| None ->
match config.Frameworks with
| Some f -> f |> List.map (fun f -> Version f.Version, f.Name)
| None ->
failwith
"Could not deduce a framework version due to lack of either Framework or Frameworks in runtimeconfig"
let compatiblyNamedRuntimes =
f.Frameworks
|> Seq.collect (fun availableFramework ->
desiredVersions
|> List.choose (fun (desiredVersion, desiredName) ->
if desiredName = availableFramework.Name then
Some
{|
Desired = desiredVersion
Name = desiredName
Installed = availableFramework
InstalledVersion = Version availableFramework.Version
|}
else
None
)
)
|> Seq.toList
match rollForward with
| RollForward.Minor ->
let available =
compatiblyNamedRuntimes
|> Seq.filter (fun data ->
data.InstalledVersion.Major = data.Desired.Major
&& data.InstalledVersion.Minor >= data.Desired.Minor
)
|> Seq.groupBy (fun data -> data.Name)
|> Seq.map (fun (name, data) ->
let data =
data
|> Seq.minBy (fun data -> data.InstalledVersion.Minor, data.InstalledVersion.Build)
name, data.Installed
)
// TODO: how do we select between many available frameworks?
|> Seq.tryHead
match available with
| Some (_, f) -> Some (Choice1Of2 f)
| None ->
// TODO: maybe we can ask the SDK. But we keep on trucking: maybe we're self-contained,
// and we'll actually find all the runtime next to the DLL.
None
| _ -> failwith "non-minor RollForward not supported yet; please shout if you want it"
let locateRuntimes (dll : FileInfo) : DirectoryInfo list =
let runtimeConfig =
let name =
if not (dll.Name.EndsWith (".dll", StringComparison.OrdinalIgnoreCase)) then
failwith $"Expected DLL %s{dll.FullName} to end in .dll"
dll.Name.Substring (0, dll.Name.Length - 4)
Path.Combine (dll.Directory.FullName, $"%s{name}.runtimeconfig.json")
|> File.ReadAllText
|> System.Text.Json.Nodes.JsonNode.Parse
|> RuntimeConfig.jsonParse
|> fun f -> f.RuntimeOptions
let availableRuntimes = DotnetEnvironmentInfo.Get ()
let runtime = selectRuntime runtimeConfig availableRuntimes
match runtime with
| None ->
// Keep on trucking: let's be optimistic and hope that we're self-contained.
[ dll.Directory ]
| Some (Choice1Of2 runtime) -> [ dll.Directory ; DirectoryInfo $"%s{runtime.Path}/%s{runtime.Version}" ]
| Some (Choice2Of2 sdk) -> [ dll.Directory ; DirectoryInfo sdk.Path ]
let main argv =
let startTime = DateTimeOffset.Now
let testDll, filter, trxPath =
match argv |> List.ofSeq with
| [ dll ] -> FileInfo dll, None, None
| [ dll ; "--trx" ; trxPath ] -> FileInfo dll, None, Some (FileInfo trxPath)
| [ dll ; "--filter" ; filter ] -> FileInfo dll, Some (Filter.parse filter), None
| [ dll ; "--trx" ; trxPath ; "--filter" ; filter ] ->
FileInfo dll, Some (Filter.parse filter), Some (FileInfo trxPath)
| [ dll ; "--filter" ; filter ; "--trx" ; trxPath ] ->
FileInfo dll, Some (Filter.parse filter), Some (FileInfo trxPath)
| _ ->
failwith
"provide exactly one arg, a test DLL; then optionally `--filter <filter>` and/or `--trx <output-filename>`."
let filter =
match filter with
| Some filter -> Filter.shouldRun filter
| None -> fun _ _ -> true
let progress = Progress.spectre ()
use _ = new SetBaseDir (testDll)
let ctx = Ctx (testDll, locateRuntimes testDll)
let assy = ctx.LoadFromAssemblyPath testDll.FullName
let testFixtures = assy.ExportedTypes |> Seq.map TestFixture.parse |> Seq.toList
let creationTime = DateTimeOffset.Now
let results = testFixtures |> List.map (TestFixture.run progress filter)
let finishTime = DateTimeOffset.Now let finishTime = DateTimeOffset.Now
let finishTimeHumanReadable = finishTime.ToString @"yyyy-MM-dd HH:mm:ss" let finishTimeHumanReadable = finishTime.ToString @"yyyy-MM-dd HH:mm:ss"
let nowMachine = finishTime.ToString @"yyyy-MM-dd_HH_mm_ss" let nowMachine = finishTime.ToString @"yyyy-MM-dd_HH_mm_ss"
@@ -270,6 +116,7 @@ module Program =
Output = Output =
{ {
StdOut = None StdOut = None
StdErr = None
ErrorInfo = None ErrorInfo = None
} }
RunInfos = RunInfos =
@@ -317,6 +164,18 @@ module Program =
| Some s -> s | Some s -> s
(Some stackTrace, message) (Some stackTrace, message)
| TestFailure.TestFailed (UserMethodFailure.BadParameters (_, expected, actual))
| TestFailure.SetUpFailed (UserMethodFailure.BadParameters (_, expected, actual))
| TestFailure.TearDownFailed (UserMethodFailure.BadParameters (_, expected, actual)) ->
let newMessage =
$"had parameter count mismatch: expected %i{expected.Length}, actual %i{actual.Length}"
let message =
match message with
| None -> newMessage
| Some message -> $"%s{message}\n%s{newMessage}"
(stackTrace, Some message)
| TestFailure.TestFailed (UserMethodFailure.ReturnedNonUnit (_, ret)) | TestFailure.TestFailed (UserMethodFailure.ReturnedNonUnit (_, ret))
| TestFailure.SetUpFailed (UserMethodFailure.ReturnedNonUnit (_, ret)) | TestFailure.SetUpFailed (UserMethodFailure.ReturnedNonUnit (_, ret))
| TestFailure.TearDownFailed (UserMethodFailure.ReturnedNonUnit (_, ret)) -> | TestFailure.TearDownFailed (UserMethodFailure.ReturnedNonUnit (_, ret)) ->
@@ -341,6 +200,14 @@ module Program =
Message = None Message = None
} }
|> Some |> Some
| Choice3Of3 (UserMethodFailure.BadParameters (_, expected, actual)) ->
{
StackTrace = None
Message =
$"parameter count mismatch, expected %i{expected.Length}, actual %i{actual.Length}"
|> Some
}
|> Some
| Choice3Of3 (UserMethodFailure.ReturnedNonUnit (_, ret)) -> | Choice3Of3 (UserMethodFailure.ReturnedNonUnit (_, ret)) ->
{ {
Message = $"returned non-unit value %O{ret}" |> Some Message = $"returned non-unit value %O{ret}" |> Some
@@ -373,46 +240,24 @@ module Program =
Output = Output =
match i.StdOut, i.StdErr, exc with match i.StdOut, i.StdErr, exc with
| None, None, None -> None | None, None, None -> None
// TODO surely stderr can be emitted | stdout, stderr, exc ->
| stdout, _stderr, exc ->
Some Some
{ {
TrxOutput.StdOut = stdout TrxOutput.StdOut = stdout
StdErr = stderr
ErrorInfo = exc ErrorInfo = exc
} }
} }
) )
let report : TrxReport = {
{ Id = Guid.NewGuid ()
Id = Guid.NewGuid () Name = $"@%s{hostname} %s{finishTimeHumanReadable}"
Name = $"@%s{hostname} %s{finishTimeHumanReadable}" Times = times
Times = times Settings = settings
Settings = settings Results = results
Results = results TestDefinitions = testDefinitions
TestDefinitions = testDefinitions TestEntries = testEntries
TestEntries = testEntries TestLists = [ testList ]
TestLists = [ testList ] ResultsSummary = resultSummary
ResultsSummary = resultSummary }
}
match trxPath with
| Some trxPath ->
let contents = TrxReport.toXml report |> fun d -> d.OuterXml
trxPath.Directory.Create ()
File.WriteAllText (trxPath.FullName, contents)
Console.Error.WriteLine $"Written TRX file: %s{trxPath.FullName}"
| None -> ()
match outcome with
| TrxOutcome.Completed -> 0
| _ -> 1
[<EntryPoint>]
let reallyMain argv =
// Hack to make sure `finally`s get run.
// (The runtime doesn't define which `finally`s, if any, run when an uncaught exception terminates execution.)
try
main argv
with _ ->
reraise ()

View File

@@ -1,5 +1,6 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System
open System.Reflection open System.Reflection
/// A modifier on whether a given test should be run. /// A modifier on whether a given test should be run.
@@ -30,6 +31,54 @@ type Combinatorial =
/// each", and so on. Spare slots are filled with `Unchecked.defaultof<_>`. /// each", and so on. Spare slots are filled with `Unchecked.defaultof<_>`.
| Sequential | Sequential
/// Describes the level of parallelism permitted in some context.
[<RequireQualifiedAccess>]
type ClassParallelScope =
/// "I may be run in parallel with other tests, although my children might not be able to run in parallel with each
/// other".
| Self
/// "The set of things I contain may be run in parallel with itself".
| Children
/// "Fixtures within me may be run in parallel with each other, but the tests within a given fixture might not
/// be runnable in parallel with each other".
| Fixtures
/// "All my descendents are happy to run in parallel with anything else, and also so am I".
| All
/// Describes the level of parallelism permitted within an assembly.
[<RequireQualifiedAccess>]
type AssemblyParallelScope =
/// "The set of things I contain may be run in parallel with itself".
| Children
/// "Fixtures within me may be run in parallel with each other, but the tests within a given fixture might not
/// necessarily be runnable in parallel with each other".
| Fixtures
/// Describes whether a test can be run concurrently with other tests.
type Parallelizable<'scope> =
/// This test is happy, under some conditions (specified by the scope), to be run alongside other tests.
| Yes of 'scope
/// This test must always be run on its own.
| No
[<RequireQualifiedAccess>]
module Parallelizable =
/// Functorial map.
let inline map<'a, 'b> ([<InlineIfLambda>] f : 'a -> 'b) (p : Parallelizable<'a>) : Parallelizable<'b> =
match p with
| Parallelizable.No -> Parallelizable.No
| Parallelizable.Yes a -> Parallelizable.Yes (f a)
/// Functorial bind.
let inline bind<'a, 'b>
([<InlineIfLambda>] f : 'a -> Parallelizable<'b>)
(p : Parallelizable<'a>)
: Parallelizable<'b>
=
match p with
| Parallelizable.No -> Parallelizable.No
| Parallelizable.Yes a -> f a
/// A single method or member which holds some tests. (Often such a member will represent only one test, but e.g. /// 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.) /// if it has [<TestCaseSource>] then it represents multiple tests.)
type SingleTestMethod = type SingleTestMethod =
@@ -48,6 +97,8 @@ type SingleTestMethod =
/// If this test has data supplied by `[<Value>]` annotations, specifies how those annotations are combined /// If this test has data supplied by `[<Value>]` annotations, specifies how those annotations are combined
/// to produce the complete collection of args. /// to produce the complete collection of args.
Combinatorial : Combinatorial option Combinatorial : Combinatorial option
/// If this test has declared a parallelisability, that goes here.
Parallelize : Parallelizable<unit> option
} }
/// Human-readable name of this test method. /// Human-readable name of this test method.
@@ -55,6 +106,7 @@ type SingleTestMethod =
/// A test fixture (usually represented by the [<TestFixture>]` attribute), which may contain many tests, /// A test fixture (usually represented by the [<TestFixture>]` attribute), which may contain many tests,
/// each of which may run many times. /// each of which may run many times.
[<NoComparison>]
type TestFixture = type TestFixture =
{ {
/// The assembly which contains this TestFixture, loaded into a separate context. /// The assembly which contains this TestFixture, loaded into a separate context.
@@ -62,6 +114,8 @@ type TestFixture =
/// Fully-qualified name of this fixture (e.g. MyThing.Test.Foo for `[<TestFixture>] module Foo` in the /// Fully-qualified name of this fixture (e.g. MyThing.Test.Foo for `[<TestFixture>] module Foo` in the
/// `MyThing.Test` assembly). /// `MyThing.Test` assembly).
Name : string Name : string
/// The type which is this fixture, containing the tests as members.
Type : Type
/// A method which is run once when this test fixture starts, before any other setup logic and before /// 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, /// any tests run. If this method fails, no tests will run and no per-test setup/teardown logic will run,
/// but OneTimeTearDown will run. /// but OneTimeTearDown will run.
@@ -77,20 +131,36 @@ type TestFixture =
/// Methods which are run in some arbitrary order after each individual test, even if the test or its setup /// 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. /// failed. If the first TearDown we run fails, we don't define whether the other TearDowns run.
TearDown : MethodInfo list TearDown : MethodInfo list
/// You might have defined e.g. `[<TestFixture true>] type Foo (v : bool) = ...`. If so, this gives the
/// various possible parameters.
Parameters : obj list list
/// The individual test methods present within this fixture. /// The individual test methods present within this fixture.
Tests : SingleTestMethod list 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. /// A test fixture about which we know nothing. No tests, no setup/teardown.
static member Empty (containingAssembly : Assembly) (name : string) = static member Empty
(ty : Type)
(par : Parallelizable<ClassParallelScope> option)
(modifiers : Modifier list)
(args : obj list list)
=
{ {
ContainingAssembly = containingAssembly ContainingAssembly = ty.Assembly
Name = name Type = ty
Name = ty.Name
OneTimeSetUp = None OneTimeSetUp = None
OneTimeTearDown = None OneTimeTearDown = None
SetUp = [] SetUp = []
TearDown = [] TearDown = []
Parameters = args
Tests = [] Tests = []
Parallelize = par
Modifiers = modifiers
} }
/// User code in the unit under test has failed somehow. /// User code in the unit under test has failed somehow.
@@ -100,6 +170,8 @@ type UserMethodFailure =
| ReturnedNonUnit of name : string * result : obj | ReturnedNonUnit of name : string * result : obj
/// A method threw. /// A method threw.
| Threw of name : string * exn | Threw of name : string * exn
/// Parameter count mismatch.
| BadParameters of name : string * expected : Type[] * actual : obj[]
/// Human-readable representation of the user failure. /// Human-readable representation of the user failure.
override this.ToString () = override this.ToString () =
@@ -108,12 +180,22 @@ type UserMethodFailure =
$"User-defined method '%s{method}' returned a non-unit: %O{ret}" $"User-defined method '%s{method}' returned a non-unit: %O{ret}"
| UserMethodFailure.Threw (method, exc) -> | UserMethodFailure.Threw (method, exc) ->
$"User-defined method '%s{method}' threw: %s{exc.Message}\n %s{exc.StackTrace}" $"User-defined method '%s{method}' threw: %s{exc.Message}\n %s{exc.StackTrace}"
| UserMethodFailure.BadParameters (method, expected, actual) ->
let expectedStr = expected |> Seq.map (fun t -> t.Name) |> String.concat ", "
let actualStr =
actual
|> Seq.map (fun s -> if isNull s then "null" else s.ToString ())
|> String.concat ", "
$"User-defined method '%s{method}' had parameter count mismatch. Expected: (%s{expectedStr}) (%i{expected.Length} params). Actual: (%s{actualStr}) (%i{actual.Length} params)"
/// Name (not fully-qualified) of the method which failed. /// Name (not fully-qualified) of the method which failed.
member this.Name = member this.Name =
match this with match this with
| UserMethodFailure.Threw (name, _) | UserMethodFailure.Threw (name, _)
| UserMethodFailure.ReturnedNonUnit (name, _) -> name | UserMethodFailure.ReturnedNonUnit (name, _) -> name
| UserMethodFailure.BadParameters (name, _, _) -> name
/// Represents the failure of a single run of one test. An error signalled this way is a user error: the unit under /// 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. /// test has misbehaved.

View File

@@ -0,0 +1,101 @@
namespace WoofWare.NUnitTestRunner
open System
open System.IO
open WoofWare.DotnetRuntimeLocator
/// Functions for locating .NET runtimes.
[<RequireQualifiedAccess>]
module DotnetRuntime =
let private selectRuntime (config : RuntimeOptions) (f : DotnetEnvironmentInfo) : DirectoryInfo list =
let rollForward =
match Environment.GetEnvironmentVariable "DOTNET_ROLL_FORWARD" with
| null ->
config.RollForward
|> Option.map RollForward.Parse
|> Option.defaultValue RollForward.Minor
| s -> RollForward.Parse s
if
Option.isSome config.IncludedFramework
|| Option.isSome config.IncludedFrameworks
then
// No need for a framework that's anywhere other than the given DLL.
[]
else
let desiredVersions =
match config.Framework with
| Some f -> [ Version f.Version, f.Name ]
| None ->
match config.Frameworks with
| Some f -> f |> List.map (fun f -> Version f.Version, f.Name)
| None ->
failwith
"Could not deduce a framework version due to lack of either Framework or Frameworks in runtimeconfig"
let compatiblyNamedRuntimes =
f.Frameworks
|> Seq.collect (fun availableFramework ->
desiredVersions
|> List.choose (fun (desiredVersion, desiredName) ->
if desiredName = availableFramework.Name then
Some
{|
Desired = desiredVersion
Name = desiredName
Installed = availableFramework
InstalledVersion = Version availableFramework.Version
|}
else
None
)
)
|> Seq.toList
match rollForward with
| RollForward.Minor ->
let available =
compatiblyNamedRuntimes
|> Seq.filter (fun data ->
data.InstalledVersion.Major = data.Desired.Major
&& data.InstalledVersion.Minor >= data.Desired.Minor
)
|> Seq.groupBy (fun data -> data.Name)
|> Seq.map (fun (name, data) ->
let data =
data
|> Seq.minBy (fun data -> data.InstalledVersion.Minor, data.InstalledVersion.Build)
name, data.Installed
)
|> Seq.toList
// TODO: maybe we can ask the SDK if we don't have any runtimes.
// But we keep on trucking: maybe we're self-contained, and we'll actually find all the runtime next to the
// DLL.
available
|> List.map (fun (_name, runtime) -> DirectoryInfo $"%s{runtime.Path}/%s{runtime.Version}")
| _ -> failwith "non-minor RollForward not supported yet; please shout if you want it"
/// Given an executable DLL, locate the .NET runtime that can best run it.
let locate (dll : FileInfo) : DirectoryInfo list =
let runtimeConfig =
let name =
if not (dll.Name.EndsWith (".dll", StringComparison.OrdinalIgnoreCase)) then
failwith $"Expected DLL %s{dll.FullName} to end in .dll"
dll.Name.Substring (0, dll.Name.Length - 4)
Path.Combine (dll.Directory.FullName, $"%s{name}.runtimeconfig.json")
|> File.ReadAllText
|> System.Text.Json.Nodes.JsonNode.Parse
|> RuntimeConfig.jsonParse
|> fun f -> f.RuntimeOptions
let availableRuntimes = DotnetEnvironmentInfo.Get ()
let runtime = selectRuntime runtimeConfig availableRuntimes
dll.Directory :: runtime

View File

@@ -0,0 +1,10 @@
namespace WoofWare.NUnitTestRunner
open System.Runtime.ExceptionServices
[<RequireQualifiedAccess>]
module internal Exception =
let reraiseWithOriginalStackTrace<'a> (e : exn) : 'a =
let edi = ExceptionDispatchInfo.Capture e
edi.Throw ()
failwith "unreachable"

View File

@@ -1,8 +1,8 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open System.IO open System.IO
open PrattParser open WoofWare.PrattParser
// Documentation: // Documentation:
// https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=mstest // https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=mstest
@@ -155,9 +155,7 @@ module internal Lexer =
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal ParsedFilter = module internal ParsedFilter =
let private unescape (s : string) : string = let private unescape (s : string) : string =
System.Xml.XmlReader System.Xml.XmlReader.Create(new StringReader ("<r>" + s + "</r>")).ReadElementString ()
.Create(new StringReader ("<r>" + s + "</r>"))
.ReadElementString ()
let private atom (inputString : string) (token : Token) : ParsedFilter option = let private atom (inputString : string) (token : Token) : ParsedFilter option =
let start, len = token.Trivia let start, len = token.Trivia

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal List = module internal List =

View File

@@ -0,0 +1,477 @@
namespace WoofWare.NUnitTestRunner
open System
open System.Threading
open System.Threading.Tasks
type private AsyncThunkEvaluator<'ret> =
abstract Eval<'a> : (unit -> Async<'a>) -> AsyncReplyChannel<Result<'a, exn>> -> 'ret
type private AsyncThunkCrate =
abstract Apply<'ret> : AsyncThunkEvaluator<'ret> -> 'ret
[<RequireQualifiedAccess>]
module private AsyncThunkCrate =
let make<'a> (t : unit -> Async<'a>) (rc : AsyncReplyChannel<Result<'a, exn>>) : AsyncThunkCrate =
{ new AsyncThunkCrate with
member _.Apply e = e.Eval t rc
}
type private FakeUnit = FakeUnit
/// A handle to a running test fixture.
type TestFixtureRunningToken = private | TestFixtureRunningToken of TestFixture
/// A handle to a test fixture whose setup method has been called.
type TestFixtureSetupToken = private | TestFixtureSetupToken of TestFixture
[<RequireQualifiedAccess>]
module private TestFixtureSetupToken =
let vouchNoSetupRequired (TestFixtureRunningToken tf) = TestFixtureSetupToken tf
/// A handle to a test fixture whose setup method has been called.
type TestFixtureTearDownToken = private | TestFixtureTearDownToken of TestFixture
[<RequireQualifiedAccess>]
module private TestFixtureTearDownToken =
let vouchNoTearDownRequired (TestFixtureSetupToken tf) = TestFixtureTearDownToken tf
[<RequireQualifiedAccess>]
type private MailboxMessage =
| Quit of AsyncReplyChannel<unit>
/// Check current state, see if we need to start more tests, etc.
| Reconcile
| RunTestAsync of
within : TestFixture *
Parallelizable<unit> option *
test : AsyncThunkCrate *
context : ExecutionContext
| BeginTestFixture of TestFixture * AsyncReplyChannel<TestFixtureRunningToken>
| EndTestFixture of TestFixtureTearDownToken * AsyncReplyChannel<unit>
type private RunningFixture =
{
Fixture : TestFixture
RunningCanParallelize : bool
Running : Task list
Waiting : ((unit -> Task) * Parallelizable<unit> option) list
}
static member Make (f : TestFixture) =
{
Fixture = f
Running = []
RunningCanParallelize = true
Waiting = []
}
type private RunningState =
{
MaxParallelism : int
// TODO: make these efficiently look-up-able
CurrentlyRunning : RunningFixture list
Waiting : (TestFixture * AsyncReplyChannel<TestFixtureRunningToken>) list
}
member this.NewTest (tf : TestFixture) (par : Parallelizable<unit> option) (test : unit -> Task) =
{
MaxParallelism = this.MaxParallelism
Waiting = this.Waiting
CurrentlyRunning =
let found = ref 0
this.CurrentlyRunning
|> List.map (fun f ->
if Object.ReferenceEquals (f.Fixture, tf) then
Interlocked.Increment found |> ignore<int>
{ f with
Waiting = (test, par) :: f.Waiting
}
else
f
)
|> fun l ->
match found.Value with
| 1 -> l
| 0 -> failwith $"Unexpectedly did not find the running test fixture '%s{tf.Name}' to add a test to"
| _ -> failwith $"Unexpectedly found the running test fixture '%s{tf.Name}' multiple times in list"
}
member this.CompleteFixture (tf : TestFixture) : RunningState =
let rec go (acc : RunningFixture list) (running : RunningFixture list) =
match running with
| [] -> failwith "Caller has somehow called EndTestFixture while we're not running that test fixture"
| runningFixture :: tail ->
if Object.ReferenceEquals (runningFixture.Fixture, tf) then
match runningFixture.Running, runningFixture.Waiting with
| [], [] -> acc @ tail
| r, [] ->
failwith $"Caller has called EndTestFixture while its tests are still running (%i{r.Length})"
| [], r ->
failwith $"Caller has called EndTestFixture while it has tests waiting to run (%i{r.Length})"
| r, s ->
failwith
$"Caller has called EndTestFixture while it has tests waiting to run (%i{s.Length}) and test running (%i{r.Length})"
else
go (runningFixture :: acc) tail
let currentlyRunning = go [] this.CurrentlyRunning
{
CurrentlyRunning = currentlyRunning
Waiting = this.Waiting
MaxParallelism = this.MaxParallelism
}
type private MailboxState =
| Idle
| Running of RunningState
/// Run some things in parallel.
/// TODO: actually implement the parallelism! Right now this just runs everything serially.
/// TODO: consume the cancellation token
type ParallelQueue
(parallelism : int option, _scope : Parallelizable<AssemblyParallelScope> option, ?ct : CancellationToken)
=
let parallelism =
match parallelism with
| None -> max (Environment.ProcessorCount / 2) 2
| Some p -> p
let rec processTask (state : MailboxState) (m : MailboxProcessor<MailboxMessage>) =
async {
let! message = m.Receive ()
match message with
| MailboxMessage.Quit rc -> rc.Reply ()
| MailboxMessage.Reconcile ->
match state with
| Idle -> return! processTask state m
| Running r ->
match r.CurrentlyRunning with
| [] ->
match r.Waiting with
| [] -> return! processTask Idle m
| (head, rc) :: tail ->
rc.Reply (TestFixtureRunningToken head)
let newRunning =
{
Fixture = head
Running = []
RunningCanParallelize = true
Waiting = []
}
let state =
{
MaxParallelism = r.MaxParallelism
CurrentlyRunning = [ newRunning ]
Waiting = tail
}
// For now, we'll just run one fixture at a time. When we run multiple fixtures in parallel,
// we probably want to call Reconcile here again.
return! processTask (Running state) m
| [ currentlyRunning ] ->
let currentlyRunningTasks =
currentlyRunning.Running |> List.filter (fun t -> not t.IsCompleted)
let r =
{ r with
CurrentlyRunning =
[
{ currentlyRunning with
Running = currentlyRunningTasks
}
]
}
match currentlyRunningTasks with
| [] ->
match currentlyRunning.Waiting with
| [] ->
// Nothing to run yet
return! processTask (Running r) m
| (head, par) :: tail ->
let par =
match par with
| None -> true
| Some Parallelizable.No -> false
| Some (Parallelizable.Yes ()) -> true
let state =
{
Fixture = currentlyRunning.Fixture
RunningCanParallelize = par
Waiting = tail
Running = [ head () ]
}
m.Post MailboxMessage.Reconcile
return!
processTask
(Running
{ r with
CurrentlyRunning = [ state ]
})
m
| currentlyRunningTasks ->
if currentlyRunningTasks.Length >= parallelism then
return! processTask (Running r) m
else
match currentlyRunning.Waiting, currentlyRunning.RunningCanParallelize with
| [], _ ->
// No new candidates.
return! processTask (Running r) m
| _, false ->
// The running test(s) can't have others added.
return! processTask (Running r) m
| (head, par) :: tail, true ->
match par with
| Some Parallelizable.No -> return! processTask (Running r) m
| Some (Parallelizable.Yes ()) ->
let state =
{
RunningState.MaxParallelism = r.MaxParallelism
Waiting = r.Waiting
CurrentlyRunning =
[
{
Fixture = currentlyRunning.Fixture
RunningCanParallelize = true
Running = head () :: currentlyRunning.Running
Waiting = tail
}
]
}
m.Post MailboxMessage.Reconcile
return! processTask (Running state) m
| None ->
match currentlyRunning.Fixture.Parallelize with
| Some Parallelizable.No
| Some (Parallelizable.Yes ClassParallelScope.Self)
| Some (Parallelizable.Yes ClassParallelScope.Fixtures) ->
// Can't add this test to the parallel queue right now
return! processTask (Running r) m
| None
| Some (Parallelizable.Yes ClassParallelScope.All)
| Some (Parallelizable.Yes ClassParallelScope.Children) ->
let state =
{
Fixture = currentlyRunning.Fixture
RunningCanParallelize = true
Waiting = tail
Running = (head ()) :: currentlyRunningTasks
}
m.Post MailboxMessage.Reconcile
return!
processTask
(Running
{ r with
CurrentlyRunning = [ state ]
})
m
| _ -> failwith "Logic error: we currently only run one fixture at a time"
| MailboxMessage.BeginTestFixture (tf, rc) ->
match state with
| Running state ->
let state =
{
MaxParallelism = state.MaxParallelism
CurrentlyRunning = state.CurrentlyRunning
Waiting = (tf, rc) :: state.Waiting
}
|> Running
m.Post MailboxMessage.Reconcile
return! processTask state m
| Idle ->
let state =
{
MaxParallelism = parallelism
CurrentlyRunning = []
Waiting = [ (tf, rc) ]
}
|> Running
m.Post MailboxMessage.Reconcile
return! processTask state m
| MailboxMessage.EndTestFixture (TestFixtureTearDownToken tf, rc) ->
match state with
| Idle ->
return failwith "Caller has somehow called EndTestFixture while we're not running a test fixture"
| Running state ->
let state = state.CompleteFixture tf
rc.Reply ()
m.Post MailboxMessage.Reconcile
return! processTask (Running state) m
| MailboxMessage.RunTestAsync (withinFixture, par, message, capturedContext) ->
let t () =
{ new AsyncThunkEvaluator<_> with
member _.Eval<'b> (t : unit -> Async<'b>) rc =
let tcs = TaskCompletionSource TaskCreationOptions.RunContinuationsAsynchronously
fun () ->
ExecutionContext.Run (
capturedContext,
(fun _ ->
async {
let! result =
async {
try
let! r = t ()
return Ok r
with e ->
return Error e
}
tcs.SetResult ()
m.Post MailboxMessage.Reconcile
rc.Reply result
}
|> Async.StartImmediate
),
()
)
|> Task.Factory.StartNew
|> ignore<Task>
tcs.Task
}
|> message.Apply
let state =
match state with
| Idle -> failwith "somehow asked the queue to run tests when there is no active fixture"
| Running state -> state.NewTest withinFixture par t |> Running
m.Post MailboxMessage.Reconcile
return! processTask state m
}
let mb = new MailboxProcessor<_> (processTask MailboxState.Idle)
do mb.Start ()
/// Request to run the given async action, freely in parallel with other running tests.
/// The resulting Task will return when the action has completed.
member _.RunAsync<'a>
(TestFixtureSetupToken parent)
(scope : Parallelizable<unit> option)
(action : unit -> Async<'a>)
: 'a Task
=
let ec = ExecutionContext.Capture ()
task {
let! result =
(fun rc -> MailboxMessage.RunTestAsync (parent, scope, AsyncThunkCrate.make action rc, ec))
|> mb.PostAndAsyncReply
|> Async.StartAsTask
match result with
| Ok o -> return o
| Error e -> return Exception.reraiseWithOriginalStackTrace e
}
/// Request to run the given action, freely in parallel with other running tests.
/// The resulting Task will return when the action has completed.
member this.Run<'a>
(parent : TestFixtureSetupToken)
(scope : Parallelizable<unit> option)
(action : unit -> 'a)
: 'a Task
=
this.RunAsync parent scope (fun () -> async.Return (action ()))
/// Declare that we wish to start the given test fixture. The resulting Task will return
/// when you are allowed to start running tests from that fixture.
/// Once you've finished running tests from that fixture, call EndTestFixture.
member _.StartTestFixture (tf : TestFixture) : Task<TestFixtureRunningToken> =
fun rc -> MailboxMessage.BeginTestFixture (tf, rc)
|> mb.PostAndAsyncReply
|> Async.StartAsTask
/// Run the given one-time setup for the test fixture.
member _.RunTestSetup (TestFixtureRunningToken parent) (action : unit -> 'a) : ('a * TestFixtureSetupToken) Task =
task {
let par =
parent.Parallelize
|> Option.map (fun p ->
match p with
| Parallelizable.No -> Parallelizable.No
| Parallelizable.Yes _ -> Parallelizable.Yes ()
)
let ec = ExecutionContext.Capture ()
let! response =
(fun rc ->
MailboxMessage.RunTestAsync (
parent,
par,
AsyncThunkCrate.make (fun () -> async.Return (action ())) rc,
ec
)
)
|> mb.PostAndAsyncReply
match response with
| Ok response -> return response, TestFixtureSetupToken parent
| Error e -> return Exception.reraiseWithOriginalStackTrace e
}
/// Run the given one-time tear-down for the test fixture.
member _.RunTestTearDown
(TestFixtureSetupToken parent)
(action : unit -> 'a)
: ('a * TestFixtureTearDownToken) Task
=
task {
let par =
parent.Parallelize
|> Option.map (fun p ->
match p with
| Parallelizable.No -> Parallelizable.No
| Parallelizable.Yes _ -> Parallelizable.Yes ()
)
let ec = ExecutionContext.Capture ()
let! response =
(fun rc ->
MailboxMessage.RunTestAsync (
parent,
par,
AsyncThunkCrate.make (fun () -> async.Return (action ())) rc,
ec
)
)
|> mb.PostAndAsyncReply
match response with
| Ok response -> return response, TestFixtureTearDownToken parent
| Error e -> return Exception.reraiseWithOriginalStackTrace e
}
/// Declare that we have finished submitting requests to run in the given test fixture.
/// You don't need to worry about when the resulting Task returns, but we provide it just in case.
member _.EndTestFixture (tf : TestFixtureTearDownToken) : Task<unit> =
(fun rc -> MailboxMessage.EndTestFixture (tf, rc))
|> mb.PostAndAsyncReply
|> Async.StartAsTask
interface IDisposable with
member _.Dispose () =
// Still race conditions, of course: people could still be submitting after we finish the sync.
mb.PostAndReply MailboxMessage.Quit
(mb :> IDisposable).Dispose ()

View File

@@ -0,0 +1,29 @@
namespace WoofWare.NUnitTestRunner
/// Our own strongly-typed rendering of the NUnit ParallelScope enum.
/// This is more tightly modelled by ClassParallelScope and AssemblyParallelScope in our own domain; this type exists
/// for the initial interop.
[<RequireQualifiedAccess>]
type ParallelScope =
/// Corresponds to NUnit's ParallelScope.Fixtures.
| Fixtures
/// Corresponds to NUnit's ParallelScope.Children.
| Children
/// Corresponds to NUnit's ParallelScope.All.
| All
/// Corresponds to NUnit's ParallelScope.Self.
| Self
/// Corresponds to NUnit's ParallelScope.None.
| None
[<RequireQualifiedAccess>]
module ParallelScope =
/// Convert the weakly-typed C# enum that is NUnit's `ParallelScope` to a strongly-typed representation.
let ofInt (n : int) =
match n with
| 512 -> ParallelScope.Fixtures
| 256 -> ParallelScope.Children
| 257 -> ParallelScope.All
| 1 -> ParallelScope.Self
| 2 -> ParallelScope.None
| _ -> failwith $"Unrecognised ParallelScope enum: %i{n}"

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal Result = module internal Result =

View File

@@ -1,32 +1,33 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open WoofWare.Myriad.Plugins
[<JsonParse>] // Myriad runs the JsonParse generator on this
type FrameworkDescription = type internal FrameworkDescription =
{ {
Name : string Name : string
Version : string Version : string
} }
[<JsonParse>] // Myriad runs the JsonParse generator on this
type RuntimeOptions = type internal RuntimeOptions =
{ {
Tfm : string Tfm : string
Framework : FrameworkDescription option Framework : FrameworkDescription option
Frameworks : FrameworkDescription list option Frameworks : FrameworkDescription list option
IncludedFramework : FrameworkDescription option
IncludedFrameworks : FrameworkDescription list option
RollForward : string option RollForward : string option
} }
[<JsonParse>] // Myriad runs the JsonParse generator on this
type RuntimeConfig = type internal RuntimeConfig =
{ {
RuntimeOptions : RuntimeOptions RuntimeOptions : RuntimeOptions
} }
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
type RollForward = type internal RollForward =
| Minor | Minor
| Major | Major
| LatestPatch | LatestPatch

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open System.Reflection open System.Reflection
@@ -18,75 +18,115 @@ module SingleTestMethod =
(attrs : CustomAttributeData list) (attrs : CustomAttributeData list)
: SingleTestMethod option * CustomAttributeData list : SingleTestMethod option * CustomAttributeData list
= =
let remaining, isTest, sources, hasData, modifiers, categories, repeat, comb = let remaining, isTest, sources, hasData, modifiers, categories, repeat, comb, par =
(([], false, [], None, [], [], None, None), attrs) (([], false, [], None, [], [], None, None, None), attrs)
||> List.fold (fun (remaining, isTest, sources, hasData, mods, cats, repeat, comb) attr -> ||> List.fold (fun (remaining, isTest, sources, hasData, mods, cats, repeat, comb, par) attr ->
match attr.AttributeType.FullName with match attr.AttributeType.FullName with
| "NUnit.Framework.TestAttribute" -> | "NUnit.Framework.TestAttribute" ->
if attr.ConstructorArguments.Count > 0 then if attr.ConstructorArguments.Count > 0 then
failwith "Unexpectedly got arguments to the Test attribute" failwith "Unexpectedly got arguments to the Test attribute"
(remaining, true, sources, hasData, mods, cats, repeat, comb) (remaining, true, sources, hasData, mods, cats, repeat, comb, par)
| "NUnit.Framework.TestCaseAttribute" -> | "NUnit.Framework.TestCaseAttribute" ->
let args = attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList let args = attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList
let args =
match args with
| [ :? System.Collections.ICollection as x ] ->
x
|> Seq.cast<CustomAttributeTypedArgument>
|> Seq.map (fun v -> v.Value)
|> Seq.toList
| _ -> args
match hasData with match hasData with
| None -> (remaining, isTest, sources, Some [ List.ofSeq args ], mods, cats, repeat, comb) | None -> (remaining, isTest, sources, Some [ List.ofSeq args ], mods, cats, repeat, comb, par)
| Some existing -> | Some existing ->
(remaining, isTest, sources, Some ((List.ofSeq args) :: existing), mods, cats, repeat, comb) let args = (List.ofSeq args) :: existing |> Some
(remaining, isTest, sources, args, mods, cats, repeat, comb, par)
| "NUnit.Framework.TestCaseSourceAttribute" -> | "NUnit.Framework.TestCaseSourceAttribute" ->
let arg = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string> let arg = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
(remaining, isTest, arg :: sources, hasData, mods, cats, repeat, comb) (remaining, isTest, arg :: sources, hasData, mods, cats, repeat, comb, par)
| "NUnit.Framework.ExplicitAttribute" -> | "NUnit.Framework.ExplicitAttribute" ->
let reason = let reason =
attr.ConstructorArguments attr.ConstructorArguments
|> Seq.tryHead |> Seq.tryHead
|> Option.map (_.Value >> unbox<string>) |> Option.map (_.Value >> unbox<string>)
(remaining, isTest, sources, hasData, (Modifier.Explicit reason) :: mods, cats, repeat, comb) (remaining, isTest, sources, hasData, (Modifier.Explicit reason) :: mods, cats, repeat, comb, par)
| "NUnit.Framework.IgnoreAttribute" -> | "NUnit.Framework.IgnoreAttribute" ->
let reason = let reason =
attr.ConstructorArguments attr.ConstructorArguments
|> Seq.tryHead |> Seq.tryHead
|> Option.map (_.Value >> unbox<string>) |> Option.map (_.Value >> unbox<string>)
(remaining, isTest, sources, hasData, (Modifier.Ignored reason) :: mods, cats, repeat, comb) (remaining, isTest, sources, hasData, (Modifier.Ignored reason) :: mods, cats, repeat, comb, par)
| "NUnit.Framework.CategoryAttribute" -> | "NUnit.Framework.CategoryAttribute" ->
let category = let category =
attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string> attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
(remaining, isTest, sources, hasData, mods, category :: cats, repeat, comb) (remaining, isTest, sources, hasData, mods, category :: cats, repeat, comb, par)
| "NUnit.Framework.RepeatAttribute" -> | "NUnit.Framework.RepeatAttribute" ->
match repeat with match repeat with
| Some _ -> failwith $"Got RepeatAttribute multiple times on %s{method.Name}" | Some _ -> failwith $"Got RepeatAttribute multiple times on %s{method.Name}"
| None -> | None ->
let repeat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<int> let repeat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<int>
(remaining, isTest, sources, hasData, mods, cats, Some repeat, comb) (remaining, isTest, sources, hasData, mods, cats, Some repeat, comb, par)
| "NUnit.Framework.CombinatorialAttribute" -> | "NUnit.Framework.CombinatorialAttribute" ->
match comb with match comb with
| Some _ -> | Some _ ->
failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}" failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}"
| None -> | None ->
(remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Combinatorial) (remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Combinatorial, par)
| "NUnit.Framework.SequentialAttribute" -> | "NUnit.Framework.SequentialAttribute" ->
match comb with match comb with
| Some _ -> | Some _ ->
failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}" failwith $"Got CombinatorialAttribute or SequentialAttribute multiple times on %s{method.Name}"
| None -> (remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Sequential) | None ->
(remaining, isTest, sources, hasData, mods, cats, repeat, Some Combinatorial.Sequential, par)
| "NUnit.Framework.NonParallelizableAttribute" ->
match par with
| Some _ -> failwith $"Got a parallelization attribute multiple times on %s{method.Name}"
| None -> (remaining, isTest, sources, hasData, mods, cats, repeat, comb, Some Parallelizable.No)
| "NUnit.Framework.ParallelizableAttribute" ->
match par with
| Some _ -> failwith $"Got multiple parallelization attributes on %s{method.Name}"
| None ->
let arg =
match Seq.toList attr.ConstructorArguments with
| [] -> Parallelizable.Yes ()
| [ x ] ->
if x.ArgumentType.Name <> "ParallelScope" then
failwith
$"Got argument %O{x.Value} of unrecognised type %s{x.ArgumentType.Name} on [<Parallelizable>] attribute; expected ParallelScope"
match ParallelScope.ofInt (unbox<int> x.Value) with
| ParallelScope.Children ->
failwith
$"Unexpected ParallelScope.Children on test %s{method.Name}; this is not valid on individual tests"
| ParallelScope.Fixtures ->
failwith
$"Unexpected ParallelScope.Children on test %s{method.Name}; this is not valid on individual tests"
| ParallelScope.All
| ParallelScope.Self -> Parallelizable.Yes ()
| ParallelScope.None -> Parallelizable.No
| s -> failwith $"Got multiple arguments on a [<Parallelizable>] attribute: %O{s}"
(remaining, isTest, sources, hasData, mods, cats, repeat, comb, Some arg)
| s when s.StartsWith ("NUnit.Framework", StringComparison.Ordinal) -> | s when s.StartsWith ("NUnit.Framework", StringComparison.Ordinal) ->
failwith $"Unrecognised attribute on function %s{method.Name}: %s{attr.AttributeType.FullName}" failwith $"Unrecognised attribute on function %s{method.Name}: %s{attr.AttributeType.FullName}"
| _ -> (attr :: remaining, isTest, sources, hasData, mods, cats, repeat, comb) | _ -> (attr :: remaining, isTest, sources, hasData, mods, cats, repeat, comb, par)
) )
let test = let test =
match isTest, sources, hasData, modifiers, categories, repeat, comb with match isTest, sources, hasData, modifiers, categories, repeat, comb, par with
| _, _ :: _, Some _, _, _, _, _ -> | _, _ :: _, Some _, _, _, _, _, _ ->
failwith failwith
$"Test '%s{method.Name}' unexpectedly has both TestData and TestCaseSource; not currently supported" $"Test '%s{method.Name}' unexpectedly has both TestData and TestCaseSource; not currently supported"
| false, [], None, [], _, _, _ -> None | false, [], None, [], _, _, _, _ -> None
| _, _ :: _, None, mods, categories, repeat, comb -> | _, _ :: _, None, mods, categories, repeat, comb, par ->
{ {
Kind = TestKind.Source sources Kind = TestKind.Source sources
Method = method Method = method
@@ -94,9 +134,10 @@ module SingleTestMethod =
Categories = categories @ parentCategories Categories = categories @ parentCategories
Repeat = repeat Repeat = repeat
Combinatorial = comb Combinatorial = comb
Parallelize = par
} }
|> Some |> Some
| _, [], Some data, mods, categories, repeat, comb -> | _, [], Some data, mods, categories, repeat, comb, par ->
{ {
Kind = TestKind.Data data Kind = TestKind.Data data
Method = method Method = method
@@ -104,9 +145,10 @@ module SingleTestMethod =
Categories = categories @ parentCategories Categories = categories @ parentCategories
Repeat = repeat Repeat = repeat
Combinatorial = comb Combinatorial = comb
Parallelize = par
} }
|> Some |> Some
| true, [], None, mods, categories, repeat, comb -> | true, [], None, mods, categories, repeat, comb, par ->
{ {
Kind = TestKind.Single Kind = TestKind.Single
Method = method Method = method
@@ -114,9 +156,10 @@ module SingleTestMethod =
Categories = categories @ parentCategories Categories = categories @ parentCategories
Repeat = repeat Repeat = repeat
Combinatorial = comb Combinatorial = comb
Parallelize = par
} }
|> Some |> Some
| false, [], None, _ :: _, _, _, _ -> | false, [], None, _ :: _, _, _, _, _ ->
failwith failwith
$"Unexpectedly got test modifiers but no test settings on '%s{method.Name}', which you probably didn't intend." $"Unexpectedly got test modifiers but no test settings on '%s{method.Name}', which you probably didn't intend."

View File

@@ -0,0 +1,745 @@
WoofWare.NUnitTestRunner.Args inherit obj, implements WoofWare.NUnitTestRunner.Args System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.Args..ctor [constructor]: (System.IO.FileInfo, System.IO.FileInfo option, (string * WoofWare.NUnitTestRunner.Filter) option, WoofWare.NUnitTestRunner.LogLevel, int option, System.TimeSpan option)
WoofWare.NUnitTestRunner.Args.Dll [property]: [read-only] System.IO.FileInfo
WoofWare.NUnitTestRunner.Args.Equals [method]: (WoofWare.NUnitTestRunner.Args, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.Args.Filter [property]: [read-only] (string * WoofWare.NUnitTestRunner.Filter) option
WoofWare.NUnitTestRunner.Args.get_Dll [method]: unit -> System.IO.FileInfo
WoofWare.NUnitTestRunner.Args.get_Filter [method]: unit -> (string * WoofWare.NUnitTestRunner.Filter) option
WoofWare.NUnitTestRunner.Args.get_LevelOfParallelism [method]: unit -> int option
WoofWare.NUnitTestRunner.Args.get_Logging [method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.Args.get_Timeout [method]: unit -> System.TimeSpan option
WoofWare.NUnitTestRunner.Args.get_Trx [method]: unit -> System.IO.FileInfo option
WoofWare.NUnitTestRunner.Args.LevelOfParallelism [property]: [read-only] int option
WoofWare.NUnitTestRunner.Args.Logging [property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.Args.Parse [static method]: string list -> WoofWare.NUnitTestRunner.Args
WoofWare.NUnitTestRunner.Args.Timeout [property]: [read-only] System.TimeSpan option
WoofWare.NUnitTestRunner.Args.Trx [property]: [read-only] System.IO.FileInfo option
WoofWare.NUnitTestRunner.AssemblyLevelAttributes inherit obj, implements WoofWare.NUnitTestRunner.AssemblyLevelAttributes System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.AssemblyLevelAttributes System.IComparable, System.IComparable, System.Collections.IStructuralComparable
WoofWare.NUnitTestRunner.AssemblyLevelAttributes..ctor [constructor]: (int option, WoofWare.NUnitTestRunner.AssemblyParallelScope WoofWare.NUnitTestRunner.Parallelizable option)
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.Equals [method]: (WoofWare.NUnitTestRunner.AssemblyLevelAttributes, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.get_Parallelism [method]: unit -> int option
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.get_Parallelizable [method]: unit -> WoofWare.NUnitTestRunner.AssemblyParallelScope WoofWare.NUnitTestRunner.Parallelizable option
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.Parallelism [property]: [read-only] int option
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.Parallelizable [property]: [read-only] WoofWare.NUnitTestRunner.AssemblyParallelScope WoofWare.NUnitTestRunner.Parallelizable option
WoofWare.NUnitTestRunner.AssemblyLevelAttributesModule inherit obj
WoofWare.NUnitTestRunner.AssemblyLevelAttributesModule.get [static method]: System.Reflection.Assembly -> WoofWare.NUnitTestRunner.AssemblyLevelAttributes
WoofWare.NUnitTestRunner.AssemblyParallelScope inherit obj, implements WoofWare.NUnitTestRunner.AssemblyParallelScope System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.AssemblyParallelScope System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
WoofWare.NUnitTestRunner.AssemblyParallelScope+Tags inherit obj
WoofWare.NUnitTestRunner.AssemblyParallelScope+Tags.Children [static field]: int = 0
WoofWare.NUnitTestRunner.AssemblyParallelScope+Tags.Fixtures [static field]: int = 1
WoofWare.NUnitTestRunner.AssemblyParallelScope.Children [static property]: [read-only] WoofWare.NUnitTestRunner.AssemblyParallelScope
WoofWare.NUnitTestRunner.AssemblyParallelScope.Equals [method]: (WoofWare.NUnitTestRunner.AssemblyParallelScope, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.AssemblyParallelScope.Fixtures [static property]: [read-only] WoofWare.NUnitTestRunner.AssemblyParallelScope
WoofWare.NUnitTestRunner.AssemblyParallelScope.get_Children [static method]: unit -> WoofWare.NUnitTestRunner.AssemblyParallelScope
WoofWare.NUnitTestRunner.AssemblyParallelScope.get_Fixtures [static method]: unit -> WoofWare.NUnitTestRunner.AssemblyParallelScope
WoofWare.NUnitTestRunner.AssemblyParallelScope.get_IsChildren [method]: unit -> bool
WoofWare.NUnitTestRunner.AssemblyParallelScope.get_IsFixtures [method]: unit -> bool
WoofWare.NUnitTestRunner.AssemblyParallelScope.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.AssemblyParallelScope.IsChildren [property]: [read-only] bool
WoofWare.NUnitTestRunner.AssemblyParallelScope.IsFixtures [property]: [read-only] bool
WoofWare.NUnitTestRunner.AssemblyParallelScope.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.BuildTrxReport inherit obj
WoofWare.NUnitTestRunner.BuildTrxReport.build [static method]: System.Reflection.Assembly -> System.DateTimeOffset -> System.DateTimeOffset -> WoofWare.NUnitTestRunner.FixtureRunResults list -> WoofWare.NUnitTestRunner.TrxReport
WoofWare.NUnitTestRunner.ClassParallelScope inherit obj, implements WoofWare.NUnitTestRunner.ClassParallelScope System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.ClassParallelScope System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 4 cases
WoofWare.NUnitTestRunner.ClassParallelScope+Tags inherit obj
WoofWare.NUnitTestRunner.ClassParallelScope+Tags.All [static field]: int = 3
WoofWare.NUnitTestRunner.ClassParallelScope+Tags.Children [static field]: int = 1
WoofWare.NUnitTestRunner.ClassParallelScope+Tags.Fixtures [static field]: int = 2
WoofWare.NUnitTestRunner.ClassParallelScope+Tags.Self [static field]: int = 0
WoofWare.NUnitTestRunner.ClassParallelScope.All [static property]: [read-only] WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.Children [static property]: [read-only] WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.Equals [method]: (WoofWare.NUnitTestRunner.ClassParallelScope, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.ClassParallelScope.Fixtures [static property]: [read-only] WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.get_All [static method]: unit -> WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.get_Children [static method]: unit -> WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.get_Fixtures [static method]: unit -> WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.get_IsAll [method]: unit -> bool
WoofWare.NUnitTestRunner.ClassParallelScope.get_IsChildren [method]: unit -> bool
WoofWare.NUnitTestRunner.ClassParallelScope.get_IsFixtures [method]: unit -> bool
WoofWare.NUnitTestRunner.ClassParallelScope.get_IsSelf [method]: unit -> bool
WoofWare.NUnitTestRunner.ClassParallelScope.get_Self [static method]: unit -> WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.ClassParallelScope.IsAll [property]: [read-only] bool
WoofWare.NUnitTestRunner.ClassParallelScope.IsChildren [property]: [read-only] bool
WoofWare.NUnitTestRunner.ClassParallelScope.IsFixtures [property]: [read-only] bool
WoofWare.NUnitTestRunner.ClassParallelScope.IsSelf [property]: [read-only] bool
WoofWare.NUnitTestRunner.ClassParallelScope.Self [static property]: [read-only] WoofWare.NUnitTestRunner.ClassParallelScope
WoofWare.NUnitTestRunner.ClassParallelScope.Tag [property]: [read-only] int
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.Equals [method]: (WoofWare.NUnitTestRunner.Combinatorial, System.Collections.IEqualityComparer) -> bool
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.DotnetRuntime inherit obj
WoofWare.NUnitTestRunner.DotnetRuntime.locate [static method]: System.IO.FileInfo -> System.IO.DirectoryInfo list
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.Equals [method]: (WoofWare.NUnitTestRunner.Filter, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.FixtureRunResults, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.IndividualTestRunMetadata, System.Collections.IEqualityComparer) -> bool
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 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
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberStart [method]: string -> unit
WoofWare.NUnitTestRunner.LoadContext inherit System.Runtime.Loader.AssemblyLoadContext
WoofWare.NUnitTestRunner.LoadContext..ctor [constructor]: (System.IO.FileInfo, System.IO.DirectoryInfo list, WoofWare.NUnitTestRunner.TestContexts)
WoofWare.NUnitTestRunner.LogLevel inherit obj, implements WoofWare.NUnitTestRunner.LogLevel System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.LogLevel System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
WoofWare.NUnitTestRunner.LogLevel+Tags inherit obj
WoofWare.NUnitTestRunner.LogLevel+Tags.Nothing [static field]: int = 0
WoofWare.NUnitTestRunner.LogLevel+Tags.Verbose [static field]: int = 1
WoofWare.NUnitTestRunner.LogLevel.Equals [method]: (WoofWare.NUnitTestRunner.LogLevel, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.LogLevel.get_IsNothing [method]: unit -> bool
WoofWare.NUnitTestRunner.LogLevel.get_IsVerbose [method]: unit -> bool
WoofWare.NUnitTestRunner.LogLevel.get_Nothing [static method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.LogLevel.get_Verbose [static method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.IsNothing [property]: [read-only] bool
WoofWare.NUnitTestRunner.LogLevel.IsVerbose [property]: [read-only] bool
WoofWare.NUnitTestRunner.LogLevel.Nothing [static property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.LogLevel.Verbose [static property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
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.Equals [method]: (WoofWare.NUnitTestRunner.Match, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.Modifier, System.Collections.IEqualityComparer) -> bool
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.Parallelizable inherit obj
WoofWare.NUnitTestRunner.Parallelizable.bind [static method]: ('a -> 'b WoofWare.NUnitTestRunner.Parallelizable) -> 'a WoofWare.NUnitTestRunner.Parallelizable -> 'b WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable.map [static method]: ('a -> 'b) -> 'a WoofWare.NUnitTestRunner.Parallelizable -> 'b WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable`1 inherit obj, implements 'scope WoofWare.NUnitTestRunner.Parallelizable System.IEquatable, System.Collections.IStructuralEquatable, 'scope WoofWare.NUnitTestRunner.Parallelizable System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
WoofWare.NUnitTestRunner.Parallelizable`1+Tags inherit obj
WoofWare.NUnitTestRunner.Parallelizable`1+Tags.No [static field]: int = 1
WoofWare.NUnitTestRunner.Parallelizable`1+Tags.Yes [static field]: int = 0
WoofWare.NUnitTestRunner.Parallelizable`1+Yes inherit 'scope WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable`1+Yes.get_Item [method]: unit -> 'scope
WoofWare.NUnitTestRunner.Parallelizable`1+Yes.Item [property]: [read-only] 'scope
WoofWare.NUnitTestRunner.Parallelizable`1.Equals [method]: ('scope WoofWare.NUnitTestRunner.Parallelizable, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.Parallelizable`1.get_IsNo [method]: unit -> bool
WoofWare.NUnitTestRunner.Parallelizable`1.get_IsYes [method]: unit -> bool
WoofWare.NUnitTestRunner.Parallelizable`1.get_No [static method]: unit -> 'scope WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable`1.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.Parallelizable`1.IsNo [property]: [read-only] bool
WoofWare.NUnitTestRunner.Parallelizable`1.IsYes [property]: [read-only] bool
WoofWare.NUnitTestRunner.Parallelizable`1.NewYes [static method]: 'scope -> 'scope WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable`1.No [static property]: [read-only] 'scope WoofWare.NUnitTestRunner.Parallelizable
WoofWare.NUnitTestRunner.Parallelizable`1.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.ParallelQueue inherit obj, implements IDisposable
WoofWare.NUnitTestRunner.ParallelQueue..ctor [constructor]: (int option, WoofWare.NUnitTestRunner.AssemblyParallelScope WoofWare.NUnitTestRunner.Parallelizable option, System.Threading.CancellationToken option)
WoofWare.NUnitTestRunner.ParallelQueue.EndTestFixture [method]: WoofWare.NUnitTestRunner.TestFixtureTearDownToken -> unit System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelQueue.Run [method]: WoofWare.NUnitTestRunner.TestFixtureSetupToken -> unit WoofWare.NUnitTestRunner.Parallelizable option -> (unit -> 'a) -> 'a System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelQueue.RunAsync [method]: WoofWare.NUnitTestRunner.TestFixtureSetupToken -> unit WoofWare.NUnitTestRunner.Parallelizable option -> (unit -> 'a Microsoft.FSharp.Control.FSharpAsync) -> 'a System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelQueue.RunTestSetup [method]: WoofWare.NUnitTestRunner.TestFixtureRunningToken -> (unit -> 'a) -> ('a * WoofWare.NUnitTestRunner.TestFixtureSetupToken) System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelQueue.RunTestTearDown [method]: WoofWare.NUnitTestRunner.TestFixtureSetupToken -> (unit -> 'a) -> ('a * WoofWare.NUnitTestRunner.TestFixtureTearDownToken) System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelQueue.StartTestFixture [method]: WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.TestFixtureRunningToken System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.ParallelScope inherit obj, implements WoofWare.NUnitTestRunner.ParallelScope System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.ParallelScope System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 5 cases
WoofWare.NUnitTestRunner.ParallelScope+Tags inherit obj
WoofWare.NUnitTestRunner.ParallelScope+Tags.All [static field]: int = 2
WoofWare.NUnitTestRunner.ParallelScope+Tags.Children [static field]: int = 1
WoofWare.NUnitTestRunner.ParallelScope+Tags.Fixtures [static field]: int = 0
WoofWare.NUnitTestRunner.ParallelScope+Tags.None [static field]: int = 4
WoofWare.NUnitTestRunner.ParallelScope+Tags.Self [static field]: int = 3
WoofWare.NUnitTestRunner.ParallelScope.All [static property]: [read-only] WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.Children [static property]: [read-only] WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.Equals [method]: (WoofWare.NUnitTestRunner.ParallelScope, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.ParallelScope.Fixtures [static property]: [read-only] WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_All [static method]: unit -> WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_Children [static method]: unit -> WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_Fixtures [static method]: unit -> WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_IsAll [method]: unit -> bool
WoofWare.NUnitTestRunner.ParallelScope.get_IsChildren [method]: unit -> bool
WoofWare.NUnitTestRunner.ParallelScope.get_IsFixtures [method]: unit -> bool
WoofWare.NUnitTestRunner.ParallelScope.get_IsNone [method]: unit -> bool
WoofWare.NUnitTestRunner.ParallelScope.get_IsSelf [method]: unit -> bool
WoofWare.NUnitTestRunner.ParallelScope.get_None [static method]: unit -> WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_Self [static method]: unit -> WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.ParallelScope.IsAll [property]: [read-only] bool
WoofWare.NUnitTestRunner.ParallelScope.IsChildren [property]: [read-only] bool
WoofWare.NUnitTestRunner.ParallelScope.IsFixtures [property]: [read-only] bool
WoofWare.NUnitTestRunner.ParallelScope.IsNone [property]: [read-only] bool
WoofWare.NUnitTestRunner.ParallelScope.IsSelf [property]: [read-only] bool
WoofWare.NUnitTestRunner.ParallelScope.None [static property]: [read-only] WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.Self [static property]: [read-only] WoofWare.NUnitTestRunner.ParallelScope
WoofWare.NUnitTestRunner.ParallelScope.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.ParallelScopeModule inherit obj
WoofWare.NUnitTestRunner.ParallelScopeModule.ofInt [static method]: int -> WoofWare.NUnitTestRunner.ParallelScope
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, unit WoofWare.NUnitTestRunner.Parallelizable option)
WoofWare.NUnitTestRunner.SingleTestMethod.Categories [property]: [read-only] string list
WoofWare.NUnitTestRunner.SingleTestMethod.Combinatorial [property]: [read-only] WoofWare.NUnitTestRunner.Combinatorial option
WoofWare.NUnitTestRunner.SingleTestMethod.Equals [method]: (WoofWare.NUnitTestRunner.SingleTestMethod, System.Collections.IEqualityComparer) -> bool
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_Parallelize [method]: unit -> unit WoofWare.NUnitTestRunner.Parallelizable option
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.Parallelize [property]: [read-only] unit WoofWare.NUnitTestRunner.Parallelizable option
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.TestContexts inherit obj, implements IDisposable
WoofWare.NUnitTestRunner.TestContexts.Empty [static method]: unit -> WoofWare.NUnitTestRunner.TestContexts
WoofWare.NUnitTestRunner.TestContexts.get_Stderr [method]: unit -> System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.get_Stdout [method]: unit -> System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.Stderr [property]: [read-only] System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.Stdout [property]: [read-only] System.IO.TextWriter
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.Equals [method]: (WoofWare.NUnitTestRunner.TestFailure, System.Collections.IEqualityComparer) -> bool
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.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 -> 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
WoofWare.NUnitTestRunner.TestFixture.get_Parallelize [method]: unit -> WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option
WoofWare.NUnitTestRunner.TestFixture.get_Parameters [method]: unit -> obj list list
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.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
WoofWare.NUnitTestRunner.TestFixture.Parallelize [property]: [read-only] WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option
WoofWare.NUnitTestRunner.TestFixture.Parameters [property]: [read-only] obj list list
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.TestFixture.Type [property]: [read-only] System.Type
WoofWare.NUnitTestRunner.TestFixtureModule inherit obj
WoofWare.NUnitTestRunner.TestFixtureModule.parse [static method]: System.Type -> WoofWare.NUnitTestRunner.TestFixture
WoofWare.NUnitTestRunner.TestFixtureModule.run [static method]: WoofWare.NUnitTestRunner.TestContexts -> WoofWare.NUnitTestRunner.ParallelQueue -> WoofWare.NUnitTestRunner.ITestProgress -> (WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.SingleTestMethod -> bool) -> WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.FixtureRunResults list System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.TestFixtureModule.runOneFixture [static method]: WoofWare.NUnitTestRunner.TestContexts -> WoofWare.NUnitTestRunner.ParallelQueue -> WoofWare.NUnitTestRunner.ITestProgress -> (WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.SingleTestMethod -> bool) -> string -> obj -> WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.FixtureRunResults System.Threading.Tasks.Task
WoofWare.NUnitTestRunner.TestFixtureRunningToken inherit obj, implements WoofWare.NUnitTestRunner.TestFixtureRunningToken System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.TestFixtureRunningToken.Equals [method]: (WoofWare.NUnitTestRunner.TestFixtureRunningToken, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.TestFixtureSetupToken inherit obj, implements WoofWare.NUnitTestRunner.TestFixtureSetupToken System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.TestFixtureSetupToken.Equals [method]: (WoofWare.NUnitTestRunner.TestFixtureSetupToken, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.TestFixtureTearDownToken inherit obj, implements WoofWare.NUnitTestRunner.TestFixtureTearDownToken System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.TestFixtureTearDownToken.Equals [method]: (WoofWare.NUnitTestRunner.TestFixtureTearDownToken, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TestKind, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TestMemberFailure, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TestMemberSuccess, System.Collections.IEqualityComparer) -> bool
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.TestProgress.toWriter [static method]: System.IO.TextWriter -> 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.Equals [method]: (WoofWare.NUnitTestRunner.TrxCounters, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxDeployment, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxErrorInfo, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxExecution, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxOutcome, System.Collections.IEqualityComparer) -> bool
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, string option, WoofWare.NUnitTestRunner.TrxErrorInfo option)
WoofWare.NUnitTestRunner.TrxOutput.Equals [method]: (WoofWare.NUnitTestRunner.TrxOutput, System.Collections.IEqualityComparer) -> bool
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_StdErr [method]: unit -> string option
WoofWare.NUnitTestRunner.TrxOutput.get_StdOut [method]: unit -> string option
WoofWare.NUnitTestRunner.TrxOutput.StdErr [property]: [read-only] 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.Equals [method]: (WoofWare.NUnitTestRunner.TrxReport, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxReportTimes, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxResultsSummary, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxRunInfo, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxTestEntry, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxTestListEntry, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxTestMethod, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxTestOutcome, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxTestSettings, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxUnitTest, System.Collections.IEqualityComparer) -> bool
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.Equals [method]: (WoofWare.NUnitTestRunner.TrxUnitTestResult, System.Collections.IEqualityComparer) -> bool
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 3 cases
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters inherit WoofWare.NUnitTestRunner.UserMethodFailure
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.actual [property]: [read-only] obj []
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.expected [property]: [read-only] System.Type []
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.get_actual [method]: unit -> obj []
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.get_expected [method]: unit -> System.Type []
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.get_name [method]: unit -> string
WoofWare.NUnitTestRunner.UserMethodFailure+BadParameters.name [property]: [read-only] string
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.BadParameters [static field]: int = 2
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.Equals [method]: (WoofWare.NUnitTestRunner.UserMethodFailure, System.Collections.IEqualityComparer) -> bool
WoofWare.NUnitTestRunner.UserMethodFailure.get_IsBadParameters [method]: unit -> bool
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.IsBadParameters [property]: [read-only] bool
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.NewBadParameters [static method]: (string, System.Type [], obj []) -> WoofWare.NUnitTestRunner.UserMethodFailure
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

View File

@@ -0,0 +1,870 @@
namespace WoofWare.NUnitTestRunner
open System
open System.Collections
open System.Diagnostics
open System.IO
open System.Reflection
open System.Threading
open System.Threading.Tasks
open Microsoft.FSharp.Core
/// 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
(outputId : OutputStreamId)
(contexts : TestContexts)
(setUp : MethodInfo list)
(tearDown : MethodInfo list)
(testId : Guid)
(test : MethodInfo)
(containingObject : obj)
(args : obj[])
: Async<Result<TestMemberSuccess, TestFailure list> * IndividualTestRunMetadata>
=
let rec runMethods
(wrap : UserMethodFailure -> TestFailure)
(toRun : MethodInfo list)
(args : obj[])
: Result<unit, TestFailure> Async
=
match toRun with
| [] -> async.Return (Ok ())
| head :: rest ->
async {
let result =
try
head.Invoke (containingObject, args) |> Ok
with
| :? TargetInvocationException as e ->
Error (UserMethodFailure.Threw (head.Name, e.InnerException))
| :? TargetParameterCountException ->
UserMethodFailure.BadParameters (
head.Name,
head.GetParameters () |> Array.map (fun pm -> pm.ParameterType),
args
)
|> Error
let! ct = Async.CancellationToken
let! result =
match result with
| Error e -> async.Return (Error (wrap e))
| Ok result ->
match result with
| :? unit -> runMethods wrap rest args
| :? Task as result ->
async {
let mutable exc = None
try
do! Async.AwaitTask result
with e ->
exc <- Some e
match exc with
| None -> return! runMethods wrap rest args
| Some e -> return Error (UserMethodFailure.Threw (head.Name, e) |> wrap)
}
// We'd like to do this type-test:
// | :? Async<unit> as result ->
// but instead we have to do all this reflective nonsense, because FSharpAsync is not part
// of the .NET runtime, so is instead in a different AssemblyLoadContext to us!
// It's in the user-code context, not ours.
| ret ->
let ty = ret.GetType ()
if ty.Namespace = "Microsoft.FSharp.Control" && ty.Name = "FSharpAsync`1" then
match ty.GenericTypeArguments |> Array.map (fun t -> t.FullName) with
| [| "Microsoft.FSharp.Core.Unit" |] ->
let asyncModule = ty.Assembly.GetType ("Microsoft.FSharp.Control.FSharpAsync")
// let catch = asyncModule.GetMethod("Catch").MakeGenericMethod [| ty.GenericTypeArguments.[0] |]
// let caught = catch.Invoke ((null: obj), [| ret |])
let startAsTask =
asyncModule.GetMethod("StartAsTask").MakeGenericMethod
[| ty.GenericTypeArguments.[0] |]
let started =
startAsTask.Invoke ((null : obj), [| ret ; (null : obj) ; (null : obj) |])
|> unbox<Task>
async {
let! res = Async.AwaitTask started |> Async.Catch
match res with
| Choice1Of2 () -> return! runMethods wrap rest args
| Choice2Of2 e ->
return
Error (
UserMethodFailure.Threw (head.Name, started.Exception) |> wrap
)
}
| _ ->
UserMethodFailure.ReturnedNonUnit (head.Name, ret)
|> wrap
|> Error
|> async.Return
else
async.Return (UserMethodFailure.ReturnedNonUnit (head.Name, ret) |> wrap |> Error)
return result
}
async {
let start = DateTimeOffset.Now
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 contexts.DumpStdout outputId with
| "" -> None
| v -> Some v
StdErr =
match contexts.DumpStderr outputId with
| "" -> None
| v -> Some v
}
let! setUpResult = runMethods TestFailure.SetUpFailed setUp [||]
sw.Stop ()
match setUpResult with
| Error e -> return Error [ e ], metadata ()
| Ok () ->
sw.Start ()
let! result = runMethods TestFailure.TestFailed [ test ] args
sw.Stop ()
let result =
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)))
| _ -> 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 ()
return
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
(contexts : TestContexts)
(par : ParallelQueue)
(running : TestFixtureSetupToken)
(progress : ITestProgress)
(setUp : MethodInfo list)
(tearDown : MethodInfo list)
(containingObject : obj)
(test : SingleTestMethod)
: (Result<TestMemberSuccess, TestMemberFailure> * IndividualTestRunMetadata) Task 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) |> Task.FromResult |> 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)
)
match resultPreRun with
| Some result ->
let failureMetadata =
{
Total = TimeSpan.Zero
Start = DateTimeOffset.Now
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) |> Task.FromResult |> List.singleton
| 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) :?> 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"
// TODO: need to capture this stdout/stderr
(argsMem.Invoke (arg, [||]) |> unbox<obj[]>)
else
[| arg |]
]
|> Ok
match individualTests with
| Error e ->
let failureMetadata =
{
Total = TimeSpan.Zero
Start = DateTimeOffset.Now
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) |> Task.FromResult |> List.singleton
| Ok individualTests ->
let count = test.Repeat |> Option.defaultValue 1
Seq.init count (fun _ -> individualTests)
|> Seq.concat
|> Seq.map (fun (testGuid, args) ->
task {
let runMe () =
async {
progress.OnTestMemberStart test.Name
let oldValue = contexts.AsyncLocal.Value
let outputId = contexts.NewOutputs ()
contexts.AsyncLocal.Value <- outputId
let! result, meta =
runOne outputId contexts setUp tearDown testGuid test.Method containingObject args
contexts.AsyncLocal.Value <- oldValue
progress.OnTestMemberFinished test.Name
return result, meta
}
let! results, summary = par.RunAsync running test.Parallelize runMe
match results with
| Ok results -> return Ok results, summary
| Error e -> return 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 runOneFixture
(contexts : TestContexts)
(par : ParallelQueue)
(progress : ITestProgress)
(filter : TestFixture -> SingleTestMethod -> bool)
(name : string)
(containingObject : obj)
(tests : TestFixture)
: FixtureRunResults Task
=
task {
let! running = par.StartTestFixture tests
progress.OnTestFixtureStart name tests.Tests.Length
let oldWorkDir = Environment.CurrentDirectory
Environment.CurrentDirectory <- FileInfo(tests.ContainingAssembly.Location).Directory.FullName
let sw = Stopwatch.StartNew ()
let startTime = DateTimeOffset.UtcNow
let endMetadata (outputId : OutputStreamId) =
let stdOut = contexts.DumpStdout outputId
let stdErr = contexts.DumpStderr outputId
{
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 = 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, running =
match tests.OneTimeSetUp with
| Some su ->
par.RunTestSetup
running
(fun () ->
let oldValue = contexts.AsyncLocal.Value
let newOutputs = contexts.NewOutputs ()
contexts.AsyncLocal.Value <- newOutputs
let result =
try
match su.Invoke (containingObject, [||]) with
| :? unit -> None
| ret ->
Some (UserMethodFailure.ReturnedNonUnit (su.Name, ret), endMetadata newOutputs)
with :? TargetInvocationException as e ->
Some (UserMethodFailure.Threw (su.Name, e.InnerException), endMetadata newOutputs)
contexts.AsyncLocal.Value <- oldValue
match result with
| None -> Ok (Some newOutputs)
| Some err -> Error (err, newOutputs)
)
| _ -> Task.FromResult (Ok None, TestFixtureSetupToken.vouchNoSetupRequired running)
let testFailures = ResizeArray<TestMemberFailure * IndividualTestRunMetadata> ()
let successes =
ResizeArray<SingleTestMethod * TestMemberSuccess * IndividualTestRunMetadata> ()
let testsRun =
match setupResult with
| Error _ ->
// Don't run any tests if setup failed.
Task.FromResult ()
| Ok _ ->
tests.Tests
|> Seq.filter (fun test ->
if filter tests test then
true
else
progress.OnTestMemberSkipped test.Name
false
)
|> Seq.map (fun test ->
task {
let testSuccess = ref 0
let results =
runTestsFromMember
contexts
par
running
progress
tests.SetUp
tests.TearDown
containingObject
test
let! result =
results
|> List.map (fun t ->
task {
let! result, report = t
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))
}
)
|> Task.WhenAll
result |> Array.iter id
}
)
|> Task.WhenAll
|> fun t ->
task {
let! t = t
return t |> Array.iter id
}
do! testsRun
// Unconditionally run OneTimeTearDown if it exists.
let! tearDownError, tornDown =
match tests.OneTimeTearDown with
| Some td ->
par.RunTestTearDown
running
(fun () ->
let oldValue = contexts.AsyncLocal.Value
let outputs = contexts.NewOutputs ()
contexts.AsyncLocal.Value <- outputs
let result =
try
match td.Invoke (containingObject, [||]) with
| :? unit -> None
| ret ->
Some (UserMethodFailure.ReturnedNonUnit (td.Name, ret), endMetadata outputs)
with :? TargetInvocationException as e ->
Some (UserMethodFailure.Threw (td.Name, e.InnerException), endMetadata outputs)
contexts.AsyncLocal.Value <- oldValue
match result with
| None -> Ok (Some outputs)
| Some err -> Error (err, outputs)
)
| _ -> Task.FromResult (Ok None, TestFixtureTearDownToken.vouchNoTearDownRequired running)
Environment.CurrentDirectory <- oldWorkDir
do! par.EndTestFixture tornDown
// TODO: we have access to stdout/err of OneTimeSetUp and OneTimeTearDown here, but we throw them away.
return
{
Failed = testFailures |> Seq.toList
Success = successes |> Seq.toList
OtherFailures =
[ tearDownError ; setupResult ]
|> List.choose (
function
| Error (e, _) -> Some e
| Ok _ -> None
)
}
}
/// 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, 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, mods, par
| "NUnit.Framework.TestFixtureAttribute" ->
let newArgs =
match attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList with
| [ :? ICollection as x ] ->
x |> Seq.cast<CustomAttributeTypedArgument> |> Seq.map _.Value |> Seq.toList
| xs -> xs
categories, newArgs :: args, mods, par
| "NUnit.Framework.NonParallelizableAttribute" ->
match par with
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
| 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, mods, Some (Parallelizable.Yes ClassParallelScope.Self)
| [ v ] ->
match v.Value with
| :? int as v ->
match ParallelScope.ofInt v with
| ParallelScope.Fixtures ->
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Fixtures)
| ParallelScope.Children ->
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Children)
| ParallelScope.All ->
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.All)
| ParallelScope.Self ->
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}"
| "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 mods args, 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
)
/// 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)
(progress : ITestProgress)
(filter : TestFixture -> SingleTestMethod -> bool)
(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
|> List.map (fun args ->
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, args))
else
None
)
|> Option.toObj
let name =
if isNull args then
tests.Name
else
let args = args |> Seq.map (fun o -> o.ToString ()) |> String.concat ","
$"%s{tests.Name}(%s{args})"
runOneFixture contexts par progress filter name containingObject tests
)
|> Task.WhenAll
|> fun t ->
task {
let! t = t
return Array.toList t
}

View File

@@ -1,6 +1,7 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open System.IO
/// Represents something which knows how to report progress through a test suite. /// 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 /// Note that we don't guarantee anything about parallelism; you must make sure
@@ -9,6 +10,8 @@ type ITestProgress =
/// Called just before we start executing the setup logic for the given test fixture. /// 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. /// We tell you how many test methods there are in the fixture.
abstract OnTestFixtureStart : name : string -> testCount : int -> unit 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. /// Called just before we start executing the test(s) indicated by a particular method.
abstract OnTestMemberStart : name : string -> unit abstract OnTestMemberStart : name : string -> unit
/// Called when a test fails. (This may be called repeatedly with the same `name`, e.g. if the test /// Called when a test fails. (This may be called repeatedly with the same `name`, e.g. if the test
@@ -24,22 +27,28 @@ type ITestProgress =
/// Methods for constructing specific ITestProgress objects. /// Methods for constructing specific ITestProgress objects.
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module TestProgress = module TestProgress =
/// An ITestProgress which logs to stderr. /// An ITestProgress which logs to the given writer.
let toStderr () : ITestProgress = let toWriter (writer : TextWriter) : ITestProgress =
{ new ITestProgress with { new ITestProgress with
member _.OnTestFixtureStart name testCount = member _.OnTestFixtureStart name testCount =
let plural = if testCount = 1 then "" else "s" let plural = if testCount = 1 then "" else "s"
Console.Error.WriteLine $"Running test fixture: %s{name} (%i{testCount} test%s{plural} to run)" 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 = member _.OnTestMemberStart name =
Console.Error.WriteLine $"Running test: %s{name}" writer.WriteLine $"Running test: %s{name}"
member _.OnTestFailed name failure = member _.OnTestFailed name failure =
Console.Error.WriteLine $"Test failed: %O{failure}" writer.WriteLine $"Test failed: %O{failure}"
member _.OnTestMemberFinished name = member _.OnTestMemberFinished name =
Console.Error.WriteLine $"Finished test %s{name}" writer.WriteLine $"Finished test %s{name}"
member _.OnTestMemberSkipped name = member _.OnTestMemberSkipped name =
Console.Error.WriteLine $"Skipping test due to filter: %s{name}" writer.WriteLine $"Skipping test due to filter: %s{name}"
} }
/// An ITestProgress which logs to stderr.
let toStderr () : ITestProgress = toWriter Console.Error

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System open System
open System.Xml open System.Xml
@@ -290,6 +290,8 @@ type TrxOutput =
{ {
/// What the entity printed to standard output. /// What the entity printed to standard output.
StdOut : string option StdOut : string option
/// What the entity printed to standard error.
StdErr : string option
/// Description of any error the entity encountered. /// Description of any error the entity encountered.
ErrorInfo : TrxErrorInfo option ErrorInfo : TrxErrorInfo option
} }
@@ -305,6 +307,14 @@ type TrxOutput =
childNode.AppendChild text |> ignore<XmlNode> childNode.AppendChild text |> ignore<XmlNode>
node.AppendChild childNode |> ignore<XmlNode> node.AppendChild childNode |> ignore<XmlNode>
match this.StdErr with
| None -> ()
| Some stderr ->
let text = doc.CreateTextNode stderr
let childNode = doc.CreateElement ("StdErr", XmlUtil.NS)
childNode.AppendChild text |> ignore<XmlNode>
node.AppendChild childNode |> ignore<XmlNode>
match this.ErrorInfo with match this.ErrorInfo with
| None -> () | None -> ()
| Some errInfo -> node.AppendChild (errInfo.toXml doc) |> ignore<XmlNode> | Some errInfo -> node.AppendChild (errInfo.toXml doc) |> ignore<XmlNode>
@@ -317,6 +327,11 @@ type TrxOutput =
| NodeWithNamedChild "StdOut" (OneChildNode "StdOut" (NoChildrenNode stdout)) -> Some stdout | NodeWithNamedChild "StdOut" (OneChildNode "StdOut" (NoChildrenNode stdout)) -> Some stdout
| _ -> None | _ -> None
let stderr =
match node with
| NodeWithNamedChild "StdErr" (OneChildNode "StdErr" (NoChildrenNode stdout)) -> Some stdout
| _ -> None
let errorInfo = let errorInfo =
match node with match node with
| NodeWithNamedChild "ErrorInfo" node -> | NodeWithNamedChild "ErrorInfo" node ->
@@ -330,6 +345,7 @@ type TrxOutput =
| Ok errorInfo -> | Ok errorInfo ->
{ {
StdOut = stdout StdOut = stdout
StdErr = stderr
ErrorInfo = errorInfo ErrorInfo = errorInfo
} }
|> Ok |> Ok

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<Authors>Patrick Stevens</Authors> <Authors>Patrick Stevens</Authors>
<Copyright>Copyright (c) Patrick Stevens 2024</Copyright> <Copyright>Copyright (c) Patrick Stevens 2024</Copyright>
@@ -14,20 +14,38 @@
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId> <PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarnOn>FS3559</WarnOn> <WarnOn>FS3559</WarnOn>
<WoofWareMyriadPluginVersion>8.1.1</WoofWareMyriadPluginVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyInfo.fs" /> <Compile Include="AssemblyInfo.fs" />
<Compile Include="RuntimeConfig.fs" />
<Compile Include="GeneratedRuntimeConfig.fs">
<MyriadFile>RuntimeConfig.fs</MyriadFile>
<MyriadParams>
<RuntimeOptions>JsonParse</RuntimeOptions>
<RuntimeConfig>JsonParse</RuntimeConfig>
<FrameworkDescription>JsonParse</FrameworkDescription>
</MyriadParams>
</Compile>
<Compile Include="ParallelScope.fs" />
<Compile Include="DotnetRuntime.fs" />
<Compile Include="Array.fs" /> <Compile Include="Array.fs" />
<Compile Include="Exception.fs" />
<Compile Include="List.fs" /> <Compile Include="List.fs" />
<Compile Include="Result.fs" /> <Compile Include="Result.fs" />
<Compile Include="Domain.fs" /> <Compile Include="Domain.fs" />
<Compile Include="Filter.fs" /> <Compile Include="Filter.fs" />
<Compile Include="Args.fs" />
<Compile Include="ParallelQueue.fs" />
<Compile Include="SingleTestMethod.fs" /> <Compile Include="SingleTestMethod.fs" />
<Compile Include="TestProgress.fs" /> <Compile Include="TestProgress.fs" />
<Compile Include="Context.fs" />
<Compile Include="TestFixture.fs" /> <Compile Include="TestFixture.fs" />
<Compile Include="Xml.fs" /> <Compile Include="Xml.fs" />
<Compile Include="TrxReport.fs" /> <Compile Include="TrxReport.fs" />
<Compile Include="CreateTrxReport.fs" />
<Compile Include="AssemblyLevelAttributes.fs" />
<None Include="..\README.md"> <None Include="..\README.md">
<Pack>True</Pack> <Pack>True</Pack>
<PackagePath>\</PackagePath> <PackagePath>\</PackagePath>
@@ -36,8 +54,15 @@
<EmbeddedResource Include="version.json" /> <EmbeddedResource Include="version.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="WoofWare.PrattParser" Version="0.1.2" /> <PackageReference Include="WoofWare.PrattParser" Version="0.2.4" />
<PackageReference Update="FSharp.Core" Version="6.0.0" /> <PackageReference Update="FSharp.Core" Version="6.0.1" />
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.1.12" />
<PackageReference Include="Myriad.SDK" Version="0.8.3" PrivateAssets="all" />
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<MyriadSdkGenerator Include="$(NuGetPackageRoot)/woofware.myriad.plugins/$(WoofWareMyriadPluginVersion)/lib/net6.0/WoofWare.Myriad.Plugins.dll" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,4 +1,4 @@
namespace TestRunner namespace WoofWare.NUnitTestRunner
open System.Xml open System.Xml

View File

@@ -1,9 +1,11 @@
{ {
"version": "0.7-prerelease", "version": "0.22",
"publicReleaseRefSpec": ["^refs/heads/main$"], "publicReleaseRefSpec": [
"^refs/heads/main$"
],
"pathFilters": [ "pathFilters": [
"./", "./",
":/Directory.Build.props", ":/Directory.Build.props",
":/README.md" ":/README.md"
] ]
} }

View File

@@ -0,0 +1,35 @@
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using WoofWare.NUnitTestRunner.StartupHook;
namespace WoofWare.NUnitTestRunner.StartupHook
{
internal class StartupAssemblyLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
public StartupAssemblyLoadContext()
{
_resolver = new AssemblyDependencyResolver(Assembly.GetExecutingAssembly().Location);
}
protected override Assembly Load(AssemblyName assemblyName)
{
var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
}
}
}
// Must be internal and called `StartupHook`
internal class StartupHook
{
public static void Initialize()
{
var loadContext = new StartupAssemblyLoadContext();
var assembly = loadContext.LoadFromAssemblyName(new AssemblyName("WoofWare.NUnitTestRunner.StartupHookLogic"));
assembly.DefinedTypes.First(x => x.Name == "StartupHookLogic").GetDeclaredMethod("DoIt")!.Invoke(null, null);
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj"/>
</ItemGroup>
<ItemGroup>
<Compile Include="StartupHook.cs"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,102 @@
using System.Reflection;
using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Core;
namespace WoofWare.NUnitTestRunner.StartupHookLogic;
public class StartupHookLogic
{
private static void DoIt()
{
// Load test runner lib
var nunitLib = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_LIB");
if (string.IsNullOrEmpty(nunitLib))
{
throw new ArgumentException("WoofWare.NUnitTestRunner hook expects to run with WOOFWARE_NUNIT_LIB set to WoofWare.NUnitTestRunner.Lib.dll");
}
Assembly.LoadFrom(nunitLib);
var startTime = DateTimeOffset.Now;
// Arg parsing
var filterVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_FILTER");
static bool NoFilter(TestFixture f, SingleTestMethod g)
{
return true;
}
FSharpFunc<TestFixture, FSharpFunc<SingleTestMethod, bool>> filter;
if (string.IsNullOrEmpty(filterVar))
{
filter = FuncConvert.FromFunc<TestFixture, SingleTestMethod, bool>(NoFilter);
}
else
{
filter = FilterModule.shouldRun(FilterModule.parse(filterVar));
}
var assy = Assembly.GetEntryAssembly()!;
var attrs = AssemblyLevelAttributesModule.get(assy);
FSharpOption<int> levelOfParallelism;
var parallelismVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_PARALLELISM_LEVEL");
if (string.IsNullOrEmpty(parallelismVar))
{
levelOfParallelism = attrs.Parallelism;
}
else
{
levelOfParallelism = FSharpOption<int>.Some(Int32.Parse(parallelismVar));
}
var testFixtures = assy.ExportedTypes.Select(TestFixtureModule.parse);
using var par =
new ParallelQueue(levelOfParallelism, attrs.Parallelizable, FSharpOption<CancellationToken>.None);
var creationTime = DateTimeOffset.Now;
var timeoutVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_TIMEOUT_SECS");
TimeSpan timeout;
if (string.IsNullOrEmpty(timeoutVar))
{
timeout = TimeSpan.FromHours(2.0);
}
else
{
timeout = TimeSpan.FromSeconds(Int32.Parse(timeoutVar));
}
var normalErr = Console.Error;
using var contexts = TestContexts.Empty();
Console.SetOut(contexts.Stdout);
Console.SetError(contexts.Stderr);
var results =
Task.WhenAll(testFixtures.Select(x =>
TestFixtureModule.run(contexts, par, TestProgress.toWriter(normalErr), filter, x)));
if (!results.Wait(timeout))
{
throw new Exception($"Tests failed to terminate within timeout of {timeout}");
}
var sorted =
results.Result.SelectMany(x => x);
var report = BuildTrxReport.build(assy, creationTime, startTime, ListModule.OfSeq(sorted));
var trxFile = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_GENERATE_TRX");
if (!string.IsNullOrEmpty(trxFile))
{
var contents = TrxReportModule.toXml(report).OuterXml;
var trxPath = new FileInfo(trxFile);
trxPath.Directory!.Create();
File.WriteAllText(trxPath.FullName, contents);
normalErr.WriteLine($"Written TRX file: {trxPath.FullName}");
}
if (report.ResultsSummary.Outcome.Equals(TrxOutcome.Completed))
Environment.Exit(0);
else
Environment.Exit(1);
}
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj"/>
</ItemGroup>
<ItemGroup>
<Compile Include="StartupHookLogic.cs"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,52 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WoofWare.NUnitTestRunner", "WoofWare.NUnitTestRunner\WoofWare.NUnitTestRunner.fsproj", "{D4CAE716-79EB-4174-B58C-54E66CF16536}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Consumer", "Consumer\Consumer.fsproj", "{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WoofWare.NUnitTestRunner.Lib", "WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj", "{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WoofWare.NUnitTestRunner.Test", "WoofWare.NUnitTestRunner\WoofWare.NUnitTestRunner.Test\WoofWare.NUnitTestRunner.Test.fsproj", "{443B01B3-2A8C-45CF-96D6-1D890EEA0533}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHook", "WoofWare.NUnitTestRunner.StartupHook\WoofWare.NUnitTestRunner.StartupHook.csproj", "{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHookLogic", "WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj", "{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FailingConsumer", "FailingConsumer\FailingConsumer.fsproj", "{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4CAE716-79EB-4174-B58C-54E66CF16536}.Release|Any CPU.Build.0 = Release|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C87D399-62EB-4A5F-8F6C-3FD6F1B31684}.Release|Any CPU.Build.0 = Release|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C32F4B9-4CF3-4204-BD24-B32D7E64F5C4}.Release|Any CPU.Build.0 = Release|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Debug|Any CPU.Build.0 = Debug|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Release|Any CPU.ActiveCfg = Release|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Release|Any CPU.Build.0 = Release|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Release|Any CPU.Build.0 = Release|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Release|Any CPU.Build.0 = Release|Any CPU
{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,146 @@
namespace WoofWare.NUnitTestRunner
open System
open System.Diagnostics
open System.IO
open System.Reflection
open System.Threading.Tasks
open Spectre.Console
module Program =
// This is actually transcribed into C# in WoofWare.NUnitTestRunner.StartupHookLogic.
let execute argv =
let startTime = DateTimeOffset.Now
let args = argv |> List.ofArray |> Args.Parse
let filter =
match args.Filter with
| Some (_, filter) -> Filter.shouldRun filter
| None -> fun _ _ -> true
let stderr =
let consoleSettings = AnsiConsoleSettings ()
consoleSettings.Out <- AnsiConsoleOutput Console.Error
AnsiConsole.Create consoleSettings
let progress = Progress.spectre stderr
let runtime = DotnetRuntime.locate args.Dll
match args.Logging with
| LogLevel.Nothing -> ()
| LogLevel.Verbose ->
for d in runtime do
stderr.WriteLine $".NET runtime directory: %s{d.FullName}"
use contexts = TestContexts.Empty ()
let ctx = LoadContext (args.Dll, runtime, contexts)
let assy = ctx.LoadFromAssemblyPath args.Dll.FullName
let attrs = AssemblyLevelAttributes.get assy
let levelOfParallelism =
match args.LevelOfParallelism, attrs.Parallelism with
| None, None -> None
| Some taken, Some ignored ->
match args.Logging with
| LogLevel.Nothing -> ()
| LogLevel.Verbose ->
stderr.WriteLine
$"Taking parallelism %i{taken} from command line, ignoring value %i{ignored} from assembly"
Some taken
| Some x, None
| None, Some x -> Some x
let testFixtures = assy.ExportedTypes |> Seq.map TestFixture.parse |> Seq.toList
use par = new ParallelQueue (levelOfParallelism, attrs.Parallelizable)
let creationTime = DateTimeOffset.Now
let results =
testFixtures
|> List.map (TestFixture.run contexts par progress filter)
|> Task.WhenAll
let timeout =
match args.Timeout with
| None -> TimeSpan.FromHours 2.0
| Some t -> t
if not (results.Wait timeout) then
failwith "Tests failed to terminate within two hours"
let results = results.Result |> Seq.concat |> List.ofSeq
let report = BuildTrxReport.build assy creationTime startTime results
match args.Trx with
| Some trxPath ->
let contents = TrxReport.toXml report |> fun d -> d.OuterXml
trxPath.Directory.Create ()
File.WriteAllText (trxPath.FullName, contents)
Console.Error.WriteLine $"Written TRX file: %s{trxPath.FullName}"
| None -> ()
match report.ResultsSummary.Outcome with
| TrxOutcome.Completed -> 0
| _ -> 1
let main argv =
let args = argv |> List.ofArray |> Args.Parse
let psi = ProcessStartInfo "dotnet"
match args.Trx with
| None -> ()
| Some trx -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_GENERATE_TRX", trx.FullName)
match args.LevelOfParallelism with
| None -> ()
| Some par -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_PARALLELISM_LEVEL", string<int> par)
match args.Filter with
| None -> ()
| Some (filter, _) -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_FILTER", filter)
match args.Timeout with
| None -> ()
| Some timeout ->
psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_TIMEOUT_SECS", string<int> (int<float> timeout.TotalSeconds))
psi.ArgumentList.Add "exec"
psi.ArgumentList.Add args.Dll.FullName
let us = Assembly.GetExecutingAssembly().Location |> FileInfo
let startupHook =
Path.Combine (us.Directory.FullName, "WoofWare.NUnitTestRunner.StartupHook.dll")
psi.EnvironmentVariables.Add ("DOTNET_STARTUP_HOOKS", startupHook)
psi.EnvironmentVariables.Add (
"WOOFWARE_NUNIT_LIB",
Path.Combine (us.Directory.FullName, "WoofWare.NUnitTestRunner.Lib.dll")
)
use proc = new Process ()
proc.StartInfo <- psi
if not (proc.Start ()) then
failwith "Failed to start dotnet"
proc.WaitForExit ()
proc.ExitCode
[<EntryPoint>]
let reallyMain argv =
// Hack to make sure `finally`s get run.
// (The runtime doesn't define which `finally`s, if any, run when an uncaught exception terminates execution.)
try
main argv
with _ ->
reraise ()

View File

@@ -0,0 +1,28 @@
namespace WoofWare.NUnitTestRunner
open Spectre.Console
[<RequireQualifiedAccess>]
module Progress =
let spectre (console : IAnsiConsole) : ITestProgress =
{ new ITestProgress with
member _.OnTestFailed name failure =
console.MarkupLine
$"[red]Test '%s{Markup.Escape name}' failed: %s{Markup.Escape (failure.ToString ())}[/]"
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}[/]"
member _.OnTestMemberSkipped name =
console.MarkupLine $"[yellow]Skipping test due to filter: %s{Markup.Escape name}[/]"
member _.OnTestMemberStart name =
console.MarkupLine $"[white]Running test: %s{Markup.Escape name}[/]"
}

View File

@@ -1,4 +1,4 @@
namespace TestRunner.Test namespace WoofWare.NUnitTestRunner.Test
open System open System
open System.IO open System.IO

View File

@@ -1,6 +1,6 @@
namespace TestRunner.Test namespace WoofWare.NUnitTestRunner.Test
open TestRunner open WoofWare.NUnitTestRunner
open NUnit.Framework open NUnit.Framework
open FsUnitTyped open FsUnitTyped

View File

@@ -1,8 +1,8 @@
namespace TestRunner.Test namespace WoofWare.NUnitTestRunner.Test
open FsCheck open FsCheck
open FsUnitTyped open FsUnitTyped
open TestRunner open WoofWare.NUnitTestRunner
open NUnit.Framework open NUnit.Framework
[<TestFixture>] [<TestFixture>]
@@ -11,6 +11,8 @@ module TestList =
[<Test>] [<Test>]
let ``combinations has right size`` () = let ``combinations has right size`` () =
let property (xs : int list list) = let property (xs : int list list) =
let xs = if xs.Length > 6 then xs |> List.take 6 else xs
let xs = xs |> List.map (fun xs -> if xs.Length > 6 then xs |> List.take 6 else xs)
let combs = List.combinations xs let combs = List.combinations xs
combs.Length combs.Length

View File

@@ -1,4 +1,4 @@
namespace TestRunner.Test namespace WoofWare.NUnitTestRunner.Test
open NUnit.Framework open NUnit.Framework
open ApiSurface open ApiSurface
@@ -6,7 +6,7 @@ open ApiSurface
[<TestFixture>] [<TestFixture>]
module TestSurface = module TestSurface =
let assembly = typeof<TestRunner.Combinatorial>.Assembly let assembly = typeof<WoofWare.NUnitTestRunner.Combinatorial>.Assembly
[<Test>] [<Test>]
let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly
@@ -20,6 +20,6 @@ module TestSurface =
DocCoverage.assertFullyDocumented assembly DocCoverage.assertFullyDocumented assembly
[<Test>] [<Test>]
[<Explicit "Not yet published">] // https://github.com/nunit/nunit3-vs-adapter/issues/876
let ``Ensure version is monotonic`` () = let EnsureVersionIsMonotonic () =
MonotonicVersion.validate assembly "CHOOSE A NAME" MonotonicVersion.validate assembly "WoofWare.NUnitTestRunner.Lib"

View File

@@ -0,0 +1,396 @@
namespace WoofWare.NUnitTestRunner.Test
open System
open System.Text
open System.Threading
open System.Threading.Tasks
open NUnit.Framework
open FsUnitTyped
open WoofWare.NUnitTestRunner
[<TestFixture>]
module TestSynchronizationContext =
[<Test>]
let ``ExecutionContext flows correctly through synchronous operations`` () =
task {
let dummyFixture =
TestFixture.Empty typeof<obj> (Some (Parallelizable.Yes ClassParallelScope.All)) [] []
use contexts = TestContexts.Empty ()
use queue = new ParallelQueue (Some 4, None)
// Track which context values we see during execution
let contextValues = System.Collections.Concurrent.ConcurrentBag<Guid * Guid> ()
// Start the fixture
let! running = queue.StartTestFixture dummyFixture
let! _, setup = queue.RunTestSetup running (fun () -> ())
// Create several synchronous operations with different context values
let tasks =
[ 1..10 ]
|> List.map (fun _ ->
task {
do! Task.Yield ()
// Set a unique context value
let outputId = contexts.NewOutputs ()
let (OutputStreamId expectedId) = outputId
contexts.AsyncLocal.Value <- outputId
// Run a synchronous operation that checks the context
let! actualId =
queue.Run
setup
None
(fun () ->
// Check context immediately
let immediate = contexts.AsyncLocal.Value
let (OutputStreamId immediateGuid) = immediate
contextValues.Add (expectedId, immediateGuid)
// Do some work that might cause context issues
Thread.Sleep 10
// Check context after work
let afterWork = contexts.AsyncLocal.Value
let (OutputStreamId afterWorkGuid) = afterWork
contextValues.Add (expectedId, afterWorkGuid)
// Simulate calling into framework code that might use ExecutionContext
let mutable capturedValue = Guid.Empty
ExecutionContext.Run (
ExecutionContext.Capture (),
(fun _ ->
let current = contexts.AsyncLocal.Value
let (OutputStreamId currentGuid) = current
capturedValue <- currentGuid
),
()
)
contextValues.Add (expectedId, capturedValue)
afterWorkGuid
)
// Verify the returned value matches what we set
actualId |> shouldEqual expectedId
}
)
// Wait for all tasks
let! results = Task.WhenAll tasks
results |> Array.iter id
// Verify all context values were correct
let allValues = contextValues |> Seq.toList
allValues |> shouldHaveLength 30 // 3 checks per operation * 10 operations
// Every captured value should match its expected value
allValues
|> List.iter (fun (expected, actual) -> actual |> shouldEqual expected)
// Clean up
let! _, teardown = queue.RunTestTearDown setup (fun () -> ())
do! queue.EndTestFixture teardown
}
[<Test>]
let ``ExecutionContext isolation between concurrent synchronous operations`` () =
task {
let dummyFixture =
TestFixture.Empty typeof<obj> (Some (Parallelizable.Yes ClassParallelScope.All)) [] []
use contexts = TestContexts.Empty ()
use queue = new ParallelQueue (Some 4, None)
let! running = queue.StartTestFixture dummyFixture
let! _, setup = queue.RunTestSetup running (fun () -> ())
// Use a barrier to ensure operations run concurrently
let barrier = new Barrier (3)
let seenValues = System.Collections.Concurrent.ConcurrentBag<int * Guid> ()
let outputIds = System.Collections.Concurrent.ConcurrentBag<OutputStreamId> ()
// Create operations that will definitely run concurrently
let tasks =
[ 1..3 ]
|> List.map (fun i ->
task {
// Each task sets its own context value
let outputId = contexts.NewOutputs ()
let (OutputStreamId myId) = outputId
contexts.AsyncLocal.Value <- outputId
outputIds.Add outputId
let! result =
queue.Run
setup
(Some (Parallelizable.Yes ()))
(fun () ->
// Wait for all tasks to reach this point
barrier.SignalAndWait ()
// Now check what value we see
let currentValue = contexts.AsyncLocal.Value
match currentValue with
| OutputStreamId guid -> seenValues.Add (i, guid)
// Do some synchronous work
Thread.Sleep 5
// Check again after work
let afterWork = contexts.AsyncLocal.Value
match afterWork with
| OutputStreamId guid ->
// Also verify we can write to the correct streams
contexts.Stdout.WriteLine $"Task %i{i} sees context %O{guid}"
guid
)
// Each task should see its own value
result |> shouldEqual myId
}
)
let! results = Task.WhenAll tasks
results |> Array.iter id
// Verify we saw 3 different values (one per task)
let values = seenValues |> Seq.toList
values |> shouldHaveLength 3
// All seen values should be different (no context bleeding)
let uniqueValues = values |> List.map snd |> List.distinct
uniqueValues |> shouldHaveLength 3
let! _, teardown = queue.RunTestTearDown setup (fun () -> ())
do! queue.EndTestFixture teardown
// Verify stdout content for each task
let collectedOutputs = outputIds |> Seq.toList
collectedOutputs |> shouldHaveLength 3
for outputId in collectedOutputs do
let content = contexts.DumpStdout outputId
content |> shouldNotEqual ""
let (OutputStreamId guid) = outputId
content |> shouldContainText (guid.ToString ())
}
[<Test>]
let ``ExecutionContext flows correctly through nested synchronous operations`` () =
task {
let dummyFixture =
TestFixture.Empty typeof<obj> (Some (Parallelizable.Yes ClassParallelScope.All)) [] []
use contexts = TestContexts.Empty ()
use queue = new ParallelQueue (Some 4, None)
let! running = queue.StartTestFixture dummyFixture
let! _, setup = queue.RunTestSetup running (fun () -> ())
// Set an initial context
let outputId = contexts.NewOutputs ()
let (OutputStreamId outerGuid) = outputId
contexts.AsyncLocal.Value <- outputId
let! result =
queue.Run
setup
None
(fun () ->
// Check we have the outer context
let outer = contexts.AsyncLocal.Value
let (OutputStreamId outerSeen) = outer
outerSeen |> shouldEqual outerGuid
// Now change the context for a nested operation
let innerOutputId = contexts.NewOutputs ()
let (OutputStreamId innerGuid) = innerOutputId
contexts.AsyncLocal.Value <- innerOutputId
// Use Task.Run to potentially hop threads
let innerResult =
Task
.Run(fun () ->
let inner = contexts.AsyncLocal.Value
let (OutputStreamId innerSeen) = inner
innerSeen |> shouldEqual innerGuid
innerSeen
)
.Result
// After the nested operation, we should still have our inner context
let afterNested = contexts.AsyncLocal.Value
let (OutputStreamId afterNestedGuid) = afterNested
afterNestedGuid |> shouldEqual innerGuid
(outerSeen, innerResult, afterNestedGuid)
)
// Unpack results
let seenOuter, seenInner, seenAfter = result
seenOuter |> shouldEqual outerGuid
seenInner |> shouldNotEqual outerGuid
seenAfter |> shouldEqual seenInner
let! _, teardown = queue.RunTestTearDown setup (fun () -> ())
do! queue.EndTestFixture teardown
}
[<Test>]
let ``ExecutionContext flows correctly through async operations`` () =
task {
// Create a test fixture
let dummyFixture =
TestFixture.Empty typeof<obj> (Some (Parallelizable.Yes ClassParallelScope.All)) [] []
use contexts = TestContexts.Empty ()
use queue = new ParallelQueue (Some 4, None)
// Track which context values we see during execution
let contextValues = System.Collections.Concurrent.ConcurrentBag<Guid * Guid> ()
// Start the fixture
let! running = queue.StartTestFixture dummyFixture
let! _, setup = queue.RunTestSetup running (fun () -> ())
// Create several async operations with different context values
let tasks =
[ 1..10 ]
|> List.map (fun i ->
task {
// Set a unique context value
let expectedId = Guid.NewGuid ()
let outputId = OutputStreamId expectedId
contexts.AsyncLocal.Value <- outputId
// Run an async operation that checks the context at multiple points
let! actualId =
queue.RunAsync
setup
None
(fun () ->
async {
// Check context immediately
let immediate = contexts.AsyncLocal.Value
let (OutputStreamId immediateGuid) = immediate
contextValues.Add (expectedId, immediateGuid)
// Yield to allow potential context loss
do! Async.Sleep 10
// Check context after yield
let afterYield = contexts.AsyncLocal.Value
let (OutputStreamId afterYieldGuid) = afterYield
contextValues.Add (expectedId, afterYieldGuid)
// Do some actual async work
do! Task.Delay (10) |> Async.AwaitTask
// Check context after task
let afterTask = contexts.AsyncLocal.Value
let (OutputStreamId afterTaskGuid) = afterTask
contextValues.Add (expectedId, afterTaskGuid)
return afterTaskGuid
}
)
// Verify the returned value matches what we set
actualId |> shouldEqual expectedId
}
)
// Wait for all tasks
let! results = Task.WhenAll (tasks)
results |> Array.iter id
// Verify all context values were correct
let allValues = contextValues |> Seq.toList
allValues |> shouldHaveLength 30 // 3 checks per operation * 10 operations
// Every captured value should match its expected value
allValues
|> List.iter (fun (expected, actual) -> actual |> shouldEqual expected)
// Clean up
let! _, teardown = queue.RunTestTearDown setup (fun () -> ())
do! queue.EndTestFixture teardown
}
[<Test>]
let ``ExecutionContext isolation between concurrent operations`` () =
task {
let dummyFixture =
TestFixture.Empty typeof<obj> (Some (Parallelizable.Yes ClassParallelScope.All)) [] []
use contexts = TestContexts.Empty ()
use queue = new ParallelQueue (Some 4, None)
let! running = queue.StartTestFixture dummyFixture
let! _, setup = queue.RunTestSetup running (fun () -> ())
// Use a barrier to ensure operations run concurrently
let barrier = new Barrier (3)
let seenValues = System.Collections.Concurrent.ConcurrentBag<int * Guid> ()
// Create operations that will definitely run concurrently
let tasks =
[ 1..3 ]
|> List.map (fun i ->
task {
// Each task sets its own context value
let myId = Guid.NewGuid ()
contexts.AsyncLocal.Value <- OutputStreamId myId
let! result =
queue.RunAsync
setup
(Some (Parallelizable.Yes ()))
(fun () ->
async {
// Wait for all tasks to reach this point
barrier.SignalAndWait () |> ignore
// Now check what value we see
let currentValue = contexts.AsyncLocal.Value
match currentValue with
| OutputStreamId guid -> seenValues.Add (i, guid)
// Do some async work
do! Async.Sleep 5
// Check again after async work
let afterAsync = contexts.AsyncLocal.Value
match afterAsync with
| OutputStreamId guid -> return guid
}
)
// Each task should see its own value
result |> shouldEqual myId
}
)
let! results = Task.WhenAll (tasks)
results |> Array.iter id
// Verify we saw 3 different values (one per task)
let values = seenValues |> Seq.toList
values |> shouldHaveLength 3
// All seen values should be different (no context bleeding)
let uniqueValues = values |> List.map snd |> List.distinct
uniqueValues |> shouldHaveLength 3
let! _, teardown = queue.RunTestTearDown setup (fun () -> ())
do! queue.EndTestFixture teardown
}

View File

@@ -1,7 +1,7 @@
namespace TestRunner.Test namespace WoofWare.NUnitTestRunner.Test
open System open System
open TestRunner open WoofWare.NUnitTestRunner
open NUnit.Framework open NUnit.Framework
open FsUnitTyped open FsUnitTyped
@@ -197,6 +197,7 @@ Running all tests in /Users/patrick/Documents/GitHub/TestRunner/TestRunner/TestR
Ensure version is monotonic: Not yet published Ensure version is monotonic: Not yet published
NUnit Adapter 4.5.0.0: Test execution complete NUnit Adapter 4.5.0.0: Test execution complete
""" """
StdErr = None
ErrorInfo = None ErrorInfo = None
} }
Outcome = TrxOutcome.Failed Outcome = TrxOutcome.Failed

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject> <IsTestProject>true</IsTestProject>
</PropertyGroup> </PropertyGroup>
@@ -11,21 +11,22 @@
<Compile Include="TestFilter.fs" /> <Compile Include="TestFilter.fs" />
<Compile Include="TestList.fs" /> <Compile Include="TestList.fs" />
<Compile Include="TestSurface.fs" /> <Compile Include="TestSurface.fs" />
<Compile Include="TestSynchronizationContext.fs" />
<Compile Include="TestTrx.fs" /> <Compile Include="TestTrx.fs" />
<EmbeddedResource Include="Example1.trx" /> <EmbeddedResource Include="Example1.trx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ApiSurface" Version="4.0.40" /> <PackageReference Include="ApiSurface" Version="5.0.2" />
<PackageReference Include="FsCheck" Version="3.0.0-rc3" /> <PackageReference Include="FsCheck" Version="3.3.1" />
<PackageReference Include="FsUnit" Version="6.0.0" /> <PackageReference Include="FsUnit" Version="7.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="NUnit" Version="4.1.0" /> <PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/> <PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\TestRunner.Lib\TestRunner.Lib.fsproj" /> <ProjectReference Include="..\..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -2,7 +2,8 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<RollForward>Major</RollForward>
<PackAsTool>true</PackAsTool> <PackAsTool>true</PackAsTool>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<Authors>Patrick Stevens</Authors> <Authors>Patrick Stevens</Authors>
@@ -16,15 +17,9 @@
<PackageId>WoofWare.NUnitTestRunner</PackageId> <PackageId>WoofWare.NUnitTestRunner</PackageId>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarnOn>FS3559</WarnOn> <WarnOn>FS3559</WarnOn>
<WoofWareMyriadPluginVersion>2.1.40</WoofWareMyriadPluginVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="RuntimeConfig.fs" />
<Compile Include="GeneratedRuntimeConfig.fs">
<MyriadFile>RuntimeConfig.fs</MyriadFile>
</Compile>
<Compile Include="Seq.fs" />
<Compile Include="Progress.fs" /> <Compile Include="Progress.fs" />
<Compile Include="Program.fs" /> <Compile Include="Program.fs" />
<None Include="..\README.md"> <None Include="..\README.md">
@@ -34,18 +29,16 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\TestRunner.Lib\TestRunner.Lib.fsproj" /> <ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHook\WoofWare.NUnitTestRunner.StartupHook.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.49.1" /> <PackageReference Include="Spectre.Console" Version="0.51.1" />
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.1.3" />
<PackageReference Include="WoofWare.Myriad.Plugins.Attributes" Version="3.1.4" />
<PackageReference Include="Myriad.SDK" Version="0.8.3" />
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<MyriadSdkGenerator Include="$(NuGetPackageRoot)/woofware.myriad.plugins/$(WoofWareMyriadPluginVersion)/lib/net6.0/WoofWare.Myriad.Plugins.dll" /> <EmbeddedResource Include="version.json" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

View File

@@ -0,0 +1,13 @@
{
"version": "0.3",
"publicReleaseRefSpec": [
"^refs/heads/main$"
],
"pathFilters": [
"./",
":^WoofWare.NUnitTestRunner.Test",
":/WoofWare.NUnitTestRunner.Lib",
":/Directory.Build.props",
":/README.md"
]
}

View File

@@ -4,13 +4,13 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable> <IsPublishable>false</IsPublishable>
<RestorePackagesPath>../.analyzerpackages/</RestorePackagesPath> <RestorePackagesPath>../.analyzerpackages/</RestorePackagesPath>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder> <DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
<AutomaticallyUseReferenceAssemblyPackages>false</AutomaticallyUseReferenceAssemblyPackages> <!-- We don't want to build this project, so we do not need the reference assemblies for the framework we chose.--> <AutomaticallyUseReferenceAssemblyPackages>false</AutomaticallyUseReferenceAssemblyPackages> <!-- We don't want to build this project, so we do not need the reference assemblies for the framework we chose.-->
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.10.0]" /> <PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.17.0]" />
</ItemGroup> </ItemGroup>
</Project> </Project>

12
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1731533236,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1717399147, "lastModified": 1758262103,
"narHash": "sha256-eCWaE/q1VItpFAxxLVt171MdtDcjEnwi6QB/yuF73JU=", "narHash": "sha256-aBGl3XEOsjWw6W3AHiKibN7FeoG73dutQQEqnd/etR8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4a4ecb0ab415c9fccfb005567a215e6a9564cdf5", "rev": "12bd230118a1901a4a5d393f9f56b6ad7e571d01",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -14,10 +14,10 @@
flake-utils.lib.eachDefaultSystem (system: let flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
pname = "unofficial-nunit-runner"; pname = "unofficial-nunit-runner";
dotnet-sdk = pkgs.dotnet-sdk_8; dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
dotnet-runtime = pkgs.dotnetCorePackages.runtime_8_0; dotnet-runtime = pkgs.dotnetCorePackages.runtime_9_0;
version = "0.1"; version = "0.1";
dotnetTool = dllOverride: toolName: toolVersion: sha256: dotnetTool = dllOverride: toolName: toolVersion: hash:
pkgs.stdenvNoCC.mkDerivation rec { pkgs.stdenvNoCC.mkDerivation rec {
name = toolName; name = toolName;
version = toolVersion; version = toolVersion;
@@ -25,8 +25,8 @@
src = pkgs.fetchNuGet { src = pkgs.fetchNuGet {
pname = name; pname = name;
version = version; version = version;
sha256 = sha256; hash = hash;
installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin''; installPhase = ''mkdir -p $out/bin && cp -r tools/net*/any/* $out/bin'';
}; };
installPhase = let installPhase = let
dll = dll =
@@ -42,26 +42,32 @@
''; '';
}; };
in { in {
packages = { packages = let
fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).sha256; deps = builtins.fromJSON (builtins.readFile ./nix/deps.json);
fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).sha256; in {
fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") deps)).hash;
fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") deps)).hash;
default = pkgs.buildDotnetModule { default = pkgs.buildDotnetModule {
inherit pname version dotnet-sdk dotnet-runtime; inherit pname version dotnet-sdk dotnet-runtime;
name = "unofficial-nunit-runner"; name = "unofficial-nunit-runner";
src = ./.; src = ./.;
projectFile = "./TestRunner/TestRunner.fsproj"; projectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.fsproj";
testProjectFile = "./TestRunner/TestRunner.Test/TestRunner.Test.fsproj"; testProjectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.Test/WoofWare.NUnitTestRunner.Test.fsproj";
nugetDeps = ./nix/deps.nix; # `nix build .#default.passthru.fetch-deps && ./result` and put the result here disabledTests = ["WoofWare.NUnitTestRunner.Test.TestSurface.EnsureVersionIsMonotonic"];
nugetDeps = ./nix/deps.json; # `nix build .#default.fetch-deps && ./result nix/deps.json`
doCheck = true; doCheck = true;
}; };
}; };
devShell = pkgs.mkShell { devShells = {
buildInputs = [dotnet-sdk]; default = pkgs.mkShell {
packages = [ packages = [
pkgs.alejandra dotnet-sdk
pkgs.nodePackages.markdown-link-check pkgs.alejandra
pkgs.shellcheck pkgs.nodePackages.markdown-link-check
]; pkgs.shellcheck
pkgs.xmlstarlet
];
};
}; };
}); });
} }

367
nix/deps.json Normal file
View File

@@ -0,0 +1,367 @@
[
{
"pname": "ApiSurface",
"version": "5.0.2",
"hash": "sha256-zcq1H1ccQzsZQf4kolzoOBSbyz07skihgPAvQ9Jri+E="
},
{
"pname": "fantomas",
"version": "7.0.3",
"hash": "sha256-0XlfV7SxXPDnk/CjkUesJSaH0cxlNHJ+Jj86zNUhkNA="
},
{
"pname": "Fantomas.Core",
"version": "6.1.1",
"hash": "sha256-FcTLHQFvKkQY/kV08jhhy/St/+FmXpp3epp/R3zUXMA="
},
{
"pname": "Fantomas.FCS",
"version": "6.1.1",
"hash": "sha256-NuZ8msPEHYA8T3EYREB28F1RcNgUU8V54eg2+UttYxw="
},
{
"pname": "FsCheck",
"version": "3.3.1",
"hash": "sha256-k65ksdOSOGz+meRUUND+yuqJtm5ChaKuaxmRIdKzx2Y="
},
{
"pname": "fsharp-analyzers",
"version": "0.32.1",
"hash": "sha256-le6rPnAF7cKGBZ2w8H2u9glK+6rT2ZjiAVnrkH2IhrM="
},
{
"pname": "FSharp.Core",
"version": "4.3.4",
"hash": "sha256-styyo+6mJy+yxE0NZG/b1hxkAjPOnJfMgd9zWzCJ5uk="
},
{
"pname": "FSharp.Core",
"version": "6.0.1",
"hash": "sha256-Ehsgt3nCJijpaVuJguC1TPVEKSkJd6PSc07D2ZQSemI="
},
{
"pname": "FSharp.Core",
"version": "9.0.303",
"hash": "sha256-AxR6wqodeU23KOTgkUfIgbavgbcSuzD4UBP+tiFydgA="
},
{
"pname": "FsUnit",
"version": "7.1.1",
"hash": "sha256-UMCEGKxQ4ytjmPuVpiNaAPbi3RQH9gqa61JJIUS/6hg="
},
{
"pname": "Microsoft.ApplicationInsights",
"version": "2.22.0",
"hash": "sha256-mUQ63atpT00r49ca50uZu2YCiLg3yd6r3HzTryqcuEA="
},
{
"pname": "Microsoft.AspNetCore.App.Ref",
"version": "6.0.36",
"hash": "sha256-9jDkWbjw/nd8yqdzVTagCuqr6owJ/DUMi4BlUZT4hWU="
},
{
"pname": "Microsoft.AspNetCore.App.Runtime.linux-arm64",
"version": "6.0.36",
"hash": "sha256-JQULJyF0ivLoUU1JaFfK/HHg+/qzpN7V2RR2Cc+WlQ4="
},
{
"pname": "Microsoft.AspNetCore.App.Runtime.linux-x64",
"version": "6.0.36",
"hash": "sha256-zUsVIpV481vMLAXaLEEUpEMA9/f1HGOnvaQnaWdzlyY="
},
{
"pname": "Microsoft.AspNetCore.App.Runtime.osx-arm64",
"version": "6.0.36",
"hash": "sha256-2seqZcz0JeUjkzh3QcGa9TcJ4LUafpFjTRk+Nm8T6T0="
},
{
"pname": "Microsoft.AspNetCore.App.Runtime.osx-x64",
"version": "6.0.36",
"hash": "sha256-yxLafxiBKkvfkDggPk0P9YZIHBkDJOsFTO7/V9mEHuU="
},
{
"pname": "Microsoft.CodeCoverage",
"version": "17.14.1",
"hash": "sha256-f8QytG8GvRoP47rO2KEmnDLxIpyesaq26TFjDdW40Gs="
},
{
"pname": "Microsoft.NET.Test.Sdk",
"version": "17.14.1",
"hash": "sha256-mZUzDFvFp7x1nKrcnRd0hhbNu5g8EQYt8SKnRgdhT/A="
},
{
"pname": "Microsoft.NETCore.App.Host.linux-arm64",
"version": "6.0.36",
"hash": "sha256-9lC/LYnthYhjkWWz2kkFCvlA5LJOv11jdt59SDnpdy0="
},
{
"pname": "Microsoft.NETCore.App.Host.linux-x64",
"version": "6.0.36",
"hash": "sha256-VFRDzx7LJuvI5yzKdGmw/31NYVbwHWPKQvueQt5xc10="
},
{
"pname": "Microsoft.NETCore.App.Host.osx-arm64",
"version": "6.0.36",
"hash": "sha256-DaSWwYACJGolEBuMhzDVCj/rQTdDt061xCVi+gyQnuo="
},
{
"pname": "Microsoft.NETCore.App.Host.osx-x64",
"version": "6.0.36",
"hash": "sha256-FrRny9EI6HKCKQbu6mcLj5w4ooSRrODD4Vj2ZMGnMd4="
},
{
"pname": "Microsoft.NETCore.App.Ref",
"version": "6.0.36",
"hash": "sha256-9LZgVoIFF8qNyUu8kdJrYGLutMF/cL2K82HN2ywwlx8="
},
{
"pname": "Microsoft.NETCore.App.Runtime.linux-arm64",
"version": "6.0.36",
"hash": "sha256-k3rxvUhCEU0pVH8KgEMtkPiSOibn+nBh+0zT2xIfId8="
},
{
"pname": "Microsoft.NETCore.App.Runtime.linux-x64",
"version": "6.0.36",
"hash": "sha256-U8wJ2snSDFqeAgDVLXjnniidC7Cr5aJ1/h/BMSlyu0c="
},
{
"pname": "Microsoft.NETCore.App.Runtime.osx-arm64",
"version": "6.0.36",
"hash": "sha256-UfLcrL2Gj/OLz0s92Oo+OCJeDpZFAcQLPLiSNND8D5Y="
},
{
"pname": "Microsoft.NETCore.App.Runtime.osx-x64",
"version": "6.0.36",
"hash": "sha256-0xIJYFzxdMcnCj3wzkFRQZSnQcPHzPHMzePRIOA3oJs="
},
{
"pname": "Microsoft.NETCore.Platforms",
"version": "1.1.0",
"hash": "sha256-FeM40ktcObQJk4nMYShB61H/E8B7tIKfl9ObJ0IOcCM="
},
{
"pname": "Microsoft.NETCore.Platforms",
"version": "1.1.1",
"hash": "sha256-8hLiUKvy/YirCWlFwzdejD2Db3DaXhHxT7GSZx/znJg="
},
{
"pname": "Microsoft.NETCore.Targets",
"version": "1.1.0",
"hash": "sha256-0AqQ2gMS8iNlYkrD+BxtIg7cXMnr9xZHtKAuN4bjfaQ="
},
{
"pname": "Microsoft.NETCore.Targets",
"version": "1.1.3",
"hash": "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc="
},
{
"pname": "Microsoft.Testing.Extensions.Telemetry",
"version": "1.5.3",
"hash": "sha256-bIXwPSa3jkr2b6xINOqMUs6/uj/r4oVFM7xq3uVIZDU="
},
{
"pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions",
"version": "1.5.3",
"hash": "sha256-IfMRfcyaIKEMRtx326ICKtinDBEfGw/Sv8ZHawJ96Yc="
},
{
"pname": "Microsoft.Testing.Extensions.VSTestBridge",
"version": "1.5.3",
"hash": "sha256-XpM/yFjhLSsuzyDV+xKubs4V1zVVYiV05E0+N4S1h0g="
},
{
"pname": "Microsoft.Testing.Platform",
"version": "1.5.3",
"hash": "sha256-y61Iih6w5D79dmrj2V675mcaeIiHoj1HSa1FRit2BLM="
},
{
"pname": "Microsoft.Testing.Platform.MSBuild",
"version": "1.5.3",
"hash": "sha256-YspvjE5Jfi587TAfsvfDVJXNrFOkx1B3y1CKV6m7YLY="
},
{
"pname": "Microsoft.TestPlatform.ObjectModel",
"version": "17.12.0",
"hash": "sha256-3XBHBSuCxggAIlHXmKNQNlPqMqwFlM952Av6RrLw1/w="
},
{
"pname": "Microsoft.TestPlatform.ObjectModel",
"version": "17.14.1",
"hash": "sha256-QMf6O+w0IT+16Mrzo7wn+N20f3L1/mDhs/qjmEo1rYs="
},
{
"pname": "Microsoft.TestPlatform.TestHost",
"version": "17.14.1",
"hash": "sha256-1cxHWcvHRD7orQ3EEEPPxVGEkTpxom1/zoICC9SInJs="
},
{
"pname": "Myriad.Core",
"version": "0.8.3",
"hash": "sha256-vBOxfq8QriX/yUtaXN69rEQaY/psRNJWxqATLidrt2g="
},
{
"pname": "Myriad.Sdk",
"version": "0.8.3",
"hash": "sha256-7O397WKhskKOvE3MkJT37BvxorDWngDR6gTUogtDZ2M="
},
{
"pname": "Nerdbank.GitVersioning",
"version": "3.8.118",
"hash": "sha256-Hmyy0ZKOmwN4zIhI4+MqoN8geZNc1sd033aZJ6APrO8="
},
{
"pname": "Newtonsoft.Json",
"version": "13.0.3",
"hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc="
},
{
"pname": "NuGet.Common",
"version": "6.14.0",
"hash": "sha256-jDOwt3veI1GSG8CfBnf2+dJxD3E/Nmlc+vHtD4J76Ms="
},
{
"pname": "NuGet.Configuration",
"version": "6.14.0",
"hash": "sha256-1PN9s6fhCw3wd2260U6hQ4vG3jIvcG8GIn1oQgxMXA0="
},
{
"pname": "NuGet.Frameworks",
"version": "6.14.0",
"hash": "sha256-3ViM3R1ucQMEL2hQYsivT86kI6veMQK2xDsiAcFcVQk="
},
{
"pname": "NuGet.Packaging",
"version": "6.14.0",
"hash": "sha256-Yafbnxs3maj55bJ1oKQiZ0QkntFUzXdhorL94YEUOhY="
},
{
"pname": "NuGet.Protocol",
"version": "6.14.0",
"hash": "sha256-uLDKfs+QN1MdnuQtTES8qfNzzsmYKM6XB9pwJc4G+eo="
},
{
"pname": "NuGet.Versioning",
"version": "6.14.0",
"hash": "sha256-DqdOJgsphKxSvqB8b60zNPCaiLfbiu3WnUJ/90feLrY="
},
{
"pname": "NUnit",
"version": "4.3.2",
"hash": "sha256-0RWe8uFoxYp6qhPlDDEghOMcKJgyw2ybvEoAqBLebeE="
},
{
"pname": "NUnit3TestAdapter",
"version": "5.0.0",
"hash": "sha256-7jZM4qAbIzne3AcdFfMbvbgogqpxvVe6q2S7Ls8xQy0="
},
{
"pname": "runtime.any.System.Runtime",
"version": "4.3.0",
"hash": "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM="
},
{
"pname": "runtime.native.System",
"version": "4.3.0",
"hash": "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y="
},
{
"pname": "runtime.unix.System.Private.Uri",
"version": "4.3.0",
"hash": "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs="
},
{
"pname": "Spectre.Console",
"version": "0.51.1",
"hash": "sha256-FQAK07dEwEsNYVI1T3S488LHv8AXJ+ZeA9N2hPpWBoo="
},
{
"pname": "System.Collections.Immutable",
"version": "8.0.0",
"hash": "sha256-F7OVjKNwpqbUh8lTidbqJWYi476nsq9n+6k0+QVRo3w="
},
{
"pname": "System.Diagnostics.DiagnosticSource",
"version": "5.0.0",
"hash": "sha256-6mW3N6FvcdNH/pB58pl+pFSCGWgyaP4hfVtC/SMWDV4="
},
{
"pname": "System.Diagnostics.DiagnosticSource",
"version": "7.0.0",
"hash": "sha256-9Wk8cHSkjKtqkN6xW7KnXoQVtF/VNbKeBq79WqDesMs="
},
{
"pname": "System.Formats.Asn1",
"version": "6.0.0",
"hash": "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8="
},
{
"pname": "System.Memory",
"version": "4.5.5",
"hash": "sha256-EPQ9o1Kin7KzGI5O3U3PUQAZTItSbk9h/i4rViN3WiI="
},
{
"pname": "System.Private.Uri",
"version": "4.3.0",
"hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM="
},
{
"pname": "System.Reflection.Metadata",
"version": "8.0.0",
"hash": "sha256-dQGC30JauIDWNWXMrSNOJncVa1umR1sijazYwUDdSIE="
},
{
"pname": "System.Runtime",
"version": "4.3.1",
"hash": "sha256-R9T68AzS1PJJ7v6ARz9vo88pKL1dWqLOANg4pkQjkA0="
},
{
"pname": "System.Runtime.CompilerServices.Unsafe",
"version": "6.0.0",
"hash": "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I="
},
{
"pname": "System.Security.Cryptography.Pkcs",
"version": "6.0.4",
"hash": "sha256-2e0aRybote+OR66bHaNiYpF//4fCiaO3zbR2e9GABUI="
},
{
"pname": "System.Security.Cryptography.ProtectedData",
"version": "4.4.0",
"hash": "sha256-Ri53QmFX8I8UH0x4PikQ1ZA07ZSnBUXStd5rBfGWFOE="
},
{
"pname": "System.Text.Json",
"version": "8.0.5",
"hash": "sha256-yKxo54w5odWT6nPruUVsaX53oPRe+gKzGvLnnxtwP68="
},
{
"pname": "TypeEquality",
"version": "0.3.0",
"hash": "sha256-V50xAOzzyUJrY+MYPRxtnqW5MVeATXCes89wPprv1r4="
},
{
"pname": "WoofWare.DotnetRuntimeLocator",
"version": "0.1.12",
"hash": "sha256-6pNZs0/R2LnLKSODq9DyHhGo2C+SDyz9k7D/13/78so="
},
{
"pname": "WoofWare.Myriad.Plugins",
"version": "8.1.1",
"hash": "sha256-Cx7/+5+qc8lhxb0On/OW58PrabadMfbcNP1TvLZGHrY="
},
{
"pname": "WoofWare.Myriad.Plugins.Attributes",
"version": "3.7.1",
"hash": "sha256-Mn0OVvC/AwTYg6+3MCKLkNKGGSdzLfBOaLapxHsUDCw="
},
{
"pname": "WoofWare.PrattParser",
"version": "0.2.4",
"hash": "sha256-aNTa2C300jUCsQ+iVSoothbCvBWdg7OzCJknwG5HV6g="
},
{
"pname": "WoofWare.Whippet.Fantomas",
"version": "0.6.3",
"hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw="
}
]

View File

@@ -1,204 +0,0 @@
# This file was automatically generated by passthru.fetch-deps.
# Please dont edit it manually, your changes might get overwritten!
{fetchNuGet}: [
(fetchNuGet {
pname = "ApiSurface";
version = "4.0.40";
sha256 = "1c9z0b6minlripwrjmv4yd5w8zj4lcpak4x41izh7ygx8kgmbvx0";
})
(fetchNuGet {
pname = "fantomas";
version = "6.3.7";
sha256 = "1z1a5bw7vwz6g8nvfgkvx66jnm4hmvn62vbyq0as60nw0jlvaidl";
})
(fetchNuGet {
pname = "FsCheck";
version = "3.0.0-rc3";
sha256 = "1rn4x9qh479927viwww3dy0mikcdcq3pfqv1hzbbawnwxfzm17z1";
})
(fetchNuGet {
pname = "fsharp-analyzers";
version = "0.26.0";
sha256 = "0xgv5kvbwfdvcp6s8x7xagbbi4s3mqa4ixni6pazqvyflbgnah7b";
})
(fetchNuGet {
pname = "FSharp.Core";
version = "6.0.0";
sha256 = "1hjhvr39c1vpgrdmf8xln5q86424fqkvy9nirkr29vl2461d2039";
})
(fetchNuGet {
pname = "FSharp.Core";
version = "8.0.300";
sha256 = "158xxr9hnhz2ibyzzp2d249angvxfc58ifflm4g3hz8qx9zxaq04";
})
(fetchNuGet {
pname = "FsUnit";
version = "6.0.0";
sha256 = "18q3p0z155znwj1l0qq3vq9nh9wl2i4mlfx4pmrnia4czr0xdkmb";
})
(fetchNuGet {
pname = "Microsoft.CodeCoverage";
version = "17.10.0";
sha256 = "0s0v7jmrq85n356xv7zixvwa4z94fszjcr5vll8x4im1a2lp00f9";
})
(fetchNuGet {
pname = "Microsoft.NET.Test.Sdk";
version = "17.10.0";
sha256 = "13g8fwl09li8fc71nk13dgkb7gahd4qhamyg2xby7am63nlchhdf";
})
(fetchNuGet {
pname = "Microsoft.NETCore.Platforms";
version = "2.0.0";
sha256 = "1fk2fk2639i7nzy58m9dvpdnzql4vb8yl8vr19r2fp8lmj9w2jr0";
})
(fetchNuGet {
pname = "Microsoft.TestPlatform.ObjectModel";
version = "17.10.0";
sha256 = "07j69cw8r39533w4p39mnj00kahazz38760in3jfc45kmlcdb26x";
})
(fetchNuGet {
pname = "Microsoft.TestPlatform.TestHost";
version = "17.10.0";
sha256 = "1bl471s7fx9jycr0cc8rylwf34mrvlg9qn1an6l86nisavfcyb7v";
})
(fetchNuGet {
pname = "Myriad.Sdk";
version = "0.8.3";
sha256 = "0qv78c5s5m04xb8h17nnn2ig26zcyya91k2dpj745cm1cbnzvvgc";
})
(fetchNuGet {
pname = "Nerdbank.GitVersioning";
version = "3.6.139";
sha256 = "0npcryhq3r0c2zi940jk39h13mzc4hyg7z8gm6jdmxi1aqv1vh8c";
})
(fetchNuGet {
pname = "NETStandard.Library.Ref";
version = "2.1.0";
sha256 = "12n76gymxq715lkrw841vi5r84kx746cxxssp22pd08as75jzsj6";
})
(fetchNuGet {
pname = "Newtonsoft.Json";
version = "13.0.1";
sha256 = "0fijg0w6iwap8gvzyjnndds0q4b8anwxxvik7y8vgq97dram4srb";
})
(fetchNuGet {
pname = "Newtonsoft.Json";
version = "13.0.3";
sha256 = "0xrwysmrn4midrjal8g2hr1bbg38iyisl0svamb11arqws4w2bw7";
})
(fetchNuGet {
pname = "NuGet.Common";
version = "6.10.0";
sha256 = "0nizrnilmlcqbm945293h8q3wfqfchb4xi8g50x4kjn0rbpd1kbh";
})
(fetchNuGet {
pname = "NuGet.Configuration";
version = "6.10.0";
sha256 = "1aqaknaawnqx4mnvx9qw73wvj48jjzv0d78dzwl7m9zjlrl9myhz";
})
(fetchNuGet {
pname = "NuGet.Frameworks";
version = "6.10.0";
sha256 = "0hrd8y31zx9a0wps49czw0qgbrakb49zn3abfgylc9xrq990zkqk";
})
(fetchNuGet {
pname = "NuGet.Packaging";
version = "6.10.0";
sha256 = "18s53cvrf51lihmaqqdf48p2qi6ky1l48jv0hvbp76cxwdg7rba4";
})
(fetchNuGet {
pname = "NuGet.Protocol";
version = "6.10.0";
sha256 = "0hmv4q0ks9i34mfgpb13l01la9v3jjllfh1qd3aqv105xrqrdxac";
})
(fetchNuGet {
pname = "NuGet.Versioning";
version = "6.10.0";
sha256 = "1x19njx4x0sw9fz8y5fibi15xfsrw5avir0cx0599yd7p3ykik5g";
})
(fetchNuGet {
pname = "NUnit";
version = "4.1.0";
sha256 = "0fj6xwgqaxq3mrai86bklclfmjkzf038mrslwfqf4ignaz9f7g5j";
})
(fetchNuGet {
pname = "NUnit3TestAdapter";
version = "4.5.0";
sha256 = "1srx1629s0k1kmf02nmz251q07vj6pv58mdafcr5dr0bbn1fh78i";
})
(fetchNuGet {
pname = "Spectre.Console";
version = "0.49.1";
sha256 = "0fhl96p3xjd5k1wwvhs80cp35rrlgnza6mw9vy0knhmf7ji9b95n";
})
(fetchNuGet {
pname = "System.Formats.Asn1";
version = "6.0.0";
sha256 = "1vvr7hs4qzjqb37r0w1mxq7xql2b17la63jwvmgv65s1hj00g8r9";
})
(fetchNuGet {
pname = "System.IO.Abstractions";
version = "4.2.13";
sha256 = "0s784iphsmj4vhkrzq9q3w39vsn76w44zclx3hsygsw458zbyh4y";
})
(fetchNuGet {
pname = "System.IO.FileSystem.AccessControl";
version = "4.5.0";
sha256 = "1gq4s8w7ds1sp8f9wqzf8nrzal40q5cd2w4pkf4fscrl2ih3hkkj";
})
(fetchNuGet {
pname = "System.Reflection.Metadata";
version = "1.6.0";
sha256 = "1wdbavrrkajy7qbdblpbpbalbdl48q3h34cchz24gvdgyrlf15r4";
})
(fetchNuGet {
pname = "System.Security.AccessControl";
version = "4.5.0";
sha256 = "1wvwanz33fzzbnd2jalar0p0z3x0ba53vzx1kazlskp7pwyhlnq0";
})
(fetchNuGet {
pname = "System.Security.Cryptography.Pkcs";
version = "6.0.4";
sha256 = "0hh5h38pnxmlrnvs72f2hzzpz4b2caiiv6xf8y7fzdg84r3imvfr";
})
(fetchNuGet {
pname = "System.Security.Cryptography.ProtectedData";
version = "4.4.0";
sha256 = "1q8ljvqhasyynp94a1d7jknk946m20lkwy2c3wa8zw2pc517fbj6";
})
(fetchNuGet {
pname = "System.Security.Principal.Windows";
version = "4.5.0";
sha256 = "0rmj89wsl5yzwh0kqjgx45vzf694v9p92r4x4q6yxldk1cv1hi86";
})
(fetchNuGet {
pname = "System.Text.Encodings.Web";
version = "7.0.0";
sha256 = "1151hbyrcf8kyg1jz8k9awpbic98lwz9x129rg7zk1wrs6vjlpxl";
})
(fetchNuGet {
pname = "System.Text.Json";
version = "7.0.3";
sha256 = "0zjrnc9lshagm6kdb9bdh45dmlnkpwcpyssa896sda93ngbmj8k9";
})
(fetchNuGet {
pname = "WoofWare.DotnetRuntimeLocator";
version = "0.1.3";
sha256 = "0qw41mcvx4qy012pj1dlpdfwsz036qrx7xnzsirk5fz715f1a45m";
})
(fetchNuGet {
pname = "WoofWare.Myriad.Plugins";
version = "2.1.40";
sha256 = "025lv42zjvqpr2di0iaqhqpricqary3l2a3cxgjjl0zxzflfbmx2";
})
(fetchNuGet {
pname = "WoofWare.Myriad.Plugins.Attributes";
version = "3.1.4";
sha256 = "06yw013f2qs2r8bxvja2c5kzbqc5knd3sc3pf6w5gaz4fbzwc2c3";
})
(fetchNuGet {
pname = "WoofWare.PrattParser";
version = "0.1.2";
sha256 = "0spypcwsbn805yrs6grjj68ccva902lhkq93mxy32rdply1xs34q";
})
]