// ==================== 状态管理测试 ==================== import { createInitialState, resetForRebirth, serializeState, deserializeState } from '../src/engine/state.js'; let passCount = 0; let failCount = 0; function assert(condition, message) { if (condition) { passCount++; } else { failCount++; console.error('FAIL:', message); } } function testCreateInitialState() { const state = createInitialState(); assert(state.day === 0, 'day should be 0'); assert(state.year === 0, 'year should be 0'); assert(state.age === 0, 'age should be 0'); assert(state.reincarnation === 0, 'reincarnation should be 0'); assert(state.alive === true, 'alive should be true'); assert(state.identity === null, 'identity should be null'); assert(state.stats.body === 0, 'stats.body should be 0'); assert(state.stats.wisdom === 0, 'stats.wisdom should be 0'); assert(state.stats.charm === 0, 'stats.charm should be 0'); assert(state.stats.destiny === 0, 'stats.destiny should be 0'); assert(state.stats.business === 0, 'stats.business should be 0'); assert(state.stats.intelligence === 0, 'stats.intelligence should be 0'); assert(Array.isArray(state.talents) && state.talents.length === 0, 'talents should be empty array'); assert(Object.keys(state.careers).length === 0, 'careers should be empty object'); assert(state.money === 0, 'money should be 0'); assert(Object.keys(state.shopItems).length === 0, 'shopItems should be empty object'); assert(Object.keys(state.activeBuffs).length === 0, 'activeBuffs should be empty object'); assert(Object.keys(state.artifacts).length === 0, 'artifacts should be empty object'); assert(Object.keys(state.worldFlags).length === 0, 'worldFlags should be empty object'); assert(Object.keys(state.npcs).length === 0, 'npcs should be empty object'); assert(state.invasionsTriggered.military_40 === false, 'invasionsTriggered.military_40 should be false'); assert(state.invasionsTriggered.spiritual_45 === false, 'invasionsTriggered.spiritual_45 should be false'); assert(state.invasionsTriggered.political_50 === false, 'invasionsTriggered.political_50 should be false'); assert(state.invasionsTriggered.final_60 === false, 'invasionsTriggered.final_60 should be false'); assert(state.breakthroughRoute === null, 'breakthroughRoute should be null'); assert(state.speed === 0, 'speed should be 0'); assert(state.paused === false, 'paused should be false'); assert(Array.isArray(state.logs) && state.logs.length === 0, 'logs should be empty array'); assert(state.triggeredEvents instanceof Set, 'triggeredEvents should be a Set'); assert(Object.keys(state.metaExp).length === 0, 'metaExp should be empty object'); assert(Array.isArray(state.memories) && state.memories.length === 0, 'memories should be empty array'); assert(state.unlockedEntries instanceof Set, 'unlockedEntries should be a Set'); assert(Array.isArray(state.history) && state.history.length === 0, 'history should be empty array'); assert(state.unlockedShopPool instanceof Set, 'unlockedShopPool should be a Set'); } function testResetForRebirth() { const state = createInitialState(); // 模拟一轮游戏数据 state.reincarnation = 2; state.age = 30; state.day = 100; state.money = 5000; state.careers = { merchant: { level: 3 } }; state.identity = 'merchant'; state.stats = { body: 10, wisdom: 15, charm: 8, destiny: 5, business: 20, intelligence: 12 }; state.artifacts = { ringOfLuck: true }; state.metaExp = { merchant: 100 }; state.memories = ['memory1']; state.unlockedEntries.add('entry1'); state.unlockedShopPool.add('item1'); state.history = [{ reincarnation: 0, age: 20 }]; resetForRebirth(state); // 验证重置 assert(state.age === 0, 'age should reset to 0'); assert(state.day === 0, 'day should reset to 0'); assert(state.year === 0, 'year should reset to 0'); assert(state.alive === true, 'alive should reset to true'); assert(state.money === 0, 'money should reset to 0'); assert(Object.keys(state.careers).length === 0, 'careers should reset to empty'); assert(state.identity === null, 'identity should reset to null'); assert(state.stats.body === 0, 'stats.body should reset to 0'); assert(state.reincarnation === 3, 'reincarnation should increment by 1'); // 验证保留 assert(state.artifacts.ringOfLuck === true, 'artifacts should be preserved'); assert(state.metaExp.merchant === 100, 'metaExp should be preserved'); assert(state.memories.length === 1, 'memories should be preserved'); assert(state.unlockedEntries.has('entry1'), 'unlockedEntries should be preserved'); assert(state.unlockedShopPool.has('item1'), 'unlockedShopPool should be preserved'); assert(state.history.length === 2, 'history should have new record appended'); assert(state.history[state.history.length - 1].reincarnation === 2, 'new history record should have correct reincarnation'); assert(state.history[state.history.length - 1].age === 30, 'new history record should have correct age'); assert(state.history[state.history.length - 1].money === 5000, 'new history record should have correct money'); } function testSerializeDeserialize() { const state = createInitialState(); state.triggeredEvents.add('event1'); state.triggeredEvents.add('event2'); state.unlockedEntries.add('entry1'); state.unlockedShopPool.add('item1'); state.unlockedShopPool.add('item2'); state.age = 25; state.money = 1000; const serialized = serializeState(state); // 验证序列化后的 Set 变为 Array assert(Array.isArray(serialized.triggeredEvents), 'serialized triggeredEvents should be Array'); assert(serialized.triggeredEvents.includes('event1'), 'serialized triggeredEvents should contain event1'); assert(Array.isArray(serialized.unlockedEntries), 'serialized unlockedEntries should be Array'); assert(Array.isArray(serialized.unlockedShopPool), 'serialized unlockedShopPool should be Array'); assert(serialized.unlockedShopPool.includes('item2'), 'serialized unlockedShopPool should contain item2'); // 验证 JSON 可序列化 const jsonStr = JSON.stringify(serialized); const parsed = JSON.parse(jsonStr); // 反序列化到新对象 const target = createInitialState(); deserializeState(parsed, target); assert(target.triggeredEvents instanceof Set, 'deserialized triggeredEvents should be Set'); assert(target.triggeredEvents.has('event1'), 'deserialized triggeredEvents should have event1'); assert(target.triggeredEvents.has('event2'), 'deserialized triggeredEvents should have event2'); assert(target.unlockedEntries instanceof Set, 'deserialized unlockedEntries should be Set'); assert(target.unlockedEntries.has('entry1'), 'deserialized unlockedEntries should have entry1'); assert(target.unlockedShopPool instanceof Set, 'deserialized unlockedShopPool should be Set'); assert(target.unlockedShopPool.has('item1'), 'deserialized unlockedShopPool should have item1'); assert(target.age === 25, 'deserialized age should be 25'); assert(target.money === 1000, 'deserialized money should be 1000'); } // 运行测试 testCreateInitialState(); testResetForRebirth(); testSerializeDeserialize(); if (failCount === 0) { console.log('All state tests PASS'); } else { console.log(`${passCount} passed, ${failCount} failed`); process.exit(1); }