Files
OpenFrontIO/tests/UnitGrid.test.ts
T
evanpelle ca522a5937 refactor cosmetics out of PlayerInfo (#1299)
## Description:

Remove Cosmetics from PlayerInfo. The game engine should have no
knowledge of cosmetics since they shouldn't affect game play at all.
Instead pass player cosmetics into the GameView.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2025-06-28 12:33:19 -07:00

140 lines
4.6 KiB
TypeScript

import { PlayerInfo, PlayerType, UnitType } from "../src/core/game/Game";
import { UnitGrid } from "../src/core/game/UnitGrid";
import { setup } from "./util/Setup";
async function checkRange(
mapName: string,
unitPosX: number,
rangeCheck: number,
range: number,
) {
const game = await setup(mapName, { infiniteGold: true, instantBuild: true });
const grid = new UnitGrid(game.map());
const player = game.addPlayer(
new PlayerInfo("test_player", PlayerType.Human, null, "test_id"),
);
const unitTile = game.map().ref(unitPosX, 0);
grid.addUnit(player.buildUnit(UnitType.DefensePost, unitTile, {}));
const tileToCheck = game.map().ref(rangeCheck, 0);
return grid.hasUnitNearby(
tileToCheck,
range,
UnitType.DefensePost,
"test_id",
);
}
async function nearbyUnits(
mapName: string,
unitPosX: number,
rangeCheck: number,
range: number,
unitTypes: UnitType[],
) {
const game = await setup(mapName, { infiniteGold: true, instantBuild: true });
const grid = new UnitGrid(game.map());
const player = game.addPlayer(
new PlayerInfo("test_player", PlayerType.Human, null, "test_id"),
);
const unitTile = game.map().ref(unitPosX, 0);
for (const unitType of unitTypes) {
grid.addUnit(player.buildUnit(unitType, unitTile, {}));
}
const tileToCheck = game.map().ref(rangeCheck, 0);
return grid.nearbyUnits(tileToCheck, range, unitTypes);
}
describe("Unit Grid range tests", () => {
const hasUnitCases = [
["plains", 0, 10, 0, true], // Same spot
["plains", 0, 10, 10, true], // Exactly on the range
["plains", 0, 10, 11, false], // Exactly 1px outside
["big_plains", 0, 198, 42, true], // Inside huge range
["big_plains", 0, 198, 199, false], // Exactly 1px outside huge range
];
describe("Is unit in range", () => {
test.each(hasUnitCases)(
"on %p map, look if unit at position %p with a range of %p is in range of %p position, returns %p",
async (
mapName: string,
unitPosX: number,
range: number,
rangeCheck: number,
expectedResult: boolean,
) => {
const result = await checkRange(mapName, unitPosX, rangeCheck, range);
expect(result).toBe(expectedResult);
},
);
});
const unitsInRangeCases = [
["plains", 0, 10, 0, [UnitType.Warship], 1], // Same spot
["plains", 0, 10, 0, [UnitType.City, UnitType.Port], 2], // 2 in range
["plains", 0, 10, 0, [], 0], // no unit
["plains", 0, 10, 10, [UnitType.City], 1], // Exactly on the range
["plains", 0, 10, 11, [UnitType.DefensePost], 0], // 1px outside
["big_plains", 0, 198, 42, [UnitType.TradeShip], 1], // Inside huge range
["big_plains", 0, 198, 199, [UnitType.TransportShip], 0], // 1px outside
];
describe("Retrieve all units in range", () => {
test.each(unitsInRangeCases)(
"on %p map, look if unit at position %p with a range of %p is in range of %p position, returns %p",
async (
mapName: string,
unitPosX: number,
range: number,
rangeCheck: number,
units: UnitType[],
expectedResult: number,
) => {
const result = await nearbyUnits(
mapName,
unitPosX,
rangeCheck,
range,
units,
);
expect(result.length).toBe(expectedResult);
},
);
test("Wrong unit type in range", async () => {
const game = await setup("plains", {
infiniteGold: true,
instantBuild: true,
});
const grid = new UnitGrid(game.map());
const player = game.addPlayer(
new PlayerInfo("test_player", PlayerType.Human, null, "test_id"),
);
const unitTile = game.map().ref(0, 0);
grid.addUnit(player.buildUnit(UnitType.City, unitTile, {}));
const tileToCheck = game.map().ref(0, 0);
expect(grid.nearbyUnits(tileToCheck, 10, [UnitType.Port])).toHaveLength(
0,
);
});
test("One inside, one outside of range", async () => {
const game = await setup("plains", {
infiniteGold: true,
instantBuild: true,
});
const grid = new UnitGrid(game.map());
const player = game.addPlayer(
new PlayerInfo("test_player", PlayerType.Human, null, "test_id"),
);
const unitType = UnitType.City;
const unitTile = game.map().ref(0, 0);
grid.addUnit(player.buildUnit(unitType, unitTile, {}));
const outsideTile = game.map().ref(99, 0);
grid.addUnit(player.buildUnit(unitType, outsideTile, {}));
const tileToCheck = game.map().ref(0, 0);
expect(grid.nearbyUnits(tileToCheck, 10, [unitType])).toHaveLength(1);
});
});
});