fix(ui-migration): 显式校验源数据顶层数组键,禁止静默兜底
添加 readArray() 辅助函数,对四处顶层数组键 (ObjectList, ImageFileList,
LayerList, GroupList) 显式校验,缺失或非数组时即刻抛 SourceError,
不再用 ?? [] 蒙混。遵循 CLAUDE.md 第二准则:数据缺失/非法一律显式暴露。
新增四个测试用例分别验证各键缺失时的错误行为。删除测试文件中未使用的
mkdirSync 导入。条目级缺省值 (entry.Event ?? {}, ObjectList ?? []) 保留,
因为单个对象/层没有事件/对象是合理的合法缺省。
真实数据护栏数字不变: 991 对象 / 55 界面 / 80 组 / 439 图 / 139 多帧图。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { join } from 'node:path';
|
||||
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
||||
import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { ROOT } from '../lib/paths.mjs';
|
||||
import { loadSource, SourceError } from '../ui-migration/gameabc-source.mjs';
|
||||
@@ -67,6 +67,50 @@ test('loadSource 对缺失文件显式抛错', () => {
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('loadSource 缺少顶层数组键 ObjectList 时显式抛错', () => {
|
||||
const dir = fakeSource({
|
||||
'gameabc_Object.json': { Property: [] }, // 缺 ObjectList
|
||||
});
|
||||
try {
|
||||
assert.throws(() => loadSource(dir), SourceError);
|
||||
assert.throws(() => loadSource(dir), /ObjectList/);
|
||||
assert.throws(() => loadSource(dir), /gameabc_Object\.json/);
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('loadSource 缺少顶层数组键 ImageFileList 时显式抛错', () => {
|
||||
const dir = fakeSource({
|
||||
'gameabc_Image.json': { id: 1 }, // 缺 ImageFileList
|
||||
});
|
||||
try {
|
||||
assert.throws(() => loadSource(dir), SourceError);
|
||||
assert.throws(() => loadSource(dir), /ImageFileList/);
|
||||
assert.throws(() => loadSource(dir), /gameabc_Image\.json/);
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('loadSource 缺少顶层数组键 LayerList 时显式抛错', () => {
|
||||
const dir = fakeSource({
|
||||
'gameabc_Layer.json': { Property: {} }, // 缺 LayerList
|
||||
});
|
||||
try {
|
||||
assert.throws(() => loadSource(dir), SourceError);
|
||||
assert.throws(() => loadSource(dir), /LayerList/);
|
||||
assert.throws(() => loadSource(dir), /gameabc_Layer\.json/);
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('loadSource 缺少顶层数组键 GroupList 时显式抛错', () => {
|
||||
const dir = fakeSource({
|
||||
'gameabc_GroupList.json': { data: [] }, // 缺 GroupList
|
||||
});
|
||||
try {
|
||||
assert.throws(() => loadSource(dir), SourceError);
|
||||
assert.throws(() => loadSource(dir), /GroupList/);
|
||||
assert.throws(() => loadSource(dir), /gameabc_GroupList\.json/);
|
||||
} finally { rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('loadSource 在真实源数据上得到已知规模(回归护栏)', () => {
|
||||
const s = loadSource(REAL_SOURCE);
|
||||
assert.equal(s.objects.size, 991, '对象总数');
|
||||
|
||||
Reference in New Issue
Block a user