65 lines
2.9 KiB
JavaScript
65 lines
2.9 KiB
JavaScript
import { TestCase } from "./framework/test_case.js";
|
|
import { smallState, seaTile } from "./framework/helpers.js";
|
|
import { PROTO_UNITS, TRAINABLE_UNIT_IDS } from "../shared/data.js";
|
|
|
|
export class SubmarineTest extends TestCase {
|
|
test_the_submarine_is_a_trainable_naval_unit() {
|
|
const proto = PROTO_UNITS.find((u) => u.id === "submarine");
|
|
this.assertNotNull(proto, "the submarine exists");
|
|
this.assertTrue(proto.naval, "it is a naval unit");
|
|
this.assertTrue(proto.submarine, "and is marked a submarine");
|
|
this.assertTrue(TRAINABLE_UNIT_IDS.includes("submarine"), "it can be trained");
|
|
this.assertTrue(proto.icon && proto.icon.length > 0, "it carries an icon");
|
|
}
|
|
|
|
test_an_enemy_submarine_is_hidden_until_a_naval_unit_is_beside_it() {
|
|
const state = smallState();
|
|
const spot = seaTile(state);
|
|
this.assertNotNull(spot, "the fixture has open sea");
|
|
const sub = state._spawnUnit(spot, 1, this.subProto(state));
|
|
// No French naval unit anywhere near: the submarine is invisible.
|
|
let ids = (state.snapshot(0).units || []).map((unit) => unit.id);
|
|
this.assertFalse(ids.includes(sub.id), "the submarine is hidden");
|
|
// A submarine not at war is still hidden: the vision rule is not about war.
|
|
ids = (state.snapshot(1).units || []).map((unit) => unit.id);
|
|
this.assertTrue(ids.includes(sub.id), "its own nation always sees it");
|
|
}
|
|
|
|
test_a_naval_unit_on_or_beside_the_submarine_reveals_it() {
|
|
const state = smallState();
|
|
const spot = seaTile(state);
|
|
const sub = state._spawnUnit(spot, 1, this.subProto(state));
|
|
const battleship = state.protoUnits.find((u) => u.id === "battleship");
|
|
// A French battleship on the same tile sees it.
|
|
state._spawnUnit(spot, 0, battleship);
|
|
let ids = (state.snapshot(0).units || []).map((unit) => unit.id);
|
|
this.assertTrue(ids.includes(sub.id), "a naval unit on the tile reveals it");
|
|
}
|
|
|
|
test_a_distant_naval_unit_does_not_reveal_it() {
|
|
const state = smallState();
|
|
const spot = seaTile(state);
|
|
const sub = state._spawnUnit(spot, 1, this.subProto(state));
|
|
const battleship = state.protoUnits.find((u) => u.id === "battleship");
|
|
// Find a sea tile two steps away, so it is out of the direct ring.
|
|
let distant = null;
|
|
for (const k in state.tiles) {
|
|
const parts = k.split(",").map(Number);
|
|
const coords = { x: parts[0], y: parts[1] };
|
|
if (state.tiles[k].terrainClass !== "Sea") continue;
|
|
if (state.topology.tileDistance(coords, spot) === 2) {
|
|
distant = coords;
|
|
break;
|
|
}
|
|
}
|
|
this.assertNotNull(distant, "a sea tile two steps away");
|
|
state._spawnUnit(distant, 0, battleship);
|
|
const ids = (state.snapshot(0).units || []).map((unit) => unit.id);
|
|
this.assertFalse(ids.includes(sub.id), "a unit two tiles away does not reveal it");
|
|
}
|
|
|
|
subProto(state) {
|
|
return state.protoUnits.find((u) => u.id === "submarine");
|
|
}
|
|
}
|