Files
Battle-for-Tismo/tests/descriptions_test.js
T

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`));
}
}