const test = require('node:test'); const assert = require('node:assert/strict'); const { loadMembers } = require('./new-player-ab-test-support.cjs'); function setup(newMode) { const events = []; const streak = {}; const win = { active: false, getChildByName: () => streak }; const cc = { error: assert.fail, fx: { GameConfig: { GM_INFO: { level: 20, addLevel: 5 }, canSettleCareer: () => true, getFeatureUnlockLevel: () => 20, } }, }; const Map = loadMembers('assets/Script/Map.ts', [ 'autoNextAfterNewMode', 'showWinWhenReady', 'playWinSettlement', 'onNewModeConfirmed', 'onNewModeReturned', 'onNewModeClosed', 'settlementAnimationTime', 'settlementAnimationSpeed', 'hideNewModeSettlementDecorations', ], { cc }); const map = Object.assign(new Map(), { new_mode: newMode ? 3 : 0, gameOverNode: { active: false }, isMapRuntimeAlive: () => true, ensureWinLoaded: done => done(null, win), getWinRoot: () => win, releaseBlockAssets() {}, releaseLosePanel() {}, setPassProgress: () => events.push('pass'), createRank: () => events.push('rank'), createCareer: () => events.push('career'), Settlement: () => events.push('animation'), openWinStreak: () => events.push('streak'), openNewMode: type => events.push(`intro:${type}`), releaseNewModePanel: () => events.push('close'), winLevel: () => assert.fail('must not enter the next level automatically'), scheduleOnce: () => assert.fail('must not schedule automatic progression'), }); return { map, events, win }; } test('new gameplay introduction accompanies the same full settlement as ordinary wins', () => { const normal = setup(false), introduced = setup(true); normal.map.showWinWhenReady(); introduced.map.showWinWhenReady(); assert.deepEqual(normal.events, ['pass', 'rank', 'career', 'animation', 'streak']); assert.deepEqual(introduced.events, [...normal.events, 'intro:0']); assert.equal(introduced.win.active, true); assert.equal(introduced.map.gameOverNode.active, true); assert.equal(introduced.map.settlementAnimationTime(2), 2); assert.equal(introduced.map.settlementAnimationSpeed(), 1); assert.equal(introduced.map.hideNewModeSettlementDecorations(), false); }); test('introduction buttons only close the panel without repeating settlement or advancing', () => { for (const action of ['onNewModeConfirmed', 'onNewModeReturned']) { const { map, events } = setup(true); map.showWinWhenReady(); const before = events.slice(); map[action](); assert.deepEqual(events, [...before, 'close']); assert.equal(map.autoNextAfterNewMode, false); assert.equal(map.gameOverNode.active, true); } });