Files
pbakaus_impeccable/tests/critique-storage.test.mjs
T
Paul BakausandGitHub e46e0da885 Centralize critique snapshot reading (#511)
Make critique storage the single owner of snapshot discovery and frontmatter parsing, and keep context signals focused on summarizing the canonical result.

AI-assisted: Prepared by Codex under pbakaus's scheduled architecture-refactor authorization.
2026-08-05 15:27:02 -07:00

231 lines
8.4 KiB
JavaScript

/**
* Tests for critique snapshot persistence.
* Run with: node --test tests/critique-storage.test.mjs
*/
import { describe, it, beforeEach, afterEach } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
const SCRIPT = fileURLToPath(new URL('../skill/scripts/critique-storage.mjs', import.meta.url));
import {
slugFromTarget,
writeSnapshot,
readLatestSnapshot,
readLatestSnapshotAcrossTargets,
readTrend,
nowFilenameStamp,
} from '../skill/scripts/critique-storage.mjs';
let cwd;
beforeEach(() => { cwd = mkdtempSync(join(tmpdir(), 'imp-critique-')); });
afterEach(() => { rmSync(cwd, { recursive: true, force: true }); });
describe('slugFromTarget', () => {
it('kebabs a relative file path', () => {
assert.equal(slugFromTarget('site/pages/index.astro', { cwd }), 'site-pages-index-astro');
});
it('kebabs an absolute path inside cwd by relativizing', () => {
const abs = join(cwd, 'site/pages/index.astro');
assert.equal(slugFromTarget(abs, { cwd }), 'site-pages-index-astro');
});
it('uses basename for absolute paths outside cwd', () => {
// Sibling path, not under cwd
const abs = join(tmpdir(), 'somewhere', 'else', 'page.html');
assert.equal(slugFromTarget(abs, { cwd }), 'page-html');
});
it('drops port from URL', () => {
assert.equal(slugFromTarget('http://localhost:3000/pricing', { cwd }), 'localhost-pricing');
});
it('normalizes URL casing and trailing slash', () => {
assert.equal(
slugFromTarget('https://Impeccable.Style/docs/audit/', { cwd }),
'impeccable-style-docs-audit',
);
});
it('strips query strings', () => {
assert.equal(
slugFromTarget('https://example.com/x?utm=1&foo=bar', { cwd }),
'example-com-x',
);
});
it('returns null for empty / project-root inputs', () => {
assert.equal(slugFromTarget('', { cwd }), null);
assert.equal(slugFromTarget('.', { cwd }), null);
assert.equal(slugFromTarget(null, { cwd }), null);
});
it('caps overly long slugs from the tail', () => {
const longPath = 'a/'.repeat(60) + 'file.tsx'; // way over 50
const slug = slugFromTarget(longPath, { cwd });
assert.ok(slug.length <= 50);
assert.ok(slug.endsWith('file-tsx'));
});
it('is stable: same input → same slug', () => {
const a = slugFromTarget('site/pages/index.astro', { cwd });
const b = slugFromTarget('site/pages/index.astro', { cwd });
assert.equal(a, b);
});
});
describe('nowFilenameStamp', () => {
it('is windows-safe (no colons or dots in the time fragment)', () => {
const stamp = nowFilenameStamp(new Date('2026-05-12T18:30:00.123Z'));
assert.equal(stamp, '2026-05-12T18-30-00Z');
});
});
describe('writeSnapshot + readLatestSnapshot', () => {
it('round-trips body and frontmatter', () => {
const out = writeSnapshot({
slug: 'index-astro',
meta: { target: 'the homepage', total_score: 28, p0_count: 1, p1_count: 3 },
body: '# Critique\n\nP0: nested cards',
cwd,
});
assert.ok(out.endsWith('__index-astro.md'));
const latest = readLatestSnapshot('index-astro', { cwd });
assert.equal(latest.meta.slug, 'index-astro');
assert.equal(latest.meta.target, 'the homepage');
assert.equal(latest.meta.total_score, 28);
assert.match(latest.body, /P0: nested cards/);
});
it('returns null when no snapshot for slug', () => {
assert.equal(readLatestSnapshot('nope', { cwd }), null);
});
it('picks the newest by filename when multiple exist', () => {
writeSnapshot({ slug: 'index-astro', meta: { total_score: 22 }, body: 'old', cwd, now: new Date('2026-05-01T00:00:00Z') });
writeSnapshot({ slug: 'index-astro', meta: { total_score: 30 }, body: 'new', cwd, now: new Date('2026-05-12T00:00:00Z') });
const latest = readLatestSnapshot('index-astro', { cwd });
assert.equal(latest.meta.total_score, 30);
assert.match(latest.body, /new/);
});
it('picks the newest snapshot across target slugs', () => {
writeSnapshot({ slug: 'home', meta: {}, body: 'old', cwd, now: new Date('2026-05-01T00:00:00Z') });
writeSnapshot({ slug: 'pricing', meta: {}, body: 'new', cwd, now: new Date('2026-05-12T00:00:00Z') });
writeFileSync(join(cwd, '.impeccable', 'critique', 'ignore.md'), '# Critique ignores\n');
writeFileSync(join(cwd, '.impeccable', 'critique', '9999-not-a-snapshot.md'), '# Draft\n');
const latest = readLatestSnapshotAcrossTargets({ cwd });
assert.equal(latest.meta.slug, 'pricing');
assert.match(latest.body, /new/);
});
it('does not see snapshots for a different slug', () => {
writeSnapshot({ slug: 'pricing-astro', meta: { total_score: 10 }, body: 'b', cwd });
assert.equal(readLatestSnapshot('index-astro', { cwd }), null);
});
it('caller-supplied meta cannot override computed timestamp or slug', () => {
// Defends against a corrupt IMPECCABLE_CRITIQUE_META blob (parsed from
// an env var) silently rewriting fields that must agree with the
// filename. Otherwise readTrend would attribute scores to the wrong
// timestamps with no error.
const out = writeSnapshot({
slug: 'index-astro',
meta: { timestamp: 'NOT_A_REAL_STAMP', slug: 'somewhere-else', total_score: 50 },
body: 'b',
cwd,
now: new Date('2026-05-12T18:30:00Z'),
});
const latest = readLatestSnapshot('index-astro', { cwd });
assert.equal(latest.meta.slug, 'index-astro');
assert.equal(latest.meta.timestamp, '2026-05-12T18-30-00Z');
// The legit meta field still lands.
assert.equal(latest.meta.total_score, 50);
// The filename matches the computed slug.
assert.ok(out.endsWith('2026-05-12T18-30-00Z__index-astro.md'));
});
it('quotes values containing : or # to keep parsing simple', () => {
writeSnapshot({
slug: 'x',
meta: { target: 'docs: critique # main' },
body: '...',
cwd,
});
const latest = readLatestSnapshot('x', { cwd });
assert.equal(latest.meta.target, 'docs: critique # main');
});
});
describe('CLI entry point', () => {
// Why a subprocess test: the CLI guard at the bottom of the script
// previously compared import.meta.url to `file://${process.argv[1]}`,
// which silently broke on Windows (forward vs back slashes) — exit 0,
// no output, save skipped. The exported functions kept passing because
// tests never spawned the script as a process. See issue #155.
it('slug subcommand prints a slug and exits 0', () => {
const r = spawnSync(process.execPath, [SCRIPT, 'slug', 'site/pages/index.astro'], {
cwd,
encoding: 'utf-8',
});
assert.equal(r.status, 0, `stderr: ${r.stderr}`);
assert.equal(r.stdout.trim(), 'site-pages-index-astro');
});
it('slug subcommand exits 1 with a message for empty input', () => {
const r = spawnSync(process.execPath, [SCRIPT, 'slug', ''], { cwd, encoding: 'utf-8' });
assert.equal(r.status, 1);
assert.match(r.stderr, /no stable slug/);
});
it('runs when invoked through a symlinked harness path', () => {
const linkedScript = join(cwd, 'linked-critique-storage.mjs');
symlinkSync(SCRIPT, linkedScript);
const r = spawnSync(process.execPath, [linkedScript, 'slug', 'index.html'], {
cwd,
encoding: 'utf-8',
});
assert.equal(r.status, 0, `stderr: ${r.stderr}`);
assert.equal(r.stdout.trim(), 'index-html');
});
it('latest subcommand exits 2 when no snapshot exists', () => {
const r = spawnSync(process.execPath, [SCRIPT, 'latest', 'never-written'], {
cwd,
encoding: 'utf-8',
});
assert.equal(r.status, 2);
});
});
describe('readTrend', () => {
it('returns last N entries oldest → newest, filtered by slug', () => {
for (let i = 0; i < 6; i++) {
writeSnapshot({
slug: 'index-astro',
meta: { total_score: 20 + i },
body: `run ${i}`,
cwd,
now: new Date(2026, 4, i + 1),
});
}
writeSnapshot({ slug: 'pricing-astro', meta: { total_score: 99 }, body: 'unrelated', cwd });
const trend = readTrend('index-astro', { limit: 5, cwd });
assert.equal(trend.length, 5);
assert.equal(trend[0].total_score, 21); // dropped the oldest
assert.equal(trend[4].total_score, 25);
});
it('returns empty when no snapshots', () => {
assert.deepEqual(readTrend('nope', { cwd }), []);
});
});