Files
AIHostingTycoon/packages/game-engine/src/__test-utils__/createTestState.ts
T
josh a8746246f8
Balance Check / balance-simulation (push) Successful in 7m0s
Balance Check / multi-run-balance (push) Failing after 20m5s
CI / build-and-push (push) Successful in 1m18s
Add Vitest test suite with 184 tests covering all game engine systems
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 09:41:56 -04:00

69 lines
2.3 KiB
TypeScript

import type { GameState } from '@ai-tycoon/shared';
import {
INITIAL_SETTINGS, SAVE_VERSION,
INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE,
INITIAL_RESEARCH, INITIAL_MODELS, INITIAL_MARKET,
INITIAL_COMPETITORS, INITIAL_TALENT, INITIAL_DATA,
INITIAL_REPUTATION, INITIAL_ACHIEVEMENTS,
} from '@ai-tycoon/shared';
export type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T;
function deepMerge<T>(target: T, source: DeepPartial<T>): T {
if (source === undefined || source === null) return target;
if (typeof target !== 'object' || target === null) return source as T;
if (Array.isArray(source)) return source as unknown as T;
const result = { ...target };
for (const key of Object.keys(source) as (keyof T)[]) {
const srcVal = source[key];
if (srcVal === undefined) continue;
const tgtVal = result[key];
if (
typeof tgtVal === 'object' && tgtVal !== null && !Array.isArray(tgtVal) &&
typeof srcVal === 'object' && srcVal !== null && !Array.isArray(srcVal)
) {
result[key] = deepMerge(tgtVal, srcVal as DeepPartial<typeof tgtVal>);
} else {
result[key] = srcVal as T[keyof T];
}
}
return result;
}
function baseState(): GameState {
return {
meta: {
saveVersion: SAVE_VERSION,
companyName: 'TestCorp',
currentEra: 'startup',
tickCount: 0,
lastTickTimestamp: Date.now(),
gameSpeed: 1,
isPaused: false,
createdAt: Date.now(),
totalPlayTime: 0,
settings: { ...INITIAL_SETTINGS },
},
economy: structuredClone(INITIAL_ECONOMY),
infrastructure: structuredClone(INITIAL_INFRASTRUCTURE),
compute: structuredClone(INITIAL_COMPUTE),
research: structuredClone(INITIAL_RESEARCH),
models: structuredClone(INITIAL_MODELS),
market: structuredClone(INITIAL_MARKET),
competitors: structuredClone(INITIAL_COMPETITORS),
talent: structuredClone(INITIAL_TALENT),
data: structuredClone(INITIAL_DATA),
reputation: structuredClone(INITIAL_REPUTATION),
achievements: structuredClone(INITIAL_ACHIEVEMENTS),
};
}
export function createTestState(overrides?: DeepPartial<GameState>): GameState {
const state = baseState();
if (!overrides) return state;
return deepMerge(state, overrides);
}