Files
erqiwang_youle/client/tests/test_index_load_order.js
T
joywayerandClaude Opus 5 22e43cf2e6 二七王:平台接线与加载段
SubGameHooks 只解包转交、不写业务:_ReceiveData 收到的是完整包,
按 rpc 分发;Free 的参数是平台已取出的 deskfree、可能为 null;
appStart 只记座位与房间选项,UI 初始化留给 C 阶段。

index.html 里 handler 排在 Dispatcher 之前——后者注册时要引用全部 handler。

另加 test_index_load_order.js:按 index.html 实际 script 顺序自动加载
codes/ 全部文件 + 3 个框架依赖,验证顺序无遗漏、无环,并断言
EQW_Dispatcher 路由表确已注册,作为长期守卫。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 20:16:45 +08:00

110 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// index.html 加载顺序自检(task-13 步骤6守卫):
// 按 index.html 里 <script src> 的实际先后顺序,抽取「codes/ 全部文件 + 它们依赖的
// 3 个框架文件(EventBus/SpriteEventController/AlignmentUtils)」,依次用 vm 加载,
// 确认:1) 无异常抛出(顺序错了会因引用未定义全局而报错)
// 2) 关键全局全部就绪
// 3) EQW_Dispatcher 的路由表确已注册(hasHandler('chupai1') === true)
// 这份顺序即是 index.html 的真实加载顺序,不是我们另行假设的一份。
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const t = require('./_assert')();
const ROOT = path.resolve(__dirname, '..', '..');
const indexHtml = fs.readFileSync(path.join(ROOT, 'client', 'index.html'), 'utf8');
// 抽取全部本地 <script src="..."> 路径,按文档出现顺序
const scriptRe = /<script[^>]*\ssrc="([^"]+)"[^>]*><\/script>/g;
const allSrcs = [];
let m;
while ((m = scriptRe.exec(indexHtml)) !== null) {
allSrcs.push(m[1]);
}
t.eq('index.html 至少解析出脚本标签', allSrcs.length > 0, true);
// 只保留:codes/ 下全部文件 + 3 个框架依赖文件,其余(vendor/引擎/大厅平台代码等)
// 无法在 Node 里单独跑,本自检不覆盖,留给「浏览器人工验证」。
const NEEDED_FRAMEWORK = [
'js/gameabc-framework/system/EventBus.js',
'js/gameabc-framework/system/SpriteEventController.js',
'js/gameabc-framework/ui/AlignmentUtils.js'
];
const relevant = allSrcs.filter(function (src) {
return NEEDED_FRAMEWORK.indexOf(src) !== -1 || src.indexOf('js/01_SubGame/codes/') === 0;
});
// 期望齐全的清单:本任务新增/相关的 state/ net/ 文件,一个都不能漏
const EXPECT_PRESENT = [
'js/01_SubGame/codes/state/Events.js',
'js/01_SubGame/codes/state/GameState.js',
'js/01_SubGame/codes/state/RoomOptions.js',
'js/01_SubGame/codes/net/handlers/FailHandler.js',
'js/01_SubGame/codes/net/handlers/DealHandler.js',
'js/01_SubGame/codes/net/handlers/CallHandler.js',
'js/01_SubGame/codes/net/handlers/MainHandler.js',
'js/01_SubGame/codes/net/handlers/BuryHandler.js',
'js/01_SubGame/codes/net/handlers/PlayHandler.js',
'js/01_SubGame/codes/net/handlers/QueryHandler.js',
'js/01_SubGame/codes/net/handlers/ReadyHandler.js',
'js/01_SubGame/codes/net/handlers/ResultHandler.js',
'js/01_SubGame/codes/net/handlers/ResyncHandler.js',
'js/01_SubGame/codes/net/Dispatcher.js',
'js/01_SubGame/codes/net/Rpc.js',
'js/01_SubGame/codes/SubGameHooks.js'
];
EXPECT_PRESENT.forEach(function (src) {
t.eq('index.html 含脚本 ' + src, allSrcs.indexOf(src) !== -1, true);
});
// 相对顺序断言:handler 全部排在 Dispatcher 之前;state/ 排在 net/handlers/ 之前
const idx = {};
relevant.forEach(function (src, i) { idx[src] = i; });
var dispatcherIdx = idx['js/01_SubGame/codes/net/Dispatcher.js'];
[
'js/01_SubGame/codes/net/handlers/FailHandler.js',
'js/01_SubGame/codes/net/handlers/DealHandler.js',
'js/01_SubGame/codes/net/handlers/CallHandler.js',
'js/01_SubGame/codes/net/handlers/MainHandler.js',
'js/01_SubGame/codes/net/handlers/BuryHandler.js',
'js/01_SubGame/codes/net/handlers/PlayHandler.js',
'js/01_SubGame/codes/net/handlers/QueryHandler.js',
'js/01_SubGame/codes/net/handlers/ReadyHandler.js',
'js/01_SubGame/codes/net/handlers/ResultHandler.js',
'js/01_SubGame/codes/net/handlers/ResyncHandler.js'
].forEach(function (h) {
t.eq('handler 排在 Dispatcher 之前: ' + h, idx[h] < dispatcherIdx, true);
});
t.eq('state/ 排在 net/handlers/ 之前', idx['js/01_SubGame/codes/state/GameState.js'] < idx['js/01_SubGame/codes/net/handlers/FailHandler.js'], true);
t.eq('SubGameHooks 排在 Dispatcher 之后', idx['js/01_SubGame/codes/SubGameHooks.js'] > dispatcherIdx, true);
// 依次实际加载,确认不抛异常,且顺序自洽
global.window = global;
let loadErr = null;
try {
relevant.forEach(function (src) {
const abs = path.join(ROOT, 'client', src);
const code = fs.readFileSync(abs, 'utf8');
vm.runInThisContext(code, { filename: src });
});
} catch (e) {
loadErr = e;
}
t.eq('按 index.html 顺序加载无异常', loadErr ? (loadErr.stack || String(loadErr)) : null, null);
// 关键全局就绪
[
'EQW_Events', 'EQW_GameState', 'EQW_RoomOptions_Parse', 'EQW_Dispatcher', 'EQW_Rpc',
'EQW_DealHandler', 'EQW_CallHandler', 'EQW_MainHandler', 'EQW_BuryHandler', 'EQW_PlayHandler',
'EQW_QueryHandler', 'EQW_ReadyHandler', 'EQW_ResultHandler', 'EQW_ResyncHandler', 'EQW_FailHandler',
'SubGameHooks'
].forEach(function (name) {
t.eq('全局就绪: ' + name, typeof global[name] !== 'undefined', true);
});
// 路由表确已注册
if (typeof global.EQW_Dispatcher !== 'undefined') {
t.eq("EQW_Dispatcher.hasHandler('chupai1')", global.EQW_Dispatcher.hasHandler('chupai1'), true);
}
process.exit(t.done('index_load_order') ? 0 : 1);