From ffbcb05d56485e3c62a94c9ce3a32f02de43f80f Mon Sep 17 00:00:00 2001 From: JerrettDavis Date: Fri, 22 May 2026 16:11:07 -0500 Subject: [PATCH] test(phase-h.5): cover Extensions.Diagnostics and Extensions.Events with ~18 TinyBDD scenarios - New test project: WorkflowFramework.Extensions.Diagnostics.Tests - TimingMiddlewareScenarios: 5 scenarios (TimingsKey constant, timing stored, multi-step timings, timing on throw, non-negative elapsed) - MetricsMiddlewareScenarios: 5 scenarios (initial state, increment TotalSteps, increment FailedSteps, AverageDuration positive, accumulation) - New test project: WorkflowFramework.Extensions.Events.Tests - InMemoryEventBusScenarios: 8 scenarios (no-sub goes to DeadLetters, subscriber delivery, not dead with subscriber, dispose unsubscribes, WaitForEvent resolves, timeout returns null, null throws, multiple subscribers) - All 18 scenarios green on net8.0, net9.0, net10.0 - Both projects added to WorkflowFramework.slnx Co-Authored-By: Claude Opus 4.6 --- WorkflowFramework.slnx | 2 + .../Diagnostics/MetricsMiddlewareScenarios.cs | 114 +++ .../Diagnostics/TimingMiddlewareScenarios.cs | 122 +++ ...mework.Extensions.Diagnostics.Tests.csproj | 23 + .../packages.lock.json | 821 ++++++++++++++++++ .../Events/InMemoryEventBusScenarios.cs | 166 ++++ ...owFramework.Extensions.Events.Tests.csproj | 22 + .../packages.lock.json | 816 +++++++++++++++++ 8 files changed, 2086 insertions(+) create mode 100644 tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/MetricsMiddlewareScenarios.cs create mode 100644 tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/TimingMiddlewareScenarios.cs create mode 100644 tests/WorkflowFramework.Extensions.Diagnostics.Tests/WorkflowFramework.Extensions.Diagnostics.Tests.csproj create mode 100644 tests/WorkflowFramework.Extensions.Diagnostics.Tests/packages.lock.json create mode 100644 tests/WorkflowFramework.Extensions.Events.Tests/Events/InMemoryEventBusScenarios.cs create mode 100644 tests/WorkflowFramework.Extensions.Events.Tests/WorkflowFramework.Extensions.Events.Tests.csproj create mode 100644 tests/WorkflowFramework.Extensions.Events.Tests/packages.lock.json diff --git a/WorkflowFramework.slnx b/WorkflowFramework.slnx index 7843670..05af7b1 100644 --- a/WorkflowFramework.slnx +++ b/WorkflowFramework.slnx @@ -93,6 +93,8 @@ + + diff --git a/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/MetricsMiddlewareScenarios.cs b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/MetricsMiddlewareScenarios.cs new file mode 100644 index 0000000..97d8d83 --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/MetricsMiddlewareScenarios.cs @@ -0,0 +1,114 @@ +using FluentAssertions; +using TinyBDD; +using TinyBDD.Xunit; +using WorkflowFramework.Extensions.Diagnostics; +using Xunit; +using Xunit.Abstractions; + +namespace WorkflowFramework.Extensions.Diagnostics.Tests.Diagnostics; + +[Feature("MetricsMiddleware — collects workflow execution counters")] +public class MetricsMiddlewareScenarios : TinyBddXunitBase +{ + public MetricsMiddlewareScenarios(ITestOutputHelper output) : base(output) { } + + private sealed class LambdaStep : IStep + { + private readonly Func _fn; + public LambdaStep(string name, Func fn) { Name = name; _fn = fn; } + public string Name { get; } + public Task ExecuteAsync(IWorkflowContext context) => _fn(context); + } + + [Scenario("Initial state has zero counters"), Fact] + public async Task InitialState_ZeroCounters() + { + var mw = new MetricsMiddleware(); + + await Given("a fresh MetricsMiddleware", () => mw) + .Then("TotalSteps=0, FailedSteps=0, AverageDuration=Zero", m => + { + m.TotalSteps.Should().Be(0); + m.FailedSteps.Should().Be(0); + m.AverageDuration.Should().Be(TimeSpan.Zero); + return true; + }) + .AssertPassed(); + } + + [Scenario("Successful step increments TotalSteps"), Fact] + public async Task SuccessfulStep_IncrementsTotalSteps() + { + var mw = new MetricsMiddleware(); + var step = new LambdaStep("ok", _ => Task.CompletedTask); + var ctx = new WorkflowContext(); + + await mw.InvokeAsync(ctx, step, c => step.ExecuteAsync(c)); + + await Given("one successful step", () => mw.TotalSteps) + .Then("TotalSteps is 1", t => + { + t.Should().Be(1); + return true; + }) + .AssertPassed(); + } + + [Scenario("Failing step increments both TotalSteps and FailedSteps"), Fact] + public async Task FailingStep_IncrementsBothCounters() + { + var mw = new MetricsMiddleware(); + var step = new LambdaStep("fail", _ => throw new InvalidOperationException("boom")); + var ctx = new WorkflowContext(); + + try { await mw.InvokeAsync(ctx, step, c => step.ExecuteAsync(c)); } + catch { /* expected */ } + + await Given("one failing step", () => (mw.TotalSteps, mw.FailedSteps)) + .Then("TotalSteps=1 and FailedSteps=1", t => + { + t.TotalSteps.Should().Be(1); + t.FailedSteps.Should().Be(1); + return true; + }) + .AssertPassed(); + } + + [Scenario("AverageDuration is positive after step execution"), Fact] + public async Task AverageDuration_IsPositive_AfterExecution() + { + var mw = new MetricsMiddleware(); + var step = new LambdaStep("timed", _ => Task.CompletedTask); + var ctx = new WorkflowContext(); + + await mw.InvokeAsync(ctx, step, c => step.ExecuteAsync(c)); + + await Given("one step executed", () => mw.AverageDuration) + .Then("AverageDuration is >= zero", d => + { + d.Should().BeGreaterThanOrEqualTo(TimeSpan.Zero); + return true; + }) + .AssertPassed(); + } + + [Scenario("Multiple steps accumulate TotalSteps correctly"), Fact] + public async Task MultipleSteps_AccumulateCount() + { + var mw = new MetricsMiddleware(); + var ctx = new WorkflowContext(); + for (int i = 0; i < 5; i++) + { + var step = new LambdaStep($"step-{i}", _ => Task.CompletedTask); + await mw.InvokeAsync(ctx, step, c => step.ExecuteAsync(c)); + } + + await Given("5 steps executed", () => mw.TotalSteps) + .Then("TotalSteps is 5", t => + { + t.Should().Be(5); + return true; + }) + .AssertPassed(); + } +} diff --git a/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/TimingMiddlewareScenarios.cs b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/TimingMiddlewareScenarios.cs new file mode 100644 index 0000000..83a1686 --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/Diagnostics/TimingMiddlewareScenarios.cs @@ -0,0 +1,122 @@ +using FluentAssertions; +using TinyBDD; +using TinyBDD.Xunit; +using WorkflowFramework.Extensions.Diagnostics; +using Xunit; +using Xunit.Abstractions; + +namespace WorkflowFramework.Extensions.Diagnostics.Tests.Diagnostics; + +[Feature("TimingMiddleware — measures and stores step execution time")] +public class TimingMiddlewareScenarios : TinyBddXunitBase +{ + public TimingMiddlewareScenarios(ITestOutputHelper output) : base(output) { } + + private static IStep MakeStep(string name, int delayMs = 0) => + new LambdaStep(name, async ctx => + { + if (delayMs > 0) await Task.Delay(delayMs); + }); + + private sealed class LambdaStep : IStep + { + private readonly Func _fn; + public LambdaStep(string name, Func fn) { Name = name; _fn = fn; } + public string Name { get; } + public Task ExecuteAsync(IWorkflowContext context) => _fn(context); + } + + [Scenario("TimingsKey constant has expected value"), Fact] + public async Task TimingsKey_HasExpectedValue() + { + await Given("TimingMiddleware.TimingsKey constant", () => TimingMiddleware.TimingsKey) + .Then("value is 'WorkflowFramework.StepTimings'", k => + { + k.Should().Be("WorkflowFramework.StepTimings"); + return true; + }) + .AssertPassed(); + } + + [Scenario("InvokeAsync stores timing for the step"), Fact] + public async Task InvokeAsync_StoresTiming() + { + var middleware = new TimingMiddleware(); + var context = new WorkflowContext(); + var step = MakeStep("my-step"); + + await middleware.InvokeAsync(context, step, ctx => step.ExecuteAsync(ctx)); + + await Given("TimingMiddleware applied to my-step", () => context.Properties) + .Then("timings dictionary contains 'my-step'", props => + { + props.Should().ContainKey(TimingMiddleware.TimingsKey); + var timings = (Dictionary)props[TimingMiddleware.TimingsKey]; + timings.Should().ContainKey("my-step"); + return true; + }) + .AssertPassed(); + } + + [Scenario("Multiple steps each get their own timing entry"), Fact] + public async Task MultipleSteps_EachGetTimingEntry() + { + var middleware = new TimingMiddleware(); + var context = new WorkflowContext(); + var step1 = MakeStep("step-a"); + var step2 = MakeStep("step-b"); + + await middleware.InvokeAsync(context, step1, ctx => step1.ExecuteAsync(ctx)); + await middleware.InvokeAsync(context, step2, ctx => step2.ExecuteAsync(ctx)); + + await Given("two steps both measured by TimingMiddleware", () => context.Properties[TimingMiddleware.TimingsKey]) + .Then("both entries exist in timings", obj => + { + var timings = (Dictionary)obj!; + timings.Should().ContainKey("step-a").And.ContainKey("step-b"); + return true; + }) + .AssertPassed(); + } + + [Scenario("Timing is still recorded when step throws"), Fact] + public async Task InvokeAsync_StillRecordsTiming_WhenStepThrows() + { + var middleware = new TimingMiddleware(); + var context = new WorkflowContext(); + var step = new LambdaStep("throwing-step", _ => throw new InvalidOperationException("boom")); + + try { await middleware.InvokeAsync(context, step, ctx => step.ExecuteAsync(ctx)); } + catch { /* expected */ } + + await Given("step throws during execution", () => context.Properties) + .Then("timing entry still recorded (finally block)", props => + { + props.Should().ContainKey(TimingMiddleware.TimingsKey); + var timings = (Dictionary)props[TimingMiddleware.TimingsKey]; + timings.Should().ContainKey("throwing-step"); + return true; + }) + .AssertPassed(); + } + + [Scenario("Recorded elapsed time is non-negative"), Fact] + public async Task RecordedElapsedTime_IsNonNegative() + { + var middleware = new TimingMiddleware(); + var context = new WorkflowContext(); + var step = MakeStep("quick"); + + await middleware.InvokeAsync(context, step, ctx => step.ExecuteAsync(ctx)); + + var timings = (Dictionary)context.Properties[TimingMiddleware.TimingsKey]; + + await Given("step executed and timed", () => timings["quick"]) + .Then("elapsed is >= 0", elapsed => + { + elapsed.Should().BeGreaterThanOrEqualTo(TimeSpan.Zero); + return true; + }) + .AssertPassed(); + } +} diff --git a/tests/WorkflowFramework.Extensions.Diagnostics.Tests/WorkflowFramework.Extensions.Diagnostics.Tests.csproj b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/WorkflowFramework.Extensions.Diagnostics.Tests.csproj new file mode 100644 index 0000000..ad68c44 --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/WorkflowFramework.Extensions.Diagnostics.Tests.csproj @@ -0,0 +1,23 @@ + + + WorkflowFramework.Extensions.Diagnostics.Tests + false + + + + + + + + + + + + + + + + + + + diff --git a/tests/WorkflowFramework.Extensions.Diagnostics.Tests/packages.lock.json b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/packages.lock.json new file mode 100644 index 0000000..4e7bdfc --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Diagnostics.Tests/packages.lock.json @@ -0,0 +1,821 @@ +{ + "version": 2, + "dependencies": { + "net10.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Direct", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.diagnostics": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[10.0.5, )", + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + } + }, + "net8.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Direct", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.diagnostics": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[10.0.5, )", + "System.Diagnostics.DiagnosticSource": "[10.0.5, )", + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "CCbzHQ26L3jskdwHh+4bxxW84lUMIrAAmeSlpO69AlrQV0DKbj1/I+feLaLSuZeqXPr9UlSy0OcgZoXOk2a6/g==" + } + }, + "net9.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Direct", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.diagnostics": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[10.0.5, )", + "System.Diagnostics.DiagnosticSource": "[10.0.5, )", + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "CCbzHQ26L3jskdwHh+4bxxW84lUMIrAAmeSlpO69AlrQV0DKbj1/I+feLaLSuZeqXPr9UlSy0OcgZoXOk2a6/g==" + } + } + } +} \ No newline at end of file diff --git a/tests/WorkflowFramework.Extensions.Events.Tests/Events/InMemoryEventBusScenarios.cs b/tests/WorkflowFramework.Extensions.Events.Tests/Events/InMemoryEventBusScenarios.cs new file mode 100644 index 0000000..2777354 --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Events.Tests/Events/InMemoryEventBusScenarios.cs @@ -0,0 +1,166 @@ +using FluentAssertions; +using TinyBDD; +using TinyBDD.Xunit; +using WorkflowFramework.Extensions.Events; +using Xunit; +using Xunit.Abstractions; + +namespace WorkflowFramework.Extensions.Events.Tests.Events; + +[Feature("InMemoryEventBus — in-memory event pub/sub bus")] +public class InMemoryEventBusScenarios : TinyBddXunitBase +{ + public InMemoryEventBusScenarios(ITestOutputHelper output) : base(output) { } + + private static WorkflowEvent MakeEvent(string type, string correlationId = "corr-1") => + new WorkflowEvent { EventType = type, CorrelationId = correlationId }; + + [Scenario("Published event with no subscribers goes to DeadLetters"), Fact] + public async Task Publish_NoSubscribers_GoesToDeadLetters() + { + var bus = new InMemoryEventBus(); + var evt = MakeEvent("no-sub"); + + await bus.PublishAsync(evt); + + await Given("event published with no subscribers", () => bus.DeadLetters) + .Then("event ends up in DeadLetters", dl => + { + dl.Should().Contain(evt); + return true; + }) + .AssertPassed(); + } + + [Scenario("Published event is delivered to subscriber"), Fact] + public async Task Publish_WithSubscriber_DeliversEvent() + { + var bus = new InMemoryEventBus(); + WorkflowEvent? received = null; + bus.Subscribe("order.placed", evt => { received = evt; return Task.CompletedTask; }); + + var toPublish = MakeEvent("order.placed"); + await bus.PublishAsync(toPublish); + + await Given("event published with a subscriber", () => received) + .Then("subscriber received the event", r => + { + r.Should().NotBeNull(); + r!.EventType.Should().Be("order.placed"); + return true; + }) + .AssertPassed(); + } + + [Scenario("Published event does NOT go to DeadLetters when subscriber exists"), Fact] + public async Task Publish_WithSubscriber_NotInDeadLetters() + { + var bus = new InMemoryEventBus(); + bus.Subscribe("live-type", _ => Task.CompletedTask); + await bus.PublishAsync(MakeEvent("live-type")); + + await Given("subscriber exists for event type", () => bus.DeadLetters) + .Then("DeadLetters is empty", dl => + { + dl.Should().BeEmpty(); + return true; + }) + .AssertPassed(); + } + + [Scenario("Subscribe returns disposable that unsubscribes"), Fact] + public async Task Subscribe_Disposable_Unsubscribes() + { + var bus = new InMemoryEventBus(); + var count = 0; + using (var sub = bus.Subscribe("tick", _ => { count++; return Task.CompletedTask; })) + { + await bus.PublishAsync(MakeEvent("tick")); + } + // After dispose + await bus.PublishAsync(MakeEvent("tick")); + + await Given("subscription disposed, then second event published", () => count) + .Then("handler was called only once (before unsubscribe)", c => + { + c.Should().Be(1); + return true; + }) + .AssertPassed(); + } + + [Scenario("WaitForEventAsync resolves when matching event published"), Fact] + public async Task WaitForEventAsync_ResolvesOnMatch() + { + var bus = new InMemoryEventBus(); + var waitTask = bus.WaitForEventAsync("payment.done", "order-42", TimeSpan.FromSeconds(5)); + + _ = Task.Run(async () => + { + await Task.Delay(30); + await bus.PublishAsync(new WorkflowEvent { EventType = "payment.done", CorrelationId = "order-42" }); + }); + + var result = await waitTask; + + await Given("WaitForEventAsync called, event published concurrently", () => result) + .Then("result is not null and has correct type/correlationId", r => + { + r.Should().NotBeNull(); + r!.EventType.Should().Be("payment.done"); + r.CorrelationId.Should().Be("order-42"); + return true; + }) + .AssertPassed(); + } + + [Scenario("WaitForEventAsync returns null on timeout"), Fact] + public async Task WaitForEventAsync_ReturnsNullOnTimeout() + { + var bus = new InMemoryEventBus(); + var result = await bus.WaitForEventAsync("never.happens", "x", TimeSpan.FromMilliseconds(30)); + + await Given("no event published within timeout", () => result) + .Then("result is null", r => + { + r.Should().BeNull(); + return true; + }) + .AssertPassed(); + } + + [Scenario("PublishAsync with null event throws ArgumentNullException"), Fact] + public async Task Publish_NullEvent_Throws() + { + var bus = new InMemoryEventBus(); + Exception? caught = null; + try { await bus.PublishAsync(null!); } + catch (Exception ex) { caught = ex; } + + await Given("null event published", () => caught) + .Then("ArgumentNullException thrown", ex => + { + ex.Should().BeOfType(); + return true; + }) + .AssertPassed(); + } + + [Scenario("Multiple subscribers all receive the event"), Fact] + public async Task MultipleSubscribers_AllReceive() + { + var bus = new InMemoryEventBus(); + var count = 0; + bus.Subscribe("shared", _ => { count++; return Task.CompletedTask; }); + bus.Subscribe("shared", _ => { count++; return Task.CompletedTask; }); + await bus.PublishAsync(MakeEvent("shared")); + + await Given("two subscribers on same event type", () => count) + .Then("both handlers were called", c => + { + c.Should().Be(2); + return true; + }) + .AssertPassed(); + } +} diff --git a/tests/WorkflowFramework.Extensions.Events.Tests/WorkflowFramework.Extensions.Events.Tests.csproj b/tests/WorkflowFramework.Extensions.Events.Tests/WorkflowFramework.Extensions.Events.Tests.csproj new file mode 100644 index 0000000..2a927bb --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Events.Tests/WorkflowFramework.Extensions.Events.Tests.csproj @@ -0,0 +1,22 @@ + + + WorkflowFramework.Extensions.Events.Tests + false + + + + + + + + + + + + + + + + + + diff --git a/tests/WorkflowFramework.Extensions.Events.Tests/packages.lock.json b/tests/WorkflowFramework.Extensions.Events.Tests/packages.lock.json new file mode 100644 index 0000000..c7b2d4d --- /dev/null +++ b/tests/WorkflowFramework.Extensions.Events.Tests/packages.lock.json @@ -0,0 +1,816 @@ +{ + "version": 2, + "dependencies": { + "net10.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.events": { + "type": "Project", + "dependencies": { + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + } + }, + "net8.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.events": { + "type": "Project", + "dependencies": { + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "CCbzHQ26L3jskdwHh+4bxxW84lUMIrAAmeSlpO69AlrQV0DKbj1/I+feLaLSuZeqXPr9UlSy0OcgZoXOk2a6/g==" + } + }, + "net9.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg==" + }, + "FluentAssertions": { + "type": "Direct", + "requested": "[8.3.0, )", + "resolved": "8.3.0", + "contentHash": "iri1druxHPUAvaFqTUKJG7NOHwnOLmWwfDorgezZWpeBWBJmk2o8niI7jL7zW9TEFGnUpMJi/JLG6FXgr3cM3A==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.0.1, )", + "resolved": "18.0.1", + "contentHash": "WNpu6vI2rA0pXY4r7NKxCN16XRWl5uHu6qjuyVLoDo6oYEggIQefrMjkRuibQHm/NslIUNCcKftvoWAN80MSAg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.0.1", + "Microsoft.TestPlatform.TestHost": "18.0.1" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NSubstitute": { + "type": "Direct", + "requested": "[5.3.0, )", + "resolved": "5.3.0", + "contentHash": "lJ47Cps5Qzr86N99lcwd+OUvQma7+fBgr8+Mn+aOC0WrlqMNkdivaYD9IvnZ5Mqo6Ky3LS7ZI+tUq1/s9ERd0Q==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "TinyBDD": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "H9FEUkilavosn+wNDUItTPxOYRtQXzyt0dz+1wTyUKeijvois0FX2fkHEde08ockkOpebqffJxSleIH+7jZe7w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "TinyBDD.Xunit": { + "type": "Direct", + "requested": "[0.19.16, )", + "resolved": "0.19.16", + "contentHash": "DgqB3Il3xiidn065cOga4HbyXWRV3hdgrKQKWThaXCWH40XkyWMt6ZttRuVs4LgFf73OSIsgxjrt3Tm7731O1g==", + "dependencies": { + "TinyBDD": "0.19.16", + "xunit.abstractions": "2.0.3", + "xunit.extensibility.core": "2.9.3" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "K9O9TOzugqOo4LJ87uuq1VG8RAqGp20Ng85Wx932oT5LNBkIgeeGYubVW5UMnOOTanFNbGavmbuYrJr4INzSwg==" + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "O+utSr97NAJowIQT/OVp3Lh9QgW/wALVTP4RG1m2AfFP4IyJmJz0ZBmFJUsRQiAPgq6IRC0t8AAzsiPIsaUDEA==" + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Options": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.5", + "contentHash": "/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.0.1", + "contentHash": "uDJKAEjFTaa2wHdWlfo6ektyoh+WD4/Eesrwb4FpBFKsLGehhACVnwwTI4qD3FrIlIEPlxdXg3SyrYRIcO+RRQ==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.0.1", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "lcyUiXTsETK2ALsZrX+nWuHSIQeazhqPphLfaRxzdGaG93+0kELqpgEHtwWOlQe7+jSFnKwaCAgL4kjeZCQJnw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "workflowframework": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", + "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", + "PatternKit.Core": "[0.105.0, )" + } + }, + "workflowframework.extensions.events": { + "type": "Project", + "dependencies": { + "WorkflowFramework": "[1.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.5", + "Microsoft.Extensions.Logging.Abstractions": "10.0.5" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "System.Diagnostics.DiagnosticSource": "10.0.5" + } + }, + "Microsoft.Extensions.Options": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.5", + "Microsoft.Extensions.Primitives": "10.0.5" + } + }, + "PatternKit.Core": { + "type": "CentralTransitive", + "requested": "[0.105.0, )", + "resolved": "0.105.0", + "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "CentralTransitive", + "requested": "[10.0.5, )", + "resolved": "10.0.5", + "contentHash": "CCbzHQ26L3jskdwHh+4bxxW84lUMIrAAmeSlpO69AlrQV0DKbj1/I+feLaLSuZeqXPr9UlSy0OcgZoXOk2a6/g==" + } + } + } +} \ No newline at end of file