43 lines
3.4 KiB
JavaScript
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);
|
|
});
|