- 逻辑/宿主两层:balance/shop-core/lines/loop-proof 纯逻辑零DOM受控时间随机;render/hostfx/audio-director/palette/assets/main 宿主层 - 手感链:同帧涟漪+弹簧按压/quadOut弧线飞行/连击升调/大额成交hit-stop+屏震+闪白/冷却期InputBuffer补打 - 美术:16件同风格词(主会话目检4张:水彩绘本暖色族高度统一)+P5派生压力色板+vignette联动 - 收编亲验:49/49+全仓155/155绿/隔离零外溢/IP gate源码资产零命中/逻辑层禁API零真调/manifest抽查5/5哈希一致 - mmx对账:quota面零增量(image/music不走Token Plan),权威用量=台账16次,扣费留月度并账 - 计数笔误15→16已纠;状态③收编提交完成,构建+e2e四件套接续 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
38 lines
1.7 KiB
JavaScript
38 lines
1.7 KiB
JavaScript
/**
|
||
* loop-proof.test.mjs — 闭环可达 / 失败态可达(结构深度的两份客观证明)
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
import { test } from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import { proveCoreLoop, proveFailure } from '../src/loop-proof.js';
|
||
|
||
test('闭环可达:开局→进货定价→营业接待→首日结算→首次升级,操作数 ≤ 64', () => {
|
||
const proof = proveCoreLoop();
|
||
assert.ok(proof.ok, `闭环证明失败:${proof.failReason}(ops=${proof.ops.join('|')})`);
|
||
assert.ok(proof.opCount <= 64, `操作数超限:${proof.opCount}`);
|
||
assert.ok(proof.served > 0, '首日应有成交');
|
||
assert.ok(proof.upgradeId, '应完成首次升级');
|
||
assert.equal(proof.day, 2, '首次升级落在第 2 天开市前(首段落内)');
|
||
// 关键路径节点齐备(人读得懂的 op 流水)。
|
||
assert.ok(proof.ops[0] === 'startGame');
|
||
assert.ok(proof.ops.includes('startDay'));
|
||
assert.ok(proof.ops.includes('confirmSettle'));
|
||
assert.ok(proof.ops.some((o) => o.startsWith('buyUpgrade(')));
|
||
});
|
||
|
||
test('闭环证明确定性:同种子重跑逐字段一致', () => {
|
||
const a = proveCoreLoop(20260612);
|
||
const b = proveCoreLoop(20260612);
|
||
assert.deepEqual(a, b);
|
||
});
|
||
|
||
test('失败态可达:摆烂经营 → 罚没 + 停业(非只胜不败)', () => {
|
||
const proof = proveFailure();
|
||
assert.ok(proof.ok, `失败态证明未达成(${proof.days} 天内未停业)`);
|
||
assert.ok(proof.reason === 'reputation' || proof.reason === 'bankrupt', `失败原因应为声誉/破产,实际 ${proof.reason}`);
|
||
assert.ok(proof.events.some((s) => s.includes('fined')), '失败路径上应出现罚没');
|
||
assert.ok(proof.events.some((s) => s.includes('gameover')), '应出现失败终态事件');
|
||
});
|