Files
Battle-for-Tismo/tests/scenario_test.js

118 lines
4.0 KiB
JavaScript

import { TestCase } from "./framework/test_case.js";
import { smallState } from "./framework/helpers.js";
import {
STARTING_FORCES,
STARTING_RESERVE_DAYS,
} from "../shared/game_state/scenario.js";
import { STORABLE_RESOURCE_IDS } from "../shared/data.js";
function unitsWithProto(state, protoId) {
const index = state.protoUnits.findIndex((unit) => unit.id === protoId);
return state.units.filter((unit) => unit.proto === index);
}
function countAt(state, protoId, coords) {
return unitsWithProto(state, protoId).filter(
(unit) => unit.coords.x === coords.x && unit.coords.y === coords.y
).length;
}
export class ScenarioTest extends TestCase {
test_every_city_opens_with_a_barracks_and_the_capital_an_airport() {
const state = smallState();
state.applyStartingScenario();
const barracks = state.buildingIndexById("barracks");
const airport = state.buildingIndexById("airport");
for (const city of state.cities) {
this.assertEqual(state.getCityBuildingLevel(city, barracks), 1, "the city barracks");
this.assertEqual(
state.getCityBuildingLevel(city, airport),
city.isCapital ? 1 : 0,
`the airport in ${city.name}`
);
}
}
test_every_city_opens_with_its_infantry_and_artillery() {
const state = smallState();
state.applyStartingScenario();
for (const city of state.cities) {
this.assertEqual(
countAt(state, "modern_infantry", city.coords),
STARTING_FORCES.infantryPerCity,
`infantry in ${city.name}`
);
this.assertEqual(
countAt(state, "artillery", city.coords),
STARTING_FORCES.artilleryPerCity,
`artillery in ${city.name}`
);
}
}
test_every_port_launches_its_flotilla_onto_the_water() {
const state = smallState();
state.applyStartingScenario();
for (let civ = 0; civ < state.civilisations.length; civ++) {
const ports = state.cities.filter(
(city) => city.civ === civ && state.hasCityBuilding(city, "port")
).length;
const launches = unitsWithProto(state, "launch").filter((unit) => unit.civ === civ);
const battleships = unitsWithProto(state, "battleship").filter((unit) => unit.civ === civ);
this.assertEqual(launches.length, STARTING_FORCES.launchesPerPort * ports, `launches of civ ${civ}`);
this.assertEqual(
battleships.length,
STARTING_FORCES.battleshipsPerPort * ports,
`battleships of civ ${civ}`
);
for (const unit of launches.concat(battleships)) {
const tile = state.tiles[`${unit.coords.x},${unit.coords.y}`];
this.assertEqual(tile && tile.terrainClass, "Sea", "the warship floats");
}
}
}
test_the_capital_fields_the_air_force() {
const state = smallState();
state.applyStartingScenario();
for (const city of state.cities) {
if (!city.isCapital) continue;
this.assertEqual(
countAt(state, "jet_fighter", city.coords),
STARTING_FORCES.fightersPerCapital,
`fighters in ${city.name}`
);
this.assertEqual(
countAt(state, "bomber", city.coords),
STARTING_FORCES.bombersPerCapital,
`bombers in ${city.name}`
);
}
}
test_each_region_opens_with_a_year_of_its_consumption() {
const state = smallState();
state.applyStartingScenario();
for (const city of state.cities) {
const consumption = state.getRegionResourceInfo(city).consumption;
const stock = state.getCityResourceStock(city);
for (const id of STORABLE_RESOURCE_IDS) {
this.assertApprox(
stock[id],
(consumption[id] || 0) * STARTING_RESERVE_DAYS,
1e-6,
`${id} in ${city.name}`
);
}
}
}
test_the_scenario_replaces_any_starting_units() {
const state = smallState();
state.applyStartingScenario();
const once = state.units.length;
state.applyStartingScenario();
this.assertEqual(state.units.length, once, "re-applying does not stack a second army");
}
}