fix(skin): 修复最终评审发现的 6 处缺陷(junction 排除失效/meta 静默丢失等)
跨任务视角发现的问题:Critical1 materialize.mjs 的 junction 排除比较在 Windows 上因长路径前缀恒假、从未生效,且测试夹具的 junction 指向真源自身, 掩盖了此问题;Critical2 composeSkin 例外通道在 uuid 缺失/框架侧无 meta 时 静默失败,违反第二准则;Important3 可覆盖范围误把 theme/ 下的框架 TS 代码 也纳入;Important5 cli-entry 测试漏注册 check-skin/build-game;Important6 composeSkin 与 check-skin 各自拼路径,未共用 paths.mjs 权威推导;Important7 --platform 缺值时静默落到默认平台。逐条修复并补测试,Critical1 用诱饵框架 目录验证过能真正杀掉该 bug(变异推演见 fix report)。 spec §5 step5 的 dist/<name>/ 拷贝按要求标注为本期未实现,不实现。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,13 +54,20 @@ function scaffold(gameVersion = '3.8.8') {
|
||||
writeFileSync(join(hostProject, 'package.json'), JSON.stringify({ name: 'YouleNexus', creator: { version: '3.8.8' } }));
|
||||
put(frameworkSrc, 'ui/atlas-hall/btn.png', DEFAULT_BTN);
|
||||
|
||||
// junction 故意指向一个诱饵目录而非 frameworkSrc 自身,与 materialize.test.mjs 同理:
|
||||
// 否则"经 junction 拷来的字节"与"从真源拷来的字节"完全相同,测不出 Critical 1 那类 bug。
|
||||
const frameworkDecoy = join(root, 'decoy', 'assets', 'framework');
|
||||
mkdirSync(frameworkDecoy, { recursive: true });
|
||||
put(frameworkDecoy, 'ui/atlas-hall/btn.png', DEFAULT_BTN);
|
||||
put(frameworkDecoy, 'ui/atlas-hall/__decoy_marker__.png', DEFAULT_BTN);
|
||||
|
||||
const gamesDir = join(root, 'games');
|
||||
const gameDir = join(gamesDir, 'demo');
|
||||
mkdirSync(join(gameDir, 'assets'), { recursive: true });
|
||||
writeFileSync(join(gameDir, 'package.json'), JSON.stringify({ name: 'demo', creator: { version: gameVersion } }));
|
||||
symlinkSync(frameworkSrc, join(gameDir, 'assets', 'framework'), LINK_TYPE);
|
||||
symlinkSync(frameworkDecoy, join(gameDir, 'assets', 'framework'), LINK_TYPE);
|
||||
|
||||
return { root, hostProject, frameworkSrc, gamesDir, gameDir, workspace: join(root, 'build-workspace') };
|
||||
return { root, hostProject, frameworkSrc, frameworkDecoy, gamesDir, gameDir, workspace: join(root, 'build-workspace') };
|
||||
}
|
||||
function cleanup(root) { rmSync(root, { recursive: true, force: true }); }
|
||||
|
||||
@@ -83,6 +90,8 @@ test('buildGame 走通全流程:实体化 → 合成 → 调构建 → 写 bui
|
||||
|
||||
assert.ok(readFileSync(join(r.workspaceDir, 'assets', 'framework', 'ui', 'atlas-hall', 'btn.png')).equals(SKINNED));
|
||||
assert.ok(readFileSync(join(s.frameworkSrc, 'ui', 'atlas-hall', 'btn.png')).equals(DEFAULT_BTN), '框架真源必须只读:合成只能发生在临时工作区');
|
||||
assert.ok(!existsSync(join(r.workspaceDir, 'assets', 'framework', 'ui', 'atlas-hall', '__decoy_marker__.png')),
|
||||
'framework 必须来自 frameworkSrc 真源,不能残留 junction 诱饵目标独有的文件(Critical 1)');
|
||||
assert.equal(calls.length, 1);
|
||||
assert.equal(calls[0][0], r.workspaceDir);
|
||||
assert.equal(calls[0][1], 'web-mobile');
|
||||
|
||||
Reference in New Issue
Block a user