Files
gbrain/test/cli-format-query-score.test.ts
Garry TanandClaude Fable 5 cb2b44ba11 fix(doctor,cli,search): singleton P0s — NaN score prefix, missing put_page arbiter check, ranking-inversion receipt
- #468: gbrain query printed '[NaN]' when a non-finite score reached the
  formatter (NaN.toFixed(4) is truthy, so the '?' fallback never fired).
  Gate on Number.isFinite in src/cli.ts formatResult.
- #550: new doctor check pages_slug_unique_index probes pg_indexes for a
  non-partial unique index on pages(source_id, slug) — matched by COLUMNS,
  not constraint name — and fails with an apply-migrations --force-schema
  hint when absent. Wired into both the local buildChecks db phase and
  doctorReportRemote (mirrors the #2038 timeline_dedup shape check).
- #895: repro receipt — the reported inversion (backlink-magnet concept
  page outranking the exact-name person page on 'Who is Zhang San') no
  longer reproduces on master (title-match boost + backlink floor gating).
  Pinned by test/ranking-exact-name-backlink-inversion.test.ts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 14:36:24 -07:00

36 lines
1.2 KiB
TypeScript

/**
* #468 — `[NaN]` score prefix in `gbrain query` output.
*
* NaN.toFixed(4) returns the truthy string 'NaN', so the old
* `r.score?.toFixed(4) || '?'` fallback never fired and the CLI printed
* '[NaN] slug -- ...'. The formatter must gate on Number.isFinite.
*/
import { describe, test, expect } from 'bun:test';
import { formatResult } from '../src/cli.ts';
describe('formatResult — query score prefix (#468)', () => {
test('finite score renders 4 decimal places', () => {
const out = formatResult('query', [
{ score: 0.4922, slug: 'people/zhangsan', chunk_text: 'Zhang San' },
]);
expect(out).toContain('[0.4922] people/zhangsan');
});
test('NaN score renders ? — never the string NaN', () => {
const out = formatResult('query', [
{ score: NaN, slug: 'people/zhangsan', chunk_text: 'Zhang San' },
]);
expect(out).toContain('[?] people/zhangsan');
expect(out).not.toContain('NaN');
});
test('missing and Infinity scores also render ?', () => {
const out = formatResult('search', [
{ slug: 'a', chunk_text: '' },
{ score: Infinity, slug: 'b', chunk_text: '' },
]);
expect(out).toContain('[?] a');
expect(out).toContain('[?] b');
});
});