Files
brain/tools/mentor-nogo-counter.test.mjs
T

42 lines
2.7 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { bumpMentorNoGo, MENTOR_ESCALATE_AFTER } from './mentor-nogo-counter.mjs';
describe('bumpMentorNoGo', () => {
const mem = () => {
const store = {};
return {
readFileSync: (p) => { if (!(p in store)) { const e = new Error('no'); e.code = 'ENOENT'; throw e; } return store[p]; },
writeFileSync: (p, d) => { store[p] = d; },
mkdirSync: () => {},
};
};
it('инкремент на blocked, сброс на allow', () => {
const fsImpl = mem(); const dir = '/r'; const sessionId = 's1';
expect(bumpMentorNoGo({ sessionId, blocked: true, fsImpl, dir })).toBe(1);
expect(bumpMentorNoGo({ sessionId, blocked: true, fsImpl, dir })).toBe(2);
expect(bumpMentorNoGo({ sessionId, blocked: false, fsImpl, dir })).toBe(0);
expect(bumpMentorNoGo({ sessionId, blocked: true, fsImpl, dir })).toBe(1);
});
it('Фаза 4: два разных task-id в одной сессии → независимые счётчики (per-task стэк)', () => {
const fsImpl = mem(); const dir = '/r';
expect(bumpMentorNoGo({ taskId: 'task:A', blocked: true, fsImpl, dir })).toBe(1);
expect(bumpMentorNoGo({ taskId: 'task:B', blocked: true, fsImpl, dir })).toBe(1); // B независим от A
expect(bumpMentorNoGo({ taskId: 'task:A', blocked: true, fsImpl, dir })).toBe(2);
expect(bumpMentorNoGo({ taskId: 'task:B', blocked: false, fsImpl, dir })).toBe(0); // сброс только B
expect(bumpMentorNoGo({ taskId: 'task:A', blocked: true, fsImpl, dir })).toBe(3); // A не тронут
});
it('SP2c-3: spec и plan одной задачи → независимые потолки (per-стадия §0/§6)', () => {
const fsImpl = mem(); const dir = '/r';
expect(bumpMentorNoGo({ taskId: 'task:A', stage: 'spec', blocked: true, fsImpl, dir })).toBe(1);
expect(bumpMentorNoGo({ taskId: 'task:A', stage: 'plan', blocked: true, fsImpl, dir })).toBe(1); // план независим от спеки
expect(bumpMentorNoGo({ taskId: 'task:A', stage: 'spec', blocked: true, fsImpl, dir })).toBe(2);
expect(bumpMentorNoGo({ taskId: 'task:A', stage: 'plan', blocked: false, fsImpl, dir })).toBe(0); // сброс только plan
expect(bumpMentorNoGo({ taskId: 'task:A', stage: 'spec', blocked: true, fsImpl, dir })).toBe(3); // spec не тронут
});
it('порог эскалации = 3', () => { expect(MENTOR_ESCALATE_AFTER).toBe(3); });
it('небезопасный sessionId санитизируется (не падает)', () => {
const fsImpl = mem();
expect(bumpMentorNoGo({ sessionId: '../../x', blocked: true, fsImpl, dir: '/r' })).toBe(1);
});
});