tests: restore 'requires' data key in sample fixtures (rename touched string text)

This commit is contained in:
alex 2026-09-07 22:13:11 -04:00
parent 587e4ab9fb
commit 4dc323f674
7 changed files with 15 additions and 15 deletions

View file

@ -26,7 +26,7 @@ Species parse_species(std::string_view name); // case-insensitive; "NPC
struct Problem { struct Problem {
enum class Kind { enum class Kind {
MissingBlock, // file has no top-level block of the expected name MissingBlock, // file has no top-level block of the expected name
MissingKey, // a key the schema requires_tech is absent MissingKey, // a key the schema requires is absent
BadValue, // a value does not have the expected shape (kept in raw) BadValue, // a value does not have the expected shape (kept in raw)
Unparsed, // a structured value (allows string, turret row) could not be parsed Unparsed, // a structured value (allows string, turret row) could not be parsed
Duplicate, // an id / name occurs twice Duplicate, // an id / name occurs twice

View file

@ -1,7 +1,7 @@
// game::data -- ShipSectionDef: one `Species/<Race>/sections/*.shipsection`. // game::data -- ShipSectionDef: one `Species/<Race>/sections/*.shipsection`.
// //
// shipsection { // shipsection {
// model PATH requires_tech TECH... section_type command|mission|engine // model PATH requires TECH... section_type command|mission|engine
// section_class destroyer|cruiser|dreadnought // section_class destroyer|cruiser|dreadnought
// health mass cost cpoints crew socket_fore/socket_aft NODE // health mass cost cpoints crew socket_fore/socket_aft NODE
// option TECH -- one-member option group // option TECH -- one-member option group

View file

@ -2,7 +2,7 @@
// //
// weapon { // weapon {
// name @WEAPON_X weaponclass bullet weaponfamily gauss // name @WEAPON_X weaponclass bullet weaponfamily gauss
// requires_tech TECH [requires_tech TECH2] cost N // requires TECH [requires TECH2] cost N
// turretsize small turretclass standard // turretsize small turretclass standard
// burst_volleys N recharge_time T range R range_planet RP // burst_volleys N recharge_time T range R range_planet RP
// fc_* true/false rating_* N // fc_* true/false rating_* N

View file

@ -394,14 +394,14 @@ std::vector<Violation> Ruleset::validate(const Design& d) const {
// -- tech gating ---------------------------------------------------------- // -- tech gating ----------------------------------------------------------
// Engine-generated hidden designs (the per-race "Default Assault Shuttle") // Engine-generated hidden designs (the per-race "Default Assault Shuttle")
// exist in every save regardless of research: the Tarkas _AssaultShuttle // exist in every save regardless of research: the Tarkas _AssaultShuttle
// requires_tech DRN_AdvFrm and the design is there on turn 1. Gating on hidden // requires DRN_AdvFrm and the design is there on turn 1. Gating on hidden
// designs is therefore reported at warn level. // designs is therefore reported at warn level.
const Level gate = hidden ? Level::Warn : Level::Error; const Level gate = hidden ? Level::Warn : Level::Error;
for (const Filled* p : present) { for (const Filled* p : present) {
const ShipSectionDef& s = *p->def; const ShipSectionDef& s = *p->def;
for (const std::string& t : s.requires_tech) { for (const std::string& t : s.requires_tech) {
if (!cat.tech.find(t) && !data::is_group_ref(t)) if (!cat.tech.find(t) && !data::is_group_ref(t))
add(v, "C1", Level::Warn, s.stem + " requires_tech unknown tech " + t, p->slot); add(v, "C1", Level::Warn, s.stem + " requires unknown tech " + t, p->slot);
else if (known && !known->satisfies(cat.tech, t)) else if (known && !known->satisfies(cat.tech, t))
add(v, "C1", gate, s.stem + " requires_tech " + t, p->slot); add(v, "C1", gate, s.stem + " requires_tech " + t, p->slot);
if (unobtainable(t, race)) if (unobtainable(t, race))

View file

@ -22,10 +22,10 @@ fs::path make_root() {
fs::path root = fs::temp_directory_path() / ("game_data_test_" + std::to_string(static_cast<long long>(stamp))); fs::path root = fs::temp_directory_path() / ("game_data_test_" + std::to_string(static_cast<long long>(stamp)));
fs::remove_all(root); fs::remove_all(root);
put(root / "Weapons/bal_gauss.weapon", put(root / "Weapons/bal_gauss.weapon",
"weapon { name @WEAPON_BAL_GAUSS weaponclass bullet requires_tech WEP_GsDrvr cost 50 turretsize small turretclass standard\n" "weapon { name @WEAPON_BAL_GAUSS weaponclass bullet requires WEP_GsDrvr cost 50 turretsize small turretclass standard\n"
" bolt { rangetable { max_range 455 } dam_pop 3500 } }\n"); " bolt { rangetable { max_range 455 } dam_pop 3500 } }\n");
put(root / "Weapons/las_odd.weapon", put(root / "Weapons/las_odd.weapon",
"weapon { name @WEAPON_LAS_ODD weaponclass beam requires_tech WEP_NOPE requires_tech wep_gsdrvr turretsize Large turretclass Beam }\n"); "weapon { name @WEAPON_LAS_ODD weaponclass beam requires WEP_NOPE requires wep_gsdrvr turretsize Large turretclass Beam }\n");
put(root / "Weapons/mis.weapon", put(root / "Weapons/mis.weapon",
"weapon { name @WEAPON_MIS weaponclass missile turretsize medium turretclass missile }\n"); "weapon { name @WEAPON_MIS weaponclass missile turretsize medium turretclass missile }\n");
put(root / "Weapons/_weapons.txt", "// ids\n8 bal_gauss.weapon\n21 mis.weapon\n// DELETED - 36\n40 ghost.weapon\n"); put(root / "Weapons/_weapons.txt", "// ids\n8 bal_gauss.weapon\n21 mis.weapon\n// DELETED - 36\n40 ghost.weapon\n");
@ -38,7 +38,7 @@ fs::path make_root() {
" bank { turretclass standard turretsize small mount { node N1 } } }\n"); " bank { turretclass standard turretsize small mount { node N1 } } }\n");
put(root / "Species/Human/sections/DEFission.shipsection", put(root / "Species/Human/sections/DEFission.shipsection",
"shipsection { model b.X section_type engine section_class destroyer health 1 mass 2 socket_fore EngineNode\n" "shipsection { model b.X section_type engine section_class destroyer health 1 mass 2 socket_fore EngineNode\n"
" requires_tech DRV_Fissn requires_tech grp_torps requires_tech GRP_Empty\n" " requires DRV_Fissn requires grp_torps requires GRP_Empty\n"
" bank { turretclass strafe turretsize small mount { node N1 } } }\n"); " bank { turretclass strafe turretsize small mount { node N1 } } }\n");
put(root / "Species/Human/sections/_shipsections.txt", "1 DECommand.shipsection\n47 defission.SHIPSECTION\n98 DEWar.shipsection\n"); put(root / "Species/Human/sections/_shipsections.txt", "1 DECommand.shipsection\n47 defission.SHIPSECTION\n98 DEWar.shipsection\n");
put(root / "Species/_NPC/sections/_Herald.shipsection", put(root / "Species/_NPC/sections/_Herald.shipsection",

View file

@ -43,7 +43,7 @@ std::string de_armor(const char* extra = "") {
std::string de_fission(const char* drive) { std::string de_fission(const char* drive) {
return "shipsection { model c.X Section_Type Engine section_class Destroyer socket_fore EngineNode\n" return "shipsection { model c.X Section_Type Engine section_class Destroyer socket_fore EngineNode\n"
" requires_tech DRV_Fissn requires_tech " + std::string(drive) + " requires DRV_Fissn requires_tech " + std::string(drive) +
"\n health 450 mass 2500 cost 5000 cpoints 1380 engine_techera fission ftlspeed .2 nodespeed 4 range 9\n" + "\n health 450 mass 2500 cost 5000 cpoints 1380 engine_techera fission ftlspeed .2 nodespeed 4 range 9\n" +
std::string(kArmorOptions) + " option DRV_RecFiss\n" std::string(kArmorOptions) + " option DRV_RecFiss\n"
" netforcelimits { force_forward 23000 force_right 23000 force_up 23000 torque_yaw 5 torque_pitch 5 torque_roll 5 speed 40 rotspeed 10 }\n" + " netforcelimits { force_forward 23000 force_right 23000 force_up 23000 torque_yaw 5 torque_pitch 5 torque_roll 5 speed 40 rotspeed 10 }\n" +
@ -59,7 +59,7 @@ std::string de_platform() {
const char* kRider = "shipsection { model r.X section_class destroyer design_class rider entity_class rider health 50 mass 100 cost 100 }\n"; const char* kRider = "shipsection { model r.X section_class destroyer design_class rider entity_class rider health 50 mass 100 cost 100 }\n";
const char* kRiderGated = const char* kRiderGated =
"shipsection { model r.X section_class destroyer design_class rider entity_class rider requires_tech DRN_AdvFrm health 50 mass 100 cost 100 }\n"; "shipsection { model r.X section_class destroyer design_class rider entity_class rider requires DRN_AdvFrm health 50 mass 100 cost 100 }\n";
void write_human(const fs::path& r) { void write_human(const fs::path& r) {
fs::path s = r / "Species/Human/sections"; fs::path s = r / "Species/Human/sections";
@ -75,10 +75,10 @@ void write_human(const fs::path& r) {
bank("strafe", "small", 4) + bank("standard", "large", 1) + "}\n"); bank("strafe", "small", 4) + bank("standard", "large", 1) + "}\n");
put(s / "DETorpedo.shipsection", put(s / "DETorpedo.shipsection",
"shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n"
" requires_tech GRP_Torps\n" + bank("torpedo", "large", 1) + bank("missile", "medium", 1) + "}\n"); " requires GRP_Torps\n" + bank("torpedo", "large", 1) + bank("missile", "medium", 1) + "}\n");
put(s / "DEAssaultShuttle.shipsection", put(s / "DEAssaultShuttle.shipsection",
"shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n"
" requires_tech DRN_AdvFrm\n" + bank("assaultshuttlerider", "large", 1) + bank("tarkahunter", "large", 1) + "}\n"); " requires DRN_AdvFrm\n" + bank("assaultshuttlerider", "large", 1) + bank("tarkahunter", "large", 1) + "}\n");
put(s / "DEPlanetMissile.shipsection", put(s / "DEPlanetMissile.shipsection",
"shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" + "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" +
bank("planetmissile", "large", 1) + "}\n"); bank("planetmissile", "large", 1) + "}\n");
@ -90,12 +90,12 @@ void write_human(const fs::path& r) {
bank("standard", "large", 2) + "}\n"); bank("standard", "large", 2) + "}\n");
put(s / "CRFission.shipsection", put(s / "CRFission.shipsection",
"shipsection { model f.X section_type engine section_class cruiser socket_fore EngineNode health 1 mass 30 cost 300 crew 15\n" "shipsection { model f.X section_type engine section_class cruiser socket_fore EngineNode health 1 mass 30 cost 300 crew 15\n"
" requires_tech DRV_Fissn requires_tech DRV_Node engine_techera fission ftlspeed .2 nodespeed 4\n" + " requires DRV_Fissn requires DRV_Node engine_techera fission ftlspeed .2 nodespeed 4\n" +
bank("standard", "medium", 1) + "}\n"); bank("standard", "medium", 1) + "}\n");
// the station triple (design_class station: no hull-class tech; partners pinned) // the station triple (design_class station: no hull-class tech; partners pinned)
put(s / "DNStation.shipsection", put(s / "DNStation.shipsection",
"shipsection { model g.X section_type mission section_class dreadnought socket_fore Fore socket_aft Aft\n" "shipsection { model g.X section_type mission section_class dreadnought socket_fore Fore socket_aft Aft\n"
" requires_tech IND_OrbCom health 9000 mass 100000 cost 700000 crew 100 entity_class \"Station\" design_class station command_quota 46\n" " requires IND_OrbCom health 9000 mass 100000 cost 700000 crew 100 entity_class \"Station\" design_class station command_quota 46\n"
" explicit_command_section \"DNStation_Fore\" explicit_engine_section \"DNStation_Aft\"\n" + " explicit_command_section \"DNStation_Fore\" explicit_engine_section \"DNStation_Aft\"\n" +
bank("standard", "large", 2) + "}\n"); bank("standard", "large", 2) + "}\n");
put(s / "DNStation_Fore.shipsection", put(s / "DNStation_Fore.shipsection",

View file

@ -42,7 +42,7 @@ TEST(C1_group_requirements) {
TEST(C1_unknown_tech_is_a_warning) { TEST(C1_unknown_tech_is_a_warning) {
Design d = armor(); Design d = armor();
d.engine() = use("DEOddTech", {"bal_gauss"}); d.engine() = use("DEOddTech", {"bal_gauss"});
// DEOddTech requires_tech DRV_Fissn (known) and XXX_Nowhere (not in the tree): // DEOddTech requires DRV_Fissn (known) and XXX_Nowhere (not in the tree):
// a token the tree cannot satisfy is reported, never an error. // a token the tree cannot satisfy is reported, never an error.
std::vector<Violation> v = mini_rules().validate(d); std::vector<Violation> v = mini_rules().validate(d);
CHECK_EQ(join(rules_at(v, Level::Error)), ""); CHECK_EQ(join(rules_at(v, Level::Error)), "");