397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72 lines
2.6 KiB
JavaScript
72 lines
2.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
parsePrompt, extractJson, formatRecall, buildHookOutput, rufloBinCandidates,
|
|
} from './ruflo-recall-hook.mjs';
|
|
|
|
test('parsePrompt: extracts the prompt field', () => {
|
|
assert.equal(parsePrompt('{"prompt":"hello world"}'), 'hello world');
|
|
});
|
|
test('parsePrompt: empty string when field is missing', () => {
|
|
assert.equal(parsePrompt('{"other":1}'), '');
|
|
});
|
|
test('parsePrompt: empty string on invalid JSON (fail-open)', () => {
|
|
assert.equal(parsePrompt('not json at all'), '');
|
|
});
|
|
test('parsePrompt: empty string when prompt is not a string', () => {
|
|
assert.equal(parsePrompt('{"prompt":123}'), '');
|
|
});
|
|
|
|
test('extractJson: pulls the JSON object out of noisy ruflo stdout', () => {
|
|
const stdout =
|
|
'[INFO] Searching: "x" (semantic)\n\n' +
|
|
'✅ Using sql.js\n' +
|
|
'{\n "query": "x",\n "results": []\n}\n';
|
|
const obj = extractJson(stdout);
|
|
assert.equal(obj.query, 'x');
|
|
assert.deepEqual(obj.results, []);
|
|
});
|
|
test('extractJson: null when there is no JSON', () => {
|
|
assert.equal(extractJson('[INFO] only noise, no braces'), null);
|
|
});
|
|
test('extractJson: null on malformed JSON (fail-open)', () => {
|
|
assert.equal(extractJson('noise {not: valid'), null);
|
|
});
|
|
|
|
test('formatRecall: empty string when there are no results', () => {
|
|
assert.equal(formatRecall({ results: [] }), '');
|
|
assert.equal(formatRecall(null), '');
|
|
assert.equal(formatRecall({}), '');
|
|
});
|
|
test('formatRecall: formats at most 3 results and tags the block', () => {
|
|
const out = formatRecall({
|
|
results: [
|
|
{ key: 'k1', preview: 'p1' },
|
|
{ key: 'k2', preview: 'p2' },
|
|
{ key: 'k3', preview: 'p3' },
|
|
{ key: 'k4', preview: 'p4' },
|
|
],
|
|
});
|
|
assert.ok(out.includes('k1') && out.includes('k3'));
|
|
assert.ok(!out.includes('k4'));
|
|
assert.ok(out.includes('ruflo memory recall'));
|
|
});
|
|
|
|
test('buildHookOutput: correct UserPromptSubmit payload shape', () => {
|
|
const o = buildHookOutput('some context');
|
|
assert.equal(o.hookSpecificOutput.hookEventName, 'UserPromptSubmit');
|
|
assert.equal(o.hookSpecificOutput.additionalContext, 'some context');
|
|
});
|
|
|
|
test('rufloBinCandidates: RUFLO_RECALL_BIN override wins', () => {
|
|
assert.deepEqual(rufloBinCandidates({ RUFLO_RECALL_BIN: 'X:/r.js' }), ['X:/r.js']);
|
|
});
|
|
test('rufloBinCandidates: builds an APPDATA-based candidate', () => {
|
|
const c = rufloBinCandidates({ APPDATA: 'C:/Users/X/AppData/Roaming' });
|
|
assert.equal(c.length, 1);
|
|
assert.ok(c[0].includes('ruflo') && c[0].endsWith('ruflo.js'));
|
|
});
|
|
test('rufloBinCandidates: empty array when no env hints', () => {
|
|
assert.deepEqual(rufloBinCandidates({}), []);
|
|
});
|