import { applyEffect } from '../src/engine/effectApplier.js'; function assert(cond, msg) { if (!cond) throw new Error(msg); } function createState() { return { day: 5, year: 1, age: 10, alive: true, money: 0, stats: { body: 0, wisdom: 0, charm: 0, destiny: 0, business: 0, intelligence: 0 }, careers: {}, shopItems: {}, activeBuffs: {}, artifacts: {}, worldFlags: {}, logs: [], }; } // === addMoney === { const state = createState(); applyEffect({ type: 'addMoney', value: 100 }, state); assert(state.money === 100, 'addMoney should add to money'); } { const state = createState(); state.money = 50; applyEffect({ type: 'addMoney', value: 25 }, state); assert(state.money === 75, 'addMoney should add to existing money'); } // === addStat === { const state = createState(); applyEffect({ type: 'addStat', stat: 'body', value: 5 }, state); assert(state.stats.body === 5, 'addStat should add to stat'); } { const state = createState(); state.stats.body = 10; applyEffect({ type: 'addStat', stat: 'body', value: 3 }, state); assert(state.stats.body === 13, 'addStat should add to existing stat'); } // === setStat === { const state = createState(); applyEffect({ type: 'setStat', stat: 'wisdom', value: 20 }, state); assert(state.stats.wisdom === 20, 'setStat should set stat to value'); } { const state = createState(); state.stats.wisdom = 50; applyEffect({ type: 'setStat', stat: 'wisdom', value: 10 }, state); assert(state.stats.wisdom === 10, 'setStat should overwrite existing stat'); } // === setFlag === { const state = createState(); applyEffect({ type: 'setFlag', flag: 'met_taoist', value: true }, state); assert(state.worldFlags.met_taoist === true, 'setFlag should set flag'); } { const state = createState(); state.worldFlags.met_taoist = true; applyEffect({ type: 'setFlag', flag: 'met_taoist', value: false }, state); assert(state.worldFlags.met_taoist === false, 'setFlag should overwrite flag'); } // === unlockCareer === { const state = createState(); applyEffect({ type: 'unlockCareer', careerId: 'student' }, state); assert(state.careers.student !== undefined, 'unlockCareer should create career'); assert(state.careers.student.level === 0, 'unlockCareer should set level to 0'); assert(state.careers.student.exp === 0, 'unlockCareer should set exp to 0'); } { const state = createState(); state.careers.student = { level: 5, exp: 100 }; applyEffect({ type: 'unlockCareer', careerId: 'student' }, state); assert(state.careers.student.level === 5, 'unlockCareer should not overwrite existing career'); assert(state.careers.student.exp === 100, 'unlockCareer should not overwrite existing career exp'); } // === addExp === { const state = createState(); applyEffect({ type: 'addExp', careerId: 'student', value: 50 }, state); assert(state.careers.student !== undefined, 'addExp should create career if missing'); assert(state.careers.student.exp === 50, 'addExp should add exp'); } { const state = createState(); state.careers.student = { level: 1, exp: 10 }; applyEffect({ type: 'addExp', careerId: 'student', value: 20 }, state); assert(state.careers.student.exp === 30, 'addExp should add to existing exp'); } // === addItem === { const state = createState(); applyEffect({ type: 'addItem', itemId: 'taoist_license' }, state); assert(state.shopItems.taoist_license === 1, 'addItem should add item'); } { const state = createState(); state.shopItems.taoist_license = 2; applyEffect({ type: 'addItem', itemId: 'taoist_license' }, state); assert(state.shopItems.taoist_license === 3, 'addItem should increment existing item'); } // === addBuff === { const state = createState(); applyEffect({ type: 'addBuff', buffId: 'blessing', duration: 10 }, state); assert(state.activeBuffs.blessing !== undefined, 'addBuff should add buff'); assert(state.activeBuffs.blessing.expiresDay === 15, 'addBuff should calculate expiresDay'); } { const state = createState(); applyEffect({ type: 'addBuff', buffId: 'curse', duration: -1 }, state); assert(state.activeBuffs.curse !== undefined, 'addBuff should add permanent buff'); assert(state.activeBuffs.curse.expiresDay === -1, 'addBuff should set expiresDay to -1 for permanent'); } // === upgradeArtifact === { const state = createState(); applyEffect({ type: 'upgradeArtifact', artifactId: 'immortal_sword' }, state); assert(state.artifacts.immortal_sword === 1, 'upgradeArtifact should add artifact'); } { const state = createState(); state.artifacts.immortal_sword = 2; applyEffect({ type: 'upgradeArtifact', artifactId: 'immortal_sword' }, state); assert(state.artifacts.immortal_sword === 3, 'upgradeArtifact should increment existing artifact'); } // === addLog === { const state = createState(); applyEffect({ type: 'addLog', text: 'Test log entry' }, state); assert(state.logs.length === 1, 'addLog should add log entry'); assert(state.logs[0].text === 'Test log entry', 'addLog should set text'); assert(state.logs[0].day === 5, 'addLog should set day'); assert(state.logs[0].year === 1, 'addLog should set year'); assert(state.logs[0].age === 10, 'addLog should set age'); assert(state.logs[0].type === 'normal', 'addLog should default type to normal'); assert(typeof state.logs[0].timestamp === 'number', 'addLog should set timestamp'); } { const state = createState(); applyEffect({ type: 'addLog', text: 'First' }, state); applyEffect({ type: 'addLog', text: 'Second' }, state); assert(state.logs.length === 2, 'addLog should add multiple entries'); assert(state.logs[0].text === 'Second', 'addLog should add newest to front'); assert(state.logs[1].text === 'First', 'addLog should keep older entries at back'); } { const state = createState(); for (let i = 0; i < 510; i++) { applyEffect({ type: 'addLog', text: `Log ${i}` }, state); } assert(state.logs.length === 500, 'addLog should cap at 500 entries'); assert(state.logs[0].text === 'Log 509', 'addLog should keep newest entries'); } // === die === { const state = createState(); applyEffect({ type: 'die', reason: 'old_age' }, state); assert(state.alive === false, 'die should set alive to false'); assert(state.deathReason === 'old_age', 'die should set deathReason'); } // === edge cases === { const state = createState(); applyEffect(null, state); assert(state.money === 0, 'null effect should not modify state'); } { const state = createState(); applyEffect({}, state); assert(state.money === 0, 'empty effect should not modify state'); } { const state = createState(); applyEffect({ type: 'unknownEffect' }, state); assert(state.money === 0, 'unknown effect should not modify state'); } console.log('All effectApplier tests PASS');