Files
erqiwang_youle/client/tests/test_spriteindex.js
T
joywayerandClaude Opus 5 1976edf9bd 二七王:前端 SpriteIndex,精灵键名扁平索引
布局配置按键名引用精灵,本模块把嵌套的精灵常量展平供查。
重复键与未知键一律抛错——静默覆盖会让界面指向别处的精灵且极难排查。
用例含真实常量的全量建索引校验。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 21:06:15 +08:00

88 lines
3.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.
// View → group → 精灵 的常量树 → 扁平键名索引
const { load, throws } = require('./_load');
const t = require('./_assert')();
load('client/js/01_SubGame/codes/core/SpriteIndex.js');
// ---- 展平:Layer 与 group 的 id 都不进索引,精灵进 ----
const tree = {
TopInfoView: {
Layer: 101,
TopInfo: { id: 201, BTN_A: 1001, BTN_B: 1002 }
},
PlayerMarkView: {
Layer: 101,
LeftMark: { id: 202, P_LEFT_BANKER: 1100 },
RightMark: { id: 203, P_RIGHT_BANKER: 1110 }
}
};
t.eq('展平结果', EQW_SpriteIndex.build(tree),
{ BTN_A: 1001, BTN_B: 1002, P_LEFT_BANKER: 1100, P_RIGHT_BANKER: 1110 });
// ---- Layer 与 group 的 id 不进索引 ----
const flat = EQW_SpriteIndex.build(tree);
t.eq('Layer 不进索引', flat.Layer, undefined);
t.eq('group 的 id 不进索引', flat.id, undefined);
// ---- 群组映射:精灵 → 它所属的群组 ID ----
t.eq('群组映射', EQW_SpriteIndex.buildGroupMap(tree),
{ BTN_A: 201, BTN_B: 201, P_LEFT_BANKER: 202, P_RIGHT_BANKER: 203 });
// ---- 反面:一个 View 恰好一个 Layer;Layer1/Layer2 这种多图层写法要报错 ----
// (跨图层的界面应拆成两个 View,各带自己的 Layer——一个 View 将来对应一个 BaseComponent)
const multiLayer = {
OverlayView: { Layer1: 104, Layer2: 105, Bar: { id: 230, TIP_BG: 1750 } }
};
t.eq('多 Layer 写法报错', throws(() => EQW_SpriteIndex.build(multiLayer)), true);
// ---- 反面:View 缺 Layer 声明要报错 ----
const noLayer = { ViewA: { G1: { id: 201, BTN: 1001 } } };
t.eq('View 缺 Layer 报错', throws(() => EQW_SpriteIndex.build(noLayer)), true);
// ---- 反面:重复键报错,不静默覆盖 ----
const dupTree = {
ViewA: { Layer: 101, G1: { id: 201, SAME: 1001 } },
ViewB: { Layer: 102, G2: { id: 202, SAME: 1002 } }
};
t.eq('重复键报错', throws(() => EQW_SpriteIndex.build(dupTree)), true);
// ---- 反面:精灵值不是数字要报错 ----
const badValue = { ViewA: { Layer: 101, G1: { id: 201, NESTED: { x: 1 } } } };
t.eq('精灵值非数字报错', throws(() => EQW_SpriteIndex.build(badValue)), true);
// ---- 反面:View 下混入标量键(不是 group 容器)要报错 ----
// 例如把群组 ID 误写成 View 级的 `Group: 201`,而不是包进 group 容器
const strayScalar = { ViewA: { Layer: 101, Group: 201, G1: { id: 202, BTN: 1001 } } };
t.eq('View 下混入标量键报错', throws(() => EQW_SpriteIndex.build(strayScalar)), true);
// ---- 反面:group 容器缺 id 要报错 ----
const noGroupId = { ViewA: { Layer: 101, G1: { BTN: 1001 } } };
t.eq('group 缺 id 报错', throws(() => EQW_SpriteIndex.build(noGroupId)), true);
// ---- idOf / groupIdOf:查得到 / 查不到抛错 ----
EQW_SpriteIndex.init(tree);
t.eq('idOf 查到', EQW_SpriteIndex.idOf('BTN_A'), 1001);
t.eq('groupIdOf 查到', EQW_SpriteIndex.groupIdOf('P_RIGHT_BANKER'), 203);
t.eq('idOf 查不到抛错', throws(() => EQW_SpriteIndex.idOf('NOT_EXIST')), true);
t.eq('groupIdOf 查不到抛错', throws(() => EQW_SpriteIndex.groupIdOf('NOT_EXIST')), true);
// ---- 空树 ----
t.eq('空树', EQW_SpriteIndex.build({}), {});
// ---- 真实常量:EQW_Sprites 能完整建索引且无重复键 ----
load('client/js/01_SubGame/codes/config/Layers.js');
load('client/js/01_SubGame/codes/config/Groups.js');
load('client/js/01_SubGame/codes/config/Sprites_Table.js');
load('client/js/01_SubGame/codes/config/Sprites_Cards.js');
load('client/js/01_SubGame/codes/config/Sprites_Action.js');
load('client/js/01_SubGame/codes/config/Sprites_Result.js');
load('client/js/01_SubGame/codes/config/Sprites_CreateRoom.js');
let realOk = true;
let realIndex = {};
try { realIndex = EQW_SpriteIndex.build(EQW_Sprites); } catch (e) { realOk = false; console.log('建索引失败: ' + e.message); }
t.eq('真实精灵常量无重复键', realOk, true);
t.eq('真实精灵数量 > 200', Object.keys(realIndex).length > 200, true);
process.exit(t.done('spriteindex') ? 0 : 1);