mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 23:00:03 +00:00
feat(cli): give every preview lifecycle op one JSON document (#3309)
`--status`, `--stop`, `--list` and `--kill-all` emit a schema-versioned envelope with an `ok` discriminant under `--json`, from one writer and one failure-payload builder. Human output is unchanged; the JSON path is additive. The value is in the failure paths. An agent that gets a bare error line on stderr and an empty stdout cannot tell a crash from a "not running", so every failure is a document too — including a missing project, which under `--json` resolves through the throwing resolver rather than the human-shaped nudge.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
lifecycleFailurePayload,
|
||||
lifecyclePayload,
|
||||
writeLifecycleJson,
|
||||
type PreviewLifecycleSession,
|
||||
} from "./previewLifecycleOutput.js";
|
||||
|
||||
const session: PreviewLifecycleSession = {
|
||||
state: "started",
|
||||
mode: "background",
|
||||
projectName: "demo",
|
||||
projectDir: "/tmp/demo",
|
||||
host: "127.0.0.1",
|
||||
port: 3002,
|
||||
pid: 42,
|
||||
serverUrl: "http://127.0.0.1:3002",
|
||||
studioUrl: "http://127.0.0.1:3002/#project/demo",
|
||||
ready: true,
|
||||
logPath: "/tmp/demo.log",
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("preview lifecycle JSON", () => {
|
||||
it("versions a managed start result", () => {
|
||||
expect(lifecyclePayload("start", session)).toEqual({
|
||||
schemaVersion: 1,
|
||||
operation: "start",
|
||||
ok: true,
|
||||
result: session,
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
["status", { state: "not-running", projectDir: "/tmp/demo" }],
|
||||
["stop", { state: "stopped", projectDir: "/tmp/demo" }],
|
||||
["list", { state: "listed", sessions: [session] }],
|
||||
["kill-all", { state: "killed-all", stopped: 1 }],
|
||||
] as const)("versions the %s result", (operation, result) => {
|
||||
expect(lifecyclePayload(operation, result)).toMatchObject({
|
||||
schemaVersion: 1,
|
||||
operation,
|
||||
ok: true,
|
||||
result,
|
||||
});
|
||||
});
|
||||
|
||||
it("writes exactly one parseable JSON document", () => {
|
||||
const log = vi.spyOn(console, "log").mockImplementation(() => {});
|
||||
|
||||
writeLifecycleJson(lifecyclePayload("start", { ...session, pid: null, state: "reused" }));
|
||||
|
||||
expect(log).toHaveBeenCalledOnce();
|
||||
const [line] = log.mock.calls[0] as [string];
|
||||
expect(JSON.parse(line)).toEqual({
|
||||
schemaVersion: 1,
|
||||
operation: "start",
|
||||
ok: true,
|
||||
result: { ...session, pid: null, state: "reused" },
|
||||
});
|
||||
});
|
||||
|
||||
it("versions lifecycle failures with a stable code", () => {
|
||||
expect(
|
||||
lifecycleFailurePayload(
|
||||
"start",
|
||||
"conflicting-lifecycle-flags",
|
||||
"--background and --foreground cannot be used together",
|
||||
),
|
||||
).toEqual({
|
||||
schemaVersion: 1,
|
||||
operation: "start",
|
||||
ok: false,
|
||||
error: {
|
||||
code: "conflicting-lifecycle-flags",
|
||||
message: "--background and --foreground cannot be used together",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user