122 lines
4.6 KiB
JavaScript
122 lines
4.6 KiB
JavaScript
import { TestCase } from "./framework/test_case.js";
|
|
import {
|
|
RESOURCE_BUILDINGS,
|
|
RESOURCE_RULES,
|
|
TILE_IMPROVEMENTS,
|
|
STATUSES,
|
|
POLICY_OPINION,
|
|
opinionToPoints,
|
|
SPY_OPERATIONS,
|
|
AIR_DEFENSE,
|
|
SATELLITE,
|
|
SABOTAGE,
|
|
PARALLEL_LINES_PER_LEVEL,
|
|
buildingById,
|
|
policyById,
|
|
} from "../shared/data.js";
|
|
import { formatEnergy, formatResourceAmount } from "../shared/resources.js";
|
|
import { formatNumber, formatPercent } from "../shared/text_format.js";
|
|
|
|
// Every figure a description quotes must be derived from the same field the
|
|
// simulation applies, never typed in. These tests recompute the figure and
|
|
// assert the description shows it, so a rule change that leaves the prose stale
|
|
// fails here.
|
|
export class DescriptionsTest extends TestCase {
|
|
test_resource_building_descriptions_quote_their_output() {
|
|
for (const proto of RESOURCE_BUILDINGS) {
|
|
const output = formatResourceAmount(proto.resource, proto.outputPerDay);
|
|
this.assertTrue(
|
|
proto.description.includes(output),
|
|
`${proto.id} should quote ${output}: ${proto.description}`
|
|
);
|
|
}
|
|
}
|
|
|
|
test_material_producer_descriptions_quote_their_energy_ratio() {
|
|
const ratios = {
|
|
steel_mill: RESOURCE_RULES.energyPerSteelTonne,
|
|
gold_mine: RESOURCE_RULES.energyPerLuxuryCarat.gold_mine,
|
|
diamond_mine: RESOURCE_RULES.energyPerLuxuryCarat.diamond_mine,
|
|
chip_foundry: RESOURCE_RULES.energyPerHighTechUnit,
|
|
};
|
|
for (const [id, ratio] of Object.entries(ratios)) {
|
|
const proto = RESOURCE_BUILDINGS.find((b) => b.id === id);
|
|
const energy = formatEnergy(ratio);
|
|
this.assertTrue(
|
|
proto.description.includes(energy),
|
|
`${id} should quote ${energy} per unit: ${proto.description}`
|
|
);
|
|
}
|
|
}
|
|
|
|
test_building_descriptions_quote_their_rules() {
|
|
const shelters = buildingById("shelters");
|
|
const protection = formatPercent(shelters.civilianProtectionPerLevel);
|
|
this.assertTrue(shelters.description.includes(protection), `shelters quote ${protection}`);
|
|
|
|
const air = buildingById("aa_building");
|
|
this.assertTrue(air.description.includes(`${AIR_DEFENSE.rangeTiles} tiles`), "air defense range");
|
|
|
|
const port = buildingById("port");
|
|
const production = formatNumber(port.productionPerSeaTilePerLevel);
|
|
this.assertTrue(port.description.includes(production), `port quote ${production}`);
|
|
|
|
const space = buildingById("space_launch_center");
|
|
this.assertTrue(space.description.includes(`${SATELLITE.revealEveryDays} days`), "satellite cadence");
|
|
this.assertTrue(
|
|
space.description.includes(String(SATELLITE.perLaunchCentreLevel)),
|
|
"satellites per centre level"
|
|
);
|
|
|
|
for (const id of ["barracks", "shipyard"]) {
|
|
const proto = buildingById(id);
|
|
this.assertTrue(
|
|
proto.description.includes(String(PARALLEL_LINES_PER_LEVEL)),
|
|
`${id} quotes ${PARALLEL_LINES_PER_LEVEL} line(s)`
|
|
);
|
|
}
|
|
}
|
|
|
|
test_improvement_descriptions_quote_their_range() {
|
|
for (const [id, field] of [["radar_tower", "vision"], ["coastal_cannon", "range"]]) {
|
|
const proto = TILE_IMPROVEMENTS.find((i) => i.id === id);
|
|
this.assertTrue(
|
|
proto.description.includes(String(proto[field])),
|
|
`${id} quotes its ${field} (${proto[field]})`
|
|
);
|
|
}
|
|
}
|
|
|
|
test_status_descriptions_quote_their_effect() {
|
|
const encircled = STATUSES.find((s) => s.id === "encircled");
|
|
this.assertTrue(encircled.description.includes(formatPercent(encircled.hpLossPerDay)));
|
|
this.assertTrue(encircled.description.includes(formatPercent(encircled.cityHpLossPerDay)));
|
|
|
|
const battle = STATUSES.find((s) => s.id === "battle");
|
|
this.assertTrue(battle.description.includes(String(battle.upkeepMultiplier)));
|
|
}
|
|
|
|
test_policy_effects_quote_their_opinion_shift() {
|
|
const expected = [
|
|
["champion", "championTarget", "targetEffect"],
|
|
["champion", "championMajority", "politicalCost"],
|
|
["protect", "protectTarget", "targetEffect"],
|
|
["protect", "protectMajority", "politicalCost"],
|
|
["expel", "expelTarget", "politicalCost"],
|
|
["immigration", "immigrationOthers", "politicalCost"],
|
|
];
|
|
for (const [id, field, slot] of expected) {
|
|
const points = opinionToPoints(POLICY_OPINION[field]);
|
|
this.assertTrue(
|
|
policyById(id)[slot].includes(String(Math.abs(points))),
|
|
`${id}.${slot} should quote ${Math.abs(points)} points`
|
|
);
|
|
}
|
|
}
|
|
|
|
test_spy_operation_descriptions_quote_their_block() {
|
|
const sabotage = SPY_OPERATIONS.find((op) => op.id === "sabotage");
|
|
this.assertTrue(sabotage.description.includes(`${SABOTAGE.blockDays} days`));
|
|
}
|
|
}
|