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>
42 lines
2.2 KiB
JavaScript
42 lines
2.2 KiB
JavaScript
/**
|
||
* 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), '不应再含标准路径');
|
||
});
|