|
|
@@ -6,10 +6,12 @@ import { fileURLToPath } from 'node:url'
|
|
|
import {
|
|
|
normalizeSessionLog,
|
|
|
normalizeSessionSnapshot,
|
|
|
+ normalizeSessionSnapshots,
|
|
|
normalizeStdout,
|
|
|
scrubRequestHeaders,
|
|
|
type NormalizeContext,
|
|
|
} from '@deepseek-ai/dsh-session-snapshot'
|
|
|
+import { prepareSessionEventNotificationsForComparison } from '@deepseek-ai/dsh-llm-replay'
|
|
|
import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke'
|
|
|
import {
|
|
|
decompressZstdFrame,
|
|
|
@@ -61,6 +63,24 @@ interface DeepSeekDefaultsServer {
|
|
|
close(): Promise<void>
|
|
|
}
|
|
|
|
|
|
+/** Compare one current Session with an older committed generation in memory. */
|
|
|
+async function expectSessionSnapshot(
|
|
|
+ actual: string,
|
|
|
+ context: NormalizeContext,
|
|
|
+ expectedPath: string,
|
|
|
+): Promise<void> {
|
|
|
+ const [normalizedActual] = normalizeSessionSnapshots([actual], context)
|
|
|
+ const expected = await readFile(expectedPath, 'utf8')
|
|
|
+ const [normalizedExpected] = normalizeSessionSnapshots([expected], context, { sourcePaths: [expectedPath] })
|
|
|
+ expect(parseJsonl(normalizedActual ?? '')).toEqual(parseJsonl(normalizedExpected ?? ''))
|
|
|
+}
|
|
|
+
|
|
|
+/** Compare current headless session-event wrappers with a committed v1 stream. */
|
|
|
+async function expectHeadlessStream(normalized: string, expectedPath: string): Promise<void> {
|
|
|
+ const expected = prepareSessionEventNotificationsForComparison(await readFile(expectedPath, 'utf8'))
|
|
|
+ expect(parseJsonl(normalized)).toEqual(parseJsonl(expected))
|
|
|
+}
|
|
|
+
|
|
|
/** Serve one deterministic DeepSeek-compatible response while retaining its request body. */
|
|
|
async function deepseekDefaultsServer(): Promise<DeepSeekDefaultsServer> {
|
|
|
const requests: JsonObject[] = []
|
|
|
@@ -218,7 +238,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
const context = contextFromLogs([actual.content])
|
|
|
const session = normalizeSessionSnapshot(actual.content, context)
|
|
|
if (refreshing) await writeFile(headlessSessionExpected, session)
|
|
|
- await expect(session).toMatchFileSnapshot(headlessSessionExpected)
|
|
|
+ await expectSessionSnapshot(session, context, headlessSessionExpected)
|
|
|
expect(session).toContain(task)
|
|
|
expect(session).toContain('CLI tool round trip complete: CLI_TOOL_ROUND_TRIP')
|
|
|
},
|
|
|
@@ -303,7 +323,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
expect(result.stderr).toBe('')
|
|
|
const normalized = normalizeHeadlessStream(result.stdout, runCwd)
|
|
|
if (refreshing) await writeFile(streamExpected, normalized)
|
|
|
- expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
|
|
+ await expectHeadlessStream(normalized, streamExpected)
|
|
|
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
|
|
|
|
|
it('logs actionable missing-credential guidance through the one-shot app', async () => {
|
|
|
@@ -332,7 +352,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
expect(result.stderr).toBe('')
|
|
|
const normalized = normalizeHeadlessStream(result.stdout, runCwd)
|
|
|
if (refreshing) await writeFile(streamExpected, normalized)
|
|
|
- expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
|
|
+ await expectHeadlessStream(normalized, streamExpected)
|
|
|
// The durable failure leads with the credential store — the path that
|
|
|
// keeps the secret out of configuration files — then names the launching
|
|
|
// environment, and stops there: configuration carries the reference, so
|
|
|
@@ -369,7 +389,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
expect(result.stderr).toBe('')
|
|
|
const normalized = normalizeHeadlessStream(result.stdout, runCwd)
|
|
|
if (refreshing) await writeFile(streamExpected, normalized)
|
|
|
- expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
|
|
+ await expectHeadlessStream(normalized, streamExpected)
|
|
|
// The durable failure names the reference to correct and the writer that
|
|
|
// usually owns it, and stays true in a composition that mounts no Models
|
|
|
// page at all.
|
|
|
@@ -663,7 +683,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
expect(result.stderr).toBe('')
|
|
|
const normalized = normalizeGoalStream(result.stdout, runCwd)
|
|
|
if (refreshing) await writeFile(streamExpected, normalized)
|
|
|
- expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
|
|
+ await expectHeadlessStream(normalized, streamExpected)
|
|
|
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
|
|
|
|
|
it('delivers a continuable child result without parent polling', async () => {
|
|
|
@@ -720,7 +740,7 @@ describe('headless stream-json snapshots', () => {
|
|
|
const context = contextFromLogs([parent.content, child.content])
|
|
|
const normalizedChild = normalizeSessionSnapshot(child.content, context)
|
|
|
if (refreshing) await writeFile(childExpected, normalizedChild)
|
|
|
- await expect(normalizedChild).toMatchFileSnapshot(childExpected)
|
|
|
+ await expectSessionSnapshot(normalizedChild, context, childExpected)
|
|
|
expect(normalizedChild).toContain('CHILD_RESULT')
|
|
|
expect(normalizedChild).not.toContain('"name":"report"')
|
|
|
},
|
|
|
@@ -734,6 +754,6 @@ describe('headless stream-json snapshots', () => {
|
|
|
})
|
|
|
const normalized = normalizeHeadlessStream(result.stdout, runCwd)
|
|
|
if (refreshing) await writeFile(streamExpected, normalized)
|
|
|
- expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
|
|
+ await expectHeadlessStream(normalized, streamExpected)
|
|
|
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
|
|
})
|