From f3550b67a453062b2a401b72ddc0ead3c5efd993 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 8 Oct 2026 22:26:34 +0200 Subject: [PATCH] Tests: roles-backfill fallout (Tractor Beam has no stat, Longinus fitted by name) ShippedCatalogRolesAreLive skips gear with no PerformanceStat at all (Tractor Beam is a thruster kind with none). TheEnvelopeComesFromTheGear fits the Longinus by name: the generator's picks follow the item stream and every authored ProductRole draws from it, so the generated hull stopped carrying Large Drives (Medium Drive and RevvITup instead). Its forward bound is the drives' own thrust, since a Large Drive now rolls 0.8x to 1.2x. Co-Authored-By: Claude Sonnet 5.5 --- tests/Aetheria.Shared.Tests/CatalogRoleTests.cs | 4 +++- tests/Aetheria.Shared.Tests/EvasionTermTests.cs | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/Aetheria.Shared.Tests/CatalogRoleTests.cs b/tests/Aetheria.Shared.Tests/CatalogRoleTests.cs index 2bab3218d..665602de3 100644 --- a/tests/Aetheria.Shared.Tests/CatalogRoleTests.cs +++ b/tests/Aetheria.Shared.Tests/CatalogRoleTests.cs @@ -34,7 +34,9 @@ public sealed class CatalogRoleTests .Where(i => i is WeaponItemData || (i is GearData && QualityGearKinds.Contains(i.HardpointType))) .OrderBy(i => i.Name, StringComparer.Ordinal)) { - var varying = StatsOf(design).Where(s => s.Min != s.Max).ToArray(); + var stats = StatsOf(design).ToArray(); + if (stats.Length == 0) continue; // Tractor Beam: a thruster kind with no stat at all, so nothing for quality to vary + var varying = stats.Where(s => s.Min != s.Max).ToArray(); var read = varying.SelectMany(NamedQualityRoles).Distinct().OrderBy(r => r, StringComparer.Ordinal).ToArray(); var declared = (design.Roles ?? new List()).Select(r => r.Name).OrderBy(r => r, StringComparer.Ordinal).ToArray(); if (varying.Length == 0) broken.Add($"{design.Name}: every stat is flat"); diff --git a/tests/Aetheria.Shared.Tests/EvasionTermTests.cs b/tests/Aetheria.Shared.Tests/EvasionTermTests.cs index 93eef6145..594019d43 100644 --- a/tests/Aetheria.Shared.Tests/EvasionTermTests.cs +++ b/tests/Aetheria.Shared.Tests/EvasionTermTests.cs @@ -283,7 +283,17 @@ public sealed partial class RunStartTests [Fact] public void TheEnvelopeComesFromTheGear() { - var (_, longinus, _) = EvFleet(); + // The Longinus is fitted by name, not generated: what the generator picks follows the item stream, and every role a + // product authors draws from it (roles-backfill), so a generated hull would stop carrying these drives. + Ship longinus = null; + var scenario = new Scripted(false, stage => + { + stage.Player(stage.Bare("Djinni"), float2(-50000, -50000)); + longinus = stage.Place(EvLonginus(stage), float2(-30000, -30000), facing: float2(0, 1)) as Ship; + }); + var (_, _, _, failures) = Launch(scenario, Inputs(() => GalaxySeed)); + Assert.True(failures.Count == 0, string.Join("; ", failures)); + Assert.NotNull(longinus); EvSettle(longinus); // A thruster's Thrust property is refreshed only while it fires: turn each way so the flank thrusters hold what // they push with, then read the envelope at rest. @@ -306,7 +316,8 @@ public sealed partial class RunStartTests var envelope = longinus.Envelope; var mass = longinus.Mass; - Assert.InRange(envelope.Forward, 500000f / mass * .99f, 500000f / mass * 1.01f); + var forward = largeDrives.Sum(t => t.Thrust) / mass; // each drive's own thrust: a Large Drive's roll moves it between 0.8x and 1.2x + Assert.InRange(envelope.Forward, forward * .99f, forward * 1.01f); Assert.Equal(0f, envelope.Reverse); var flankAcceleration = flanks.Max(t => t.Thrust) / mass; Assert.InRange(envelope.Left, flankAcceleration * .99f, flankAcceleration * 1.01f);