返回 CodeWhale
pet-expression.test.mjs
根目录 / pet / tests / pet-expression.test.mjs
1 import test from 'node:test';
2 import assert from 'node:assert/strict';
3 import { readFileSync } from 'node:fs';
4 import { PetNative } from '../dist/core/pet-native.js';
5 import { PetWorld } from '../dist/core/pet-world.js';
6 import { PetSim, digest } from '../dist/core/pet-sim.js';
7 import { compilePetTelemetry, encodePetJSONL } from '../dist/core/pet-telemetry.js';
8 import { petDemoEvents } from '../dist/core/pet-demo.js';
9
10 const points = readFileSync(new URL('../public/whale-points.tsv', import.meta.url), 'utf8').trim().split('\n').map(row => row.trim().split(/\s+/).map(Number));
11 const tape = compilePetTelemetry(petDemoEvents(), 80_000);
12
13 test('native hosts replay checkpoint-free exports from the beginning in their recorded expression version', () => {
14 for (const version of [1, 2]) {
15 const source = new PetNative(JSON.stringify(points), encodePetJSONL(tape), '[]', false, version);
16 for (let i = 0; i < 540; i++) source.step(1 / 30, true);
17 const recording = JSON.parse(source.recording());
18 if (version === 1) delete recording.expressionVersion;
19 const restored = new PetNative(JSON.stringify(points));
20 restored.restoreRecording(JSON.stringify(recording));
21 assert.equal(JSON.parse(restored.snapshot()).timeMs, 0);
22 assert.equal(JSON.parse(restored.recording()).expressionVersion, version);
23 const expected = new PetNative(JSON.stringify(points), encodePetJSONL(tape), '[]', false, version);
24 for (let i = 0; i < 720; i++) assert.equal(restored.step(1 / 30, true), expected.step(1 / 30, true));
25 const before = restored.recording(true);
26 recording.checkpoint = null;
27 assert.throws(() => restored.restoreRecording(JSON.stringify(recording)));
28 assert.equal(restored.recording(true), before);
29 }
30 });
31
32 test('recordings without an expression version retain v1 after checkpoint hydration and subsequent work', () => {
33 const legacy = new PetNative(JSON.stringify(points), encodePetJSONL(tape), '[]', false, 1);
34 for (let i = 0; i < 540; i++) legacy.step(1 / 30, true);
35 const saved = JSON.parse(legacy.recording(true));
36 delete saved.expressionVersion; delete saved.checkpoint.sim.expressionVersion;
37 const restored = new PetNative(JSON.stringify(points));
38 restored.restoreRecording(JSON.stringify(saved));
39 assert.equal(JSON.parse(restored.recording()).expressionVersion, 1);
40 for (let i = 0; i < 240; i++) assert.equal(restored.step(1 / 30, i % 40 < 30), legacy.step(1 / 30, i % 40 < 30));
41 });
42
43 test('unknown or mismatched expression versions are rejected before replacing the current habitat', () => {
44 const pet = new PetNative(JSON.stringify(points)); pet.step(1, true);
45 const before = pet.recording(true), saved = JSON.parse(before);
46 for (const edit of [r => r.expressionVersion = 3, r => r.expressionVersion = null,
47 r => r.checkpoint.sim.expressionVersion = 99, r => r.checkpoint.sim.expressionVersion = 1]) {
48 const candidate = structuredClone(saved); edit(candidate);
49 assert.throws(() => pet.restoreRecording(JSON.stringify(candidate)), /version/);
50 assert.equal(pet.recording(true), before);
51 }
52 });
53
54 test('field expressions preserve all particle identities and the unchanged home form', () => {
55 const old = new PetSim(points, 0xC0FFEE, 1), field = new PetSim(points);
56 const state = { activity: .1, coherence: .9, attention: 0, channel: 'reasoning', observed: 1, roamX: 0, roamY: 0, flip: 1, lit: 1 };
57 for (let i = 0; i < 60; i++) { old.step(1 / 30, state, { motion: true, sensitivity: 1 }); field.step(1 / 30, state, { motion: true, sensitivity: 1 }); }
58 assert.equal(digest(old), digest(field));
59 state.activity = .8; state.channel = 'code';
60 for (let i = 0; i < 120; i++) { old.step(1 / 30, state, { motion: true, sensitivity: 1 }); field.step(1 / 30, state, { motion: true, sensitivity: 1 }); }
61 assert.notEqual(digest(old), digest(field));
62 assert.deepEqual(field.checkpoint().body, old.checkpoint().body);
63 assert.equal(field.p.length, 980);
64 });
65
66 test('new worlds show a human junction without the legacy approach-to-owner steering', () => {
67 const tape = compilePetTelemetry([{ schemaVersion: 1, id: 'request', traceId: 't', startTime: 0, endTime: 40_000,
68 agentId: 'parent', category: 'human', name: 'request', status: 'pending', attributes: {} }], 40_000);
69 const legacy = new PetWorld(points, tape, [], 1), modern = new PetWorld(points, tape);
70 for (let i = 0; i < 900; i++) { legacy.step(1 / 30); modern.step(1 / 30); }
71 assert.equal(modern.frame.needs, 'call'); // Recorded request remains visible.
72 assert.equal(legacy.checkpoint().targetX, 0);
73 assert.notEqual(modern.checkpoint().targetX, 0);
74 assert.deepEqual(modern.tape, legacy.tape);
75 });
76
76 lines Plain Text