397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
3.4 KiB
JavaScript
85 lines
3.4 KiB
JavaScript
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);
|
||
});
|
||
});
|