Files
pbakaus_impeccable/tests/cli-ignores.test.js
T
Paul BakausandGitHub 51d01e3a5f [codex] Add design-aware detector rules (#252)
* Add design-aware detector rules

* Fix design-aware detector noise

* Unify CLI and hook detector ignores

* Fix remaining design-system review findings

* Add detector ignore CLI

* Fix design detector review findings

* Fix design color source false positives

* Fix core test suite registration

* Add design-aware detector docs

* Fix font priority design-system parsing

* Fix color ignore value matching
2026-06-15 21:06:17 -07:00

98 lines
3.5 KiB
JavaScript

import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { mkdtempSync, rmSync, readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { spawnSync } from 'node:child_process';
const CLI = resolve('cli/bin/cli.js');
describe('impeccable ignores CLI', () => {
let root;
beforeEach(() => {
root = mkdtempSync(join(tmpdir(), 'imp-ignores-'));
});
afterEach(() => {
rmSync(root, { recursive: true, force: true });
});
function run(args, options = {}) {
const result = spawnSync(process.execPath, [CLI, 'ignores', ...args], {
cwd: root,
encoding: 'utf-8',
...options,
});
if (result.error) throw result.error;
return result;
}
function readConfig(name = 'config.json') {
return JSON.parse(readFileSync(join(root, '.impeccable', name), 'utf-8'));
}
test('adds and lists shared file and value ignores under detector', () => {
expect(run(['add-file', 'src/legacy/**']).status).toBe(0);
expect(run(['add-value', 'overused-font', 'Inter', '--reason', 'Brand font']).status).toBe(0);
const raw = readConfig();
expect(raw.hook).toBeUndefined();
expect(raw.detector.ignoreFiles).toEqual(['src/legacy/**']);
expect(raw.detector.ignoreValues.map(({ rule, value, reason }) => ({ rule, value, reason }))).toEqual([
{ rule: 'overused-font', value: 'inter', reason: 'Brand font' },
]);
expect(raw.detector.designSystem).toBeUndefined();
const listed = run(['list']);
expect(listed.status).toBe(0);
expect(listed.stdout).toContain('ignoreFiles: src/legacy/**');
expect(listed.stdout).toContain('overused-font=inter');
});
test('supports scoped wildcard value ignores and removal', () => {
expect(run(['add-value', 'design-system-color', '*', '--file', 'site/styles/demo.css']).status).toBe(0);
let raw = readConfig();
expect(raw.detector.ignoreValues).toEqual([
expect.objectContaining({
rule: 'design-system-color',
value: '*',
files: ['site/styles/demo.css'],
}),
]);
expect(run(['remove-value', 'design-system-color', '*', '--file', 'site/styles/demo.css']).status).toBe(0);
raw = readConfig();
expect(raw.detector.ignoreValues).toEqual([]);
});
test('rejects broad wildcard value ignores', () => {
const result = run(['add-value', 'design-system-color', '*']);
expect(result.status).not.toBe(0);
expect(result.stderr).toContain('Wildcard value ignores must be scoped');
expect(existsSync(join(root, '.impeccable', 'config.json'))).toBe(false);
});
test('removes an existing broad wildcard value ignore', () => {
mkdirSync(join(root, '.impeccable'), { recursive: true });
writeFileSync(join(root, '.impeccable', 'config.json'), JSON.stringify({
detector: {
ignoreValues: [{ rule: 'design-system-color', value: '*' }],
},
}));
const result = run(['remove-value', 'design-system-color', '*']);
expect(result.status).toBe(0);
expect(readConfig().detector.ignoreValues).toEqual([]);
});
test('writes local ignores without overriding shared design-system config', () => {
expect(run(['add-value', 'overused-font', 'Inter', '--local']).status).toBe(0);
const local = readConfig('config.local.json');
expect(local.detector.ignoreValues.map(({ rule, value }) => ({ rule, value }))).toEqual([
{ rule: 'overused-font', value: 'inter' },
]);
expect(local.detector.designSystem).toBeUndefined();
});
});