Advertisement

← ubon

src/__tests__/ndjson-schema.test.ts

1.9 KB Download file
import { existsSync, mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { spawnSync } from 'child_process';

const CLI = join(process.cwd(), 'dist', 'cli.js');
const hasDist = existsSync(CLI);

describe('CLI: --ndjson + --schema + deterministic JSON', () => {
  let dir: string;
  beforeAll(() => {
    if (!hasDist) return;
    dir = mkdtempSync(join(tmpdir(), 'ubon-output-'));
    mkdirSync(join(dir, 'app/api/chat'), { recursive: true });
    writeFileSync(
      join(dir, 'app/api/chat/route.ts'),
      `const apiKey = "sk-${'a'.repeat(48)}";\nexport async function POST() { return new Response(apiKey); }\n`
    );
  });

  afterAll(() => {
    if (dir) rmSync(dir, { recursive: true, force: true });
  });

  (hasDist ? it : it.skip)('emits one JSON object per line in --ndjson mode', () => {
    const res = spawnSync('node', [CLI, 'check', '-d', dir, '--ndjson', '--no-result-cache'], {
      encoding: 'utf8'
    });
    const lines = res.stdout.trim().split('\n').filter(Boolean);
    expect(lines.length).toBeGreaterThan(0);
    for (const line of lines) {
      expect(() => JSON.parse(line)).not.toThrow();
    }
  });

  (hasDist ? it : it.skip)('--schema prints the JSON schema and exits 0', () => {
    const res = spawnSync('node', [CLI, 'check', '--schema'], { encoding: 'utf8' });
    expect(res.status).toBe(0);
    const obj = JSON.parse(res.stdout);
    expect(obj.$schema || obj.title || obj.properties).toBeTruthy();
  });

  (hasDist ? it : it.skip)('produces byte-for-byte identical --json output across runs', () => {
    const args = ['check', '-d', dir, '--json', '--no-result-cache'];
    const a = spawnSync('node', [CLI, ...args], { encoding: 'utf8' }).stdout;
    const b = spawnSync('node', [CLI, ...args], { encoding: 'utf8' }).stdout;
    expect(a).toBe(b);
  });
});