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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEEDToolBox.Core.Engineering;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Outfitting;
using XFEEDToolBox.Core.Presentation;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;

[TestFixture]
public class InterfaceRefinementTests
{
    private static NavigationLegPreview Leg(int number)=>new(number,number,$"Star {number}","K",20,true,false,number==1,null);
    [Test] public void RouteHistorySurvivesSuffixUpdatesAndArrivalClearing()
    {
        var route=new NavigationItinerary();route.UpdateRoute([Leg(1),Leg(2),Leg(3)]);route.ConfirmPosition(1);
        route.UpdateRoute([Leg(2) with{Number=1},Leg(3) with{Number=2}]);
        var rows=route.Present(NavigationRunState.Running,"正在充能","Star 2");
        Check.Equal(3,rows.Count);Check.Equal(NavigationLegState.Completed,rows[0].Status);
        Check.Equal(NavigationLegState.Running,rows[1].Status);Check.Equal("正在充能",rows[1].Message);Check.Equal(2,rows[1].Number);
        Check.Equal(NavigationLegState.Waiting,rows[2].Status);Check.Equal("",rows[2].Message);
        route.ConfirmPosition(3);route.UpdateRoute([]);Check.That(route.Present(NavigationRunState.Completed).All(r=>r.Status==NavigationLegState.Completed));
    }
    [Test] public void FailureAndCancellationOnlyMarkThePendingHop()
    {
        var route=new NavigationItinerary();route.UpdateRoute([Leg(1),Leg(2),Leg(3)]);route.ConfirmPosition(1);
        foreach(var (state,expected) in new[]{(NavigationRunState.Failed,NavigationLegState.Error),(NavigationRunState.Stopped,NavigationLegState.Warning)})
        {
            var rows=route.Present(state,"测试状态");Check.Equal(NavigationLegState.Completed,rows[0].Status);Check.Equal(expected,rows[1].Status);Check.Equal(NavigationLegState.Waiting,rows[2].Status);
        }
        route.Reset();Check.Equal(0,route.Present(NavigationRunState.Idle).Count);
    }
    [Test] public void ChangedGameRouteReplacesTheOldSequence()
    {
        var route=new NavigationItinerary();route.UpdateRoute([Leg(1),Leg(2),Leg(3)]);
        route.UpdateRoute([Leg(5),Leg(6)]);var rows=route.Present(NavigationRunState.Idle);
        Check.That(rows.Select(r=>r.SystemAddress).SequenceEqual(new long[]{5,6}));Check.That(rows.Select(r=>r.Number).SequenceEqual(new[]{1,2}));
    }
    [Test] public void LiveRefitUpdatesDoNotReplaceTheSelectedSlotOrPropertyRows()
    {
        var module=new FittedModule{Slot="LargeHardpoint1",Item="hpt_multicannon_gimbal_large",Health=1,Engineering=new(){Level=3,Quality=.65}};
        var slot=new RefitSlot{Slot=module.Slot,Module=module,Category="hardpoint",Capacity=3};
        var slots=new LiveCollection<RefitSlotLiveRow,RefitSlot,string>(s=>s.Slot,s=>new(s));slots.Apply([slot]);var selected=slots.Single();
        var events=new List<string>();selected.PropertyChanged+=(_,e)=>events.Add(e.PropertyName!);
        var delta=slots.Apply([slot with{Module=module with{Health=.8,Engineering=module.Engineering with{Level=4,Quality=.2}}}]);
        Check.That(ReferenceEquals(selected,slots.Single()));Check.Equal(0,delta.Added+delta.Removed+delta.Moved);Check.Equal("G4",selected.CurrentGrade);Check.That(!events.Contains(nameof(RefitSlotLiveRow.IconItem)));
        var properties=new LiveCollection<RefitPropertyLiveRow,RefitPropertyRow,string>(p=>p.OriginalName,p=>new(p));
        properties.Apply([new("完整度","Integrity","100%")]);var health=properties.Single();
        var change=properties.Apply([new("完整度","Integrity","80%")]);Check.That(ReferenceEquals(health,properties.Single()));Check.Equal("80%",health.Value);Check.Equal(0,change.Added+change.Removed);
    }
    [Test] public void ModuleBrowserOnlyOffersCompatibleTypesThenTheirModels()
    {
        var catalog=OutfittingCatalog.Default;var doc=ShipRefit.Create(new(){ShipId=1,Type="anaconda",ConfigurationAt=DateTimeOffset.UtcNow,Modules=[]},catalog);
        var slots=new[]{doc.Slots.Single(s=>s.Slot=="SmallHardpoint1"),doc.Slots.Single(s=>s.Slot=="Slot01_Size7"),doc.Slots.Single(s=>s.Slot=="Military01")};
        var choices=ShipRefit.Choices(new(),catalog);
        foreach(var slot in slots)
        {
            var compatible=RefitModuleBrowser.Compatible(doc,slot,choices,catalog);var types=RefitModuleBrowser.Types(compatible);
            Check.That(compatible.Count>0&&types.Count>0&&compatible.All(c=>ShipRefit.Fits(doc,slot,c.Definition,catalog)));
            Check.Equal(types.Count,types.Select(t=>t.Key).Distinct().Count());
            foreach(var type in types)Check.That(compatible.Any(c=>XFEEDToolBox.Core.Outfitting.RefitModuleBrowser.TypeKey(c.Definition)==type.Key)&&!type.Name.Contains("1A "));
        }
    }
    [Test] public void CancelledEngineeringCalculationDoesNotReturnAMaterialBudget()
    {
        using var stop=new CancellationTokenSource();stop.Cancel();
        Check.Throws<OperationCanceledException>(()=>EngineeringPlanner.Calculate(EngineeringCatalog.Default,new(){Item="hpt_multicannon_gimbal_large"},"Overcharged Weapon",5,1,null,new(){Rank=5,Progress="Unlocked"},[],token:stop.Token));
    }
}