ktg-plugin-marketplace/plugins/voyage/scripts/gen-expected-prom.mjs
Kjell Tore Guttormsen 2349d1d431 feat(voyage): add lib/exporters/textfile-format.mjs — Prometheus text-format pure transform SC #12
Step 9 av v4.1-execute (Wave 2, Session 3).

Pure function transformToPrometheus(records) → Prometheus text-format 0.0.4.

Hard rules:
- NO client-side timestamps (research/01 node_exporter#1284 mitigation)
- Allowlist-redacted records ONLY (caller responsibility — Step 11 enforces)
- UTF-8 metric names normalized: lowercase, [.\\-\\s] → _, voyage_ prefix
- Empty input → empty string output
- Sorted output for determinism (snapshot-test-friendly)

Heuristic metric typing:
- counter: *_total, *_count, *_passed, *_failed, *_skipped
- histogram: *_ms, *_duration, *_p\\d+, *_seconds
- gauge: everything else (Prometheus convention)

Snapshot: tests/fixtures/expected.prom byte-for-byte match.
Regenerate: node scripts/gen-expected-prom.mjs > tests/fixtures/expected.prom

Tester (6 nye, baseline 400 → 406):
- Snapshot byte-for-byte match (SC #12)
- Empty input handling (null, undefined, [])
- Allowlist-redaction sanity (post-bash-stats uten command_excerpt)
- NO client-side timestamps (token-count-assertion per linje)
- normalizeMetricName edge-cases
- Determinism (identisk input → identisk output)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 09:30:58 +02:00

21 lines
925 B
JavaScript

#!/usr/bin/env node
// scripts/gen-expected-prom.mjs
// Regenerate tests/fixtures/expected.prom snapshot from tests/fixtures/stats-sample.jsonl.
//
// Usage:
// node scripts/gen-expected-prom.mjs > tests/fixtures/expected.prom
//
// When the snapshot is stale (e.g. after intentional format change or new
// stats-sample row), regenerate via the command above and inspect the diff.
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { transformToPrometheus } from '../lib/exporters/textfile-format.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const SAMPLE_PATH = join(__dirname, '..', 'tests', 'fixtures', 'stats-sample.jsonl');
const text = readFileSync(SAMPLE_PATH, 'utf-8');
const records = text.trim().split('\n').filter(Boolean).map(line => JSON.parse(line));
process.stdout.write(transformToPrometheus(records));