MatchMaster/tools/verify-popup-preload-policy.cjs

94 lines
3.6 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const ts = require('typescript');
const source = ts.transpileModule(
fs.readFileSync('assets/Script/module/Tool/GameTool.ts', 'utf8'),
{ compilerOptions: { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.CommonJS } },
).outputText;
const subpackageRequests = [];
const bundleRequests = [];
const bundles = new Map();
let activePrefabLoads = 0;
let maxPrefabLoads = 0;
let instantiateCalls = 0;
let deviceInfo = { platform: 'android', memorySize: 2048 };
const wx = {
getDeviceInfo: () => deviceInfo,
preDownloadSubpackage(options) { subpackageRequests.push(options); },
};
const cc = {
Prefab: class {},
sys: {
WECHAT_GAME: 'wechat', platform: 'wechat',
OS_ANDROID: 'Android', OS_IOS: 'iOS', os: 'Android',
},
fx: {},
game: {},
director: { getScene: () => ({ name: 'HomeScene' }) },
warn() {},
instantiate() { instantiateCalls++; throw new Error('Home warmup must not instantiate'); },
assetManager: {
getBundle: name => bundles.get(name) || null,
removeBundle(bundle) { bundles.delete(bundle.name); },
loadBundle(name, callback) {
bundleRequests.push(name);
activePrefabLoads++;
maxPrefabLoads = Math.max(maxPrefabLoads, activePrefabLoads);
const bundle = {
name,
releaseAll() {},
load(path, type, done) {
setImmediate(() => {
activePrefabLoads--;
done(null, { path });
});
},
};
bundles.set(name, bundle);
setImmediate(() => callback(null, bundle));
},
},
};
const moduleObject = { exports: {} };
vm.runInNewContext(source, {
module: moduleObject,
exports: moduleObject.exports,
require: () => ({ default: {}, MiniGameSdk: { API: {} } }),
cc, wx, console, setTimeout, clearTimeout, setImmediate,
});
const gameTool = moduleObject.exports.GameTool;
cc.fx.GameTool = gameTool;
(async () => {
const diskReady = gameTool.predownloadGameplayPopupSubpackages(false);
assert.equal(subpackageRequests.length, 5, 'all five disk downloads should start together');
const expectedOrder = ['pause', 'win', 'propWindow', 'NewMode', 'lose'];
assert.deepEqual(subpackageRequests.map(request => request.name), expectedOrder,
'disk requests must follow the gameplay warmup order');
subpackageRequests.forEach(request => request.success());
assert.equal(await diskReady, true);
assert.equal(await gameTool.warmupHomeGameplayPopupAssets(), true);
assert.deepEqual(bundleRequests, expectedOrder, 'Bundle requests must use the same order');
assert.equal(maxPrefabLoads, 2, 'Prefab decode concurrency must stay at two');
assert.equal(instantiateCalls, 0, 'HomeScene must not instantiate popup nodes');
assert.equal(gameTool.beginGameplayPopupGameSceneReloadRetention(), true);
assert.equal(gameTool.shouldRetainGameplayPopupBundlesForGameSceneReload(), true);
gameTool.finishGameplayPopupGameSceneReloadRetention();
assert.equal(gameTool.shouldRetainGameplayPopupBundlesForGameSceneReload(), false);
deviceInfo = { platform: 'ios', memorySize: 4096 };
cc.sys.os = cc.sys.OS_IOS;
assert.equal(gameTool.beginGameplayPopupGameSceneReloadRetention(), false,
'low-memory iOS must never retain bundles across GameScene reload');
console.log('Popup preload and retention policy checks passed');
})().catch(error => {
console.error(error);
process.exitCode = 1;
});