feat: make search() FTS-safe; complete Tier 2 helper-shape contract tests

search() falls back to safe per-token quoting on malformed FTS input instead of
crashing (documented in api-reference.md). Adds raw() to the doc-synced shape
contract. Full suite 107/107.
This commit is contained in:
tommy0103
2026-07-08 16:35:10 +08:00
parent 25537d3a53
commit a32461b2ab
5 changed files with 260 additions and 19 deletions
+6 -8
View File
@@ -108,16 +108,14 @@ test('unknown verb prints usage to stderr and exits non-zero', () => {
assert.match(result.stderr, /--build/);
});
test('--search shares the { error, stack } envelope instead of crashing to stderr', () => {
// A hyphenated term is FTS5 syntax and makes search() throw. The uniform
// error envelope (see docs/adr/0002) requires this surface as { error, stack }
// on stdout with exit 1 — the same shape as --query/--attune — not a raw crash.
test('--search tolerates FTS-special input via safe tokenization', () => {
// A hyphenated term is FTS5 operator syntax. search() falls back to safe
// per-token quoting instead of crashing, so the CLI returns an array, not an
// error. (The uniform { error, stack } envelope is exercised via --query/--attune.)
const home = tempHome();
const result = runRuntime(['--search', 'foo-bar'], { home });
assert.equal(result.status, 1);
const payload = JSON.parse(result.stdout);
assert.equal(typeof payload.error, 'string');
assert.equal(typeof payload.stack, 'string');
assert.equal(result.status, 0, result.stderr || result.stdout);
assert.ok(Array.isArray(JSON.parse(result.stdout)), 'search must return a JSON array');
});