397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
3.4 KiB
JavaScript
57 lines
3.4 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { classifyMutationResult, runMutationForFile } from './mutate-runner.mjs';
|
|
import { mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
|
|
describe('classifyMutationResult (чистая классификация P18)', () => {
|
|
it('baseline не зелёный → killed:false reason baseline-not-green', () => {
|
|
expect(classifyMutationResult({ baselineGreen: false, mutantOutcomes: [] }))
|
|
.toEqual({ mutationKilled: false, reason: 'baseline-not-green' });
|
|
});
|
|
it('нет валидных мутантов (все loadError) → no-valid-mutants', () => {
|
|
expect(classifyMutationResult({ baselineGreen: true, mutantOutcomes: [{ allGreen: false, loadError: true }] }))
|
|
.toEqual({ mutationKilled: false, reason: 'no-valid-mutants' });
|
|
});
|
|
it('хоть один валидный мутант покраснел (allGreen:false, не loadError) → killed', () => {
|
|
expect(classifyMutationResult({ baselineGreen: true, mutantOutcomes: [
|
|
{ allGreen: true, loadError: false }, { allGreen: false, loadError: false } ] }))
|
|
.toEqual({ mutationKilled: true, reason: 'ok' });
|
|
});
|
|
it('все валидные мутанты выжили (тест ничего не проверяет) → mutation-survived', () => {
|
|
expect(classifyMutationResult({ baselineGreen: true, mutantOutcomes: [{ allGreen: true, loadError: false }] }))
|
|
.toEqual({ mutationKilled: false, reason: 'mutation-survived' });
|
|
});
|
|
});
|
|
|
|
describe('runMutationForFile (in-place + восстановление SE-LB-3)', () => {
|
|
it('восстанавливает оригинал файла после прогона (даже если мутант валит тест)', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'mut-'));
|
|
const file = join(dir, 'x.mjs');
|
|
const original = 'export const f = (a, b) => a === b;\n';
|
|
writeFileSync(file, original);
|
|
// Фейковый runTest: baseline зелёный; на мутированном содержимом (=== заменён) — красный.
|
|
const runTest = () => {
|
|
const cur = readFileSync(file, 'utf-8');
|
|
const baseline = cur === original;
|
|
return { allGreen: baseline, numPassed: baseline ? 1 : 0, numFailed: baseline ? 0 : 1, loadError: false };
|
|
};
|
|
const res = runMutationForFile({ filePath: file, generate: (s) => [{ label: 'm', mutated: s.replace('===', '!==') }], runTest });
|
|
expect(res.baselineGreen).toBe(true);
|
|
expect(res.mutantOutcomes.some((o) => o.allGreen === false)).toBe(true);
|
|
expect(readFileSync(file, 'utf-8')).toBe(original); // восстановлен
|
|
rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
it('baseline красный → мутацию не запускает, baselineGreen:false, файл цел', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'mut-'));
|
|
const file = join(dir, 'y.mjs');
|
|
writeFileSync(file, 'broken');
|
|
const runTest = () => ({ allGreen: false, numPassed: 0, numFailed: 1, loadError: false });
|
|
const res = runMutationForFile({ filePath: file, generate: () => [{ label: 'm', mutated: 'mutant' }], runTest });
|
|
expect(res.baselineGreen).toBe(false);
|
|
expect(res.mutantOutcomes).toEqual([]);
|
|
expect(readFileSync(file, 'utf-8')).toBe('broken');
|
|
rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
});
|