n8n/packages/testing/rules-engine/src/rule-runner.test.ts
Declan Carroll 3922984b74
ci: Add rules engine and code health packages (no-changelog) (#27815)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:20:11 +00:00

81 lines
2.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { BaseRule } from './base-rule.js';
import { RuleRunner } from './rule-runner.js';
import type { Violation } from './types.js';
class TestRule extends BaseRule<{ value: string }> {
readonly id = 'test-rule';
readonly name = 'Test Rule';
readonly description = 'A test rule';
readonly severity = 'error' as const;
analyze(context: { value: string }): Violation[] {
if (context.value === 'bad') {
return [this.createViolation('test.ts', 1, 1, 'Found bad value')];
}
return [];
}
}
describe('RuleRunner', () => {
it('runs registered rules and returns report', async () => {
const runner = new RuleRunner<{ value: string }>();
runner.registerRule(new TestRule());
const report = await runner.run({ value: 'bad' }, '/root');
expect(report.summary.totalViolations).toBe(1);
expect(report.results[0].rule).toBe('test-rule');
expect(report.results[0].violations[0].message).toBe('Found bad value');
});
it('returns zero violations for clean context', async () => {
const runner = new RuleRunner<{ value: string }>();
runner.registerRule(new TestRule());
const report = await runner.run({ value: 'good' }, '/root');
expect(report.summary.totalViolations).toBe(0);
});
it('respects enableOnly', async () => {
const runner = new RuleRunner<{ value: string }>();
runner.registerRule(new TestRule());
runner.enableOnly(['nonexistent']);
const report = await runner.run({ value: 'bad' }, '/root');
expect(report.results).toHaveLength(0);
expect(report.rules.disabled).toContain('test-rule');
});
it('applies settings to disable rules', async () => {
const runner = new RuleRunner<{ value: string }>();
runner.registerRule(new TestRule());
runner.applySettings({ 'test-rule': { enabled: false } });
const report = await runner.run({ value: 'bad' }, '/root');
expect(report.results).toHaveLength(0);
});
it('runs a single rule by id', async () => {
const runner = new RuleRunner<{ value: string }>();
runner.registerRule(new TestRule());
const report = await runner.runRule('test-rule', { value: 'bad' }, '/root');
expect(report).not.toBeNull();
expect(report!.summary.totalViolations).toBe(1);
});
it('returns null for unknown rule id', async () => {
const runner = new RuleRunner<{ value: string }>();
const report = await runner.runRule('unknown', { value: 'bad' }, '/root');
expect(report).toBeNull();
});
});