115 lines
5.9 KiB
JavaScript
115 lines
5.9 KiB
JavaScript
// TYPESCRIPT_PATH may point to the TypeScript bundled with Cocos Creator.
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
const ts = require(process.env.TYPESCRIPT_PATH || 'typescript');
|
|
const blockFile = 'assets/Script/Block.ts';
|
|
const collideFile = 'assets/Script/lq_collide_system/lq_collide.ts';
|
|
function method(file, name, globals = {}) {
|
|
const source = ts.createSourceFile(file, fs.readFileSync(path.join(__dirname, '..', file), 'utf8'), ts.ScriptTarget.Latest, true);
|
|
const cls = source.statements.find(node => ts.isClassDeclaration(node));
|
|
const member = cls.members.find(node => node.name && node.name.getText(source) === name);
|
|
assert.ok(member, name);
|
|
const code = ts.transpileModule('class Subject {' + member.getText(source) + '}\nSubject;',
|
|
{ compilerOptions: { target: ts.ScriptTarget.ES2017 } }).outputText;
|
|
return vm.runInNewContext(code, { console, ...globals }).prototype[name];
|
|
}
|
|
const refresh = method(blockFile, 'refreshOldRainbowVisual');
|
|
const sameColorTile = method(blockFile, 'canPassSameColorSimpleBlock');
|
|
const BlockType = { 普通块: 0, 叠加块上: 10, 粘合块: 9, 变色块: 20, 单色地块: 22, 问号块: 16 };
|
|
function makeBlock(oldRainbow = true, color = 5, type = 2) {
|
|
const sprite = {};
|
|
const children = {
|
|
icon: { active: true, getComponent: () => sprite },
|
|
rainbow_old: { active: false },
|
|
key: { active: true },
|
|
flowerSend: { active: true },
|
|
};
|
|
return { oldRainbow, color, type, block_Info: { block: 5, type, color, flowerSend: 4 },
|
|
node: { getChildByName: name => children[name], children: Object.values(children) },
|
|
refreshOldRainbowVisual: refresh, children, sprite };
|
|
}
|
|
|
|
test('old rainbow visuals preserve real color, type and attachments through color refresh and thaw', () => {
|
|
const globals = { cc: { Sprite: {} }, BlockType, MapConroler: { _instance: {} },
|
|
BlockAssetManager: { instance: { getFrame: name => name } }, blockTexturePath: (color, shape) => `${color}color${shape}` };
|
|
const initColor = method(blockFile, 'initColor', globals);
|
|
const resetFreeze = method(blockFile, 'resetFreeze', globals);
|
|
const b = makeBlock();
|
|
initColor.call(b, false);
|
|
assert.equal(b.color, 5);
|
|
assert.equal(b.type, 2);
|
|
assert.equal(b.sprite.spriteFrame, '5color5');
|
|
assert.equal(b.children.icon.active, false);
|
|
assert.equal(b.children.rainbow_old.active, true);
|
|
assert.equal(b.children.key.active, true);
|
|
assert.equal(b.children.flowerSend.active, true);
|
|
b.type = b.block_Info.type = 4;
|
|
b.children.rainbow_old.active = false;
|
|
b.children.icon.active = true;
|
|
resetFreeze.call(b);
|
|
assert.equal(b.type, 0);
|
|
assert.equal(b.color, 5);
|
|
assert.equal(b.oldRainbow, true);
|
|
assert.equal(b.children.rainbow_old.active, true);
|
|
assert.equal(b.children.icon.active, false);
|
|
const ordinary = makeBlock(false);
|
|
refresh.call(ordinary);
|
|
assert.equal(ordinary.children.icon.active, true);
|
|
});
|
|
|
|
test('initializing a reused block removes old rainbow capability and overlay', () => {
|
|
const b = makeBlock();
|
|
let destroyed = false;
|
|
b.children.rainbow_old.removeFromParent = () => { delete b.children.rainbow_old; };
|
|
b.children.rainbow_old.destroy = () => { destroyed = true; };
|
|
b.node.on = () => {};
|
|
b.node._touchListener = { setSwallowTouches() {} };
|
|
Object.assign(b, { jsonDeepClone: v => JSON.parse(JSON.stringify(v)), initColor() {}, initType() {}, initBlocks() {}, flowerType: 0 });
|
|
const init = method(blockFile, 'init', { cc: { Node: { EventType: {} } }, BlockType,
|
|
MapConroler: { _instance: { mapInfo: [] } }, setTimeout() {} });
|
|
init.call(b, { type: 0, color: 7, block: 5, id: 9 });
|
|
assert.equal(destroyed, true);
|
|
assert.equal(b.oldRainbow, false);
|
|
assert.equal(b.color, 7);
|
|
assert.equal(b.type, 0);
|
|
assert.equal(b.children.icon.active, true);
|
|
});
|
|
|
|
test('opening conversion blocks input before reading a touch event', () => {
|
|
const touchStart = method(blockFile, 'touchStart', { MapConroler: { _instance: { oldRainbowPreparing: true } } });
|
|
touchStart.call({}, { getLocation() { throw Error('opening conversion accepted a touch'); } });
|
|
});
|
|
|
|
test('old rainbow passes both kinds of monochrome tile, but not walls, vines or composite restrictions', () => {
|
|
const map = { riseFallBlock: [] };
|
|
const disable = method(collideFile, 'disableCollider', { MapConroler: { _instance: map } });
|
|
let id = 0;
|
|
const make = (color, type = 0, oldRainbow = false, info = {}) => {
|
|
const block = { color, type, oldRainbow, block_Info: info, canPassSameColorSimpleBlock: sameColorTile };
|
|
return { block, node: { name: 'left', parent: { uuid: ++id, getComponent: () => block } } };
|
|
};
|
|
for (let color = 1; color <= 10; color++) {
|
|
const rainbow = make(5, 2, true), tile = make(color, 22);
|
|
assert.equal(disable.call(rainbow, tile), true);
|
|
assert.equal(disable.call(tile, rainbow), true);
|
|
assert.equal(disable.call(rainbow, make(color)), false);
|
|
assert.equal(disable.call(make(5, 0, true, { floorMove: true }), tile), false);
|
|
const covered = make(5, 0, true); covered.block.flowerType = 2;
|
|
assert.equal(disable.call(covered, tile), false);
|
|
const ordinary = make(color === 5 ? 6 : 5);
|
|
assert.equal(disable.call(ordinary, tile), false);
|
|
}
|
|
const rainbow = make(5, 0, true);
|
|
const fixed = { node: { name: 'rise', parent: { uuid: ++id, getComponent: () => null } } };
|
|
map.riseFallBlock = [fixed.node.parent];
|
|
assert.equal(disable.call(rainbow, fixed), true);
|
|
map.riseFallBlock = [];
|
|
assert.equal(disable.call(rainbow, fixed), false, 'unregistered rise includes vines and poles');
|
|
fixed.node.name = 'wall';
|
|
assert.equal(disable.call(rainbow, fixed), false);
|
|
assert.equal(rainbow.block.color, 5);
|
|
});
|