lili d763755117 feat(adapter): E2 从 sourceProject 真构建 formalize——scaffold-from-source + 单测
U2(plan 002):把「sourceProject → 可构建 game 工件」从手工探针formalize成可复用函数,
即后端确定性 modify guard-pending 在等的引擎线交付物(plan 001 U6 / plan 002 KTD2)。
- buildFactorySource(sourceProject)→ generated-factory.js 文本(适配器 import + 内联 source + 默认导出工厂)。
- scaffoldFromSource(...)→ 写 generated-factory + 拷 entry-bundle/index 模板,返 build.mjs 入口。
- 零依赖单测 3/3:文本合契约 / 内联 source 往返深等 / adapterImport 可覆盖。
- e2e 验(集成段,本机):scaffoldFromSource 落变体源(5 目标)→ build.mjs → 211KB bundle(LittleJS 真入包);
  端到端九门由 _adapter-probe 验过(046454d9)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:51:20 -07:00

42 lines
2.2 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.

/**
* scaffold.test.mjs —— E2 buildFactorySource 零依赖 node 单测node --test
* owner前端+引擎线Mac计划 002 U2。验「SourceProject → generated-factory.js 文本」工件正确。
*
* 注scaffoldFromSource 的 fs 编排 + build.mjs 全链是集成段(需 esbuild),已由 _adapter-probe 真九门验证(commit 046454d9);
* 本单测只覆盖纯文本生成 buildFactorySource(零 fs/零 esbuild,守 package.json「lane 本机零依赖只跑 node --test」)。
*/
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { buildFactorySource, STD_ADAPTER_IMPORT } from './scaffold-from-source.mjs';
const HERE = dirname(fileURLToPath(import.meta.url));
const SOURCE = JSON.parse(readFileSync(join(HERE, 'fixtures', 'tap-target.source.json'), 'utf8'));
test('buildFactorySource 产合契约 generated-factory 文本', () => {
const src = buildFactorySource(SOURCE);
// 适配器 import(标准深度)+ 默认导出工厂 + 内联 SOURCE。
assert.ok(src.includes(`import { adaptGameDefinition } from '${STD_ADAPTER_IMPORT}'`), '应含适配器 import');
assert.ok(src.includes('export default adaptGameDefinition(SOURCE)'), '应默认导出工厂');
assert.ok(src.includes('const SOURCE ='), '应内联 SOURCE 常量');
});
test('内联 SOURCE 可往返 parse 且与原 SourceProject 深等', () => {
const src = buildFactorySource(SOURCE);
// 抽出 "const SOURCE = {...};" 的 JSON 体,JSON.parse 往返应与原 source 深等(无丢字段/无污染)。
const m = src.match(/const SOURCE = ([\s\S]*?);\nexport default/);
assert.ok(m, '应能定位内联 SOURCE 字面量');
const roundTrip = JSON.parse(m[1]);
assert.deepEqual(roundTrip, SOURCE, '内联 source 应与原 SourceProject 深等');
});
test('adapterImport 可覆盖(非标准深度 game 目录)', () => {
const src = buildFactorySource(SOURCE, { adapterImport: '../../src/adapter/create-game-from-definition.js' });
assert.ok(src.includes(`from '../../src/adapter/create-game-from-definition.js'`), '应用覆盖的 import 路径');
assert.ok(!src.includes(STD_ADAPTER_IMPORT), '不应再含标准路径');
});