mirror of
https://github.com/Smaug123/unofficial-nunit-runner
synced 2025-10-06 01:48:38 +00:00
Compare commits
106 Commits
WoofWare.N
...
WoofWare.N
Author | SHA1 | Date | |
---|---|---|---|
|
81aa6832d5 | ||
|
a20f32de02 | ||
|
1e53e72d4a | ||
|
b38a3fcc02 | ||
|
73dc21e11f | ||
|
5b54bb256e | ||
|
b56e1b1542 | ||
|
ba46b1edb6 | ||
|
72674e1711 | ||
|
c4b862bdd8 | ||
|
4c629b1d64 | ||
|
e67820c56d | ||
|
31bff4cb03 | ||
|
d081cfaafb | ||
|
c237df3885 | ||
|
3b9b9eb4c8 | ||
|
12e3fc0e4f | ||
|
208b809096 | ||
|
b4e5baddcf | ||
|
5597b3f2f8 | ||
|
fcfdcef6cf | ||
|
eeada219f6 | ||
|
99e0fdff08 | ||
|
fda4e7ba60 | ||
|
dfdfa84733 | ||
|
c218110749 | ||
|
309968721c | ||
|
876ca9e625 | ||
|
59f9789cdc | ||
|
c8c28b9a32 | ||
|
6d87610017 | ||
|
9f28334b7f | ||
|
5cf2261d7f | ||
|
c3589820c3 | ||
|
5d0c205f21 | ||
|
16135fbd56 | ||
|
cbc51cde14 | ||
|
6a4b900aa9 | ||
|
4169289ded | ||
|
7df58d5309 | ||
|
ac4c8c245e | ||
|
3e79e79978 | ||
|
c16e7dd1ee | ||
|
cd66617ce7 | ||
|
144f71a417 | ||
|
3673fc56ee | ||
|
5f74b41825 | ||
|
2068007da0 | ||
|
6fd824c065 | ||
|
0480d5c151 | ||
|
9107b1b502 | ||
|
6583b9e025 | ||
|
48f7302391 | ||
|
d1fa66a2e8 | ||
|
e75c584a43 | ||
|
d7bdd38253 | ||
|
b7d87459d9 | ||
|
992679d8ca | ||
|
011a5129cc | ||
|
46a13d1583 | ||
|
1a291a2ac7 | ||
|
fd34215461 | ||
|
eda120332a | ||
|
799e5c8c3a | ||
|
172865b2a1 | ||
|
f264fca446 | ||
|
8dd18603d6 | ||
|
012b4a6e03 | ||
|
51918f6d35 | ||
|
225b2645b0 | ||
|
5c05d29917 | ||
|
33aa337598 | ||
|
daa53a84a5 | ||
|
4c9568819a | ||
|
6ab8316b2b | ||
|
600772a81f | ||
|
c6b735816e | ||
|
29c3c17bc0 | ||
|
512b41d7c1 | ||
|
f920e597bd | ||
|
226da02b1b | ||
|
e9b9366b90 | ||
|
e7c31b5366 | ||
|
9d26610384 | ||
|
61fbb5f55b | ||
|
d9938d96a3 | ||
|
874a367ce3 | ||
|
4300fbe6b8 | ||
|
402b98f85c | ||
|
a795d6222c | ||
|
cf482b677b | ||
|
db27a7acc8 | ||
|
99826df864 | ||
|
1c93b2c4b2 | ||
|
4369b35dd1 | ||
|
a183455f55 | ||
|
de5f5a64ef | ||
|
fdddbf828b | ||
|
67d9d71100 | ||
|
c39745280b | ||
|
26c29d63bc | ||
|
78f7f76074 | ||
|
c2401207c4 | ||
|
46e097a02e | ||
|
7c23c3bb1c | ||
|
ace1417de6 |
@@ -3,13 +3,13 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"fantomas": {
|
"fantomas": {
|
||||||
"version": "6.3.15",
|
"version": "7.0.3",
|
||||||
"commands": [
|
"commands": [
|
||||||
"fantomas"
|
"fantomas"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fsharp-analyzers": {
|
"fsharp-analyzers": {
|
||||||
"version": "0.27.0",
|
"version": "0.32.1",
|
||||||
"commands": [
|
"commands": [
|
||||||
"fsharp-analyzers"
|
"fsharp-analyzers"
|
||||||
]
|
]
|
||||||
|
22
.envrc
22
.envrc
@@ -1 +1,23 @@
|
|||||||
use flake
|
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
|
||||||
|
231
.github/workflows/dotnet.yaml
vendored
231
.github/workflows/dotnet.yaml
vendored
@@ -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@v30
|
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}} --framework net8.0'
|
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@v30
|
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,52 +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 ./WoofWare.NUnitTestRunner/bin/Release/net6.0/WoofWare.NUnitTestRunner.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
|
|
||||||
with:
|
|
||||||
TRX_PATH: ${{ github.workspace }}/TrxOut
|
|
||||||
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
selftest-net6:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: none
|
|
||||||
checks: write
|
|
||||||
contents: read
|
|
||||||
deployments: none
|
|
||||||
id-token: none
|
|
||||||
issues: none
|
|
||||||
discussions: none
|
|
||||||
packages: none
|
|
||||||
pages: none
|
|
||||||
pull-requests: read
|
|
||||||
repository-projects: none
|
|
||||||
security-events: none
|
|
||||||
statuses: read
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
|
||||||
- name: Install Nix
|
|
||||||
uses: cachix/install-nix-action@v30
|
|
||||||
with:
|
|
||||||
extra_nix_config: |
|
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Restore dependencies
|
|
||||||
run: nix develop --command dotnet restore
|
|
||||||
- name: Build runner
|
|
||||||
run: 'nix develop --command dotnet build WoofWare.NUnitTestRunner --configuration Release'
|
|
||||||
- name: Build target
|
|
||||||
run: 'nix develop --command dotnet build Consumer --configuration Release'
|
|
||||||
- name: Test using self
|
|
||||||
run: 'nix develop .#net6 --command ./WoofWare.NUnitTestRunner/bin/Release/net6.0/WoofWare.NUnitTestRunner ./Consumer/bin/Release/net6.0/Consumer.dll --trx TrxOut/out.trx'
|
|
||||||
- name: Parse Trx files
|
|
||||||
uses: NasAmin/trx-parser@v0.6.0
|
|
||||||
if: always()
|
|
||||||
id: trx-parser
|
id: trx-parser
|
||||||
with:
|
with:
|
||||||
TRX_PATH: ${{ github.workspace }}/TrxOut
|
TRX_PATH: ${{ github.workspace }}/TrxOut
|
||||||
@@ -128,11 +109,11 @@ 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@v30
|
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 }}
|
||||||
@@ -147,9 +128,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@v30
|
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 }}
|
||||||
@@ -162,9 +143,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@v30
|
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 }}
|
||||||
@@ -175,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@v30
|
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 }}
|
||||||
@@ -190,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@v30
|
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 }}
|
||||||
@@ -203,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@v30
|
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 }}
|
||||||
@@ -213,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@v30
|
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 }}
|
||||||
@@ -243,7 +224,7 @@ jobs:
|
|||||||
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
|
||||||
@@ -251,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
|
||||||
@@ -259,28 +240,9 @@ 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:
|
|
||||||
needs: [nuget-pack]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Download NuGet artifact (lib)
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nuget-package-lib
|
|
||||||
- name: Download NuGet artifact (tool)
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nuget-package-tool
|
|
||||||
- name: Tag and release tool
|
|
||||||
env:
|
|
||||||
DRY_RUN: 1
|
|
||||||
GITHUB_TOKEN: mock-token
|
|
||||||
run: sh .github/workflows/tag.sh
|
|
||||||
|
|
||||||
all-required-checks-complete:
|
all-required-checks-complete:
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
needs: [check-dotnet-format, check-nix-format, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-tool-dry-run]
|
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: G-Research/common-actions/check-required-lite@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
- uses: G-Research/common-actions/check-required-lite@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
||||||
@@ -297,12 +259,12 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Download NuGet artifact
|
- 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
|
path: packed
|
||||||
- name: Attest Build Provenance
|
- name: Attest Build Provenance
|
||||||
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
|
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
|
||||||
with:
|
with:
|
||||||
subject-path: "packed/*.nupkg"
|
subject-path: "packed/*.nupkg"
|
||||||
|
|
||||||
@@ -316,12 +278,12 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Download NuGet artifact
|
- name: Download NuGet artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: nuget-package-tool
|
name: nuget-package-tool
|
||||||
path: packed
|
path: packed
|
||||||
- name: Attest Build Provenance
|
- name: Attest Build Provenance
|
||||||
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
|
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
|
||||||
with:
|
with:
|
||||||
subject-path: "packed/*.nupkg"
|
subject-path: "packed/*.nupkg"
|
||||||
|
|
||||||
@@ -335,25 +297,30 @@ jobs:
|
|||||||
attestations: write
|
attestations: write
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v30
|
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
|
- 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
|
path: packed
|
||||||
- name: Identify .NET
|
- name: Identify .NET
|
||||||
id: identify-dotnet
|
id: identify-dotnet
|
||||||
run: nix develop --command bash -c "echo dotnet=$(which dotnet) >> $GITHUB_OUTPUT"
|
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
|
- name: Publish NuGet package
|
||||||
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
||||||
with:
|
with:
|
||||||
package-name: WoofWare.NUnitTestRunner.Lib
|
package-name: WoofWare.NUnitTestRunner.Lib
|
||||||
nuget-key: ${{ secrets.NUGET_API_KEY }}
|
nuget-key: ${{ steps.login.outputs.NUGET_API_KEY }}
|
||||||
nupkg-dir: packed/
|
nupkg-dir: packed/
|
||||||
dotnet: ${{ steps.identify-dotnet.outputs.dotnet }}
|
dotnet: ${{ steps.identify-dotnet.outputs.dotnet }}
|
||||||
|
|
||||||
@@ -367,29 +334,71 @@ jobs:
|
|||||||
attestations: write
|
attestations: write
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v30
|
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
|
- name: Download NuGet artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: nuget-package-tool
|
name: nuget-package-tool
|
||||||
path: packed
|
path: packed
|
||||||
- name: Identify .NET
|
- name: Identify .NET
|
||||||
id: identify-dotnet
|
id: identify-dotnet
|
||||||
run: nix develop --command bash -c "echo dotnet=$(which dotnet) >> $GITHUB_OUTPUT"
|
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
|
- name: Publish NuGet package
|
||||||
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
uses: G-Research/common-actions/publish-nuget@2b7dc49cb14f3344fbe6019c14a31165e258c059
|
||||||
with:
|
with:
|
||||||
package-name: WoofWare.NUnitTestRunner
|
package-name: WoofWare.NUnitTestRunner
|
||||||
nuget-key: ${{ secrets.NUGET_API_KEY }}
|
nuget-key: ${{ steps.login.outputs.NUGET_API_KEY }}
|
||||||
nupkg-dir: packed/
|
nupkg-dir: packed/
|
||||||
dotnet: ${{ steps.identify-dotnet.outputs.dotnet }}
|
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]
|
||||||
@@ -397,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 }}
|
||||||
|
12
.github/workflows/flake_update.yaml
vendored
12
.github/workflows/flake_update.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: DeterminateSystems/nix-installer-action@main
|
uses: DeterminateSystems/nix-installer-action@main
|
||||||
@@ -21,18 +21,18 @@ jobs:
|
|||||||
- name: Update Nix flake
|
- name: Update Nix flake
|
||||||
run: 'nix flake update'
|
run: 'nix flake update'
|
||||||
|
|
||||||
- name: Build passthru
|
- name: Build fetch-deps
|
||||||
run: 'nix build ".#default.passthru.fetch-deps"'
|
run: 'nix build ".#default.fetch-deps"'
|
||||||
|
|
||||||
- name: Run passthru
|
- name: Run fetch-deps
|
||||||
run: ./result nix/deps.nix
|
run: ./result nix/deps.json
|
||||||
|
|
||||||
- name: Format
|
- name: Format
|
||||||
run: 'nix develop --command alejandra .'
|
run: 'nix develop --command alejandra .'
|
||||||
|
|
||||||
- name: Create token
|
- name: Create token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@v1
|
uses: actions/create-github-app-token@v2
|
||||||
with:
|
with:
|
||||||
# https://github.com/actions/create-github-app-token/issues/136
|
# https://github.com/actions/create-github-app-token/issues/136
|
||||||
app-id: ${{ secrets.APP_ID }}
|
app-id: ${{ secrets.APP_ID }}
|
||||||
|
124
.github/workflows/tag.sh
vendored
124
.github/workflows/tag.sh
vendored
@@ -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
|
|
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
<TargetFrameworks>net9.0</TargetFrameworks>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<IsTestProject>true</IsTestProject>
|
<IsTestProject>true</IsTestProject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
<Compile Include="NoAttribute.fs" />
|
<Compile Include="NoAttribute.fs" />
|
||||||
<Compile Include="Inconclusive.fs" />
|
<Compile Include="Inconclusive.fs" />
|
||||||
<Compile Include="RunSubProcess.fs" />
|
<Compile Include="RunSubProcess.fs" />
|
||||||
|
<Compile Include="TestAsync.fs" />
|
||||||
|
<Compile Include="TestExplicit.fs" />
|
||||||
<Compile Include="TestNonParallel.fs" />
|
<Compile Include="TestNonParallel.fs" />
|
||||||
<Compile Include="TestParallel.fs" />
|
<Compile Include="TestParallel.fs" />
|
||||||
<Compile Include="TestParallelIndividualTest.fs" />
|
<Compile Include="TestParallelIndividualTest.fs" />
|
||||||
@@ -26,10 +28,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FsUnit" Version="6.0.1" />
|
<PackageReference Include="FsUnit" Version="7.1.1" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||||
<PackageReference Include="NUnit" Version="4.2.2"/>
|
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
23
Consumer/TestAsync.fs
Normal file
23
Consumer/TestAsync.fs
Normal 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
|
||||||
|
}
|
24
Consumer/TestExplicit.fs
Normal file
24
Consumer/TestExplicit.fs
Normal 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"
|
@@ -10,7 +10,7 @@
|
|||||||
<WarnOn>FS3388,FS3559</WarnOn>
|
<WarnOn>FS3388,FS3559</WarnOn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.146" 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>
|
||||||
|
20
FailingConsumer/FailingConsumer.fsproj
Normal file
20
FailingConsumer/FailingConsumer.fsproj
Normal 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>
|
9
FailingConsumer/TestInsufficientArgs.fs
Normal file
9
FailingConsumer/TestInsufficientArgs.fs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace FailingConsumer
|
||||||
|
|
||||||
|
open NUnit.Framework
|
||||||
|
|
||||||
|
[<TestFixture>]
|
||||||
|
module TestInsufficientArgs =
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let foo (_ : int) = ()
|
1
FailingConsumer/expected.txt
Normal file
1
FailingConsumer/expected.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
foo: had parameter count mismatch: expected 1, actual 0
|
@@ -12,5 +12,8 @@ However, we would recommend phrasing some of them differently, for maximum peace
|
|||||||
## Parallelism
|
## Parallelism
|
||||||
|
|
||||||
WoofWare.NUnitTestRunner has *limited* support for parallelism.
|
WoofWare.NUnitTestRunner has *limited* support for parallelism.
|
||||||
By default, we run tests serially; we may or may not respect the NUnit parallelism attributes to any given extent (but we will never incorrectly run tests in parallel).
|
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).
|
||||||
For example, as of this writing, we do not run any tests in parallel (but the internal infrastructure is set up so that we will be able to do this soon).
|
|
||||||
|
# Licence
|
||||||
|
|
||||||
|
WoofWare.NUnitTestRunner is licensed to you under the MIT licence, a copy of which can be found at [LICENSE](./LICENSE).
|
||||||
|
@@ -10,20 +10,14 @@ open System.Threading
|
|||||||
|
|
||||||
type internal OutputStreamId = | OutputStreamId of Guid
|
type internal OutputStreamId = | OutputStreamId of Guid
|
||||||
|
|
||||||
type private ThreadAwareWriter
|
type private ThreadAwareWriter (local : AsyncLocal<OutputStreamId>, underlying : Dictionary<OutputStreamId, TextWriter>)
|
||||||
(
|
|
||||||
local : AsyncLocal<OutputStreamId>,
|
|
||||||
underlying : Dictionary<OutputStreamId, TextWriter>,
|
|
||||||
mem : Dictionary<OutputStreamId, MemoryStream>
|
|
||||||
)
|
|
||||||
=
|
=
|
||||||
inherit TextWriter ()
|
inherit TextWriter ()
|
||||||
override _.get_Encoding () = Encoding.Default
|
override _.get_Encoding () = Encoding.Default
|
||||||
|
|
||||||
override this.Write (v : char) : unit =
|
override this.Write (v : char) : unit =
|
||||||
use prev = ExecutionContext.Capture ()
|
lock
|
||||||
|
underlying
|
||||||
(fun _ ->
|
|
||||||
(fun () ->
|
(fun () ->
|
||||||
match underlying.TryGetValue local.Value with
|
match underlying.TryGetValue local.Value with
|
||||||
| true, output -> output.Write v
|
| true, output -> output.Write v
|
||||||
@@ -31,16 +25,12 @@ type private ThreadAwareWriter
|
|||||||
let wanted =
|
let wanted =
|
||||||
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
|
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
|
||||||
|
|
||||||
failwith $"no such context: %O{local.Value}\nwanted:\n"
|
failwith $"no such context: %O{local.Value}\nwanted:\n{wanted}"
|
||||||
)
|
)
|
||||||
|> lock underlying
|
|
||||||
)
|
|
||||||
|> fun action -> ExecutionContext.Run (prev, action, ())
|
|
||||||
|
|
||||||
override this.WriteLine (v : string) : unit =
|
override this.WriteLine (v : string) : unit =
|
||||||
use prev = ExecutionContext.Capture ()
|
lock
|
||||||
|
underlying
|
||||||
(fun _ ->
|
|
||||||
(fun () ->
|
(fun () ->
|
||||||
match underlying.TryGetValue local.Value with
|
match underlying.TryGetValue local.Value with
|
||||||
| true, output -> output.WriteLine v
|
| true, output -> output.WriteLine v
|
||||||
@@ -48,15 +38,13 @@ type private ThreadAwareWriter
|
|||||||
let wanted =
|
let wanted =
|
||||||
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
|
underlying |> Seq.map (fun (KeyValue (a, b)) -> $"%O{a}") |> String.concat "\n"
|
||||||
|
|
||||||
failwith $"no such context: %O{local.Value}\nwanted:\n"
|
failwith $"no such context: %O{local.Value}\nwanted:\n{wanted}"
|
||||||
)
|
)
|
||||||
|> lock underlying
|
|
||||||
)
|
|
||||||
|> fun action -> ExecutionContext.Run (prev, action, ())
|
|
||||||
|
|
||||||
/// Wraps up the necessary context to intercept global state.
|
/// Wraps up the necessary context to intercept global state.
|
||||||
|
[<NoEquality ; NoComparison>]
|
||||||
type TestContexts =
|
type TestContexts =
|
||||||
private
|
internal
|
||||||
{
|
{
|
||||||
/// Accesses to this must be locked on StdOutWriters.
|
/// Accesses to this must be locked on StdOutWriters.
|
||||||
StdOuts : Dictionary<OutputStreamId, MemoryStream>
|
StdOuts : Dictionary<OutputStreamId, MemoryStream>
|
||||||
@@ -76,8 +64,8 @@ type TestContexts =
|
|||||||
let stdoutWriters = Dictionary ()
|
let stdoutWriters = Dictionary ()
|
||||||
let stderrWriters = Dictionary ()
|
let stderrWriters = Dictionary ()
|
||||||
let local = AsyncLocal ()
|
let local = AsyncLocal ()
|
||||||
let stdoutWriter = new ThreadAwareWriter (local, stdoutWriters, stdouts)
|
let stdoutWriter = new ThreadAwareWriter (local, stdoutWriters)
|
||||||
let stderrWriter = new ThreadAwareWriter (local, stderrWriters, stderrs)
|
let stderrWriter = new ThreadAwareWriter (local, stderrWriters)
|
||||||
|
|
||||||
{
|
{
|
||||||
StdOuts = stdouts
|
StdOuts = stdouts
|
||||||
|
@@ -164,6 +164,18 @@ module BuildTrxReport =
|
|||||||
| 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)) ->
|
||||||
@@ -188,6 +200,14 @@ module BuildTrxReport =
|
|||||||
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
|
||||||
|
@@ -138,10 +138,17 @@ type TestFixture =
|
|||||||
Tests : SingleTestMethod list
|
Tests : SingleTestMethod list
|
||||||
/// If this fixture has declared a parallelisability, that goes here.
|
/// If this fixture has declared a parallelisability, that goes here.
|
||||||
Parallelize : Parallelizable<ClassParallelScope> option
|
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 (ty : Type) (par : Parallelizable<ClassParallelScope> option) (args : obj list list) =
|
static member Empty
|
||||||
|
(ty : Type)
|
||||||
|
(par : Parallelizable<ClassParallelScope> option)
|
||||||
|
(modifiers : Modifier list)
|
||||||
|
(args : obj list list)
|
||||||
|
=
|
||||||
{
|
{
|
||||||
ContainingAssembly = ty.Assembly
|
ContainingAssembly = ty.Assembly
|
||||||
Type = ty
|
Type = ty
|
||||||
@@ -153,6 +160,7 @@ type TestFixture =
|
|||||||
Parameters = args
|
Parameters = args
|
||||||
Tests = []
|
Tests = []
|
||||||
Parallelize = par
|
Parallelize = par
|
||||||
|
Modifiers = modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// User code in the unit under test has failed somehow.
|
/// User code in the unit under test has failed somehow.
|
||||||
@@ -162,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 () =
|
||||||
@@ -170,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.
|
||||||
|
10
WoofWare.NUnitTestRunner.Lib/Exception.fs
Normal file
10
WoofWare.NUnitTestRunner.Lib/Exception.fs
Normal 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"
|
@@ -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
|
||||||
|
@@ -4,16 +4,16 @@ open System
|
|||||||
open System.Threading
|
open System.Threading
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
|
|
||||||
type private ThunkEvaluator<'ret> =
|
type private AsyncThunkEvaluator<'ret> =
|
||||||
abstract Eval<'a> : (unit -> 'a) -> AsyncReplyChannel<'a> -> 'ret
|
abstract Eval<'a> : (unit -> Async<'a>) -> AsyncReplyChannel<Result<'a, exn>> -> 'ret
|
||||||
|
|
||||||
type private ThunkCrate =
|
type private AsyncThunkCrate =
|
||||||
abstract Apply<'ret> : ThunkEvaluator<'ret> -> 'ret
|
abstract Apply<'ret> : AsyncThunkEvaluator<'ret> -> 'ret
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module private ThunkCrate =
|
module private AsyncThunkCrate =
|
||||||
let make<'a> (t : unit -> 'a) (rc : AsyncReplyChannel<'a>) : ThunkCrate =
|
let make<'a> (t : unit -> Async<'a>) (rc : AsyncReplyChannel<Result<'a, exn>>) : AsyncThunkCrate =
|
||||||
{ new ThunkCrate with
|
{ new AsyncThunkCrate with
|
||||||
member _.Apply e = e.Eval t rc
|
member _.Apply e = e.Eval t rc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,11 @@ type private MailboxMessage =
|
|||||||
| Quit of AsyncReplyChannel<unit>
|
| Quit of AsyncReplyChannel<unit>
|
||||||
/// Check current state, see if we need to start more tests, etc.
|
/// Check current state, see if we need to start more tests, etc.
|
||||||
| Reconcile
|
| Reconcile
|
||||||
| RunTest of within : TestFixture * Parallelizable<unit> option * test : ThunkCrate
|
| RunTestAsync of
|
||||||
|
within : TestFixture *
|
||||||
|
Parallelizable<unit> option *
|
||||||
|
test : AsyncThunkCrate *
|
||||||
|
context : ExecutionContext
|
||||||
| BeginTestFixture of TestFixture * AsyncReplyChannel<TestFixtureRunningToken>
|
| BeginTestFixture of TestFixture * AsyncReplyChannel<TestFixtureRunningToken>
|
||||||
| EndTestFixture of TestFixtureTearDownToken * AsyncReplyChannel<unit>
|
| EndTestFixture of TestFixtureTearDownToken * AsyncReplyChannel<unit>
|
||||||
|
|
||||||
@@ -310,21 +314,31 @@ type ParallelQueue
|
|||||||
rc.Reply ()
|
rc.Reply ()
|
||||||
m.Post MailboxMessage.Reconcile
|
m.Post MailboxMessage.Reconcile
|
||||||
return! processTask (Running state) m
|
return! processTask (Running state) m
|
||||||
| MailboxMessage.RunTest (withinFixture, par, message) ->
|
| MailboxMessage.RunTestAsync (withinFixture, par, message, capturedContext) ->
|
||||||
let t () =
|
let t () =
|
||||||
{ new ThunkEvaluator<_> with
|
{ new AsyncThunkEvaluator<_> with
|
||||||
member _.Eval<'b> (t : unit -> 'b) rc =
|
member _.Eval<'b> (t : unit -> Async<'b>) rc =
|
||||||
let tcs = TaskCompletionSource ()
|
let tcs = TaskCompletionSource TaskCreationOptions.RunContinuationsAsynchronously
|
||||||
use ec = ExecutionContext.Capture ()
|
|
||||||
|
|
||||||
fun () ->
|
fun () ->
|
||||||
ExecutionContext.Run (
|
ExecutionContext.Run (
|
||||||
ec,
|
capturedContext,
|
||||||
(fun _ ->
|
(fun _ ->
|
||||||
let result = t ()
|
async {
|
||||||
tcs.SetResult ()
|
let! result =
|
||||||
m.Post MailboxMessage.Reconcile
|
async {
|
||||||
rc.Reply result
|
try
|
||||||
|
let! r = t ()
|
||||||
|
return Ok r
|
||||||
|
with e ->
|
||||||
|
return Error e
|
||||||
|
}
|
||||||
|
|
||||||
|
tcs.SetResult ()
|
||||||
|
m.Post MailboxMessage.Reconcile
|
||||||
|
rc.Reply result
|
||||||
|
}
|
||||||
|
|> Async.StartImmediate
|
||||||
),
|
),
|
||||||
()
|
()
|
||||||
)
|
)
|
||||||
@@ -348,17 +362,36 @@ type ParallelQueue
|
|||||||
let mb = new MailboxProcessor<_> (processTask MailboxState.Idle)
|
let mb = new MailboxProcessor<_> (processTask MailboxState.Idle)
|
||||||
do mb.Start ()
|
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.
|
/// Request to run the given action, freely in parallel with other running tests.
|
||||||
/// The resulting Task will return when the action has completed.
|
/// The resulting Task will return when the action has completed.
|
||||||
member _.Run<'a>
|
member this.Run<'a>
|
||||||
(TestFixtureSetupToken parent)
|
(parent : TestFixtureSetupToken)
|
||||||
(scope : Parallelizable<unit> option)
|
(scope : Parallelizable<unit> option)
|
||||||
(action : unit -> 'a)
|
(action : unit -> 'a)
|
||||||
: 'a Task
|
: 'a Task
|
||||||
=
|
=
|
||||||
(fun rc -> MailboxMessage.RunTest (parent, scope, ThunkCrate.make action rc))
|
this.RunAsync parent scope (fun () -> async.Return (action ()))
|
||||||
|> mb.PostAndAsyncReply
|
|
||||||
|> Async.StartAsTask
|
|
||||||
|
|
||||||
/// Declare that we wish to start the given test fixture. The resulting Task will return
|
/// 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.
|
/// when you are allowed to start running tests from that fixture.
|
||||||
@@ -379,11 +412,22 @@ type ParallelQueue
|
|||||||
| Parallelizable.Yes _ -> Parallelizable.Yes ()
|
| Parallelizable.Yes _ -> Parallelizable.Yes ()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let ec = ExecutionContext.Capture ()
|
||||||
|
|
||||||
let! response =
|
let! response =
|
||||||
(fun rc -> MailboxMessage.RunTest (parent, par, ThunkCrate.make action rc))
|
(fun rc ->
|
||||||
|
MailboxMessage.RunTestAsync (
|
||||||
|
parent,
|
||||||
|
par,
|
||||||
|
AsyncThunkCrate.make (fun () -> async.Return (action ())) rc,
|
||||||
|
ec
|
||||||
|
)
|
||||||
|
)
|
||||||
|> mb.PostAndAsyncReply
|
|> mb.PostAndAsyncReply
|
||||||
|
|
||||||
return response, TestFixtureSetupToken parent
|
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.
|
/// Run the given one-time tear-down for the test fixture.
|
||||||
@@ -401,11 +445,22 @@ type ParallelQueue
|
|||||||
| Parallelizable.Yes _ -> Parallelizable.Yes ()
|
| Parallelizable.Yes _ -> Parallelizable.Yes ()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let ec = ExecutionContext.Capture ()
|
||||||
|
|
||||||
let! response =
|
let! response =
|
||||||
(fun rc -> MailboxMessage.RunTest (parent, par, ThunkCrate.make action rc))
|
(fun rc ->
|
||||||
|
MailboxMessage.RunTestAsync (
|
||||||
|
parent,
|
||||||
|
par,
|
||||||
|
AsyncThunkCrate.make (fun () -> async.Return (action ())) rc,
|
||||||
|
ec
|
||||||
|
)
|
||||||
|
)
|
||||||
|> mb.PostAndAsyncReply
|
|> mb.PostAndAsyncReply
|
||||||
|
|
||||||
return response, TestFixtureTearDownToken parent
|
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.
|
/// Declare that we have finished submitting requests to run in the given test fixture.
|
||||||
|
@@ -1,16 +1,15 @@
|
|||||||
namespace WoofWare.NUnitTestRunner
|
namespace WoofWare.NUnitTestRunner
|
||||||
|
|
||||||
open System
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
|
||||||
|
|
||||||
[<JsonParse>]
|
// Myriad runs the JsonParse generator on this
|
||||||
type internal FrameworkDescription =
|
type internal FrameworkDescription =
|
||||||
{
|
{
|
||||||
Name : string
|
Name : string
|
||||||
Version : string
|
Version : string
|
||||||
}
|
}
|
||||||
|
|
||||||
[<JsonParse>]
|
// Myriad runs the JsonParse generator on this
|
||||||
type internal RuntimeOptions =
|
type internal RuntimeOptions =
|
||||||
{
|
{
|
||||||
Tfm : string
|
Tfm : string
|
||||||
@@ -21,7 +20,7 @@ type internal RuntimeOptions =
|
|||||||
RollForward : string option
|
RollForward : string option
|
||||||
}
|
}
|
||||||
|
|
||||||
[<JsonParse>]
|
// Myriad runs the JsonParse generator on this
|
||||||
type internal RuntimeConfig =
|
type internal RuntimeConfig =
|
||||||
{
|
{
|
||||||
RuntimeOptions : RuntimeOptions
|
RuntimeOptions : RuntimeOptions
|
||||||
|
@@ -170,8 +170,9 @@ WoofWare.NUnitTestRunner.IndividualTestRunMetadata.StdOut [property]: [read-only
|
|||||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestId [property]: [read-only] System.Guid
|
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestId [property]: [read-only] System.Guid
|
||||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestName [property]: [read-only] string
|
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.TestName [property]: [read-only] string
|
||||||
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.Total [property]: [read-only] System.TimeSpan
|
WoofWare.NUnitTestRunner.IndividualTestRunMetadata.Total [property]: [read-only] System.TimeSpan
|
||||||
WoofWare.NUnitTestRunner.ITestProgress - interface with 5 member(s)
|
WoofWare.NUnitTestRunner.ITestProgress - interface with 6 member(s)
|
||||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestFailed [method]: string -> WoofWare.NUnitTestRunner.TestMemberFailure -> unit
|
WoofWare.NUnitTestRunner.ITestProgress.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.OnTestFixtureStart [method]: string -> int -> unit
|
||||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberFinished [method]: string -> unit
|
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberFinished [method]: string -> unit
|
||||||
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> unit
|
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> unit
|
||||||
@@ -255,6 +256,7 @@ 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..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.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.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.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.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.ParallelQueue.StartTestFixture [method]: WoofWare.NUnitTestRunner.TestFixture -> WoofWare.NUnitTestRunner.TestFixtureRunningToken System.Threading.Tasks.Task
|
||||||
@@ -311,7 +313,7 @@ WoofWare.NUnitTestRunner.SingleTestMethod.Parallelize [property]: [read-only] un
|
|||||||
WoofWare.NUnitTestRunner.SingleTestMethod.Repeat [property]: [read-only] int option
|
WoofWare.NUnitTestRunner.SingleTestMethod.Repeat [property]: [read-only] int option
|
||||||
WoofWare.NUnitTestRunner.SingleTestMethodModule inherit obj
|
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.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 WoofWare.NUnitTestRunner.TestContexts System.IEquatable, System.Collections.IStructuralEquatable, IDisposable
|
WoofWare.NUnitTestRunner.TestContexts inherit obj, implements IDisposable
|
||||||
WoofWare.NUnitTestRunner.TestContexts.Empty [static method]: unit -> WoofWare.NUnitTestRunner.TestContexts
|
WoofWare.NUnitTestRunner.TestContexts.Empty [static method]: unit -> WoofWare.NUnitTestRunner.TestContexts
|
||||||
WoofWare.NUnitTestRunner.TestContexts.get_Stderr [method]: unit -> System.IO.TextWriter
|
WoofWare.NUnitTestRunner.TestContexts.get_Stderr [method]: unit -> System.IO.TextWriter
|
||||||
WoofWare.NUnitTestRunner.TestContexts.get_Stdout [method]: unit -> System.IO.TextWriter
|
WoofWare.NUnitTestRunner.TestContexts.get_Stdout [method]: unit -> System.IO.TextWriter
|
||||||
@@ -346,11 +348,12 @@ WoofWare.NUnitTestRunner.TestFailure.NewTearDownFailed [static method]: WoofWare
|
|||||||
WoofWare.NUnitTestRunner.TestFailure.NewTestFailed [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.TestFailure.Tag [property]: [read-only] int
|
||||||
WoofWare.NUnitTestRunner.TestFixture inherit obj, implements WoofWare.NUnitTestRunner.TestFixture System.IEquatable, System.Collections.IStructuralEquatable
|
WoofWare.NUnitTestRunner.TestFixture inherit obj, implements WoofWare.NUnitTestRunner.TestFixture System.IEquatable, System.Collections.IStructuralEquatable
|
||||||
WoofWare.NUnitTestRunner.TestFixture..ctor [constructor]: (System.Reflection.Assembly, string, System.Type, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, obj list list, WoofWare.NUnitTestRunner.SingleTestMethod list, WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option)
|
WoofWare.NUnitTestRunner.TestFixture..ctor [constructor]: (System.Reflection.Assembly, string, System.Type, System.Reflection.MethodInfo option, System.Reflection.MethodInfo option, System.Reflection.MethodInfo list, System.Reflection.MethodInfo list, obj list list, WoofWare.NUnitTestRunner.SingleTestMethod list, WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option, WoofWare.NUnitTestRunner.Modifier list)
|
||||||
WoofWare.NUnitTestRunner.TestFixture.ContainingAssembly [property]: [read-only] System.Reflection.Assembly
|
WoofWare.NUnitTestRunner.TestFixture.ContainingAssembly [property]: [read-only] System.Reflection.Assembly
|
||||||
WoofWare.NUnitTestRunner.TestFixture.Empty [static method]: System.Type -> WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option -> obj list list -> WoofWare.NUnitTestRunner.TestFixture
|
WoofWare.NUnitTestRunner.TestFixture.Empty [static method]: System.Type -> WoofWare.NUnitTestRunner.ClassParallelScope WoofWare.NUnitTestRunner.Parallelizable option -> WoofWare.NUnitTestRunner.Modifier list -> obj list list -> WoofWare.NUnitTestRunner.TestFixture
|
||||||
WoofWare.NUnitTestRunner.TestFixture.Equals [method]: (WoofWare.NUnitTestRunner.TestFixture, System.Collections.IEqualityComparer) -> bool
|
WoofWare.NUnitTestRunner.TestFixture.Equals [method]: (WoofWare.NUnitTestRunner.TestFixture, System.Collections.IEqualityComparer) -> bool
|
||||||
WoofWare.NUnitTestRunner.TestFixture.get_ContainingAssembly [method]: unit -> System.Reflection.Assembly
|
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_Name [method]: unit -> string
|
||||||
WoofWare.NUnitTestRunner.TestFixture.get_OneTimeSetUp [method]: unit -> System.Reflection.MethodInfo option
|
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_OneTimeTearDown [method]: unit -> System.Reflection.MethodInfo option
|
||||||
@@ -360,6 +363,7 @@ WoofWare.NUnitTestRunner.TestFixture.get_SetUp [method]: unit -> System.Reflecti
|
|||||||
WoofWare.NUnitTestRunner.TestFixture.get_TearDown [method]: unit -> System.Reflection.MethodInfo list
|
WoofWare.NUnitTestRunner.TestFixture.get_TearDown [method]: unit -> System.Reflection.MethodInfo list
|
||||||
WoofWare.NUnitTestRunner.TestFixture.get_Tests [method]: unit -> WoofWare.NUnitTestRunner.SingleTestMethod list
|
WoofWare.NUnitTestRunner.TestFixture.get_Tests [method]: unit -> WoofWare.NUnitTestRunner.SingleTestMethod list
|
||||||
WoofWare.NUnitTestRunner.TestFixture.get_Type [method]: unit -> System.Type
|
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.Name [property]: [read-only] string
|
||||||
WoofWare.NUnitTestRunner.TestFixture.OneTimeSetUp [property]: [read-only] System.Reflection.MethodInfo option
|
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.OneTimeTearDown [property]: [read-only] System.Reflection.MethodInfo option
|
||||||
@@ -703,13 +707,21 @@ WoofWare.NUnitTestRunner.TrxUnitTestResult.TestId [property]: [read-only] System
|
|||||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestListId [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.TestName [property]: [read-only] string
|
||||||
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestType [property]: [read-only] System.Guid
|
WoofWare.NUnitTestRunner.TrxUnitTestResult.TestType [property]: [read-only] System.Guid
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure inherit obj, implements WoofWare.NUnitTestRunner.UserMethodFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
|
WoofWare.NUnitTestRunner.UserMethodFailure 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 inherit WoofWare.NUnitTestRunner.UserMethodFailure
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_name [method]: unit -> string
|
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_name [method]: unit -> string
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_result [method]: unit -> obj
|
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.get_result [method]: unit -> obj
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.name [property]: [read-only] string
|
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.name [property]: [read-only] string
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.result [property]: [read-only] obj
|
WoofWare.NUnitTestRunner.UserMethodFailure+ReturnedNonUnit.result [property]: [read-only] obj
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+Tags inherit 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.ReturnedNonUnit [static field]: int = 0
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+Tags.Threw [static field]: int = 1
|
WoofWare.NUnitTestRunner.UserMethodFailure+Tags.Threw [static field]: int = 1
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw inherit WoofWare.NUnitTestRunner.UserMethodFailure
|
WoofWare.NUnitTestRunner.UserMethodFailure+Threw inherit WoofWare.NUnitTestRunner.UserMethodFailure
|
||||||
@@ -718,13 +730,16 @@ WoofWare.NUnitTestRunner.UserMethodFailure+Threw.get_name [method]: unit -> stri
|
|||||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.Item2 [property]: [read-only] System.Exception
|
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.Item2 [property]: [read-only] System.Exception
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.name [property]: [read-only] string
|
WoofWare.NUnitTestRunner.UserMethodFailure+Threw.name [property]: [read-only] string
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.Equals [method]: (WoofWare.NUnitTestRunner.UserMethodFailure, System.Collections.IEqualityComparer) -> bool
|
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_IsReturnedNonUnit [method]: unit -> bool
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_IsThrew [method]: unit -> bool
|
WoofWare.NUnitTestRunner.UserMethodFailure.get_IsThrew [method]: unit -> bool
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_Name [method]: unit -> string
|
WoofWare.NUnitTestRunner.UserMethodFailure.get_Name [method]: unit -> string
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.get_Tag [method]: unit -> int
|
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.IsReturnedNonUnit [property]: [read-only] bool
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.IsThrew [property]: [read-only] bool
|
WoofWare.NUnitTestRunner.UserMethodFailure.IsThrew [property]: [read-only] bool
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.Name [property]: [read-only] string
|
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.NewReturnedNonUnit [static method]: (string, obj) -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.NewThrew [static method]: (string, System.Exception) -> WoofWare.NUnitTestRunner.UserMethodFailure
|
WoofWare.NUnitTestRunner.UserMethodFailure.NewThrew [static method]: (string, System.Exception) -> WoofWare.NUnitTestRunner.UserMethodFailure
|
||||||
WoofWare.NUnitTestRunner.UserMethodFailure.Tag [property]: [read-only] int
|
WoofWare.NUnitTestRunner.UserMethodFailure.Tag [property]: [read-only] int
|
@@ -76,98 +76,168 @@ module TestFixture =
|
|||||||
(test : MethodInfo)
|
(test : MethodInfo)
|
||||||
(containingObject : obj)
|
(containingObject : obj)
|
||||||
(args : obj[])
|
(args : obj[])
|
||||||
: Result<TestMemberSuccess, TestFailure list> * IndividualTestRunMetadata
|
: Async<Result<TestMemberSuccess, TestFailure list> * IndividualTestRunMetadata>
|
||||||
=
|
=
|
||||||
let rec runMethods
|
let rec runMethods
|
||||||
(wrap : UserMethodFailure -> TestFailure)
|
(wrap : UserMethodFailure -> TestFailure)
|
||||||
(toRun : MethodInfo list)
|
(toRun : MethodInfo list)
|
||||||
(args : obj[])
|
(args : obj[])
|
||||||
: Result<unit, _>
|
: Result<unit, TestFailure> Async
|
||||||
=
|
=
|
||||||
match toRun with
|
match toRun with
|
||||||
| [] -> Ok ()
|
| [] -> async.Return (Ok ())
|
||||||
| head :: rest ->
|
| head :: rest ->
|
||||||
let result =
|
async {
|
||||||
try
|
let result =
|
||||||
head.Invoke (containingObject, args) |> Ok
|
try
|
||||||
with :? TargetInvocationException as e ->
|
head.Invoke (containingObject, args) |> Ok
|
||||||
Error (UserMethodFailure.Threw (head.Name, e.InnerException))
|
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
|
||||||
|
|
||||||
match result with
|
let! ct = Async.CancellationToken
|
||||||
| 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
|
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
|
||||||
|
|
||||||
let sw = Stopwatch.StartNew ()
|
try
|
||||||
|
do! Async.AwaitTask result
|
||||||
|
with e ->
|
||||||
|
exc <- Some e
|
||||||
|
|
||||||
let metadata () =
|
match exc with
|
||||||
let name =
|
| None -> return! runMethods wrap rest args
|
||||||
if args.Length = 0 then
|
| Some e -> return Error (UserMethodFailure.Threw (head.Name, e) |> wrap)
|
||||||
test.Name
|
}
|
||||||
else
|
// We'd like to do this type-test:
|
||||||
let argsStr = args |> Seq.map string<obj> |> String.concat ","
|
// | :? Async<unit> as result ->
|
||||||
$"%s{test.Name}(%s{argsStr})"
|
// 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
|
||||||
End = DateTimeOffset.Now
|
match ty.GenericTypeArguments |> Array.map (fun t -> t.FullName) with
|
||||||
Start = start
|
| [| "Microsoft.FSharp.Core.Unit" |] ->
|
||||||
Total = sw.Elapsed
|
let asyncModule = ty.Assembly.GetType ("Microsoft.FSharp.Control.FSharpAsync")
|
||||||
ComputerName = Environment.MachineName
|
// let catch = asyncModule.GetMethod("Catch").MakeGenericMethod [| ty.GenericTypeArguments.[0] |]
|
||||||
ExecutionId = Guid.NewGuid ()
|
// let caught = catch.Invoke ((null: obj), [| ret |])
|
||||||
TestId = testId
|
let startAsTask =
|
||||||
TestName = name
|
asyncModule.GetMethod("StartAsTask").MakeGenericMethod
|
||||||
ClassName = test.DeclaringType.FullName
|
[| ty.GenericTypeArguments.[0] |]
|
||||||
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 [||]
|
let started =
|
||||||
sw.Stop ()
|
startAsTask.Invoke ((null : obj), [| ret ; (null : obj) ; (null : obj) |])
|
||||||
|
|> unbox<Task>
|
||||||
|
|
||||||
match setUpResult with
|
async {
|
||||||
| Error e -> Error [ e ], metadata ()
|
let! res = Async.AwaitTask started |> Async.Catch
|
||||||
| Ok () ->
|
|
||||||
|
|
||||||
sw.Start ()
|
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)
|
||||||
|
|
||||||
let result =
|
return result
|
||||||
let result = runMethods TestFailure.TestFailed [ test ] args
|
}
|
||||||
|
|
||||||
|
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 ()
|
sw.Stop ()
|
||||||
|
|
||||||
match result with
|
match setUpResult with
|
||||||
| Ok () -> Ok None
|
| Error e -> return Error [ e ], metadata ()
|
||||||
| Error (TestFailure.TestFailed (UserMethodFailure.Threw (_, exc)) as orig) ->
|
| Ok () ->
|
||||||
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 ()
|
||||||
sw.Start ()
|
let! result = runMethods TestFailure.TestFailed [ test ] args
|
||||||
let tearDownResult = runMethods TestFailure.TearDownFailed tearDown [||]
|
sw.Stop ()
|
||||||
sw.Stop ()
|
|
||||||
|
|
||||||
let metadata = metadata ()
|
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
|
||||||
|
|
||||||
match result, tearDownResult with
|
// Unconditionally run TearDown after tests, even if tests failed.
|
||||||
| Ok None, Ok () -> Ok TestMemberSuccess.Ok, metadata
|
sw.Start ()
|
||||||
| Ok (Some s), Ok () -> Ok s, metadata
|
let! tearDownResult = runMethods TestFailure.TearDownFailed tearDown [||]
|
||||||
| Error e, Ok ()
|
sw.Stop ()
|
||||||
| Ok _, Error e -> Error [ e ], metadata
|
|
||||||
| Error e1, Error e2 -> Error [ e1 ; e2 ], metadata
|
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 private getValues (test : SingleTestMethod) =
|
||||||
let valuesAttrs =
|
let valuesAttrs =
|
||||||
@@ -388,20 +458,22 @@ module TestFixture =
|
|||||||
|> Seq.map (fun (testGuid, args) ->
|
|> Seq.map (fun (testGuid, args) ->
|
||||||
task {
|
task {
|
||||||
let runMe () =
|
let runMe () =
|
||||||
progress.OnTestMemberStart test.Name
|
async {
|
||||||
let oldValue = contexts.AsyncLocal.Value
|
progress.OnTestMemberStart test.Name
|
||||||
let outputId = contexts.NewOutputs ()
|
let oldValue = contexts.AsyncLocal.Value
|
||||||
contexts.AsyncLocal.Value <- outputId
|
let outputId = contexts.NewOutputs ()
|
||||||
|
contexts.AsyncLocal.Value <- outputId
|
||||||
|
|
||||||
let result, meta =
|
let! result, meta =
|
||||||
runOne outputId contexts setUp tearDown testGuid test.Method containingObject args
|
runOne outputId contexts setUp tearDown testGuid test.Method containingObject args
|
||||||
|
|
||||||
contexts.AsyncLocal.Value <- oldValue
|
contexts.AsyncLocal.Value <- oldValue
|
||||||
progress.OnTestMemberFinished test.Name
|
progress.OnTestMemberFinished test.Name
|
||||||
|
|
||||||
result, meta
|
return result, meta
|
||||||
|
}
|
||||||
|
|
||||||
let! results, summary = par.Run running test.Parallelize runMe
|
let! results, summary = par.RunAsync running test.Parallelize runMe
|
||||||
|
|
||||||
match results with
|
match results with
|
||||||
| Ok results -> return Ok results, summary
|
| Ok results -> return Ok results, summary
|
||||||
@@ -590,15 +662,15 @@ module TestFixture =
|
|||||||
/// Interpret this type as a [<TestFixture>], extracting the test members from it and annotating them with all
|
/// 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.
|
/// relevant information about how we should run them.
|
||||||
let parse (parentType : Type) : TestFixture =
|
let parse (parentType : Type) : TestFixture =
|
||||||
let categories, args, par =
|
let categories, args, mods, par =
|
||||||
(([], [], None), parentType.CustomAttributes)
|
(([], [], [], None), parentType.CustomAttributes)
|
||||||
||> Seq.fold (fun (categories, args, par) attr ->
|
||> Seq.fold (fun (categories, args, mods, par) attr ->
|
||||||
match attr.AttributeType.FullName with
|
match attr.AttributeType.FullName with
|
||||||
| "NUnit.Framework.SetUpFixtureAttribute" ->
|
| "NUnit.Framework.SetUpFixtureAttribute" ->
|
||||||
failwith "This test runner does not support SetUpFixture. Please shout if you want this."
|
failwith "This test runner does not support SetUpFixture. Please shout if you want this."
|
||||||
| "NUnit.Framework.CategoryAttribute" ->
|
| "NUnit.Framework.CategoryAttribute" ->
|
||||||
let cat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
|
let cat = attr.ConstructorArguments |> Seq.exactlyOne |> _.Value |> unbox<string>
|
||||||
cat :: categories, args, par
|
cat :: categories, args, mods, par
|
||||||
| "NUnit.Framework.TestFixtureAttribute" ->
|
| "NUnit.Framework.TestFixtureAttribute" ->
|
||||||
let newArgs =
|
let newArgs =
|
||||||
match attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList with
|
match attr.ConstructorArguments |> Seq.map _.Value |> Seq.toList with
|
||||||
@@ -606,38 +678,52 @@ module TestFixture =
|
|||||||
x |> Seq.cast<CustomAttributeTypedArgument> |> Seq.map _.Value |> Seq.toList
|
x |> Seq.cast<CustomAttributeTypedArgument> |> Seq.map _.Value |> Seq.toList
|
||||||
| xs -> xs
|
| xs -> xs
|
||||||
|
|
||||||
categories, newArgs :: args, par
|
categories, newArgs :: args, mods, par
|
||||||
| "NUnit.Framework.NonParallelizableAttribute" ->
|
| "NUnit.Framework.NonParallelizableAttribute" ->
|
||||||
match par with
|
match par with
|
||||||
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
|
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
|
||||||
| None -> categories, args, Some Parallelizable.No
|
| None -> categories, args, mods, Some Parallelizable.No
|
||||||
| "NUnit.Framework.ParallelizableAttribute" ->
|
| "NUnit.Framework.ParallelizableAttribute" ->
|
||||||
match par with
|
match par with
|
||||||
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
|
| Some _ -> failwith $"Got multiple parallelism attributes on %s{parentType.FullName}"
|
||||||
| None ->
|
| None ->
|
||||||
match attr.ConstructorArguments |> Seq.toList with
|
match attr.ConstructorArguments |> Seq.toList with
|
||||||
| [] -> categories, args, Some (Parallelizable.Yes ClassParallelScope.Self)
|
| [] -> categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Self)
|
||||||
| [ v ] ->
|
| [ v ] ->
|
||||||
match v.Value with
|
match v.Value with
|
||||||
| :? int as v ->
|
| :? int as v ->
|
||||||
match ParallelScope.ofInt v with
|
match ParallelScope.ofInt v with
|
||||||
| ParallelScope.Fixtures ->
|
| ParallelScope.Fixtures ->
|
||||||
categories, args, Some (Parallelizable.Yes ClassParallelScope.Fixtures)
|
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Fixtures)
|
||||||
| ParallelScope.Children ->
|
| ParallelScope.Children ->
|
||||||
categories, args, Some (Parallelizable.Yes ClassParallelScope.Children)
|
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Children)
|
||||||
| ParallelScope.All ->
|
| ParallelScope.All ->
|
||||||
categories, args, Some (Parallelizable.Yes ClassParallelScope.All)
|
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.All)
|
||||||
| ParallelScope.Self ->
|
| ParallelScope.Self ->
|
||||||
categories, args, Some (Parallelizable.Yes ClassParallelScope.Self)
|
categories, args, mods, Some (Parallelizable.Yes ClassParallelScope.Self)
|
||||||
| ParallelScope.None -> categories, args, Some Parallelizable.No
|
| ParallelScope.None -> categories, args, mods, Some Parallelizable.No
|
||||||
| v ->
|
| v ->
|
||||||
failwith
|
failwith
|
||||||
$"Unexpectedly non-int value %O{v} of parallel scope in %s{parentType.FullName}"
|
$"Unexpectedly non-int value %O{v} of parallel scope in %s{parentType.FullName}"
|
||||||
| _ -> failwith $"unexpectedly got multiple args to Parallelizable on %s{parentType.FullName}"
|
| _ -> failwith $"unexpectedly got multiple args to Parallelizable on %s{parentType.FullName}"
|
||||||
| _ -> categories, args, par
|
| "NUnit.Framework.ExplicitAttribute" ->
|
||||||
|
let reason =
|
||||||
|
attr.ConstructorArguments
|
||||||
|
|> Seq.tryHead
|
||||||
|
|> Option.map (_.Value >> unbox<string>)
|
||||||
|
|
||||||
|
categories, args, Modifier.Explicit reason :: mods, par
|
||||||
|
| "NUnit.Framework.IgnoreAttribute" ->
|
||||||
|
let reason =
|
||||||
|
attr.ConstructorArguments
|
||||||
|
|> Seq.tryHead
|
||||||
|
|> Option.map (_.Value >> unbox<string>)
|
||||||
|
|
||||||
|
categories, args, Modifier.Ignored reason :: mods, par
|
||||||
|
| _ -> categories, args, mods, par
|
||||||
)
|
)
|
||||||
|
|
||||||
(TestFixture.Empty parentType par args, parentType.GetRuntimeMethods ())
|
(TestFixture.Empty parentType par mods args, parentType.GetRuntimeMethods ())
|
||||||
||> Seq.fold (fun state mi ->
|
||> Seq.fold (fun state mi ->
|
||||||
((state, []), mi.CustomAttributes)
|
((state, []), mi.CustomAttributes)
|
||||||
||> Seq.fold (fun (state, unrecognisedAttrs) attr ->
|
||> Seq.fold (fun (state, unrecognisedAttrs) attr ->
|
||||||
@@ -710,6 +796,8 @@ module TestFixture =
|
|||||||
|
|
||||||
/// Run every test (except those which fail the `filter`) in this test fixture, as well as the
|
/// Run every test (except those which fail the `filter`) in this test fixture, as well as the
|
||||||
/// appropriate setup and tear-down logic.
|
/// 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
|
let run
|
||||||
(contexts : TestContexts)
|
(contexts : TestContexts)
|
||||||
(par : ParallelQueue)
|
(par : ParallelQueue)
|
||||||
@@ -718,6 +806,26 @@ module TestFixture =
|
|||||||
(tests : TestFixture)
|
(tests : TestFixture)
|
||||||
: FixtureRunResults list Task
|
: 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
|
match tests.Parameters with
|
||||||
| [] -> [ null ]
|
| [] -> [ null ]
|
||||||
| args -> args |> List.map List.toArray
|
| args -> args |> List.map List.toArray
|
||||||
|
@@ -10,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
|
||||||
@@ -32,6 +34,9 @@ module TestProgress =
|
|||||||
let plural = if testCount = 1 then "" else "s"
|
let plural = if testCount = 1 then "" else "s"
|
||||||
writer.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 =
|
||||||
writer.WriteLine $"Running test: %s{name}"
|
writer.WriteLine $"Running test: %s{name}"
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
|
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<WarnOn>FS3559</WarnOn>
|
<WarnOn>FS3559</WarnOn>
|
||||||
<WoofWareMyriadPluginVersion>4.0.6</WoofWareMyriadPluginVersion>
|
<WoofWareMyriadPluginVersion>8.1.1</WoofWareMyriadPluginVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -22,10 +22,16 @@
|
|||||||
<Compile Include="RuntimeConfig.fs" />
|
<Compile Include="RuntimeConfig.fs" />
|
||||||
<Compile Include="GeneratedRuntimeConfig.fs">
|
<Compile Include="GeneratedRuntimeConfig.fs">
|
||||||
<MyriadFile>RuntimeConfig.fs</MyriadFile>
|
<MyriadFile>RuntimeConfig.fs</MyriadFile>
|
||||||
|
<MyriadParams>
|
||||||
|
<RuntimeOptions>JsonParse</RuntimeOptions>
|
||||||
|
<RuntimeConfig>JsonParse</RuntimeConfig>
|
||||||
|
<FrameworkDescription>JsonParse</FrameworkDescription>
|
||||||
|
</MyriadParams>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ParallelScope.fs" />
|
<Compile Include="ParallelScope.fs" />
|
||||||
<Compile Include="DotnetRuntime.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" />
|
||||||
@@ -48,10 +54,9 @@
|
|||||||
<EmbeddedResource Include="version.json" />
|
<EmbeddedResource Include="version.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="WoofWare.PrattParser" Version="0.2.2" />
|
<PackageReference Include="WoofWare.PrattParser" Version="0.2.4" />
|
||||||
<PackageReference Update="FSharp.Core" Version="6.0.1" />
|
<PackageReference Update="FSharp.Core" Version="6.0.1" />
|
||||||
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.1.9" />
|
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.1.12" />
|
||||||
<PackageReference Include="WoofWare.Myriad.Plugins.Attributes" Version="3.6.4" />
|
|
||||||
<PackageReference Include="Myriad.SDK" Version="0.8.3" PrivateAssets="all" />
|
<PackageReference Include="Myriad.SDK" Version="0.8.3" PrivateAssets="all" />
|
||||||
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
|
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.18",
|
"version": "0.22",
|
||||||
"publicReleaseRefSpec": [
|
"publicReleaseRefSpec": [
|
||||||
"^refs/heads/main$"
|
"^refs/heads/main$"
|
||||||
],
|
],
|
||||||
|
@@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.St
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHookLogic", "WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj", "{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHookLogic", "WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj", "{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FailingConsumer", "FailingConsumer\FailingConsumer.fsproj", "{DA7160F5-4C3C-4D2E-918B-7DCBA3F4272E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -42,5 +44,9 @@ Global
|
|||||||
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@@ -13,6 +13,10 @@ module Progress =
|
|||||||
member _.OnTestFixtureStart name testCount =
|
member _.OnTestFixtureStart name testCount =
|
||||||
console.MarkupLine $"[white]Running tests: %s{Markup.Escape name}[/]"
|
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 =
|
member _.OnTestMemberFinished name =
|
||||||
console.MarkupLine $"[gray]Finished test: %s{Markup.Escape name}[/]"
|
console.MarkupLine $"[gray]Finished test: %s{Markup.Escape name}[/]"
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
}
|
@@ -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,17 +11,18 @@
|
|||||||
<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.1.8" />
|
<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.1" />
|
<PackageReference Include="FsUnit" Version="7.1.1" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||||
<PackageReference Include="NUnit" Version="4.2.2" />
|
<PackageReference Include="NUnit" Version="4.3.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<RollForward>Major</RollForward>
|
<RollForward>Major</RollForward>
|
||||||
<PackAsTool>true</PackAsTool>
|
<PackAsTool>true</PackAsTool>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Spectre.Console" Version="0.49.1" />
|
<PackageReference Include="Spectre.Console" Version="0.51.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2",
|
"version": "0.3",
|
||||||
"publicReleaseRefSpec": [
|
"publicReleaseRefSpec": [
|
||||||
"^refs/heads/main$"
|
"^refs/heads/main$"
|
||||||
],
|
],
|
||||||
|
@@ -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.11.0]" />
|
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.17.0]" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -5,11 +5,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1726560853,
|
"lastModified": 1731533236,
|
||||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729850857,
|
"lastModified": 1758262103,
|
||||||
"narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=",
|
"narHash": "sha256-aBGl3XEOsjWw6W3AHiKibN7FeoG73dutQQEqnd/etR8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "41dea55321e5a999b17033296ac05fe8a8b5a257",
|
"rev": "12bd230118a1901a4a5d393f9f56b6ad7e571d01",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
22
flake.nix
22
flake.nix
@@ -14,8 +14,8 @@
|
|||||||
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: hash:
|
dotnetTool = dllOverride: toolName: toolVersion: hash:
|
||||||
pkgs.stdenvNoCC.mkDerivation rec {
|
pkgs.stdenvNoCC.mkDerivation rec {
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
pname = name;
|
pname = name;
|
||||||
version = version;
|
version = version;
|
||||||
hash = hash;
|
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,9 +42,11 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
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;}))).hash;
|
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;}))).hash;
|
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";
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
projectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.fsproj";
|
projectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.fsproj";
|
||||||
testProjectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.Test/WoofWare.NUnitTestRunner.Test.fsproj";
|
testProjectFile = "./WoofWare.NUnitTestRunner/WoofWare.NUnitTestRunner.Test/WoofWare.NUnitTestRunner.Test.fsproj";
|
||||||
disabledTests = ["WoofWare.NUnitTestRunner.Test.TestSurface.EnsureVersionIsMonotonic"];
|
disabledTests = ["WoofWare.NUnitTestRunner.Test.TestSurface.EnsureVersionIsMonotonic"];
|
||||||
nugetDeps = ./nix/deps.nix; # `nix build .#default.passthru.fetch-deps && ./result nix/deps.nix`
|
nugetDeps = ./nix/deps.json; # `nix build .#default.fetch-deps && ./result nix/deps.json`
|
||||||
doCheck = true;
|
doCheck = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -63,11 +65,7 @@
|
|||||||
pkgs.alejandra
|
pkgs.alejandra
|
||||||
pkgs.nodePackages.markdown-link-check
|
pkgs.nodePackages.markdown-link-check
|
||||||
pkgs.shellcheck
|
pkgs.shellcheck
|
||||||
];
|
pkgs.xmlstarlet
|
||||||
};
|
|
||||||
net6 = pkgs.mkShell {
|
|
||||||
packages = [
|
|
||||||
pkgs.dotnetCorePackages.runtime_6_0
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
367
nix/deps.json
Normal file
367
nix/deps.json
Normal 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="
|
||||||
|
}
|
||||||
|
]
|
344
nix/deps.nix
344
nix/deps.nix
@@ -1,344 +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.1.8";
|
|
||||||
hash = "sha256-iU5v4SW2lNTMYN4uVj++nxbojgDsTCSQsowqGl75wXc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "fantomas";
|
|
||||||
version = "6.3.15";
|
|
||||||
hash = "sha256-Gjw7MxjUNckMWSfnOye4UTe5fZWnor6RHCls3PNsuG8=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Fantomas.Core";
|
|
||||||
version = "6.1.1";
|
|
||||||
hash = "sha256-FcTLHQFvKkQY/kV08jhhy/St/+FmXpp3epp/R3zUXMA=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Fantomas.FCS";
|
|
||||||
version = "6.1.1";
|
|
||||||
hash = "sha256-NuZ8msPEHYA8T3EYREB28F1RcNgUU8V54eg2+UttYxw=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "FsCheck";
|
|
||||||
version = "3.0.0-rc3";
|
|
||||||
hash = "sha256-4Z9Qv+vccrXWh2Fjdwdmjc1YgW+Dcx73ESkdAnHqxOY=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "fsharp-analyzers";
|
|
||||||
version = "0.27.0";
|
|
||||||
hash = "sha256-QhLi2veTY1wZlQKJLTyVPgx/ImkaZugQNjSN5VJCNEA=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "FSharp.Core";
|
|
||||||
version = "6.0.1";
|
|
||||||
hash = "sha256-Ehsgt3nCJijpaVuJguC1TPVEKSkJd6PSc07D2ZQSemI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "FSharp.Core";
|
|
||||||
version = "8.0.401";
|
|
||||||
hash = "sha256-+tp7/Ssr5lb55ZBTOjTuuH0rLCGfhe5Yjq4jvU5KML0=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "FsUnit";
|
|
||||||
version = "6.0.1";
|
|
||||||
hash = "sha256-vka/aAgWhDCl5tu+kgO7GtSaHOOvlSaWxG+tExwGXpI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.AspNetCore.App.Ref";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-BxvIeZIaBdC0wyDQqKW0E5axSRSrtQk3oEPsT287014=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.AspNetCore.App.Runtime.linux-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-jM/HzLumZvI939DrNb8LHnEr/in1Lws0j/FAfdXSzbk=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.AspNetCore.App.Runtime.linux-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-2eUqoTcqTU3ebv53IV6yvN9EhkOqnyBRd2tz74HuSsE=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.AspNetCore.App.Runtime.osx-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-6mY2uBhvKCpEFJLYX9+f1mpYrWdN69i+14DPjO4U8eo=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.AspNetCore.App.Runtime.osx-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-ljEkMgkgfEeqzRnmTubjSK2dzkph0cSQ7+2J986F7HI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.CodeCoverage";
|
|
||||||
version = "17.11.1";
|
|
||||||
hash = "sha256-1dLlK3NGh88PuFYZiYpT+izA96etxhU3BSgixDgdtGA=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NET.Test.Sdk";
|
|
||||||
version = "17.11.1";
|
|
||||||
hash = "sha256-0JUEucQ2lzaPgkrjm/NFLBTbqU1dfhvhN3Tl3moE6mI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Host.linux-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-yrtPCYD8skaWnfIoaUdQ1dns0YrypxDocskS2WGxF6g=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Host.linux-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-maNzxJQ5oCd86VI4ROzl4RqOV1RNXn3qWjrAfBjr2Y0=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Host.osx-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-cBcfv7tnZa2xO5T5VOx3/7EvJ5u4/C4dFnV1Jj6VFPU=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Host.osx-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-05wMp5+etiV/vgktqGo8+4XB7FNYxwCUKpJsW48tgvQ=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Ref";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-IcpSbsSHgYBbNVvbcXfmRRM9bdx3pogLncO4RuXEab0=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Runtime.linux-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-jPUhSrzqnH1GNi/c7dSnZSQhFNVGdmlAQkDLdXVWBBc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Runtime.linux-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-Gf3e0EdBEgq8GcZttTHbKGupFlDyB80nhYpBN0X9Kro=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Runtime.osx-arm64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-IGArFhlq3UzZY93lJ+WrB+zmuu/2o8lVwT7MJKpz6DE=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.App.Runtime.osx-x64";
|
|
||||||
version = "6.0.35";
|
|
||||||
hash = "sha256-EtFBg8yBNhAEQlL97oVGiu05rPMSKLd0wE44zTBT7FI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.Platforms";
|
|
||||||
version = "1.1.1";
|
|
||||||
hash = "sha256-8hLiUKvy/YirCWlFwzdejD2Db3DaXhHxT7GSZx/znJg=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.Platforms";
|
|
||||||
version = "2.0.0";
|
|
||||||
hash = "sha256-IEvBk6wUXSdyCnkj6tHahOJv290tVVT8tyemYcR0Yro=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.NETCore.Targets";
|
|
||||||
version = "1.1.3";
|
|
||||||
hash = "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.TestPlatform.ObjectModel";
|
|
||||||
version = "17.11.1";
|
|
||||||
hash = "sha256-5vX+vCzFY3S7xfMVIv8OlMMFtdedW9UIJzc0WEc+vm4=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Microsoft.TestPlatform.TestHost";
|
|
||||||
version = "17.11.1";
|
|
||||||
hash = "sha256-wSkY0H1fQAq0H3LcKT4u7Y5RzhAAPa6yueVN84g8HxU=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Myriad.Core";
|
|
||||||
version = "0.8.3";
|
|
||||||
hash = "sha256-vBOxfq8QriX/yUtaXN69rEQaY/psRNJWxqATLidrt2g=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Myriad.Sdk";
|
|
||||||
version = "0.8.3";
|
|
||||||
hash = "sha256-7O397WKhskKOvE3MkJT37BvxorDWngDR6gTUogtDZ2M=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Nerdbank.GitVersioning";
|
|
||||||
version = "3.6.146";
|
|
||||||
hash = "sha256-6lpjiwxVrwjNUhPQ6C7LzazKdBQlAbmyEQk/qxrmr8Y=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Newtonsoft.Json";
|
|
||||||
version = "13.0.1";
|
|
||||||
hash = "sha256-K2tSVW4n4beRPzPu3rlVaBEMdGvWSv/3Q1fxaDh4Mjo=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Newtonsoft.Json";
|
|
||||||
version = "13.0.3";
|
|
||||||
hash = "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Common";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-UyZtDyTuymC+sKSX+ripOI6MmJZn11loVapVs4uzaGo=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Configuration";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-JH2UCpjYg8pkqxQ4j4BrWiTKhGzgfn55NMr32wf6+FQ=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Frameworks";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-p25Oa7wJjwF+2puIhBkZZkKSuk4jGq7xikYSCdfp9Vc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Packaging";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-1yY3p5hQwbUgYCyHnBcuGWiiIib1ppPYt2ntxwXSJW0=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Protocol";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-/zFvBV83Q5oMNu68BjmrHtZMAxf/YkDJV8HSsl5GjsY=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NuGet.Versioning";
|
|
||||||
version = "6.11.1";
|
|
||||||
hash = "sha256-fl8lyChMjV7Sp8keAP7CdXZh7ARN/mU39T3gG74jDWY=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NUnit";
|
|
||||||
version = "4.2.2";
|
|
||||||
hash = "sha256-+0OS67ITalmG9arYCgQF/+YbmPRnB3pIIykew0kvoCc=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "NUnit3TestAdapter";
|
|
||||||
version = "4.6.0";
|
|
||||||
hash = "sha256-9Yav2fYhC4w0OgsyUwU4/5rDy4FVDTpKnWHuwl/uKJQ=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "runtime.any.System.Runtime";
|
|
||||||
version = "4.3.0";
|
|
||||||
hash = "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "runtime.native.System";
|
|
||||||
version = "4.3.0";
|
|
||||||
hash = "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "runtime.unix.System.Private.Uri";
|
|
||||||
version = "4.3.0";
|
|
||||||
hash = "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "Spectre.Console";
|
|
||||||
version = "0.49.1";
|
|
||||||
hash = "sha256-tqSVojyuQjuB34lXo759NOcyLgNIw815mKXJPq5JFDo=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Diagnostics.DiagnosticSource";
|
|
||||||
version = "7.0.0";
|
|
||||||
hash = "sha256-9Wk8cHSkjKtqkN6xW7KnXoQVtF/VNbKeBq79WqDesMs=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Formats.Asn1";
|
|
||||||
version = "6.0.0";
|
|
||||||
hash = "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.IO.Abstractions";
|
|
||||||
version = "4.2.13";
|
|
||||||
hash = "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.IO.FileSystem.AccessControl";
|
|
||||||
version = "4.5.0";
|
|
||||||
hash = "sha256-ck44YBQ0M+2Im5dw0VjBgFD1s0XuY54cujrodjjSBL8=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Memory";
|
|
||||||
version = "4.5.5";
|
|
||||||
hash = "sha256-EPQ9o1Kin7KzGI5O3U3PUQAZTItSbk9h/i4rViN3WiI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Private.Uri";
|
|
||||||
version = "4.3.0";
|
|
||||||
hash = "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Reflection.Metadata";
|
|
||||||
version = "1.6.0";
|
|
||||||
hash = "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Runtime";
|
|
||||||
version = "4.3.1";
|
|
||||||
hash = "sha256-R9T68AzS1PJJ7v6ARz9vo88pKL1dWqLOANg4pkQjkA0=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Runtime.CompilerServices.Unsafe";
|
|
||||||
version = "6.0.0";
|
|
||||||
hash = "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Security.AccessControl";
|
|
||||||
version = "4.5.0";
|
|
||||||
hash = "sha256-AFsKPb/nTk2/mqH/PYpaoI8PLsiKKimaXf+7Mb5VfPM=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Security.Cryptography.Pkcs";
|
|
||||||
version = "6.0.4";
|
|
||||||
hash = "sha256-2e0aRybote+OR66bHaNiYpF//4fCiaO3zbR2e9GABUI=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Security.Cryptography.ProtectedData";
|
|
||||||
version = "4.4.0";
|
|
||||||
hash = "sha256-Ri53QmFX8I8UH0x4PikQ1ZA07ZSnBUXStd5rBfGWFOE=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Security.Principal.Windows";
|
|
||||||
version = "4.5.0";
|
|
||||||
hash = "sha256-BkUYNguz0e4NJp1kkW7aJBn3dyH9STwB5N8XqnlCsmY=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Text.Encodings.Web";
|
|
||||||
version = "7.0.0";
|
|
||||||
hash = "sha256-tF8qt9GZh/nPy0mEnj6nKLG4Lldpoi/D8xM5lv2CoYQ=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "System.Text.Json";
|
|
||||||
version = "7.0.3";
|
|
||||||
hash = "sha256-aSJZ17MjqaZNQkprfxm/09LaCoFtpdWmqU9BTROzWX4=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "TypeEquality";
|
|
||||||
version = "0.3.0";
|
|
||||||
hash = "sha256-V50xAOzzyUJrY+MYPRxtnqW5MVeATXCes89wPprv1r4=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "WoofWare.DotnetRuntimeLocator";
|
|
||||||
version = "0.1.9";
|
|
||||||
hash = "sha256-0v8JQgGjS3tseA28OFmYZUcinYRArjs28BwVy3oczJM=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "WoofWare.Myriad.Plugins";
|
|
||||||
version = "4.0.6";
|
|
||||||
hash = "sha256-b0Uh512YyhYQDZ3DS6DhHLf+6pToTi+ga7mZISAucwY=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "WoofWare.Myriad.Plugins.Attributes";
|
|
||||||
version = "3.6.4";
|
|
||||||
hash = "sha256-fNWldUSkIxq5Y9nqIRSrEE8R+/pUcX1Ji/wkomATg+4=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "WoofWare.PrattParser";
|
|
||||||
version = "0.2.2";
|
|
||||||
hash = "sha256-OCsHlp/HYB/i1+h0ixq+0zxO1bXFQ6kpEWIONkOr+TE=";
|
|
||||||
})
|
|
||||||
(fetchNuGet {
|
|
||||||
pname = "WoofWare.Whippet.Fantomas";
|
|
||||||
version = "0.3.1";
|
|
||||||
hash = "sha256-i5oiqcrxzM90Ocuq5MIu2Ha5lV0aYu5nCvuwmFqp6NA=";
|
|
||||||
})
|
|
||||||
]
|
|
Reference in New Issue
Block a user