Files
Battle-for-Tismo/tests/testing_mode_test.js
T
adrien c2f131da5c Turned tile improvements into construction sites with their own budgets
Every road, railway and tile work now rises as an economic construction site instead of a queue entry. A site gathers its materials over days from reachable regions, refusing any supplier quoting above the price it was budgeted at (a 1% tolerance); a day that buys nothing stalls the site, raising a red mark and letting the nation raise the budget to current prices or cancel it. The upfront budget covers the build cost plus the market value of its steel and high-tech, energy stays a grid draw, and any money left over stays with the finished work as a maintenance reserve.

That reserve now pays the work's own daily steel and high-tech wear before the treasury is billed, so a well funded work spares the state until it runs dry; the spent money is paid into the nation's regions. Building upgrades run through the same gather-build-maintain machinery, sharing the site's kind flag and target level. The legacy tile-work queue and the market building are gone.

Bundles the in-progress chart sizing for the central bank panel.
2026-09-22 18:08:31 +02:00

141 lines
6.3 KiB
JavaScript

import { TestCase } from "./framework/test_case.js";
import { smallState, settleInlandCity } from "./framework/helpers.js";
import { GameServer } from "../server/game_server.js";
import { isLoopback, isLocalRequest } from "../server/server.js";
const BIG_BUDGET = 1.0e15;
function makeServer(testing) {
const network = { getPeerIds: () => [], send: () => {} };
const server = new GameServer(network);
server.configureGame({
seed: 12345,
player_civ: 0,
civilisations: ["france", "britain"],
testing,
});
return server;
}
export class TestingModeTest extends TestCase {
test_loopback_addresses_are_recognised() {
this.assertTrue(isLoopback("127.0.0.1"), "v4 loopback");
this.assertTrue(isLoopback("127.0.1.5"), "any 127/8 address");
this.assertTrue(isLoopback("::1"), "v6 loopback");
this.assertTrue(isLoopback("::ffff:127.0.0.1"), "mapped v4 loopback");
this.assertFalse(isLoopback("10.0.0.1"), "a private address is remote");
this.assertFalse(isLoopback("::ffff:8.8.8.8"), "a mapped public address is remote");
this.assertFalse(isLoopback(""), "an empty address is remote");
this.assertFalse(isLoopback(undefined), "a missing address is remote");
}
test_a_local_page_is_distinguished_from_a_proxied_remote_client() {
this.assertTrue(isLocalRequest("127.0.0.1", "http://127.0.0.1:27015"), "a local page");
this.assertTrue(
isLocalRequest("::ffff:127.0.0.1", "http://localhost:27015"),
"a mapped local page"
);
this.assertFalse(
isLocalRequest("127.0.0.1", "https://tismo.example.com"),
"a proxied remote page is remote even though its socket is loopback"
);
this.assertFalse(
isLocalRequest("10.0.0.1", "http://127.0.0.1:27015"),
"a remote socket is remote"
);
this.assertFalse(isLocalRequest("127.0.0.1", ""), "a missing origin is remote");
}
test_free_training_spawns_instantly_and_costs_nothing() {
const state = smallState();
state.budgets.set(0, BIG_BUDGET);
const city = state.cities.find((c) => c.civ === 0);
const artillery = state.protoUnits.findIndex((u) => u.id === "artillery");
const before = state.units.filter((u) => u.civ === 0).length;
this.assertTrue(state.requestTrain(city.id, artillery, true), "the free order is accepted");
this.assertEqual(
state.units.filter((u) => u.civ === 0).length,
before + 1,
"the unit appears at once"
);
this.assertEqual(state.getBudget(0), BIG_BUDGET, "nothing is charged");
this.assertFalse(state.training.has(city.id), "nothing is queued");
}
test_free_build_raises_the_level_instantly_and_costs_nothing() {
const state = smallState();
state.budgets.set(0, BIG_BUDGET);
const city = state.cities.find((c) => c.civ === 0);
const barracks = state.protoBuildings.findIndex((b) => b.id === "barracks");
this.assertTrue(state.requestBuild(city.id, barracks, true), "the free build is accepted");
this.assertEqual(state.getCityBuildingLevel(city, barracks), 1, "the level rose at once");
this.assertEqual(state.getBudget(0), BIG_BUDGET, "nothing is charged");
this.assertFalse(state.training.has(city.id), "nothing is queued");
}
test_free_build_still_respects_placement_rules() {
const state = smallState();
const inland = settleInlandCity(state, 0);
this.assertNotNull(inland, "the fixture has an inland city");
const shipyard = state.protoBuildings.findIndex((b) => b.id === "shipyard");
this.assertFalse(state.requestBuild(inland.id, shipyard, true), "an inland shipyard is refused");
}
test_a_normal_order_still_charges_and_queues() {
const state = smallState();
state.budgets.set(0, BIG_BUDGET);
const city = state.cities.find((c) => c.civ === 0);
const barracks = state.protoBuildings.findIndex((b) => b.id === "barracks");
this.assertTrue(state.requestBuild(city.id, barracks), "the paid order is accepted");
this.assertEqual(state.getCityBuildingLevel(city, barracks), 0, "it does not rise at once");
this.assertLess(state.getBudget(0), BIG_BUDGET, "it was charged");
this.assertTrue(state.training.has(city.id), "it went into the queue");
}
test_server_honours_free_orders_in_a_testing_game() {
const server = makeServer(true);
server.peerCiv.set(1, 0);
const city = server.state.cities.find((c) => c.civ === 0);
const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks");
const budgetBefore = server.state.getBudget(0);
this.assertTrue(
server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }),
"the order is accepted"
);
this.assertEqual(server.state.getCityBuildingLevel(city, barracks), 1, "the building went up");
this.assertEqual(server.state.getBudget(0), budgetBefore, "it was free");
this.assertTrue(server.state.testing, "the snapshot flag is set");
}
test_server_ignores_the_free_flag_in_a_normal_game() {
const server = makeServer(false);
server.peerCiv.set(1, 0);
const city = server.state.cities.find((c) => c.civ === 0);
const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks");
const budgetBefore = server.state.getBudget(0);
this.assertTrue(
server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }),
"the order is still processed"
);
this.assertEqual(server.state.getCityBuildingLevel(city, barracks), 0, "it only went into the queue");
this.assertLess(server.state.getBudget(0), budgetBefore, "the normal cost was charged");
this.assertFalse(server.state.testing, "the testing flag stays off");
}
test_a_local_peer_gets_free_orders_in_a_normal_game() {
const server = makeServer(false);
server.setPeerLocal(1, true);
server.peerCiv.set(1, 0);
const city = server.state.cities.find((c) => c.civ === 0);
const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks");
const budgetBefore = server.state.getBudget(0);
this.assertTrue(
server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }),
"the order is accepted"
);
this.assertEqual(server.state.getCityBuildingLevel(city, barracks), 1, "the building went up");
this.assertEqual(server.state.getBudget(0), budgetBefore, "it was free");
this.assertFalse(server.state.testing, "the game itself stays a normal game");
}
}