Added some initial tests for the functions present.

Had a resurgence of a bug I was pretty sure I fixed, but it came back.
Adding some tests to make sure we catch it if it comes back again.
This commit is contained in:
Tyler Marques 2025-05-27 16:30:21 -07:00
parent cad1cb0464
commit 29bc960fe3
No known key found for this signature in database
GPG key ID: CB99EDCF41D3016F
6 changed files with 1231 additions and 5 deletions

View file

@ -9,6 +9,8 @@
- `npm run dev` - Start the development server
- `npm run build` - Build for production
- `npm run lint` - Run TypeScript linting
- `npm test` - Run unit tests with Vitest
- `npm run test:ui` - Run tests with UI interface
## Project Structure
- `src/` - Source code

File diff suppressed because it is too large Load diff

View file

@ -7,11 +7,16 @@
"dev": "vite",
"dev-all": "vite --host 0.0.0.0",
"build": "tsc && vite build",
"preview": "vite preview --host 0.0.0.0"
"preview": "vite preview --host 0.0.0.0",
"test": "vitest",
"test:ui": "vitest --ui"
},
"devDependencies": {
"@vitest/ui": "^3.1.4",
"jsdom": "^26.1.0",
"typescript": "~5.7.2",
"vite": "^6.2.0"
"vite": "^6.2.0",
"vitest": "^3.1.4"
},
"dependencies": {
"@tweenjs/tween.js": "^25.0.0",

View file

@ -0,0 +1,143 @@
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { PowerENUM, ProvinceENUM, ProvTypeENUM } from '../types/map'
import { MeshBasicMaterial } from 'three'
import { updateMapOwnership } from './state'
import { gameState } from '../gameState'
// Mock the gameState import
vi.mock('../gameState', () => ({
gameState: {
gameData: {
phases: [
{
state: {
influence: {
FRANCE: ['PAR', 'BRE'],
GERMANY: ['BER', 'KIE'],
ENGLAND: ['LON', 'LVP']
}
}
}
]
},
phaseIndex: 0,
boardState: {
provinces: {
PAR: {
type: ProvTypeENUM.LAND,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
BRE: {
type: ProvTypeENUM.COAST,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
BER: {
type: ProvTypeENUM.LAND,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
KIE: {
type: ProvTypeENUM.COAST,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
LON: {
type: ProvTypeENUM.COAST,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
LVP: {
type: ProvTypeENUM.COAST,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
},
NAT: {
type: ProvTypeENUM.WATER,
owner: undefined,
mesh: {
material: new MeshBasicMaterial()
}
}
}
}
}
}))
describe('updateMapOwnership', () => {
beforeEach(() => {
// Reset all provinces to have no owner before each test
Object.values(gameState.boardState.provinces).forEach(province => {
province.owner = undefined
})
// Reset phase index
gameState.phaseIndex = 0
// Reset influence data to default
gameState.gameData.phases[0].state.influence = {
FRANCE: [ProvinceENUM.PAR, ProvinceENUM.BRE],
GERMANY: [ProvinceENUM.BER, ProvinceENUM.KIE],
ENGLAND: [ProvinceENUM.LON, ProvinceENUM.LVP]
}
})
it('should update province ownership based on influence data', () => {
updateMapOwnership()
// Check that French provinces are owned by France
expect(gameState.boardState.provinces.PAR.owner).toBe(PowerENUM.FRANCE)
expect(gameState.boardState.provinces.BRE.owner).toBe(PowerENUM.FRANCE)
// Check that German provinces are owned by Germany
expect(gameState.boardState.provinces.BER.owner).toBe(PowerENUM.GERMANY)
expect(gameState.boardState.provinces.KIE.owner).toBe(PowerENUM.GERMANY)
// Check that English provinces are owned by England
expect(gameState.boardState.provinces.LON.owner).toBe(PowerENUM.ENGLAND)
expect(gameState.boardState.provinces.LVP.owner).toBe(PowerENUM.ENGLAND)
// Check that water provinces remain unowned
expect(gameState.boardState.provinces.NAT.owner).toBeUndefined()
})
it('should clear existing ownership before setting new ownership', () => {
// Set initial ownership
gameState.boardState.provinces.PAR.owner = PowerENUM.ENGLAND
gameState.boardState.provinces.BER.owner = PowerENUM.AUSTRIA
updateMapOwnership()
// Verify ownership is correctly updated to match influence data
expect(gameState.boardState.provinces.PAR.owner).toBe(PowerENUM.FRANCE)
expect(gameState.boardState.provinces.BER.owner).toBe(PowerENUM.GERMANY)
})
it('should throw error when phase index is invalid', () => {
gameState.phaseIndex = 9999999
expect(() => updateMapOwnership()).toThrow('Current phase is undefined for index 999')
})
it('should handle empty influence data', () => {
gameState.gameData.phases[0].state.influence = {}
updateMapOwnership()
// All provinces should have no owner
Object.values(gameState.boardState.provinces).forEach(province => {
expect(province.owner).toBeUndefined()
})
})
})

View file

@ -6,6 +6,7 @@ import { MeshBasicMaterial } from "three";
import { updateRotatingDisplay } from "../components/rotatingDisplay";
export function updateSupplyCenterOwnership(centers) {
// TODO: Type the above centers. What actually is meant to come in here?
if (!centers) return;
const ownershipMap = {};
// centers is typically { "AUSTRIA":["VIE","BUD"], "FRANCE":["PAR","MAR"], ... }
@ -44,7 +45,7 @@ export function updateSupplyCenterOwnership(centers) {
});
}
export function updateLeaderboard(phase) {
export function updateLeaderboard() {
// Instead of directly updating the leaderboard HTML,
// use the rotating display component if game data exists
if (gameState.gameData) {
@ -52,10 +53,15 @@ export function updateLeaderboard(phase) {
}
}
/** Updates the ownership of the provinces in the gameState.boardState.provinces array and
* changes the color of the province on the map to correspond to the new owner's color. Or
* the default color if province.owner is undefined.
*/
export function updateMapOwnership() {
let currentPhase = gameState.gameData?.phases[gameState.phaseIndex]
if (currentPhase === undefined) {
throw "Currentphase is undefined for index " + gameState.phaseIndex;
throw "Current phase is undefined for index " + gameState.phaseIndex;
}
// Clear existing ownership to avoid stale data

View file

@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
},
})