Files
portal/tools/enforce-tdd-real-test-verifier.test.mjs
T
Дмитрий 5fd4031b1e fix(tdd-verifier): escape dots in TEST_FILE_RE (stop misclassifying *spec.mjs prod files)
Unescaped dots in /.(?:test|spec).[a-z0-9]+$/i matched the bare substring "spec"
in prod filenames ending like artifact-from-spec.mjs, so the real-test verifier
treated a production module as a test file and blocked it for lacking expect().
Anchor the dots (\.) so only genuine .test.<ext> / .spec.<ext> files match.
Real test files are still fully checked (regression guard added).
2026-06-09 17:50:19 +03:00

60 lines
2.1 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { decide } from './enforce-tdd-real-test-verifier.mjs';
describe('enforce-tdd-real-test-verifier decide()', () => {
it('allows real test with expect + it covering edited prod file', () => {
const r = decide({
filePath: 'tools/foo.test.mjs',
content: "import { foo } from './foo.mjs';\nit('foo works', () => { expect(foo()).toBe(1); });",
editedFiles: ['tools/foo.mjs'],
});
expect(r.block).toBe(false);
});
it('blocks test with no expect()', () => {
const r = decide({
filePath: 'tools/foo.test.mjs',
content: "it('does nothing', () => { /* sentinel */ });",
editedFiles: ['tools/foo.mjs'],
});
expect(r.block).toBe(true);
expect(r.reason).toMatch(/no_expect_call/);
});
it('blocks test with no it/test block', () => {
const r = decide({
filePath: 'tools/foo.test.mjs',
content: "expect(1).toBe(1);",
editedFiles: ['tools/foo.mjs'],
});
expect(r.block).toBe(true);
expect(r.reason).toMatch(/no_test_block/);
});
it('allows when filePath is not a test file (no-op)', () => {
const r = decide({
filePath: 'tools/foo.mjs',
content: 'export const foo = 1;',
editedFiles: [],
});
expect(r.block).toBe(false);
});
it('does NOT misclassify a prod file whose name merely ends in spec.<ext>', () => {
// Regex bug: unescaped dots matched the substring "spec" in 'artifact-from-spec.mjs'.
// A prod file is not a test file — it must not be checked for expect()/it().
const r = decide({
filePath: 'tools/artifact-from-spec.mjs',
content: 'export const buildArtifact = 1;',
editedFiles: [],
});
expect(r.block).toBe(false);
});
it('still treats a genuine .test.mjs as a test file (regression guard)', () => {
// Real test file with no expect() must still be blocked after the fix.
const r = decide({
filePath: 'tools/artifact-from-spec.test.mjs',
content: "it('x', () => {});",
editedFiles: [],
});
expect(r.block).toBe(true);
expect(r.reason).toMatch(/no_expect_call/);
});
});