99 lines
4.7 KiB
JavaScript
99 lines
4.7 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const { loadMembers } = require('./new-player-ab-test-support.cjs');
|
|
|
|
function fixture(legacy = false) {
|
|
const data = JSON.parse(fs.readFileSync('assets/Scene/GameScene.fire', 'utf8'));
|
|
class Widget {
|
|
static AlignMode = { ON_WINDOW_RESIZE: 1 };
|
|
updateAlignment() {
|
|
const node = this.node;
|
|
node.y = node.parent.height * (1 - node.parent.anchorY) - this.top
|
|
- node.height * (1 - node.anchorY) * node.scaleY;
|
|
}
|
|
}
|
|
const nodes = data.map(n => n.__type__ === 'cc.Node' ? {
|
|
name: n._name, children: [], components: [],
|
|
x: n._trs.array[0], y: n._trs.array[1], scaleY: n._trs.array[8],
|
|
height: n._contentSize.height, anchorY: n._anchorPoint.y,
|
|
get parent() { return this._parent; },
|
|
set parent(value) {
|
|
if (this._parent) this._parent.children = this._parent.children.filter(n => n !== this);
|
|
this._parent = value;
|
|
value.children.push(this);
|
|
},
|
|
getChildByName(name) { return this.children.find(n => n.name === name) || null; },
|
|
getComponent(type) { return this.components.find(c => c instanceof type) || null; },
|
|
addComponent(type) { const c = new type(); c.node = this; this.components.push(c); return c; },
|
|
setPosition(p) { this.x = p.x; this.y = p.y; },
|
|
convertToWorldSpaceAR(p) {
|
|
const result = { x: p.x + this.x, y: p.y + this.y };
|
|
return this.parent ? this.parent.convertToWorldSpaceAR(result) : result;
|
|
},
|
|
convertToNodeSpaceAR(p) {
|
|
const origin = this.convertToWorldSpaceAR({ x: 0, y: 0 });
|
|
return { x: p.x - origin.x, y: p.y - origin.y };
|
|
},
|
|
} : null);
|
|
nodes.forEach((node, i) => {
|
|
if (!node) return;
|
|
if (nodes[data[i]._parent?.__id__]) node.parent = nodes[data[i]._parent.__id__];
|
|
for (const ref of data[i]._components) {
|
|
const c = data[ref.__id__];
|
|
if (c.__type__ === 'cc.Widget') Object.assign(node.addComponent(Widget), { top: c._top });
|
|
}
|
|
});
|
|
const canvas = nodes.find(n => n?.name === 'Canvas');
|
|
const game = canvas.getChildByName('Game');
|
|
const gameNode = game.getChildByName('GameNode');
|
|
const top = gameNode.getChildByName('Top');
|
|
const shop = game.getChildByName('shop');
|
|
top.getComponent(Widget).updateAlignment();
|
|
if (legacy) {
|
|
shop.parent = top;
|
|
shop.y = -67.741;
|
|
shop.components = [];
|
|
} else if (shop.getComponent(Widget)) shop.getComponent(Widget).updateAlignment();
|
|
const cc = {
|
|
Widget, macro: { MAX_ZINDEX: 32767 }, isValid: node => !!node,
|
|
v2: (x, y) => ({ x, y }),
|
|
find: (path, root) => path.split('/').reduce((node, name) => node && node.getChildByName(name), root),
|
|
};
|
|
const Manager = loadMembers('assets/Script/SceneManager.ts', ['ensureGameShop', 'getWinCoinFlyTarget'], { cc });
|
|
return { manager: Object.assign(new Manager(), { node: canvas }), game, top, shop, Widget };
|
|
}
|
|
|
|
for (const legacy of [false, true]) {
|
|
test(`${legacy ? 'old' : 'new'} scene keeps Shop above Lose with valid coin children and unchanged position`, () => {
|
|
for (const height of [1280, 1920, 2400]) {
|
|
const { manager, game, shop, top, Widget } = fixture(legacy);
|
|
const before = shop.convertToWorldSpaceAR({ x: 0, y: 0 });
|
|
assert.equal(manager.ensureGameShop(), shop);
|
|
assert.equal(shop.parent, game);
|
|
assert.equal(top.getChildByName('shop'), null);
|
|
assert.equal(shop.zIndex, 32766);
|
|
shop.getComponent(Widget).updateAlignment();
|
|
assert.deepEqual(shop.convertToWorldSpaceAR({ x: 0, y: 0 }), before);
|
|
assert.ok(shop.getChildByName('coin'));
|
|
assert.equal(manager.getWinCoinFlyTarget(), shop.getChildByName('coins'));
|
|
assert.equal(manager.ensureGameShop(), shop);
|
|
assert.equal(shop.components.filter(c => c instanceof Widget).length, 1);
|
|
assert.equal(game.children.filter(n => n === shop).length, 1);
|
|
game.height = height;
|
|
shop.getComponent(Widget).updateAlignment();
|
|
assert.ok(Math.abs(shop.y - (height / 2 - 297.741)) < 1e-9);
|
|
}
|
|
});
|
|
}
|
|
|
|
test('missing Shop returns null instead of throwing while setting zIndex or resolving coins', () => {
|
|
const { manager, game, shop } = fixture();
|
|
game.children = game.children.filter(n => n !== shop);
|
|
assert.equal(manager.ensureGameShop(), null);
|
|
assert.equal(manager.getWinCoinFlyTarget(), null);
|
|
manager.node = null;
|
|
assert.equal(manager.ensureGameShop(), null);
|
|
assert.equal(manager.getWinCoinFlyTarget(), null);
|
|
});
|