using System.Text.Json;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Outfitting;
using XFEEDToolBox.Core.Presentation;
namespace XFEEDToolBox.Test;
public sealed class RefitOverviewStatsTests
{
private static ShipRefitDocument Actual()=>JsonSerializer.Deserialize<ShipRefitDocument>(File.ReadAllText(Path.Combine(AppContext.BaseDirectory,"Fixtures","edsy-actual-loadout.json")),ToolboxSettings.JsonOptions)!;
[Test] public void DefenceAndWeaponViewsUseTheCompleteEditedEdsyBuild()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);var view=ShipOverviewValues.From(stats);
Check.That(view.Hull>0&&view.Shield>0&&view.BurstDps>0);
Check.Equal(stats.Value("_armour"),view.Hull);Check.Equal(stats.Value("_shields"),view.Shield);
var damage=new[]{"dps_abs","dps_thm","dps_kin","dps_exp","dps_axe","dps_cau"}.Sum(key=>stats.Value(key)??0);
Check.That(Math.Abs(view.BurstDps!.Value-damage)<1e-8);
var expected=stats.Value("dps_nodistdraw")+(stats.Value("dps_distdraw")!*stats.Value("wepchg_sustain_cur"));
Check.That(expected is {} sustained&&Math.Abs(view.SustainedDps!.Value-sustained)<1e-8);
Check.That(view.SustainedDps>=0&&view.SustainedDps<=view.BurstDps);
var disabled=document with{Slots=document.Slots.Select(slot=>slot.Category=="hardpoint"&&slot.Module is {} module?slot with{Module=module with{Enabled=false}}:slot).ToArray()};
var unarmed=ShipOverviewValues.From(EdsyLinkCodec.Statistics(disabled));
Check.Equal(0d,unarmed.BurstDps);Check.Equal(0d,unarmed.SustainedDps);
Check.Equal(view.Hull,unarmed.Hull);Check.Equal(view.Shield,unarmed.Shield);
var full=ShipOverviewValues.From(stats,new(stats.Value("fuelcap"),1.07,stats.Value("cargocap")));
Check.Equal(full.CurrentMass,full.MaximumMass);
}
[Test] public void MissingStatsStayUnknownInEveryAdditionalView()
{
var view=ShipOverviewValues.From(null);
foreach(var rows in new[]{view.DefenceHull,view.DefenceShield,view.WeaponOutput,view.WeaponDamage,view.Capacities,view.ThermalAndCost})
Check.That(rows.Count==4&&rows.All(row=>row.Value.Contains('—')));
}
[Test] public void WholeShipDetailsContainEveryCalculatedShipAndInstalledModuleValue()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);
var sections=ShipDetailValues.Create(ShipOverviewValues.From(stats),stats,document);
var ship=sections.Single(s=>s.Key=="ship");
Check.That(ship.Values.Select(v=>v.Key).ToHashSet().SetEquals(stats.Ship.Keys));
foreach(var slot in document.Slots.Where(s=>s.Module is not null))
{
var detail=sections.Single(s=>s.Key=="module:"+slot.Slot);
Check.That(detail.Values.Select(v=>v.Key).Distinct().Count()==detail.Values.Count);
if(stats.Modules.TryGetValue(slot.Slot,out var attributes))
Check.That(attributes.Keys.All(key=>detail.Values.Any(row=>row.Key==key)));
}
Check.That(sections.SelectMany(s=>s.Values).All(v=>!v.Value.Contains("NaN")&&!v.Value.Contains("Infinity")));
Check.That(sections.Single(s=>s.Key=="weapons").Values.Any(v=>v.Name=="总爆发 DPS"&&v.Value!="—"));
}
[Test] public void DetailRowsKeepTheirIdentityWhenFlightConditionsChange()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);
var before=ShipDetailValues.Create(ShipOverviewValues.From(stats,new(Fuel:1,Cargo:0)),stats,document);
var after=ShipDetailValues.Create(ShipOverviewValues.From(stats,new(Fuel:20,Cargo:8)),stats,document);
var section=new ShipDetailSectionLiveRow(before.Single(s=>s.Key=="flight"));
var speed=section.Values[0];var original=speed.Value;
section.Update(after.Single(s=>s.Key=="flight"));section.Values.Apply(section.Record.Values);
Check.That(ReferenceEquals(speed,section.Values[0])&&speed.Value!=original);
var missing=ShipDetailValues.Create(ShipOverviewValues.Empty,null,null);
Check.That(missing.Single(s=>s.Key=="flight").Values.All(v=>v.Value.Contains('—')));
}
}
using System.Text.Json;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Outfitting;
using XFEEDToolBox.Core.Presentation;
namespace XFEEDToolBox.Test;
public sealed class RefitOverviewStatsTests
{
private static ShipRefitDocument Actual()=>JsonSerializer.Deserialize<ShipRefitDocument>(File.ReadAllText(Path.Combine(AppContext.BaseDirectory,"Fixtures","edsy-actual-loadout.json")),ToolboxSettings.JsonOptions)!;
[Test] public void DefenceAndWeaponViewsUseTheCompleteEditedEdsyBuild()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);var view=ShipOverviewValues.From(stats);
Check.That(view.Hull>0&&view.Shield>0&&view.BurstDps>0);
Check.Equal(stats.Value("_armour"),view.Hull);Check.Equal(stats.Value("_shields"),view.Shield);
var damage=new[]{"dps_abs","dps_thm","dps_kin","dps_exp","dps_axe","dps_cau"}.Sum(key=>stats.Value(key)??0);
Check.That(Math.Abs(view.BurstDps!.Value-damage)<1e-8);
var expected=stats.Value("dps_nodistdraw")+(stats.Value("dps_distdraw")!*stats.Value("wepchg_sustain_cur"));
Check.That(expected is {} sustained&&Math.Abs(view.SustainedDps!.Value-sustained)<1e-8);
Check.That(view.SustainedDps>=0&&view.SustainedDps<=view.BurstDps);
var disabled=document with{Slots=document.Slots.Select(slot=>slot.Category=="hardpoint"&&slot.Module is {} module?slot with{Module=module with{Enabled=false}}:slot).ToArray()};
var unarmed=ShipOverviewValues.From(EdsyLinkCodec.Statistics(disabled));
Check.Equal(0d,unarmed.BurstDps);Check.Equal(0d,unarmed.SustainedDps);
Check.Equal(view.Hull,unarmed.Hull);Check.Equal(view.Shield,unarmed.Shield);
var full=ShipOverviewValues.From(stats,new(stats.Value("fuelcap"),1.07,stats.Value("cargocap")));
Check.Equal(full.CurrentMass,full.MaximumMass);
}
[Test] public void MissingStatsStayUnknownInEveryAdditionalView()
{
var view=ShipOverviewValues.From(null);
foreach(var rows in new[]{view.DefenceHull,view.DefenceShield,view.WeaponOutput,view.WeaponDamage,view.Capacities,view.ThermalAndCost})
Check.That(rows.Count==4&&rows.All(row=>row.Value.Contains('—')));
}
[Test] public void WholeShipDetailsContainEveryCalculatedShipAndInstalledModuleValue()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);
var sections=ShipDetailValues.Create(ShipOverviewValues.From(stats),stats,document);
var ship=sections.Single(s=>s.Key=="ship");
Check.That(ship.Values.Select(v=>v.Key).ToHashSet().SetEquals(stats.Ship.Keys));
foreach(var slot in document.Slots.Where(s=>s.Module is not null))
{
var detail=sections.Single(s=>s.Key=="module:"+slot.Slot);
Check.That(detail.Values.Select(v=>v.Key).Distinct().Count()==detail.Values.Count);
if(stats.Modules.TryGetValue(slot.Slot,out var attributes))
Check.That(attributes.Keys.All(key=>detail.Values.Any(row=>row.Key==key)));
}
Check.That(sections.SelectMany(s=>s.Values).All(v=>!v.Value.Contains("NaN")&&!v.Value.Contains("Infinity")));
Check.That(sections.Single(s=>s.Key=="weapons").Values.Any(v=>v.Name=="总爆发 DPS"&&v.Value!="—"));
}
[Test] public void DetailRowsKeepTheirIdentityWhenFlightConditionsChange()
{
var document=Actual();var stats=EdsyLinkCodec.Statistics(document);
var before=ShipDetailValues.Create(ShipOverviewValues.From(stats,new(Fuel:1,Cargo:0)),stats,document);
var after=ShipDetailValues.Create(ShipOverviewValues.From(stats,new(Fuel:20,Cargo:8)),stats,document);
var section=new ShipDetailSectionLiveRow(before.Single(s=>s.Key=="flight"));
var speed=section.Values[0];var original=speed.Value;
section.Update(after.Single(s=>s.Key=="flight"));section.Values.Apply(section.Record.Values);
Check.That(ReferenceEquals(speed,section.Values[0])&&speed.Value!=original);
var missing=ShipDetailValues.Create(ShipOverviewValues.Empty,null,null);
Check.That(missing.Single(s=>s.Key=="flight").Values.All(v=>v.Value.Contains('—')));
}
}