using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Planning;
namespace XFEEDToolBox.Test;
[TestFixture]public sealed class TradePlanningInputTests
{
[Test]public async Task FreshCompatibleMarketsSurviveNearerCarriersAndExpiredStationsBeforeTheLimit()
{
using var temporary=new TemporaryDirectory();var repository=new MarketRepository(temporary.File("markets.db"));repository.InitializeCheap();
var at=DateTimeOffset.UtcNow;var request=Check.Request with{AsOf=at,Loop=false,MaxLegs=1,SearchRadiusLy=500};
await repository.SaveSnapshotAsync(new(Check.Station(1),[Check.Quote(1,"water",100,90)],at,DataSource.Journal));
for(var id=10;id<210;id++)
await repository.SaveSnapshotAsync(new(Check.Station(id,.1) with{IsFleetCarrier=id%2==0,IsRestricted=id%2==0},[Check.Quote(id,"water",0,200)],id%2==0?at:at.AddDays(-2),DataSource.Journal));
await repository.SaveSnapshotAsync(new(Check.Station(2,7.23),[Check.Quote(2,"water",0,180)],at,DataSource.Journal));
var old=repository.LoadRegion(1,500);Check.That(old.Truncated);Check.That(!old.Stations.Any(station=>station.MarketId==2));
var book=repository.LoadPlanningRegion(request);Check.Equal(2,book.Stations.Count);Check.That(book.Stations.Any(station=>station.MarketId==2));
var result=new TradeRoutePlanner().CalculateCandidatesWithDiagnostics(book,request);
Check.That(result.Candidates.Count>0);Check.Equal(2,result.Diagnostics.FreshStations);Check.Equal("found",result.Diagnostics.Code);
Check.Equal(2L,result.Candidates[0].Legs.Single().To.MarketId);
}
[Test]public void DiagnosticsSeparateStaleInputAndMissingMarketsFromAnEconomicSearch()
{
var planner=new TradeRoutePlanner();var request=Check.Request with{AsOf=DateTimeOffset.UtcNow,Loop=false,MaxLegs=1};
var stale=Check.TwoStations with{Quotes=Check.TwoStations.Quotes.Select(quote=>quote with{CollectedAt=request.AsOf.AddDays(-2)}).ToArray()};
var result=planner.CalculateCandidatesWithDiagnostics(stale,request);
Check.Equal("expired-or-restricted-quotes",result.Diagnostics.Code);Check.Equal(0,result.Diagnostics.FreshQuotes);Check.That(result.Diagnostics.Message.Contains("不表示"));
var one=planner.CalculateCandidatesWithDiagnostics(Check.TwoStations with{Quotes=Check.TwoStations.Quotes.Where(quote=>quote.MarketId==1).ToArray()},request);
Check.Equal("insufficient-fresh-markets",one.Diagnostics.Code);Check.Equal(1,one.Diagnostics.FreshStations);
}
[Test]public async Task PlanningReadHonoursCancellationAndDoesNotInventMissingOriginQuotes()
{
using var temporary=new TemporaryDirectory();var repository=new MarketRepository(temporary.File("markets.db"));repository.InitializeCheap();
await repository.SaveStationAsync(Check.Station(1),localObservation:true);
using var cancelled=new CancellationTokenSource();cancelled.Cancel();
Check.Throws<OperationCanceledException>(()=>repository.LoadPlanningRegion(Check.Request,token:cancelled.Token));
var book=repository.LoadPlanningRegion(Check.Request);Check.Equal(1,book.Stations.Count);Check.Equal(0,book.Quotes.Count);
Check.Equal("no-fresh-quotes",new TradeRoutePlanner().CalculateCandidatesWithDiagnostics(book,Check.Request).Diagnostics.Code);
}
}
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Planning;
namespace XFEEDToolBox.Test;
[TestFixture]public sealed class TradePlanningInputTests
{
[Test]public async Task FreshCompatibleMarketsSurviveNearerCarriersAndExpiredStationsBeforeTheLimit()
{
using var temporary=new TemporaryDirectory();var repository=new MarketRepository(temporary.File("markets.db"));repository.InitializeCheap();
var at=DateTimeOffset.UtcNow;var request=Check.Request with{AsOf=at,Loop=false,MaxLegs=1,SearchRadiusLy=500};
await repository.SaveSnapshotAsync(new(Check.Station(1),[Check.Quote(1,"water",100,90)],at,DataSource.Journal));
for(var id=10;id<210;id++)
await repository.SaveSnapshotAsync(new(Check.Station(id,.1) with{IsFleetCarrier=id%2==0,IsRestricted=id%2==0},[Check.Quote(id,"water",0,200)],id%2==0?at:at.AddDays(-2),DataSource.Journal));
await repository.SaveSnapshotAsync(new(Check.Station(2,7.23),[Check.Quote(2,"water",0,180)],at,DataSource.Journal));
var old=repository.LoadRegion(1,500);Check.That(old.Truncated);Check.That(!old.Stations.Any(station=>station.MarketId==2));
var book=repository.LoadPlanningRegion(request);Check.Equal(2,book.Stations.Count);Check.That(book.Stations.Any(station=>station.MarketId==2));
var result=new TradeRoutePlanner().CalculateCandidatesWithDiagnostics(book,request);
Check.That(result.Candidates.Count>0);Check.Equal(2,result.Diagnostics.FreshStations);Check.Equal("found",result.Diagnostics.Code);
Check.Equal(2L,result.Candidates[0].Legs.Single().To.MarketId);
}
[Test]public void DiagnosticsSeparateStaleInputAndMissingMarketsFromAnEconomicSearch()
{
var planner=new TradeRoutePlanner();var request=Check.Request with{AsOf=DateTimeOffset.UtcNow,Loop=false,MaxLegs=1};
var stale=Check.TwoStations with{Quotes=Check.TwoStations.Quotes.Select(quote=>quote with{CollectedAt=request.AsOf.AddDays(-2)}).ToArray()};
var result=planner.CalculateCandidatesWithDiagnostics(stale,request);
Check.Equal("expired-or-restricted-quotes",result.Diagnostics.Code);Check.Equal(0,result.Diagnostics.FreshQuotes);Check.That(result.Diagnostics.Message.Contains("不表示"));
var one=planner.CalculateCandidatesWithDiagnostics(Check.TwoStations with{Quotes=Check.TwoStations.Quotes.Where(quote=>quote.MarketId==1).ToArray()},request);
Check.Equal("insufficient-fresh-markets",one.Diagnostics.Code);Check.Equal(1,one.Diagnostics.FreshStations);
}
[Test]public async Task PlanningReadHonoursCancellationAndDoesNotInventMissingOriginQuotes()
{
using var temporary=new TemporaryDirectory();var repository=new MarketRepository(temporary.File("markets.db"));repository.InitializeCheap();
await repository.SaveStationAsync(Check.Station(1),localObservation:true);
using var cancelled=new CancellationTokenSource();cancelled.Cancel();
Check.Throws<OperationCanceledException>(()=>repository.LoadPlanningRegion(Check.Request,token:cancelled.Token));
var book=repository.LoadPlanningRegion(Check.Request);Check.Equal(1,book.Stations.Count);Check.Equal(0,book.Quotes.Count);
Check.Equal("no-fresh-quotes",new TradeRoutePlanner().CalculateCandidatesWithDiagnostics(book,Check.Request).Diagnostics.Code);
}
}