import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { mapSpiritTypeToComponent } from '../../scripts/legacy-layer-to-cocos-prefab.mjs'; import { ROOT } from '../../scripts/lib/paths.mjs'; const SEMANTICS = JSON.parse(readFileSync( join(ROOT, 'framework-tests', 'legacy-layer-migration', 'fixtures', 'spirit-semantics.json'), 'utf8' )); test('type=0 → cc.Sprite', () => { assert.equal(mapSpiritTypeToComponent('0'), 'cc.Sprite'); }); test('type=1 → cc.Label', () => { assert.equal(mapSpiritTypeToComponent('1'), 'cc.Label'); }); test('type=3 → cc.ProgressBar', () => { assert.equal(mapSpiritTypeToComponent('3'), 'cc.ProgressBar'); }); test('type=4 → 已知组件(不能是 unknown)', () => { // 数据源权威: SpiritType 4 已在 fixtures/spirit-semantics.json 逆向为 cc.EditBox (Task 5). assert.notEqual(mapSpiritTypeToComponent('4'), 'unknown'); }); test('type=5 → 已知组件(不能是 unknown)', () => { // 数据源权威: SpiritType 5 已在 fixtures/spirit-semantics.json 逆向为 cc.Sprite (SLICED) (Task 5). assert.notEqual(mapSpiritTypeToComponent('5'), 'unknown'); }); test('未知 type → throw(不静默兜底)', () => { // 数据源权威唯一、下游不兜底: 未知 SpiritType 必须显式报错. assert.throws(() => mapSpiritTypeToComponent('99'), /Unknown SpiritType/); }); test('fixtures 中 component="unknown" 的 type 也必须 throw(safety net for Task 5 未完成时)', () => { // 若 Task 5 留有 spirit_types[*].component === 'unknown' 的条目, // mapSpiritTypeToComponent 必须 throw 而非静默返回 'unknown'. // 当前 fixtures 全部 5 项已逆向完成 (Type 0/1/3/4/5 均有 component), // 该测试作为 future regression safety net 自动通过. for (const [type, entry] of Object.entries(SEMANTICS.spirit_types)) { if (entry.component === 'unknown') { assert.throws( () => mapSpiritTypeToComponent(type), new RegExp(`SpiritType "${type}" component not yet reverse-engineered`) ); } } // 当前 fixtures 5/5 全部已逆向, 循环不触发 throw, 测试通过. assert.equal(Object.keys(SEMANTICS.spirit_types).length, 5, 'fixtures 期望 5 个 SpiritType (0/1/3/4/5) 全部已逆向'); });