mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-13 01:28:40 +00:00
Switch to Expecto (#89)
This commit is contained in:
14
CLAUDE.md
14
CLAUDE.md
@@ -42,8 +42,13 @@ dotnet fantomas .
|
||||
```
|
||||
|
||||
### Running the Application
|
||||
A playground C# file is in CSharpExample/Class1.cs.
|
||||
This environment is convenient for running WoofWare.PawPrint against a standalone DLL.
|
||||
Interpolate the approprate strings like `{Platform}` as necessary depending on the current environment and the output of the `dotnet publish`.
|
||||
|
||||
```bash
|
||||
dotnet publish --self-contained --runtime-id osx-arm64 CSharpExample/ && dotnet run --project WoofWare.PawPrint.App/WoofWare.PawPrint.App.fsproj -- CSharpExample/bin/Debug/net9.0/osx-arm64/publish/CSharpExample.dll
|
||||
dotnet publish --self-contained --runtime {Platform} CSharpExample/
|
||||
dotnet run --project WoofWare.PawPrint.App/WoofWare.PawPrint.App.fsproj -- CSharpExample/bin/{Configuration}/{Framework}/{Platform}/publish/CSharpExample.dll
|
||||
```
|
||||
|
||||
## Architecture
|
||||
@@ -62,10 +67,13 @@ dotnet publish --self-contained --runtime-id osx-arm64 CSharpExample/ && dotnet
|
||||
- `Corelib.fs`: Core library type definitions (String, Array, etc.)
|
||||
|
||||
**WoofWare.PawPrint.Test**
|
||||
- Uses NUnit as the test framework
|
||||
- Uses Expecto as the test framework
|
||||
- Test cases are defined in `TestCases.fs`
|
||||
- C# source files in `sources/` are compiled and executed by the runtime as test cases
|
||||
- C# source files in `sources{Pure,Impure}/` are compiled and executed by the runtime as test cases
|
||||
- `TestHarness.fs` provides infrastructure for running test assemblies through the interpreter
|
||||
- Run all tests with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --no-spinner`
|
||||
- Run a specific test with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --filter-test-case StringWithinTestName --no-spinner`
|
||||
- Pending test definitions must be moved into the non-pending test case list before they can be run.
|
||||
|
||||
**WoofWare.PawPrint.App**
|
||||
- Entry point application for running the interpreter
|
||||
|
@@ -6,6 +6,11 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<WarningsAsErrors>false</WarningsAsErrors>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
7
WoofWare.PawPrint.Test/Program.fs
Normal file
7
WoofWare.PawPrint.Test/Program.fs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace WoofWare.PawPrint.Test
|
||||
|
||||
open Expecto
|
||||
|
||||
module Program =
|
||||
[<EntryPoint>]
|
||||
let main argv = runTestsInAssemblyWithCLIArgs [] argv
|
@@ -3,14 +3,11 @@ namespace WoofWare.Pawprint.Test
|
||||
open System.Collections.Immutable
|
||||
open System.IO
|
||||
open FsUnitTyped
|
||||
open NUnit.Framework
|
||||
open WoofWare.DotnetRuntimeLocator
|
||||
open WoofWare.PawPrint
|
||||
open WoofWare.PawPrint.ExternImplementations
|
||||
open WoofWare.PawPrint.Test
|
||||
|
||||
[<TestFixture>]
|
||||
[<Parallelizable(ParallelScope.All)>]
|
||||
module TestImpureCases =
|
||||
let assy = typeof<RunResult>.Assembly
|
||||
|
||||
@@ -51,8 +48,7 @@ module TestImpureCases =
|
||||
}
|
||||
]
|
||||
|
||||
[<TestCaseSource(nameof cases)>]
|
||||
let ``Can evaluate C# files`` (case : TestCase) : unit =
|
||||
let runTest (case : TestCase) : unit =
|
||||
let source = Assembly.getEmbeddedResourceAsString case.FileName assy
|
||||
let image = Roslyn.compile [ source ]
|
||||
let messages, loggerFactory = LoggerFactory.makeTest ()
|
||||
@@ -90,34 +86,23 @@ module TestImpureCases =
|
||||
|
||||
reraise ()
|
||||
|
||||
[<TestCaseSource(nameof unimplemented)>]
|
||||
[<Explicit "not yet implemented">]
|
||||
let ``Can evaluate C# files, unimplemented`` (case : TestCase) : unit =
|
||||
let source = Assembly.getEmbeddedResourceAsString case.FileName assy
|
||||
let image = Roslyn.compile [ source ]
|
||||
let messages, loggerFactory = LoggerFactory.makeTest ()
|
||||
open Expecto
|
||||
|
||||
let dotnetRuntimes =
|
||||
DotnetRuntime.SelectForDll assy.Location |> ImmutableArray.CreateRange
|
||||
|
||||
use peImage = new MemoryStream (image)
|
||||
|
||||
try
|
||||
let terminalState, terminatingThread =
|
||||
Program.run loggerFactory (Some case.FileName) peImage dotnetRuntimes case.NativeImpls []
|
||||
|
||||
let exitCode =
|
||||
match terminalState.ThreadState.[terminatingThread].MethodState.EvaluationStack.Values with
|
||||
| [] -> failwith "expected program to return a value, but it returned void"
|
||||
| head :: _ ->
|
||||
match head with
|
||||
| EvalStackValue.Int32 i -> i
|
||||
| ret -> failwith $"expected program to return an int, but it returned %O{ret}"
|
||||
|
||||
exitCode |> shouldEqual case.ExpectedReturnCode
|
||||
|
||||
with _ ->
|
||||
for message in messages () do
|
||||
System.Console.Error.WriteLine $"{message}"
|
||||
|
||||
reraise ()
|
||||
[<Tests>]
|
||||
let tests =
|
||||
testList
|
||||
"Impure cases"
|
||||
[
|
||||
testList
|
||||
"Can evaluate C# files"
|
||||
[
|
||||
for case in cases do
|
||||
testCase case.FileName (fun () -> runTest case)
|
||||
]
|
||||
ptestList
|
||||
"Can evaluate C# files (unimplemented)"
|
||||
[
|
||||
for case in unimplemented do
|
||||
testCase case.FileName (fun () -> runTest case)
|
||||
]
|
||||
]
|
||||
|
@@ -3,14 +3,11 @@ namespace WoofWare.Pawprint.Test
|
||||
open System.Collections.Immutable
|
||||
open System.IO
|
||||
open FsUnitTyped
|
||||
open NUnit.Framework
|
||||
open WoofWare.DotnetRuntimeLocator
|
||||
open WoofWare.PawPrint
|
||||
open WoofWare.PawPrint.ExternImplementations
|
||||
open WoofWare.PawPrint.Test
|
||||
|
||||
[<TestFixture>]
|
||||
[<Parallelizable(ParallelScope.All)>]
|
||||
module TestPureCases =
|
||||
let assy = typeof<RunResult>.Assembly
|
||||
|
||||
@@ -232,8 +229,7 @@ module TestPureCases =
|
||||
}
|
||||
]
|
||||
|
||||
[<TestCaseSource(nameof cases)>]
|
||||
let ``Can evaluate C# files`` (case : TestCase) : unit =
|
||||
let runTest (case : TestCase) : unit =
|
||||
let source = Assembly.getEmbeddedResourceAsString case.FileName assy
|
||||
let image = Roslyn.compile [ source ]
|
||||
let messages, loggerFactory = LoggerFactory.makeTest ()
|
||||
@@ -274,34 +270,23 @@ module TestPureCases =
|
||||
|
||||
reraise ()
|
||||
|
||||
[<TestCaseSource(nameof unimplemented)>]
|
||||
[<Explicit "not yet implemented">]
|
||||
let ``Can evaluate C# files, unimplemented`` (case : TestCase) : unit =
|
||||
let source = Assembly.getEmbeddedResourceAsString case.FileName assy
|
||||
let image = Roslyn.compile [ source ]
|
||||
let messages, loggerFactory = LoggerFactory.makeTest ()
|
||||
open Expecto
|
||||
|
||||
let dotnetRuntimes =
|
||||
DotnetRuntime.SelectForDll assy.Location |> ImmutableArray.CreateRange
|
||||
|
||||
use peImage = new MemoryStream (image)
|
||||
|
||||
try
|
||||
let terminalState, terminatingThread =
|
||||
Program.run loggerFactory (Some case.FileName) peImage dotnetRuntimes case.NativeImpls []
|
||||
|
||||
let exitCode =
|
||||
match terminalState.ThreadState.[terminatingThread].MethodState.EvaluationStack.Values with
|
||||
| [] -> failwith "expected program to return a value, but it returned void"
|
||||
| head :: _ ->
|
||||
match head with
|
||||
| EvalStackValue.Int32 i -> i
|
||||
| ret -> failwith $"expected program to return an int, but it returned %O{ret}"
|
||||
|
||||
exitCode |> shouldEqual case.ExpectedReturnCode
|
||||
|
||||
with _ ->
|
||||
for message in messages () do
|
||||
System.Console.Error.WriteLine $"{message}"
|
||||
|
||||
reraise ()
|
||||
[<Tests>]
|
||||
let tests =
|
||||
testList
|
||||
"Pure cases"
|
||||
[
|
||||
testList
|
||||
"Can evaluate C# files"
|
||||
[
|
||||
for case in cases do
|
||||
testCase case.FileName (fun () -> runTest case)
|
||||
]
|
||||
ptestList
|
||||
"Can evaluate C# files (unimplemented)"
|
||||
[
|
||||
for case in unimplemented do
|
||||
testCase case.FileName (fun () -> runTest case)
|
||||
]
|
||||
]
|
||||
|
@@ -4,9 +4,7 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
|
||||
<EnableNUnitRunner>true</EnableNUnitRunner>
|
||||
<GenerateProgramFile>false</GenerateProgramFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -17,6 +15,7 @@
|
||||
<Compile Include="TestHarness.fs"/>
|
||||
<Compile Include="TestPureCases.fs" />
|
||||
<Compile Include="TestImpureCases.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="sourcesPure\BasicLock.cs" />
|
||||
@@ -51,13 +50,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Expecto" Version="10.2.3" />
|
||||
<PackageReference Include="Expecto.Diff" Version="10.2.3" />
|
||||
<PackageReference Include="FsUnit" Version="7.1.1"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.6" />
|
||||
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.3.2"/>
|
||||
<PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.15.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
|
@@ -1,4 +1,19 @@
|
||||
[
|
||||
{
|
||||
"pname": "DiffPlex",
|
||||
"version": "1.7.1",
|
||||
"hash": "sha256-0kDBRvlMALkuE0G86ACEkZ4hNCeFwMmLPOvleMHJ6OA="
|
||||
},
|
||||
{
|
||||
"pname": "Expecto",
|
||||
"version": "10.2.3",
|
||||
"hash": "sha256-klv7QbGwd0ClMSe+wJ38URVmIawV2ksyrjzQbGhVUPg="
|
||||
},
|
||||
{
|
||||
"pname": "Expecto.Diff",
|
||||
"version": "10.2.3",
|
||||
"hash": "sha256-8WBr/2Ezit8RoOA7Pwrs50BDHkLe6a8lCkvzTcT/rkE="
|
||||
},
|
||||
{
|
||||
"pname": "fantomas",
|
||||
"version": "7.0.0",
|
||||
@@ -171,33 +186,33 @@
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.Telemetry",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-bIXwPSa3jkr2b6xINOqMUs6/uj/r4oVFM7xq3uVIZDU="
|
||||
"version": "1.6.2",
|
||||
"hash": "sha256-GZYUH+0vWAif5p4S81Oo9Tsez68ylsLjEQWhI2rgcik="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-IfMRfcyaIKEMRtx326ICKtinDBEfGw/Sv8ZHawJ96Yc="
|
||||
"version": "1.6.2",
|
||||
"hash": "sha256-UOpDBbW3xgahofRjqdw3wUj63zXVdkIAfUE7dA4uI4Y="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.VSTestBridge",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-XpM/yFjhLSsuzyDV+xKubs4V1zVVYiV05E0+N4S1h0g="
|
||||
"version": "1.6.2",
|
||||
"hash": "sha256-SWaSPgc2PQNqsz7ea/SQsmqOX6le6dmrDbwCHfbppZo="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-y61Iih6w5D79dmrj2V675mcaeIiHoj1HSa1FRit2BLM="
|
||||
"version": "1.6.2",
|
||||
"hash": "sha256-RfdgATa3aTYLpGfv8ORI5uEP8dH87L5/gBDkxAG6ho4="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform.MSBuild",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-YspvjE5Jfi587TAfsvfDVJXNrFOkx1B3y1CKV6m7YLY="
|
||||
"version": "1.6.2",
|
||||
"hash": "sha256-bzlz10QeFrCAR+1og0gXbxSbpO64wCFrwAhBUwAp0nI="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-3XBHBSuCxggAIlHXmKNQNlPqMqwFlM952Av6RrLw1/w="
|
||||
"version": "17.13.0",
|
||||
"hash": "sha256-6S0fjfj8vA+h6dJVNwLi6oZhYDO/I/6hBZaq2VTW+Uk="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
@@ -209,6 +224,11 @@
|
||||
"version": "17.14.1",
|
||||
"hash": "sha256-1cxHWcvHRD7orQ3EEEPPxVGEkTpxom1/zoICC9SInJs="
|
||||
},
|
||||
{
|
||||
"pname": "Mono.Cecil",
|
||||
"version": "0.11.4",
|
||||
"hash": "sha256-HrnRgFsOzfqAWw0fUxi/vkzZd8dMn5zueUeLQWA9qvs="
|
||||
},
|
||||
{
|
||||
"pname": "Myriad.Core",
|
||||
"version": "0.8.3",
|
||||
@@ -231,13 +251,8 @@
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
"version": "4.3.2",
|
||||
"hash": "sha256-0RWe8uFoxYp6qhPlDDEghOMcKJgyw2ybvEoAqBLebeE="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit3TestAdapter",
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-7jZM4qAbIzne3AcdFfMbvbgogqpxvVe6q2S7Ls8xQy0="
|
||||
"version": "4.0.1",
|
||||
"hash": "sha256-jd1CD5nHVXkpvBNpVDJcJyfTggCHLyDBySVSvtrA8Uk="
|
||||
},
|
||||
{
|
||||
"pname": "runtime.any.System.Runtime",
|
||||
@@ -284,11 +299,6 @@
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM="
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "1.6.0",
|
||||
"hash": "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E="
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "8.0.0",
|
||||
@@ -328,5 +338,10 @@
|
||||
"pname": "WoofWare.Whippet.Fantomas",
|
||||
"version": "0.6.3",
|
||||
"hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw="
|
||||
},
|
||||
{
|
||||
"pname": "YoloDev.Expecto.TestSdk",
|
||||
"version": "0.15.3",
|
||||
"hash": "sha256-POsY+kmSMIGev1OzF6WYk0/sKKou8Z9f7C6r6Txk9aU="
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user