118 lines
4.0 KiB
JavaScript
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");
|
|
}
|
|
}
|