85 lines
4.2 KiB
JavaScript
85 lines
4.2 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
const ts = require('typescript');
|
|
|
|
function fixture(hp, remaining) {
|
|
let now = 1800000000000;
|
|
const info = { hp, hp_Max: 5, userPowerTime: remaining ? now / 1000 + remaining : 0 };
|
|
const storage = new Map([['userPowerTime', info.userPowerTime]]);
|
|
const timers = new Set();
|
|
const label = { string: '' };
|
|
const children = {
|
|
skyLine: { active: remaining > 0, getChildByName: () => ({ getComponent: () => label }) },
|
|
man: { active: remaining === 0 && hp === 5 },
|
|
add: { active: remaining === 0 && hp < 5 },
|
|
time: { opacity: remaining > 0 ? 0 : 255 },
|
|
};
|
|
const cc = { Label: class {}, fx: {
|
|
GameConfig: { GM_INFO: info },
|
|
StorageMessage: { getStorage: key => storage.get(key), setStorage: (key, value) => storage.set(key, value) },
|
|
}, find: () => ({ getComponent: () => home }) };
|
|
const context = vm.createContext({ cc, wx: {}, Date: { now: () => now },
|
|
Utils: { setUserPowerTime() {} }, console: { log() {} } });
|
|
function run(source) {
|
|
vm.runInContext(ts.transpileModule(source, {
|
|
compilerOptions: { target: ts.ScriptTarget.ES2020, module: ts.ModuleKind.CommonJS },
|
|
}).outputText, context);
|
|
}
|
|
function parse(path) {
|
|
return ts.createSourceFile(path, fs.readFileSync(path, 'utf8'), ts.ScriptTarget.Latest, true);
|
|
}
|
|
const toolSource = parse('assets/Script/module/Tool/GameTool.ts');
|
|
let toolObject;
|
|
function visit(node) {
|
|
if (ts.isVariableDeclaration(node) && node.name.getText(toolSource) === 'GameTool') toolObject = node.initializer;
|
|
ts.forEachChild(node, visit);
|
|
}
|
|
visit(toolSource);
|
|
const toolMethods = toolObject.properties.filter(node =>
|
|
['setUserPowerTime', 'getUserPowerTime', 'getTimeMargin2'].includes(node.name?.getText(toolSource)));
|
|
run('cc.fx.GameTool = {' + toolMethods.map(node => node.getText(toolSource)).join(',\n') + '};');
|
|
cc.fx.GameTool.shushu_Track = () => {};
|
|
const homeSource = parse('assets/Script/JiaZai.ts');
|
|
const homeMethods = homeSource.statements.find(ts.isClassDeclaration).members.filter(node =>
|
|
['updatePower', 'startPowerTime', 'stopPowerTime', 'refreshStaminaDisplay'].includes(node.name?.getText(homeSource)));
|
|
run('globalThis.Home = class {' + homeMethods.map(node => node.getText(homeSource)).join('\n') + '};');
|
|
const home = new context.Home();
|
|
home.Stamina = { getChildByName: name => children[name] };
|
|
home.schedule = callback => timers.add(callback);
|
|
home.unschedule = callback => timers.delete(callback);
|
|
home.updateCoin = () => {};
|
|
if (remaining) home.updatePower();
|
|
|
|
context.exports = {};
|
|
context.require = () => ({ default: { getUid: () => 'test-user' } });
|
|
run(fs.readFileSync('assets/seven_day_gift/SevenDayGiftReward.ts', 'utf8'));
|
|
const receipt = { claimId: 'day-one', rewards: [{ type: 'infinite_health', count: 900 }] };
|
|
return { info, children, label, timers, grant() {
|
|
let completed = false;
|
|
context.exports.default.grant(receipt, success => { assert.equal(success, true); completed = true; });
|
|
assert.equal(completed, true);
|
|
}, tick() { now += 1000; [...timers].forEach(callback => callback()); } };
|
|
}
|
|
|
|
for (const hp of [5, 2]) {
|
|
for (const remaining of [0, 600]) {
|
|
test(`day-one reward shows infinite stamina: hp=${hp}, remaining=${remaining}`, () => {
|
|
const f = fixture(hp, remaining);
|
|
f.grant();
|
|
assert.equal(f.children.skyLine.active, true, 'infinite stamina becomes visible after claiming');
|
|
assert.equal(f.children.man.active, false);
|
|
assert.equal(f.children.add.active, false);
|
|
assert.equal(f.children.time.opacity, 0);
|
|
assert.equal(f.timers.size, 1, 'exactly one infinite stamina timer runs');
|
|
f.tick();
|
|
assert.equal(f.label.string, remaining ? '24:59' : '14:59');
|
|
const expiry = f.info.userPowerTime;
|
|
f.grant();
|
|
assert.equal(f.info.userPowerTime, expiry, 'repeated receipt does not add time twice');
|
|
assert.equal(f.timers.size, 1);
|
|
});
|
|
}
|
|
}
|