1d08c1bf4d
Move 4 monolithic test files (cli.test.ts, e2e.test.ts, template.test.ts, var.test.ts) from src/ into tests/ directory, split by scenario: tests/helpers.ts - shared utilities (envValue, stripVolatile) tests/put-get-has.test.ts - basic CAS storage operations tests/verify-refs-walk.test.ts - graph traversal tests/schema-validation.test.ts - Issue #50 schema validation tests/alias.test.ts - @ alias resolution tests/variable.test.ts - var set/get/delete/list/tag tests/template.test.ts - template set/get/list/delete tests/render.test.ts - render + render -p tests/pipe.test.ts - pipe composition + stdin input tests/gc.test.ts - garbage collection tests/edge-cases.test.ts - help, --store, error paths All 516 tests pass (159 CLI + 357 core/fs).
95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
import type { JSONSchema } from "@uncaged/json-cas";
|
|
import { putSchema } from "@uncaged/json-cas";
|
|
import { openStore as openFsStore } from "@uncaged/json-cas-fs";
|
|
|
|
export { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync };
|
|
export { tmpdir };
|
|
export { join, resolve };
|
|
|
|
export const entrypoint = resolve(import.meta.dir, "../src/index.ts");
|
|
export const pkgPath = resolve(import.meta.dir, "../package.json");
|
|
|
|
/** Extract the `value` field from a { type, value } envelope JSON string. */
|
|
export function envValue(json: string): unknown {
|
|
return (JSON.parse(json.trim()) as { value: unknown }).value;
|
|
}
|
|
|
|
/**
|
|
* Register a schema directly via the library (CLI schema put was removed).
|
|
* Returns the type hash.
|
|
*/
|
|
export async function putSchemaFile(
|
|
storePath: string,
|
|
schemaFilePath: string,
|
|
): Promise<string> {
|
|
const store = await openFsStore(storePath);
|
|
const schema = JSON.parse(
|
|
readFileSync(schemaFilePath, "utf-8"),
|
|
) as JSONSchema;
|
|
const hash = await putSchema(store, schema);
|
|
return hash;
|
|
}
|
|
|
|
/**
|
|
* Run CLI command. Accepts either a string[] or ...string[] (rest args).
|
|
* If first arg is an array, uses that as args. Otherwise treats all args as the command.
|
|
*/
|
|
export async function runCli(
|
|
args: string[],
|
|
storePath?: string,
|
|
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
const finalArgs = storePath
|
|
? ["bun", entrypoint, "--store", storePath, ...args]
|
|
: ["bun", entrypoint, ...args];
|
|
const proc = Bun.spawn(finalArgs, {
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
const exitCode = await proc.exited;
|
|
const stdout = await new Response(proc.stdout).text();
|
|
const stderr = await new Response(proc.stderr).text();
|
|
return { stdout, stderr, exitCode };
|
|
}
|
|
|
|
export async function runCliWithStdin(
|
|
args: string[],
|
|
storePath: string,
|
|
stdin: string,
|
|
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
const finalArgs = ["bun", entrypoint, "--store", storePath, ...args];
|
|
const proc = Bun.spawn(finalArgs, {
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
stdin: "pipe",
|
|
});
|
|
proc.stdin.write(stdin);
|
|
proc.stdin.end();
|
|
const exitCode = await proc.exited;
|
|
const stdout = await new Response(proc.stdout).text();
|
|
const stderr = await new Response(proc.stderr).text();
|
|
return { stdout, stderr, exitCode };
|
|
}
|
|
|
|
/**
|
|
* Parse JSON and strip volatile fields (timestamp, created, updated)
|
|
* so snapshots are stable across runs.
|
|
*/
|
|
export function stripVolatile(json: string): unknown {
|
|
const strip = (v: unknown): unknown => {
|
|
if (Array.isArray(v)) return v.map(strip);
|
|
if (v !== null && typeof v === "object") {
|
|
const out: Record<string, unknown> = {};
|
|
for (const [k, val] of Object.entries(v as Record<string, unknown>)) {
|
|
if (k === "timestamp" || k === "created" || k === "updated") continue;
|
|
out[k] = strip(val);
|
|
}
|
|
return out;
|
|
}
|
|
return v;
|
|
};
|
|
return strip(JSON.parse(json));
|
|
}
|