MatchMaster/tools/test-shop-stamina.cjs

91 lines
4.6 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const { loadMembers } = require('./new-player-ab-test-support.cjs');
function fixture(hp = 5, powerSeconds = 60) {
let now = 1000;
const info = { hp, hp_Max: 5, userPowerTime: powerSeconds ? now + powerSeconds : 0,
min_Time: 120, useravatarIcon: '', useravaterkuang: '', coin: 100 };
const node = () => {
const children = new Map(), component = {};
return { active: true, opacity: 255, getChildByName(name) {
if (!children.has(name)) children.set(name, node());
return children.get(name);
}, getComponent: () => component };
};
const cc = { sys: { platform: 'browser', WECHAT_GAME: 'wechat', BYTEDANCE_GAME: 'bytedance' },
Sprite: {}, Label: {}, find: () => ({ getComponent: () => null }), fx: {
GameConfig: { GM_INFO: info }, GameTool: {
getUserPowerTime() { if (info.userPowerTime <= now) { info.userPowerTime = 0; return false; } return true; },
getTimeMargin: value => String(value), getTimeMargin2: value => String(value),
getActionName() {}, loadSpineSimple() {}, getSetScreenResolutionFlag: () => false,
},
} };
const Shop = loadMembers('assets/shop/script/shop.ts', [
'init', 'setHealthInfo', 'updatePower', 'startPowerTime', 'stopPowerTime',
'startTimeCutDown', 'stopTimeCutDown', 'removeOnShowListener',
], { cc, Date: { now: () => now * 1000 }, SceneManager: {}, MapConroler: {},
NumberToImage: { numberToImageNodes() {}, numberToImageNodesCoin() {} }, console: { log() {} } });
const shop = new Shop(), scheduled = new Set();
Object.assign(shop, { node: node(), Stamina: node(), coin: node(), ui: { getSpriteFrame() {} },
refreshJungleEntryLayout() {}, openShop() {}, updateIcon() {},
schedule: callback => scheduled.add(callback), unschedule: callback => scheduled.delete(callback) });
const get = name => shop.Stamina.getChildByName(name);
const open = () => { shop.node.active = true; shop.init({}); };
const tick = seconds => { now += seconds; [...scheduled].forEach(callback => callback()); };
return { shop, info, scheduled, get, open, tick, advance: seconds => { now += seconds; } };
}
test('full stamina and infinite stamina never show both labels when repeatedly reopening the cached shop', () => {
const f = fixture();
for (let i = 0; i < 3; i++) {
f.open();
assert.equal(f.get('man').active, false, 'full label must already be hidden before the first timer tick');
assert.equal(f.get('skyLine').active, true);
assert.equal(f.scheduled.size, 1, 'reopening must not duplicate the infinite stamina timer');
f.tick(1);
assert.equal(f.get('man').active, false);
assert.equal(f.get('skyLine').getChildByName('skyTime').getComponent().string, String(59 - i));
f.shop.node.active = false;
}
});
test('a later ordinary health refresh cannot cover the infinite stamina countdown', () => {
const f = fixture(); f.open(); f.tick(1); f.shop.setHealthInfo(true);
assert.equal(f.get('man').active, false);
assert.equal(f.get('skyLine').active, true);
assert.equal(f.info.hp, 5);
});
test('full stamina without infinite stamina still displays full immediately', () => {
const f = fixture(5, 0);
for (let i = 0; i < 2; i++) {
f.open(); assert.equal(f.get('man').active, true); assert.equal(f.get('skyLine').active, false);
assert.equal(f.get('time').active, false); assert.equal(f.scheduled.size, 0);
}
});
test('infinite stamina expiring while the shop is closed restores the full label on reopening', () => {
const f = fixture(5, 2); f.open(); f.shop.node.active = false; f.advance(2); f.open();
assert.equal(f.get('skyLine').active, false); assert.equal(f.get('man').active, true);
assert.equal(f.scheduled.size, 0);
});
test('infinite stamina expiring in the open shop restores the full label', () => {
const f = fixture(5, 2); f.open(); f.tick(2);
assert.equal(f.get('skyLine').active, false); assert.equal(f.get('man').active, true);
assert.equal(f.scheduled.size, 0);
});
test('non-full stamina preserves ordinary and infinite countdown visibility', () => {
for (const power of [0, 60]) {
const f = fixture(3, power); f.open();
assert.equal(f.get('man').active, false);
assert.equal(f.get('skyLine').active, power > 0);
assert.equal(f.get('time').active, true);
assert.equal(f.get('time').opacity, power ? 0 : 255);
assert.equal(f.get('progresss').getComponent().fillRange, 3 / 5);
assert.equal(f.info.hp, 3);
}
});