using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Models;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class TradePauseMutationBarrierTests
{
private sealed class Production:ITradeCommandDriver,ITradeRunMenuRecovery
{
public int Preflights,Releases,Mutations;public Func<bool>? Allowed;
public Task PreflightAsync(CancellationToken token){Preflights++;return Task.CompletedTask;}
public Task ReleaseAllAsync(){Releases++;return Task.CompletedTask;}
public Task ServiceDockedAsync(DockedServiceRequest request,Func<CancellationToken,Task> before,CancellationToken token){Mutations++;return Task.CompletedTask;}
public Task ExecuteAsync(TradeAction action,Func<CancellationToken,Task> before,CancellationToken token){Mutations++;return Task.CompletedTask;}
public IDisposable EnterRunningMenuRecovery(Func<bool> running,CancellationToken token){Allowed=running;return new Lease();}
}
private sealed class Lease:IDisposable{public void Dispose(){}}
[Test]public async Task EveryFinancialTravelAndServiceMutationWaitsForCancellationWithoutForwarding()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);
using var stop=new CancellationTokenSource();
var operations=new[]{TradeActionKind.Buy,TradeActionKind.Sell,TradeActionKind.Travel}
.Select(kind=>barrier.ExecuteAsync(new(kind,new TradeLeg(),null),_=>Task.CompletedTask,stop.Token)).ToList();
operations.Add(barrier.ServiceDockedAsync(new(1,1),_=>Task.CompletedTask,stop.Token));
Check.That(operations.All(value=>!value.IsCompleted));Check.Equal(0,production.Mutations);
Check.Equal(1,barrier.BlockedBuys);Check.Equal(1,barrier.BlockedSells);Check.Equal(1,barrier.BlockedTravels);Check.Equal(1,barrier.BlockedServices);
stop.Cancel();foreach(var task in operations){try{await task;throw new InvalidOperationException("Mutation barrier completed as a fake success.");}catch(OperationCanceledException){}}
Check.Equal(0,production.Mutations);Check.Equal(0,TradePauseMutationBarrier.ForwardedMutations);
}
[Test]public async Task ProductionPreflightAndTrueRunnerPredicateAreRetained()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);var running=false;
await barrier.PreflightAsync(default);using var scope=barrier.EnterRunningMenuRecovery(()=>running,default);
Check.Equal(1,production.Preflights);Check.That(!production.Allowed!());running=true;Check.That(production.Allowed!());
running=false;Check.That(!production.Allowed!());await barrier.ReleaseAllAsync();Check.Equal(1,production.Releases);Check.Equal(0,production.Mutations);
}
[Test]public async Task ARejectedPreInputCheckCannotReachAnyMutationOrReportFakeCompletion()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);
try{await barrier.ExecuteAsync(new(TradeActionKind.Buy,new(),null),_=>throw new InvalidOperationException("real safety refusal"),default);throw new Exception("Refusal was ignored.");}
catch(InvalidOperationException error){Check.Equal("real safety refusal",error.Message);}
Check.Equal(0,production.Mutations);Check.Equal(0,barrier.BlockedBuys);Check.That(!barrier.FirstMutationHeld.IsCompleted);
}
}
using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Models;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class TradePauseMutationBarrierTests
{
private sealed class Production:ITradeCommandDriver,ITradeRunMenuRecovery
{
public int Preflights,Releases,Mutations;public Func<bool>? Allowed;
public Task PreflightAsync(CancellationToken token){Preflights++;return Task.CompletedTask;}
public Task ReleaseAllAsync(){Releases++;return Task.CompletedTask;}
public Task ServiceDockedAsync(DockedServiceRequest request,Func<CancellationToken,Task> before,CancellationToken token){Mutations++;return Task.CompletedTask;}
public Task ExecuteAsync(TradeAction action,Func<CancellationToken,Task> before,CancellationToken token){Mutations++;return Task.CompletedTask;}
public IDisposable EnterRunningMenuRecovery(Func<bool> running,CancellationToken token){Allowed=running;return new Lease();}
}
private sealed class Lease:IDisposable{public void Dispose(){}}
[Test]public async Task EveryFinancialTravelAndServiceMutationWaitsForCancellationWithoutForwarding()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);
using var stop=new CancellationTokenSource();
var operations=new[]{TradeActionKind.Buy,TradeActionKind.Sell,TradeActionKind.Travel}
.Select(kind=>barrier.ExecuteAsync(new(kind,new TradeLeg(),null),_=>Task.CompletedTask,stop.Token)).ToList();
operations.Add(barrier.ServiceDockedAsync(new(1,1),_=>Task.CompletedTask,stop.Token));
Check.That(operations.All(value=>!value.IsCompleted));Check.Equal(0,production.Mutations);
Check.Equal(1,barrier.BlockedBuys);Check.Equal(1,barrier.BlockedSells);Check.Equal(1,barrier.BlockedTravels);Check.Equal(1,barrier.BlockedServices);
stop.Cancel();foreach(var task in operations){try{await task;throw new InvalidOperationException("Mutation barrier completed as a fake success.");}catch(OperationCanceledException){}}
Check.Equal(0,production.Mutations);Check.Equal(0,TradePauseMutationBarrier.ForwardedMutations);
}
[Test]public async Task ProductionPreflightAndTrueRunnerPredicateAreRetained()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);var running=false;
await barrier.PreflightAsync(default);using var scope=barrier.EnterRunningMenuRecovery(()=>running,default);
Check.Equal(1,production.Preflights);Check.That(!production.Allowed!());running=true;Check.That(production.Allowed!());
running=false;Check.That(!production.Allowed!());await barrier.ReleaseAllAsync();Check.Equal(1,production.Releases);Check.Equal(0,production.Mutations);
}
[Test]public async Task ARejectedPreInputCheckCannotReachAnyMutationOrReportFakeCompletion()
{
var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);
try{await barrier.ExecuteAsync(new(TradeActionKind.Buy,new(),null),_=>throw new InvalidOperationException("real safety refusal"),default);throw new Exception("Refusal was ignored.");}
catch(InvalidOperationException error){Check.Equal("real safety refusal",error.Message);}
Check.Equal(0,production.Mutations);Check.Equal(0,barrier.BlockedBuys);Check.That(!barrier.FirstMutationHeld.IsCompleted);
}
}