Files
brain/tools/observer-routing-detector.test.mjs
T

85 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import { detectMethodDirected, loadKnownNodes } from './observer-routing-detector.mjs';
const NODES = ['brainstorming', 'discovery-interview', 'systematic-debugging'];
describe('detectMethodDirected', () => {
it('detects a directive verb followed by a node name', () => {
expect(detectMethodDirected('запусти discovery-interview по этой фиче', NODES)).toEqual({
directed: true,
node: 'discovery-interview',
});
});
it('detects "используй X"', () => {
expect(detectMethodDirected('используй systematic-debugging здесь', NODES).directed).toBe(true);
});
it('detects a /slash-command form', () => {
expect(detectMethodDirected('сделай это через /brainstorming', NODES)).toEqual({
directed: true,
node: 'brainstorming',
});
});
it('does NOT flag a bare node mention without a directive verb', () => {
expect(detectMethodDirected('почему ты выбрал brainstorming, а не план?', NODES).directed).toBe(false);
});
it('does NOT flag a prompt with no node reference', () => {
expect(detectMethodDirected('добавь колонку Город в таблицу', NODES).directed).toBe(false);
});
it('is empty-input safe', () => {
expect(detectMethodDirected('', NODES).directed).toBe(false);
expect(detectMethodDirected(null, []).directed).toBe(false);
});
});
describe('loadKnownNodes', () => {
it('loads names, skips comments and blank lines', () => {
const nodes = loadKnownNodes('tools/observer-known-nodes.txt');
expect(nodes).toContain('brainstorming');
expect(nodes).toContain('discovery-interview');
expect(nodes.every((n) => !n.startsWith('#') && n.length > 0)).toBe(true);
});
it('returns an empty array for a missing file', () => {
expect(loadKnownNodes('tools/does-not-exist.txt')).toEqual([]);
});
});
import { stripPastedContext } from './observer-routing-detector.mjs';
describe('stripPastedContext (узкий: fenced + blockquote)', () => {
it('removes fenced blocks', () => {
expect(stripPastedContext('a\n```\n/x here\n```\nb')).not.toContain('/x');
});
it('removes blockquote lines', () => {
expect(stripPastedContext('> /x cited\nkeep')).not.toContain('/x');
});
it('keeps inline backticks (FP-safe bias)', () => {
expect(stripPastedContext('use `/x` now')).toContain('/x');
});
it('is non-string safe', () => {
expect(stripPastedContext(null)).toBe('');
});
});
describe('detectMethodDirected — PASTED-context guard (4-й FP-класс)', () => {
it('does NOT flag a /node inside a fenced code block', () => {
const t = 'смотри лог:\n```\nуже использовал /brainstorming тут\n```\nчто думаешь?';
expect(detectMethodDirected(t, NODES).directed).toBe(false);
});
it('does NOT flag a blockquote-cited directive', () => {
const t = '> используй systematic-debugging здесь\nэто цитата из старого чата';
expect(detectMethodDirected(t, NODES).directed).toBe(false);
});
it('STILL flags an inline /slash directive (FP-safe bias preserved)', () => {
expect(detectMethodDirected('сделай через `/brainstorming`', NODES).directed).toBe(true);
});
it('STILL flags a plain-prose directive', () => {
expect(detectMethodDirected('запусти discovery-interview', NODES).directed).toBe(true);
});
});