using XFEExtension.NetCore.XUnit.Attributes; using XFEEDToolBox.Core.Engineering; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Core.Outfitting; namespace XFEEDToolBox.Test; [TestFixture] public class RefitTests { private static readonly OutfittingCatalog Outfitting=OutfittingCatalog.Default; private static FittedModule Cannon(string slot)=>new(){Slot=slot,Item="hpt_multicannon_gimbal_large",Name="Multi-Cannon"}; private static ShipRecord Ship()=>new(){ShipId=1,Type="anaconda",ConfigurationAt=DateTimeOffset.UtcNow,Modules=[Cannon("LargeHardpoint1"),Cannon("LargeHardpoint2")]}; private static EngineerAccess Engineer=>new(){Id=300260,Name="Tod 'The Blaster' McQuinn",Progress="Unlocked",Rank=1,ReputationMin=0,ReputationMax=0}; [Test] public void SimulationNeverMutatesSourceAndRejectsOversizedModule() { var source=Ship();var simulation=ShipRefit.Create(source,Outfitting);var definition=Outfitting.Modules.First(m=>m.Category=="hardpoint"&&m.Size==4); var choice=new RefitModuleChoice("","计划购入",new(){Item=definition.Item},definition); Check.Throws(()=>ShipRefit.Install(simulation,"LargeHardpoint1",choice,Outfitting)); var removed=ShipRefit.Install(simulation,"LargeHardpoint1",null,Outfitting); Check.That(removed.Slots.Single(s=>s.Slot=="LargeHardpoint1").Module is null);Check.Equal(2,source.Modules.Count); Check.That(simulation.Slots.Single(s=>s.Slot=="LargeHardpoint1").Module is not null); } [Test] public void OwnedModuleCannotBeDuplicatedAcrossSlots() { var simulation=ShipRefit.Create(Ship(),Outfitting);var module=Cannon("LargeHardpoint1");var choice=new RefitModuleChoice("ship:1:LargeHardpoint1","现有模块",module,Outfitting.Find(module.Item)!); Check.Throws(()=>ShipRefit.Install(simulation,"LargeHardpoint2",choice,Outfitting)); simulation=ShipRefit.Install(simulation,"LargeHardpoint1",null,Outfitting); simulation=ShipRefit.Install(simulation,"LargeHardpoint2",choice,Outfitting);Check.That(simulation.Slots.Single(s=>s.Slot=="LargeHardpoint2").Module?.Slot=="LargeHardpoint2"); } [Test] public void WholeShipSharesEngineerReputationAndSubtractsInventoryOnce() { var source=Ship();var doc=ShipRefit.Create(source,Outfitting);var target=new RefitTarget("Overcharged Weapon",5,1,"",300260,false,true); doc=ShipRefit.SetTarget(doc,"LargeHardpoint1",target);doc=ShipRefit.SetTarget(doc,"LargeHardpoint2",target); var together=ShipRefitPlanner.Calculate(doc,EngineeringCatalog.Default,[Engineer],[new("nickel","Nickel",8)]); var independent=EngineeringPlanner.Calculate(EngineeringCatalog.Default,source.Modules[0],target.Blueprint,5,1,null,Engineer,[]); Check.That(together.Complete);Check.Equal(2,together.Modules.Count);Check.Equal(15,together.Modules[1].Rolls); Check.That(together.Modules.Sum(m=>m.Rolls)m.Key=="nickel");Check.Equal(8,nickel.Owned);Check.Equal(Math.Max(0,nickel.Required-8),nickel.Missing); } [Test] public void EmptyHardpointsAreAvailableFromReferenceShape() { var doc=ShipRefit.Create(Ship(),Outfitting);var empty=doc.Slots.Single(s=>s.Slot=="HugeHardpoint1");Check.That(empty.Module is null&&empty.Capacity==4); } [Test] public void EmptyOptionalAndMilitarySlotsUseCurrentShipLayout() { var doc=ShipRefit.Create(Ship(),Outfitting); Check.That(doc.Slots.Any(s=>s.Slot=="Slot01_Size7"&&s.Module is null&&s.Capacity==7)); Check.That(doc.Slots.Any(s=>s.Slot=="Military01"&&s.Capacity==5)); Check.That(doc.Slots.All(s=>!s.Slot.StartsWith("Slot")||s.Category=="internal")); Check.Equal(doc.Slots.Count,doc.Slots.Select(s=>s.Slot).Distinct().Count()); } [Test] public void MissingRemoteShipConfigurationIsNotInvented() {Check.Throws(()=>ShipRefit.Create(new(){ShipId=2,Type="anaconda"},Outfitting));} }