79 lines
4.5 KiB
JavaScript
79 lines
4.5 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const ts = require('typescript');
|
|
const code = ts.transpileModule(fs.readFileSync('assets/Script/coin_madness/CoinMadnessHost.ts', 'utf8'), {
|
|
compilerOptions: { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.CommonJS, experimentalDecorators: true }
|
|
}).outputText;
|
|
let now = 100, calls = 0;
|
|
const service = { info: { periodId: 'p1', startsAt: 50, endsAt: 200 },
|
|
get serverNow() { return now; }, settlementNotice: 0, refreshNeedsRetry: false,
|
|
async readForDisplay() { return {}; },
|
|
async refresh() { calls++; return {}; },
|
|
async retryRecovery() { calls++; return {}; } };
|
|
class Component {
|
|
constructor() { this.jobs = new Map(); }
|
|
schedule(fn, seconds) { this.jobs.set(fn, seconds); }
|
|
scheduleOnce(fn, seconds) { this.jobs.set(fn, seconds); }
|
|
unschedule(fn) { this.jobs.delete(fn); }
|
|
}
|
|
const cc = { isValid: () => true, Label: class {}, Button: class {}, Component, _decorator: { ccclass: value => value }, game: { on() {}, off() {} }, warn() {} };
|
|
const exportsHost = {};
|
|
new Function('require', 'exports', 'cc', code)(name => {
|
|
if (name.includes('GoldMinerService')) return { default: { current: () => service } };
|
|
return {};
|
|
}, exportsHost, cc);
|
|
const flush = () => new Promise(resolve => setImmediate(resolve));
|
|
(async () => {
|
|
const host = new exportsHost.default();
|
|
host.updateEntry = host.updateTestEntry = host.refreshCoinDisplay = () => {};
|
|
host.start(); await flush();
|
|
assert.equal(calls, 1);
|
|
assert.equal([...host.jobs.values()].includes(30), false, 'no recurring network poll');
|
|
for (let i = 0; i < 100; i++) host.refreshEntryBadge();
|
|
assert.equal(calls, 1, 'local ticks do not request');
|
|
now = 201; host.refreshEntryBadge(); await flush();
|
|
assert.equal(calls, 2, 'expiry requests once');
|
|
host.refreshEntryBadge(); await flush(); assert.equal(calls, 2);
|
|
service.refreshNeedsRetry = true;
|
|
host.resumeSync(); await flush();
|
|
for (const delay of [2, 3, 5, 7, 10, 15, 25, 30, 50]) {
|
|
assert.equal(host.jobs.get(host.retrySync), delay);
|
|
host.retrySync(); await flush();
|
|
}
|
|
assert.equal(host.jobs.has(host.retrySync), false, 'retry budget exhausted');
|
|
let opened = 0, switched = 0;
|
|
host.open = () => opened++;
|
|
host.openSettlement = () => switched++;
|
|
service.settlementNotice = 100;
|
|
host.showSettlementNotice(); assert.equal(opened, 1, 'ended before login can show notice');
|
|
host.panel = { getComponent: name => name === 'CoinMadnessPanel' ? {} : null };
|
|
host.showSettlementNotice(); assert.equal(switched, 1, 'open activity switches to settlement');
|
|
host.panel = { getComponent: () => null };
|
|
host.showSettlementNotice(); assert.equal(switched, 1, 'existing settlement is not replaced');
|
|
host.showSettlementNotice = () => {};
|
|
service.refreshNeedsRetry = false;
|
|
let animated = 0;
|
|
host.panel = { getComponent: () => ({ rewardSaved: () => animated++ }) };
|
|
service.request = async (action, body, saved) => { saved(100); return {code:1,data:{granted:100}}; };
|
|
await host.requestActivity(service,'claim',{});
|
|
assert.equal(animated, 1);
|
|
assert(host.isCoinDisplayHeld(), 'successful credit waits for animation');
|
|
host.rewardArrived(); assert.equal(host.isCoinDisplayHeld(),false);
|
|
service.request = async () => ({code:0});
|
|
await host.requestActivity(service,'claim',{});
|
|
assert.equal(host.isCoinDisplayHeld(),false,'failed claim does not hold the balance');
|
|
let loads = 0;
|
|
host.node = { getComponent: () => ({ openLoad: () => loads++, closeLoad: () => loads-- }) };
|
|
host.setEntryLoading(true); host.setEntryLoading(true); assert.equal(loads, 1);
|
|
host.setEntryLoading(false); host.setEntryLoading(false); assert.equal(loads, 0);
|
|
const label = { string: '' }, time = { active: true, getComponent: () => label }, bg = { active: true };
|
|
host.entry = { getComponent: () => null, getChildByName: name => name === 'time' ? time : name === 'timeBg' ? bg : null };
|
|
host.syncing = true;
|
|
service.info.endsAt = now + 90061000;
|
|
// Fixture serverNow and endsAt use milliseconds.
|
|
host.refreshEntryBadge(); assert.equal(label.string, '1天1时');
|
|
service.info.endsAt = now + 3661000; host.refreshEntryBadge(); assert.equal(label.string, '01:01:01');
|
|
service.info.endsAt = now; host.refreshEntryBadge(); assert.equal(label.string, ''); assert.equal(bg.active, false);
|
|
console.log('PASS: local countdown, expiry sync, bounded retries and settlement display');
|
|
})().catch(error => { console.error(error); process.exitCode = 1; });
|