MatchMaster/tools/test-seven-day-loading.cjs

43 lines
3.4 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(cached = false) {
const bundles = new Map(), pending = new Map(); let parses = 0;
const bundle = (name, deps = []) => ({name, deps, releaseAll() {}, load(path, type, done) {
parses++; assert.ok(bundles.has('action_bundle')); assert.ok(bundles.has('UI')); done(null, {});
}});
const gift = bundle('seven_day_gift', ['action_bundle']);
if (cached) bundles.set(gift.name, gift);
const view = {};
const cc = { _decorator: { ccclass: x => x }, Component: class {}, Prefab: class {},
isValid: n => n && !n.destroyed,
assetManager: { getBundle: name => bundles.get(name), removeBundle: b => bundles.delete(b.name),
loadBundle: (name, options, cb) => { pending.set(name, typeof options === 'function' ? options : cb); } },
instantiate: () => ({active: false, setPosition() {}, getComponent: () => view}),
find: () => ({getComponent: () => home}) };
const parsed = ts.createSourceFile('JiaZai.ts', fs.readFileSync('assets/Script/JiaZai.ts','utf8'),99,true);
const members = parsed.statements.find(ts.isClassDeclaration).members.filter(n => ['isHomeBundleReady','loadHomeBundleWithDependencies'].includes(n.name?.getText(parsed))).map(n=>n.getText(parsed)).join('\n');
const ctx = {cc}; vm.runInNewContext(ts.transpileModule('class Home {'+members+'} globalThis.Home=Home;', {compilerOptions:{target:ts.ScriptTarget.ES2020}}).outputText,ctx);
const home = new ctx.Home(); const out = {};
vm.runInNewContext(ts.transpileModule(fs.readFileSync('assets/Script/seven_day_gift/SevenDayGiftHost.ts','utf8'),{compilerOptions:{target:ts.ScriptTarget.ES2020,module:ts.ModuleKind.CommonJS,experimentalDecorators:true}}).outputText,{cc,exports:out,require:()=>({default:{}})});
const host = new out.default(); host.node = {addChild() {}};
const finish = (name,error) => { const b=name==='seven_day_gift'?gift:bundle(name,name==='action_bundle'?['UI']:[]);if(!error)bundles.set(name,b);const cb=pending.get(name);assert.ok(cb,'missing request '+name);pending.delete(name);cb(error,b); };
return {host, pending, finish, parses:()=>parses};
}
for (const cached of [false,true]) test(`seven-day Prefab waits for nested dependencies, cached=${cached}`,()=>{
const f=fixture(cached);let completed=0;f.host.ensureGiftLoaded(error=>{assert.ifError(error);completed++;});
if(!cached)f.finish('seven_day_gift');assert.equal(f.parses(),0);
f.finish('action_bundle');assert.equal(f.parses(),0);f.finish('UI');assert.equal(f.parses(),1);assert.equal(completed,1);
});
test('dependency failure completes callback and allows retry',()=>{
const f=fixture(true);let error;f.host.ensureGiftLoaded(e=>error=e);f.finish('action_bundle',new Error('offline'));
assert.match(error.message,/offline/);assert.equal(f.host.giftLoading,false);assert.equal(f.parses(),0);
f.host.ensureGiftLoaded(e=>assert.ifError(e));f.finish('action_bundle');f.finish('UI');assert.equal(f.parses(),1);
});
test('destroyed host does not parse the Prefab after dependencies finish',()=>{
const f=fixture(true);f.host.ensureGiftLoaded(()=>assert.fail('stale callback'));f.host.node.destroyed=true;
f.finish('action_bundle');f.finish('UI');assert.equal(f.parses(),0);
});