Switch back to NUnit (#101)

This commit is contained in:
Patrick Stevens
2025-08-22 14:34:36 +01:00
committed by GitHub
parent d711d6fff5
commit cfd6716616
7 changed files with 88 additions and 149 deletions

View File

@@ -23,7 +23,7 @@ module LoggerFactory =
let makeTest () : (unit -> LogLine list) * ILoggerFactory = let makeTest () : (unit -> LogLine list) * ILoggerFactory =
// Shared sink for all loggers created by the factory. // Shared sink for all loggers created by the factory.
let sink = ResizeArray () let sink = ResizeArray ()
let isEnabled (logLevel : LogLevel) : bool = logLevel >= LogLevel.Information let isEnabled (logLevel : LogLevel) : bool = logLevel >= LogLevel.Debug
let createLogger (category : string) : ILogger = let createLogger (category : string) : ILogger =
{ new ILogger with { new ILogger with

View File

@@ -25,7 +25,7 @@ module MockEnv =
System_Threading_Monitor = System_Threading_MonitorMock.Empty System_Threading_Monitor = System_Threading_MonitorMock.Empty
} }
type TestCase = type EndToEndTestCase =
{ {
FileName : string FileName : string
ExpectedReturnCode : int ExpectedReturnCode : int

View File

@@ -3,11 +3,14 @@ namespace WoofWare.Pawprint.Test
open System.Collections.Immutable open System.Collections.Immutable
open System.IO open System.IO
open FsUnitTyped open FsUnitTyped
open NUnit.Framework
open WoofWare.DotnetRuntimeLocator open WoofWare.DotnetRuntimeLocator
open WoofWare.PawPrint open WoofWare.PawPrint
open WoofWare.PawPrint.ExternImplementations open WoofWare.PawPrint.ExternImplementations
open WoofWare.PawPrint.Test open WoofWare.PawPrint.Test
[<TestFixture>]
[<Parallelizable(ParallelScope.All)>]
module TestImpureCases = module TestImpureCases =
let assy = typeof<RunResult>.Assembly let assy = typeof<RunResult>.Assembly
@@ -20,7 +23,7 @@ module TestImpureCases =
} }
] ]
let cases : TestCase list = let cases : EndToEndTestCase list =
[ [
{ {
FileName = "InstaQuit.cs" FileName = "InstaQuit.cs"
@@ -46,7 +49,7 @@ module TestImpureCases =
} }
] ]
let runTest (case : TestCase) : unit = let runTest (case : EndToEndTestCase) : unit =
let source = Assembly.getEmbeddedResourceAsString case.FileName assy let source = Assembly.getEmbeddedResourceAsString case.FileName assy
let image = Roslyn.compile [ source ] let image = Roslyn.compile [ source ]
let messages, loggerFactory = LoggerFactory.makeTest () let messages, loggerFactory = LoggerFactory.makeTest ()
@@ -75,23 +78,9 @@ module TestImpureCases =
reraise () reraise ()
open Expecto [<TestCaseSource(nameof unimplemented)>]
[<Explicit>]
let ``Can evaluate C# files, unimplemented`` (case : EndToEndTestCase) = runTest case
[<Tests>] [<TestCaseSource(nameof cases)>]
let tests = let ``Can evaluate C# files`` (case : EndToEndTestCase) = runTest case
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)
]
]

View File

@@ -3,11 +3,14 @@ namespace WoofWare.Pawprint.Test
open System.Collections.Immutable open System.Collections.Immutable
open System.IO open System.IO
open FsUnitTyped open FsUnitTyped
open NUnit.Framework
open WoofWare.DotnetRuntimeLocator open WoofWare.DotnetRuntimeLocator
open WoofWare.PawPrint open WoofWare.PawPrint
open WoofWare.PawPrint.ExternImplementations open WoofWare.PawPrint.ExternImplementations
open WoofWare.PawPrint.Test open WoofWare.PawPrint.Test
[<TestFixture>]
[<Parallelizable(ParallelScope.All)>]
module TestPureCases = module TestPureCases =
let assy = typeof<RunResult>.Assembly let assy = typeof<RunResult>.Assembly
@@ -55,7 +58,7 @@ module TestPureCases =
} }
] ]
let cases : TestCase list = let cases : EndToEndTestCase list =
[ [
{ {
FileName = "NoOp.cs" FileName = "NoOp.cs"
@@ -144,7 +147,7 @@ module TestPureCases =
} }
] ]
let runTest (case : TestCase) : unit = let runTest (case : EndToEndTestCase) : unit =
let source = Assembly.getEmbeddedResourceAsString case.FileName assy let source = Assembly.getEmbeddedResourceAsString case.FileName assy
let image = Roslyn.compile [ source ] let image = Roslyn.compile [ source ]
let messages, loggerFactory = LoggerFactory.makeTest () let messages, loggerFactory = LoggerFactory.makeTest ()
@@ -177,23 +180,9 @@ module TestPureCases =
reraise () reraise ()
open Expecto [<TestCaseSource(nameof unimplemented)>]
[<Explicit>]
let ``Can evaluate C# files, unimplemented`` (case : EndToEndTestCase) = runTest case
[<Tests>] [<TestCaseSource(nameof cases)>]
let tests = let ``Can evaluate C# files`` (case : EndToEndTestCase) = runTest case
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)
]
]

View File

@@ -4,7 +4,6 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -15,37 +14,10 @@
<Compile Include="TestHarness.fs"/> <Compile Include="TestHarness.fs"/>
<Compile Include="TestPureCases.fs" /> <Compile Include="TestPureCases.fs" />
<Compile Include="TestImpureCases.fs" /> <Compile Include="TestImpureCases.fs" />
<Compile Include="Program.fs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="sourcesPure\BasicLock.cs" /> <EmbeddedResource Include="sourcesPure\*.cs" />
<EmbeddedResource Include="sourcesPure\Floats.cs" /> <EmbeddedResource Include="sourcesImpure\*.cs" />
<EmbeddedResource Include="sourcesPure\NoOp.cs" />
<EmbeddedResource Include="sourcesPure\InitializeArray.cs" />
<EmbeddedResource Include="sourcesPure\LdtokenField.cs" />
<EmbeddedResource Include="sourcesPure\StaticVariables.cs" />
<EmbeddedResource Include="sourcesPure\Ldelema.cs" />
<EmbeddedResource Include="sourcesPure\ExceptionWithNoOpCatch.cs" />
<EmbeddedResource Include="sourcesPure\ExceptionWithNoOpFinally.cs" />
<EmbeddedResource Include="sourcesPure\TryCatchWithThrowInBody.cs" />
<EmbeddedResource Include="sourcesPure\ComplexTryCatch.cs" />
<EmbeddedResource Include="sourcesPure\TriangleNumber.cs" />
<EmbeddedResource Include="sourcesPure\Threads.cs" />
<EmbeddedResource Include="sourcesPure\ResizeArray.cs" />
<EmbeddedResource Include="sourcesPure\ArgumentOrdering.cs" />
<EmbeddedResource Include="sourcesPure\TestShl.cs" />
<EmbeddedResource Include="sourcesPure\TestShr.cs" />
<EmbeddedResource Include="sourcesPure\TestOr.cs" />
<EmbeddedResource Include="sourcesPure\CustomDelegate.cs" />
<EmbeddedResource Include="sourcesPure\Ldind.cs" />
<EmbeddedResource Include="sourcesPure\TypeConcretization.cs" />
<EmbeddedResource Include="sourcesPure\CrossAssemblyTypes.cs" />
<EmbeddedResource Include="sourcesPure\GenericEdgeCases.cs" />
<EmbeddedResource Include="sourcesPure\Sizeof.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="sourcesImpure\WriteLine.cs" />
<EmbeddedResource Include="sourcesImpure\InstaQuit.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -53,14 +25,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Expecto" Version="10.2.3" /> <PackageReference Include="NUnit" Version="4.4.0"/>
<PackageReference Include="Expecto.Diff" Version="10.2.3" /> <PackageReference Include="NUnit3TestAdapter" Version="5.1.0"/>
<PackageReference Include="FsUnit" Version="7.1.1"/> <PackageReference Include="FsUnit" Version="7.1.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0"/> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0"/>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.6" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.6" />
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.3.2"/> <PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.3.2"/>
<PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.15.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1751498133, "lastModified": 1755736253,
"narHash": "sha256-QWJ+NQbMU+NcU2xiyo7SNox1fAuwksGlQhpzBl76g1I=", "narHash": "sha256-jlIQRypNhB1PcB1BE+expE4xZeJxzoAGr1iUbHQta8s=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d55716bb59b91ae9d1ced4b1ccdea7a442ecbfdb", "rev": "596312aae91421d6923f18cecce934a7d3bfd6b8",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -1,19 +1,4 @@
[ [
{
"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", "pname": "fantomas",
"version": "7.0.0", "version": "7.0.0",
@@ -36,8 +21,8 @@
}, },
{ {
"pname": "FSharp.Core", "pname": "FSharp.Core",
"version": "9.0.202", "version": "9.0.303",
"hash": "sha256-64Gub0qemmCoMa1tDus6TeTuB1+5sHfE6KD2j4o84mA=" "hash": "sha256-AxR6wqodeU23KOTgkUfIgbavgbcSuzD4UBP+tiFydgA="
}, },
{ {
"pname": "FsUnit", "pname": "FsUnit",
@@ -46,33 +31,33 @@
}, },
{ {
"pname": "Microsoft.ApplicationInsights", "pname": "Microsoft.ApplicationInsights",
"version": "2.22.0", "version": "2.23.0",
"hash": "sha256-mUQ63atpT00r49ca50uZu2YCiLg3yd6r3HzTryqcuEA=" "hash": "sha256-5sf3bg7CZZjHseK+F3foOchEhmVeioePxMZVvS6Rjb0="
}, },
{ {
"pname": "Microsoft.AspNetCore.App.Ref", "pname": "Microsoft.AspNetCore.App.Ref",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-NNGXfUV5RVt1VqLI99NlHoBkt2Vv/Hg3TAHzm8nGM8M=" "hash": "sha256-QySX2bih1UvwmLcn9cy1j+RuvZZwbcFKggL5Y/WcTnw="
}, },
{ {
"pname": "Microsoft.AspNetCore.App.Runtime.linux-arm64", "pname": "Microsoft.AspNetCore.App.Runtime.linux-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-Eunz3nZF5r8a9nqwdeorQPgqd5G+Z4ddofMeAk6VmnA=" "hash": "sha256-69S+Ywyc5U8PDsVkkCVvZdHOgWb6ZZ3+f4UA0MLOLFI="
}, },
{ {
"pname": "Microsoft.AspNetCore.App.Runtime.linux-x64", "pname": "Microsoft.AspNetCore.App.Runtime.linux-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-SWdah72tC5i2CQL4mRUYfHC0Kh8+C2jiskIIeC74smY=" "hash": "sha256-u50rdLuoADSDCthx2Fg+AnT192TalHhFrzFCfMgmTn4="
}, },
{ {
"pname": "Microsoft.AspNetCore.App.Runtime.osx-arm64", "pname": "Microsoft.AspNetCore.App.Runtime.osx-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-y55EGfQ2FzrY2X5+Ne5N3dqi5WNHkFTGVW1hEMrh6OI=" "hash": "sha256-QAKu2xD4UQ4+gX79ynNQ0aA07D+EW6Ke0jRiTZne8CY="
}, },
{ {
"pname": "Microsoft.AspNetCore.App.Runtime.osx-x64", "pname": "Microsoft.AspNetCore.App.Runtime.osx-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-uRCCNPevPemvKIuUxy/VtQlgskChbiAauMWVK/xhoc0=" "hash": "sha256-v5lzESMpodrH2grgk8ojA6BLDUfyxX5r6YY5Pgq61tA="
}, },
{ {
"pname": "Microsoft.CodeAnalysis.Analyzers", "pname": "Microsoft.CodeAnalysis.Analyzers",
@@ -121,48 +106,48 @@
}, },
{ {
"pname": "Microsoft.NETCore.App.Host.linux-arm64", "pname": "Microsoft.NETCore.App.Host.linux-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-pzOqFCd+UrIXmWGDfds5GxkI+Asjx30yFtLIuHFu/h4=" "hash": "sha256-R86Kqzi3FUuPZlgj3zNOObLAvXtnGrS2mxsBAxWIZrY="
}, },
{ {
"pname": "Microsoft.NETCore.App.Host.linux-x64", "pname": "Microsoft.NETCore.App.Host.linux-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-AGnEGHcO2hfvChG3xEGOTA6dX4MiYPB7FoBkmWz3dc8=" "hash": "sha256-a9t/bX+WIKOu9q2R52b/hPGwOpkAgpYuP42SW2QXTak="
}, },
{ {
"pname": "Microsoft.NETCore.App.Host.osx-arm64", "pname": "Microsoft.NETCore.App.Host.osx-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-fpMzkOWaA3OFNtHsqOk9s9xKVrcrqOyKHxE7jk8hebg=" "hash": "sha256-VaeGPR+6ApGNtQpEaky2rdUKd4X/Pp3xFGaSgUfGNiE="
}, },
{ {
"pname": "Microsoft.NETCore.App.Host.osx-x64", "pname": "Microsoft.NETCore.App.Host.osx-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-Hrn01x+S+gnGEEHhr6mN6bPyqVAhp5u3CqgWwQbh4To=" "hash": "sha256-hw7WMpTq7o544uSNvWUCIr6IRt5xZOo+eERMnwAbYyk="
}, },
{ {
"pname": "Microsoft.NETCore.App.Ref", "pname": "Microsoft.NETCore.App.Ref",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-tKawpjkMjV0ysNIWWrgHTiLxncZJDRNiDkQBwl255l4=" "hash": "sha256-4ymel0R1c0HrX0plAWubJPzev52y0Fsx1esyQ1R7bXc="
}, },
{ {
"pname": "Microsoft.NETCore.App.Runtime.linux-arm64", "pname": "Microsoft.NETCore.App.Runtime.linux-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-FutphE4bEjd8s6ZqpFXrD1zuCDkNCJ7Vnl0pBm86HBA=" "hash": "sha256-hqhpd8yT8bv05DhFTuMhfsaSISpLs3t4oM+R/ZkJH80="
}, },
{ {
"pname": "Microsoft.NETCore.App.Runtime.linux-x64", "pname": "Microsoft.NETCore.App.Runtime.linux-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-6YVEXiJ3b2gZAYri8iSRBdi/J+0DEl7FcwBX6h1Unkg=" "hash": "sha256-Ou51zUFTPESAAzP/z0+sLDAAXC54+oDlESBBT12M2lM="
}, },
{ {
"pname": "Microsoft.NETCore.App.Runtime.osx-arm64", "pname": "Microsoft.NETCore.App.Runtime.osx-arm64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-J3dfDial8GHyKQMFuBNFtOMD/mOK58vjrK2ZtrYObZg=" "hash": "sha256-IC/e8AmT9twcXwzFmXAelf4ctMbg4ancKPGrPLFMNn8="
}, },
{ {
"pname": "Microsoft.NETCore.App.Runtime.osx-x64", "pname": "Microsoft.NETCore.App.Runtime.osx-x64",
"version": "8.0.17", "version": "8.0.19",
"hash": "sha256-WnkJyhSBHMw/VtLHWy0AFwzzkbIC1YQugFuj3Adg+Ks=" "hash": "sha256-Rb0z0PT/FHyk/Fgjj9W3WDpkDMKJoXR9DgHB1cJeZSA="
}, },
{ {
"pname": "Microsoft.NETCore.Platforms", "pname": "Microsoft.NETCore.Platforms",
@@ -186,28 +171,33 @@
}, },
{ {
"pname": "Microsoft.Testing.Extensions.Telemetry", "pname": "Microsoft.Testing.Extensions.Telemetry",
"version": "1.6.2", "version": "1.7.3",
"hash": "sha256-GZYUH+0vWAif5p4S81Oo9Tsez68ylsLjEQWhI2rgcik=" "hash": "sha256-Z6WsY2FCUbNnT5HJd7IOrfOvqknVXp6PWzTVeb0idVg="
}, },
{ {
"pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions", "pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions",
"version": "1.6.2", "version": "1.7.3",
"hash": "sha256-UOpDBbW3xgahofRjqdw3wUj63zXVdkIAfUE7dA4uI4Y=" "hash": "sha256-PTee04FHyTHx/gF5NLckXuVje807G51MzkPrZ1gkgCw="
}, },
{ {
"pname": "Microsoft.Testing.Extensions.VSTestBridge", "pname": "Microsoft.Testing.Extensions.VSTestBridge",
"version": "1.6.2", "version": "1.7.3",
"hash": "sha256-SWaSPgc2PQNqsz7ea/SQsmqOX6le6dmrDbwCHfbppZo=" "hash": "sha256-8d+wZmucfSO7PsviHjVxYB4q6NcjgxvnCUpLePq35sM="
}, },
{ {
"pname": "Microsoft.Testing.Platform", "pname": "Microsoft.Testing.Platform",
"version": "1.6.2", "version": "1.7.3",
"hash": "sha256-RfdgATa3aTYLpGfv8ORI5uEP8dH87L5/gBDkxAG6ho4=" "hash": "sha256-cavX11P5o9rooqC3ZHw5h002OKRg2ZNR/VaRwpNTQYA="
}, },
{ {
"pname": "Microsoft.Testing.Platform.MSBuild", "pname": "Microsoft.Testing.Platform.MSBuild",
"version": "1.6.2", "version": "1.7.3",
"hash": "sha256-bzlz10QeFrCAR+1og0gXbxSbpO64wCFrwAhBUwAp0nI=" "hash": "sha256-cREl529UQ/c5atT8KimMgrgNdy6MrAd0sBGT8sXRRPM="
},
{
"pname": "Microsoft.TestPlatform.AdapterUtilities",
"version": "17.13.0",
"hash": "sha256-Vr+3Tad/h/nk7f/5HMExn3HvCGFCarehFAzJSfCBaOc="
}, },
{ {
"pname": "Microsoft.TestPlatform.ObjectModel", "pname": "Microsoft.TestPlatform.ObjectModel",
@@ -224,11 +214,6 @@
"version": "17.14.1", "version": "17.14.1",
"hash": "sha256-1cxHWcvHRD7orQ3EEEPPxVGEkTpxom1/zoICC9SInJs=" "hash": "sha256-1cxHWcvHRD7orQ3EEEPPxVGEkTpxom1/zoICC9SInJs="
}, },
{
"pname": "Mono.Cecil",
"version": "0.11.4",
"hash": "sha256-HrnRgFsOzfqAWw0fUxi/vkzZd8dMn5zueUeLQWA9qvs="
},
{ {
"pname": "Myriad.Core", "pname": "Myriad.Core",
"version": "0.8.3", "version": "0.8.3",
@@ -251,8 +236,13 @@
}, },
{ {
"pname": "NUnit", "pname": "NUnit",
"version": "4.0.1", "version": "4.4.0",
"hash": "sha256-jd1CD5nHVXkpvBNpVDJcJyfTggCHLyDBySVSvtrA8Uk=" "hash": "sha256-5geF5QOF+X/WkuCEgkPVKH4AdKx4U0olpU07S8+G3nU="
},
{
"pname": "NUnit3TestAdapter",
"version": "5.1.0",
"hash": "sha256-5z470sFjV67wGHaw8KfmSloIAYe81Dokp0f8I6zXsDc="
}, },
{ {
"pname": "runtime.any.System.Runtime", "pname": "runtime.any.System.Runtime",
@@ -299,6 +289,11 @@
"version": "4.3.0", "version": "4.3.0",
"hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM=" "hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM="
}, },
{
"pname": "System.Reflection.Metadata",
"version": "1.6.0",
"hash": "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E="
},
{ {
"pname": "System.Reflection.Metadata", "pname": "System.Reflection.Metadata",
"version": "8.0.0", "version": "8.0.0",
@@ -338,10 +333,5 @@
"pname": "WoofWare.Whippet.Fantomas", "pname": "WoofWare.Whippet.Fantomas",
"version": "0.6.3", "version": "0.6.3",
"hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw=" "hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw="
},
{
"pname": "YoloDev.Expecto.TestSdk",
"version": "0.15.3",
"hash": "sha256-POsY+kmSMIGev1OzF6WYk0/sKKou8Z9f7C6r6Txk9aU="
} }
] ]