From 8ef842fc75e2254a9ecb92ed364b93f44fa9fb80 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 8 Sep 2026 15:22:07 +0000 Subject: [PATCH] chore(design): pin impeccable rule ids and detector JSON shape as fixtures Real captures from a human-initiated `npx impeccable install` in a scratch directory (engine 0.1.3, linux-x64), never a runtime download: - test/fixtures/impeccable-antipatterns.json: upstream crates/live/assets/antipatterns.json at 87d8f6d6 (the state engine-v0.1.3 shipped), 61 rules, source commit recorded in `_source`. - test/fixtures/impeccable-detect-sample.json: `detect --json` over gstack's planted-slop fixture (source mode), paths normalized. - test/fixtures/review-eval-design-slop.dom.html + impeccable-detect-dom-sample.json: the same page served locally, dumped through the browse engine with the shared DOM-dump script, then scanned. Pins the load-bearing assumption that the static engine reads inline + + +
+

Welcome to Our Platform

+

Your all-in-one solution for everything you need

+ +
+ + +
+
+
+

Feature One

+

A short description of this amazing feature that will change your life.

+
+
+
+

Feature Two

+

Another incredible capability that sets us apart from the competition.

+
+
+
+

Feature Three

+

Yet another powerful tool to streamline your workflow effortlessly.

+
+
+ + + + + + diff --git a/test/impeccable-fixtures.test.ts b/test/impeccable-fixtures.test.ts new file mode 100644 index 000000000..abe60448b --- /dev/null +++ b/test/impeccable-fixtures.test.ts @@ -0,0 +1,172 @@ +/** + * impeccable fixture pins (commit 1 of the design-detector interop). + * + * gstack never runs impeccable's engine in CI. What the detector wrapper and + * the catalog rely on is pinned here from real captures instead: + * - the rule registry (61 ids) at the commit the engine-v0.1.3 release shipped + * - the `detect --json` output shape over gstack's own planted-slop fixture, + * once as a source scan and once over the rendered-DOM dump that + * lib/dom-dump-script.ts produces through the browse engine + * - the dump script's own contract (IIFE, no single quotes, no `${`) + * Re-capture protocol: test/fixtures/impeccable-captures.meta.json. + */ +import { describe, test, expect } from 'bun:test'; +import * as fs from 'fs'; +import * as path from 'path'; +import { DOM_DUMP_SCRIPT, DOM_DUMP_STYLE_ATTR, DOM_DUMP_NOTE_PREFIX } from '../lib/dom-dump-script'; + +const FIXTURES = path.join(import.meta.dir, 'fixtures'); +const read = (name: string) => fs.readFileSync(path.join(FIXTURES, name), 'utf-8'); +const json = (name: string) => JSON.parse(read(name)); + +interface RegistryEntry { id: string; name: string; category: string; description: string } +interface Finding { + antipattern: string; name: string; description: string; severity: string; + category: string; file: string; line: number; snippet: string; +} + +const registry = json('impeccable-antipatterns.json') as { _source: Record; rules: RegistryEntry[] }; +const sourceSample = json('impeccable-detect-sample.json') as Finding[]; +const domSample = json('impeccable-detect-dom-sample.json') as Finding[]; +const meta = json('impeccable-captures.meta.json'); +const dump = read('review-eval-design-slop.dom.html'); +const registryIds = new Set(registry.rules.map(r => r.id)); +const categoryOf = new Map(registry.rules.map(r => [r.id, r.category])); + +describe('impeccable rule registry fixture', () => { + test('is the upstream file at a pinned commit', () => { + expect(registry._source.path).toBe('crates/live/assets/antipatterns.json'); + expect(registry._source.commit).toMatch(/^[0-9a-f]{40}$/); + expect(registry._source.engineRelease).toBe('engine-v0.1.3'); + expect(meta.registry.commit).toBe(registry._source.commit); + }); + + test('has 61 well-formed entries with unique kebab-case ids', () => { + expect(registry.rules.length).toBe(61); + expect(meta.registry.entries).toBe(61); + for (const r of registry.rules) { + expect(r.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/); + expect(r.name.length).toBeGreaterThan(0); + expect(r.description.length).toBeGreaterThan(0); + expect(['slop', 'quality']).toContain(r.category); + } + expect(registryIds.size).toBe(61); + }); + + test('splits 32 slop / 29 quality', () => { + const slop = registry.rules.filter(r => r.category === 'slop').length; + expect(slop).toBe(32); + expect(registry.rules.length - slop).toBe(29); + }); + + test('carries the ids the doctrine names', () => { + for (const id of ['side-tab', 'overused-font', 'nested-cards', 'kicker-above-heading', 'icon-tile-stack', + 'gradient-text', 'ai-color-palette', 'cream-palette', 'dark-glow', 'pulsing-dot', 'em-dash-overuse', + 'low-contrast', 'broken-image', 'design-system-font', 'design-system-color', 'design-system-radius', + 'design-system-font-size']) { + expect(registryIds.has(id)).toBe(true); + } + }); +}); + +function checkFindings(sample: Finding[], expectedFile: string) { + expect(Array.isArray(sample)).toBe(true); + expect(sample.length).toBeGreaterThan(0); + for (const f of sample) { + expect(Object.keys(f).sort()).toEqual(meta.findingFields.slice().sort()); + expect(registryIds.has(f.antipattern)).toBe(true); + expect(f.category).toBe(categoryOf.get(f.antipattern)); + expect(typeof f.severity).toBe('string'); + expect(typeof f.line).toBe('number'); + expect(typeof f.snippet).toBe('string'); + expect(f.file).toBe(expectedFile); + expect(f.file.startsWith('/')).toBe(false); + } +} + +describe('detect --json source-scan sample', () => { + test('is a real capture over the planted-slop fixture, paths normalized', () => { + checkFindings(sourceSample, 'test/fixtures/review-eval-design-slop.html'); + expect(meta.captures['impeccable-detect-sample.json'].exit).toBe(2); + }); + + test('contains a deterministic slop id and a quality id', () => { + const ids = new Set(sourceSample.map(f => f.antipattern)); + expect(ids.has('ai-color-palette')).toBe(true); + expect(ids.has('low-contrast')).toBe(true); + }); +}); + +describe('detect --json DOM-dump sample', () => { + test('is a real capture over the committed dump, paths normalized', () => { + checkFindings(domSample, 'test/fixtures/review-eval-design-slop.dom.html'); + expect(meta.captures['impeccable-detect-dom-sample.json'].exit).toBe(2); + expect(meta.captures['impeccable-detect-dom-sample.json'].stderrBytes).toBe(0); + }); + + test('the static engine reads inlined