XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Models;

namespace XFEEDToolBox.Test;

[TestFixture]
public class CacheRegionTests
{
    private static async Task<MarketRepository> Seed(TemporaryDirectory directory,params Station[] stations)
    {
        var repository=new MarketRepository(directory.File("markets.db"));repository.InitializeCheap();var at=DateTimeOffset.UtcNow.AddMinutes(-1);
        foreach(var station in stations)
            await repository.SaveSnapshotAsync(new(station,[Check.Quote(station.MarketId,"commodity"+station.MarketId,10,9)],at,DataSource.Journal));
        return repository;
    }
    private static string Ids(IEnumerable<Station> stations)=>string.Join(',',stations.Select(station=>station.MarketId));

    [Test]public async Task NearbyStationsUseAnExactSphereAndDeterministicDistanceOrder()
    {
        using var directory=new TemporaryDirectory();var center=new Coordinates(10,20,30);
        var repository=await Seed(directory,
            Check.Station(1) with{Position=center},
            Check.Station(2) with{Position=new(13,24,30)},
            Check.Station(3) with{Position=new(14,24,30)},
            Check.Station(4) with{Position=new(8,20,30),SystemName="A"},
            Check.Station(5) with{Position=null},
            Check.Station(6) with{Position=new(12,20,30),SystemName="Z"});
        Check.Equal("1,4,6,2",Ids(repository.GetStationsNear(center,5)));
        Check.Equal("1,4",Ids(repository.GetStationsNear(center,5,limit:2)));
        Check.Equal(new Coordinates(13,24,30),repository.GetStationsNear(center,5).Last().Position!);
    }

    [Test]public async Task ExplicitCenterFiltersTheBookWhileKeepingTheActualOriginFirst()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Check.Station(1,15),Check.Station(2,0),Check.Station(3,-5),Check.Station(4,30));
        var book=repository.LoadRegion(1,20,center:new(0,0,0));
        Check.Equal("1,2,3",Ids(book.Stations));Check.Equal(new Coordinates(15,0,0),book.Stations[0].Position!);
        Check.Equal("1,2,3",string.Join(',',book.Quotes.Select(quote=>quote.MarketId).Order()));Check.That(!book.Truncated);
        Check.Equal("2,3,1",Ids(repository.GetStationsNear(new(0,0,0),20)));
    }

    [Test]public async Task OmittingTheCenterPreservesTheOriginCenteredRegion()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Check.Station(1,1000),Check.Station(2,1010),Check.Station(3,0));
        var book=repository.LoadRegion(1,25);Check.Equal("1,2",Ids(book.Stations));Check.Equal(2,book.Quotes.Count);
    }

    [Test]public async Task AnOriginOutsideTheChosenCenterIsExplicitlyRejected()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Check.Station(1,21),Check.Station(2,0));
        Check.Throws<InvalidOperationException>(()=>repository.LoadRegion(1,20,center:new(0,0,0)));
        // The actual route origin is never silently replaced by the center.
        Check.Equal(new Coordinates(21,0,0),repository.GetStation(1)!.Position!);
    }

    [Test]public async Task KnownCenterDoesNotInventAnUnknownOriginPosition()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Check.Station(1) with{Position=null},Check.Station(2,0));
        Check.Throws<ArgumentException>(()=>repository.LoadRegion(1,500,center:new(0,0,0)));
        Check.Throws<ArgumentException>(()=>repository.LoadRegion(999,500,center:new(0,0,0)));
    }

    [Test]public async Task RadiusAndCenterMustBeFiniteAndPositive()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Check.Station(1,0));var center=new Coordinates(0,0,0);
        foreach(var radius in new[]{0d,-1d,double.NaN,double.PositiveInfinity,double.NegativeInfinity,double.MaxValue})
        {
            Check.Throws<ArgumentOutOfRangeException>(()=>repository.GetStationsNear(center,radius));
            Check.Throws<ArgumentOutOfRangeException>(()=>repository.LoadRegion(1,radius,center:center));
        }
        Check.Throws<ArgumentException>(()=>repository.GetStationsNear(new(double.NaN,0,0),500));
        Check.Throws<ArgumentException>(()=>repository.LoadRegion(1,500,center:new(0,double.PositiveInfinity,0)));
    }

    [Test]public async Task TruncatedBooksIncludeOnlySelectedStationsAndTheirQuotes()
    {
        using var directory=new TemporaryDirectory();var repository=await Seed(directory,Enumerable.Range(1,5).Select(id=>Check.Station(id,id-1)).ToArray());
        var book=repository.LoadRegion(5,10,limit:2,center:new(0,0,0));
        Check.That(book.Truncated);Check.Equal("5,1",Ids(book.Stations));Check.Equal(2,book.Quotes.Count);
        Check.That(book.Quotes.All(quote=>quote.MarketId is 5 or 1));
        var full=repository.LoadRegion(5,10,limit:5,center:new(0,0,0));Check.That(!full.Truncated);Check.Equal(5,full.Quotes.Count);
    }
}