share one loadTestConfig() helper across the tests
19 test translation units each defined an identical local loadConfig(). They now include src/test/TestConfig.h, which lives off the lib/ui/app include path like SimulationTestAccess.h. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "SimulationTestAccess.h"
|
||||
#include "SurfaceMask.h"
|
||||
#include "Tick.h"
|
||||
#include "TestConfig.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers that mirror the production implementations under test.
|
||||
@@ -147,11 +148,6 @@ static void applyRotationCCW(Blueprint& bp, const GameConfig& cfg)
|
||||
}
|
||||
}
|
||||
|
||||
static GameConfig loadConfig()
|
||||
{
|
||||
return ConfigLoader::loadFromDirectory(CONFIG_DIR);
|
||||
}
|
||||
|
||||
// Mirrors BlueprintPanel::createBlueprintFromSelection's player-placeable filter:
|
||||
// building types absent from buildings.toml (HQ, stations) or with playerPlaceable=false
|
||||
// are silently excluded before the bounding-box center and offsets are computed.
|
||||
@@ -312,7 +308,7 @@ TEST_CASE("Blueprint: non-axis-aligned offset rotates correctly", "[blueprint]")
|
||||
|
||||
TEST_CASE("Blueprint: CW constellation rotation updates offset and building rotation", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
// Building one tile to the right, facing East.
|
||||
Blueprint bp;
|
||||
bp.name = "test";
|
||||
@@ -332,7 +328,7 @@ TEST_CASE("Blueprint: CW constellation rotation updates offset and building rota
|
||||
|
||||
TEST_CASE("Blueprint: CCW constellation rotation updates offset and building rotation", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
Blueprint bp;
|
||||
bp.name = "test";
|
||||
BlueprintBuilding bb;
|
||||
@@ -351,7 +347,7 @@ TEST_CASE("Blueprint: CCW constellation rotation updates offset and building rot
|
||||
|
||||
TEST_CASE("Blueprint: four CW rotations restore offset and building rotation", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
Blueprint bp;
|
||||
bp.name = "test";
|
||||
BlueprintBuilding bb;
|
||||
@@ -371,7 +367,7 @@ TEST_CASE("Blueprint: four CW rotations restore offset and building rotation", "
|
||||
|
||||
TEST_CASE("Blueprint: multi-building constellation rotates symmetrically CW", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
// Two buildings left and right of center; after CW they should be above and below.
|
||||
Blueprint bp;
|
||||
bp.name = "test";
|
||||
@@ -398,7 +394,7 @@ TEST_CASE("Blueprint: multi-building constellation rotates symmetrically CW", "[
|
||||
|
||||
TEST_CASE("Blueprint: CW rotation keeps belt adjacent to miner output port", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
|
||||
// East miner: anchor (0,0), body cells (0,0),(1,0),(0,1).
|
||||
// Output port indicator '>' at (1,1) → port tile (1,1), direction East.
|
||||
@@ -436,7 +432,7 @@ TEST_CASE("Blueprint: CW rotation keeps belt adjacent to miner output port", "[b
|
||||
|
||||
TEST_CASE("Blueprint: CCW rotation keeps belt adjacent to miner output port", "[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
|
||||
Blueprint bp;
|
||||
bp.name = "test";
|
||||
@@ -473,7 +469,7 @@ TEST_CASE("Blueprint: CCW rotation keeps belt adjacent to miner output port", "[
|
||||
TEST_CASE("Blueprint creation: non-player-placeable building alone yields empty blueprint",
|
||||
"[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
|
||||
// Hq has no entry in buildings.toml, so it is treated as non-player-placeable.
|
||||
const BuildingSpec hq{ QPoint(-5, 0), {QPoint(-5, 0)}, BuildingType::Hq, Rotation::East };
|
||||
@@ -485,7 +481,7 @@ TEST_CASE("Blueprint creation: non-player-placeable building alone yields empty
|
||||
TEST_CASE("Blueprint creation: mixed selection keeps only player-placeable buildings",
|
||||
"[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
|
||||
const BuildingSpec belt{ QPoint(-5, 0), {QPoint(-5, 0)}, BuildingType::Belt, Rotation::East };
|
||||
const BuildingSpec hq { QPoint(-3, 0), {QPoint(-3, 0)}, BuildingType::Hq, Rotation::East };
|
||||
@@ -498,7 +494,7 @@ TEST_CASE("Blueprint creation: mixed selection keeps only player-placeable build
|
||||
TEST_CASE("Blueprint creation: bounding box ignores non-player-placeable buildings",
|
||||
"[blueprint]")
|
||||
{
|
||||
const GameConfig cfg = loadConfig();
|
||||
const GameConfig cfg = loadTestConfig();
|
||||
|
||||
// Belt at (-5, 0). HQ at (-3, 0) — excluded from the blueprint.
|
||||
// If HQ were included: bboxX = [-5, -3], center.x = -4, belt offset = -1.
|
||||
@@ -520,7 +516,7 @@ TEST_CASE("Blueprint placement: buildings land at anchor + offset from cursor",
|
||||
// Simulate placing a two-belt blueprint with offsets (-1, 0) and (+1, 0)
|
||||
// at cursor tile (-5, 0). Expected anchors: (-6, 0) and (-4, 0).
|
||||
// (Belt surface_mask ["A>"] — body at relative (0,0), port at (1,0).)
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
const QPoint cursor(-5, 0);
|
||||
const QPoint offsetA(-1, 0);
|
||||
@@ -540,7 +536,7 @@ TEST_CASE("Blueprint placement: buildings land at anchor + offset from cursor",
|
||||
|
||||
TEST_CASE("Blueprint placement: cost is deducted for each building in sequence", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Find belt cost from config (belt cost = 2 in test config).
|
||||
int beltCost = 0;
|
||||
@@ -563,7 +559,7 @@ TEST_CASE("Blueprint placement: cost is deducted for each building in sequence",
|
||||
TEST_CASE("Blueprint placement: insufficient blocks returns kInvalidBuildingId and deducts nothing",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Find miner cost (15 in test config) — expensive enough to exhaust a small stock.
|
||||
int minerCost = 0;
|
||||
@@ -594,7 +590,7 @@ TEST_CASE("Blueprint placement: insufficient blocks returns kInvalidBuildingId a
|
||||
TEST_CASE("Simulation: tryPlaceBuilding rejects terrain-invalid placement and charges nothing",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
const int startBlocks = sim.getBuildingBlocksStock();
|
||||
|
||||
// A miner is all-asteroid; placing it in space (x >= 0) violates the terrain
|
||||
@@ -610,7 +606,7 @@ TEST_CASE("Simulation: tryPlaceBuilding rejects terrain-invalid placement and ch
|
||||
TEST_CASE("Simulation: tryPlaceBuilding accepts a valid asteroid spot, occupies tiles, charges cost",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
int minerCost = 0;
|
||||
for (const BuildingDef& def : sim.getConfig().buildings.buildings)
|
||||
@@ -663,7 +659,7 @@ TEST_CASE("Blueprint: building with no recipe has empty recipeId", "[blueprint]"
|
||||
|
||||
TEST_CASE("Blueprint placement: setRecipe on construction site stores recipe", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Miner body cells: (0,0),(1,0),(0,1) — all at x < 0, valid for asteroid.
|
||||
const BuildingId id = SimulationTestAccess::place(sim,BuildingType::Miner, QPoint(-2, 0), Rotation::East).value();
|
||||
@@ -679,7 +675,7 @@ TEST_CASE("Blueprint placement: setRecipe on construction site stores recipe", "
|
||||
TEST_CASE("Blueprint placement: recipe transfers to building after construction completes",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
const BuildingId id = SimulationTestAccess::place(sim,BuildingType::Miner, QPoint(-2, 0), Rotation::East).value();
|
||||
REQUIRE(id != kInvalidBuildingId);
|
||||
@@ -705,7 +701,7 @@ TEST_CASE("Blueprint placement: recipe transfers to building after construction
|
||||
|
||||
TEST_CASE("Blueprint creation: a construction site is captured", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Freshly placed → a ConstructionSite (not ticked to completion). A 1x1 belt keeps
|
||||
// the body-cell bounding-box centered on the anchor, so a single site → zero offset.
|
||||
@@ -724,7 +720,7 @@ TEST_CASE("Blueprint creation: a construction site is captured", "[blueprint]")
|
||||
|
||||
TEST_CASE("Blueprint creation: a construction site's recipe is captured", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
const BuildingId id =
|
||||
SimulationTestAccess::place(sim, BuildingType::Miner, QPoint(-2, 0), Rotation::East).value();
|
||||
@@ -740,7 +736,7 @@ TEST_CASE("Blueprint creation: a construction site's recipe is captured", "[blue
|
||||
TEST_CASE("Blueprint creation: mixed operational building and construction site are both captured",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Building A: place, configure, and tick to completion so it is operational.
|
||||
const BuildingId idA =
|
||||
@@ -772,7 +768,7 @@ TEST_CASE("Blueprint creation: mixed operational building and construction site
|
||||
|
||||
TEST_CASE("Blueprint creation: selectionHasPlaceableBuilding sees a construction site", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
REQUIRE_FALSE(selectionHasPlaceableBuilding(sim, {}));
|
||||
|
||||
@@ -787,7 +783,7 @@ TEST_CASE("Blueprint placement: interceptor schematic is unlocked at game start"
|
||||
{
|
||||
// "interceptor" has unlock_at_station_level = -1 in the test config.
|
||||
// This confirms the guard in placeBlueprintAtTile passes for start-unlocked schematics.
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
REQUIRE(sim.isSchematicUnlocked("interceptor"));
|
||||
}
|
||||
|
||||
@@ -796,7 +792,7 @@ TEST_CASE("Blueprint placement: repair_ship schematic is locked at game start",
|
||||
// "repair_ship" has unlock_at_station_level = 0 in the test config.
|
||||
// This confirms the guard in placeBlueprintAtTile blocks locked schematics,
|
||||
// leaving the shipyard's schematic unset.
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
REQUIRE_FALSE(sim.isSchematicUnlocked("repair_ship"));
|
||||
}
|
||||
|
||||
@@ -842,7 +838,7 @@ TEST_CASE("Blueprint: building without layout has nullopt shipLayout", "[bluepri
|
||||
|
||||
TEST_CASE("Blueprint placement: setShipLayout on construction site stores layout", "[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
// Shipyard surface_mask ["AAAS>","AAAS "] with Rotation::East:
|
||||
// A-tiles at (-3,0),(-2,0),(-1,0),(-3,1),(-2,1),(-1,1) — all x < 0, valid asteroid tiles.
|
||||
@@ -869,7 +865,7 @@ TEST_CASE("Blueprint placement: setShipLayout on construction site stores layout
|
||||
TEST_CASE("Blueprint placement: ship layout transfers to building after construction completes",
|
||||
"[blueprint]")
|
||||
{
|
||||
Simulation sim(loadConfig());
|
||||
Simulation sim(loadTestConfig());
|
||||
|
||||
const BuildingId id = SimulationTestAccess::place(sim,BuildingType::Shipyard, QPoint(-3, 0), Rotation::East).value();
|
||||
REQUIRE(id != kInvalidBuildingId);
|
||||
|
||||
Reference in New Issue
Block a user