1
0

cli-query-command.test.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /**
  2. * `codegraph query` score rendering (#1045).
  3. *
  4. * The human-readable output used to print `(score * 100)%` next to each hit,
  5. * but `score` is an unbounded BM25/FTS relevance magnitude (relative-ranking
  6. * only), so it rendered as nonsensical percentages like "12042%". The CLI now
  7. * shows no score — results are already in rank order, matching the MCP search
  8. * tool — while `--json` still carries the raw `score` for programmatic use.
  9. *
  10. * Exercised end-to-end against the built binary.
  11. */
  12. import { describe, it, expect, beforeEach, afterEach } from 'vitest';
  13. import { execFileSync } from 'child_process';
  14. import * as fs from 'fs';
  15. import * as os from 'os';
  16. import * as path from 'path';
  17. import { CodeGraph } from '../src';
  18. const BIN = path.resolve(__dirname, '../dist/bin/codegraph.js');
  19. function query(cwd: string, extraArgs: string[]): string {
  20. return execFileSync(process.execPath, [BIN, 'query', 'parseToken', ...extraArgs, '-p', cwd], {
  21. encoding: 'utf-8',
  22. env: { ...process.env, CODEGRAPH_NO_DAEMON: '1', CODEGRAPH_WASM_RELAUNCHED: '1' },
  23. stdio: ['ignore', 'pipe', 'ignore'], // drop stderr (SQLite experimental warning)
  24. });
  25. }
  26. describe('codegraph query — score rendering (#1045)', () => {
  27. let tempDir: string;
  28. beforeEach(async () => {
  29. tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-query-cmd-'));
  30. fs.mkdirSync(path.join(tempDir, 'src'));
  31. fs.writeFileSync(
  32. path.join(tempDir, 'src/auth.ts'),
  33. 'export function parseToken(t: string){ return t.trim(); }\n' +
  34. 'export function parseTokenExpiry(t: string){ return Date.parse(t); }\n',
  35. );
  36. const cg = CodeGraph.initSync(tempDir);
  37. await cg.indexAll();
  38. cg.close();
  39. });
  40. afterEach(() => {
  41. fs.rmSync(tempDir, { recursive: true, force: true });
  42. });
  43. it('human output ranks results without rendering a raw score as a percentage', () => {
  44. const out = query(tempDir, ['-l', '5']);
  45. // Still finds and lists the symbol...
  46. expect(out).toContain('parseToken');
  47. // ...but never prints the bogus `(12042%)`-style score.
  48. expect(out).not.toMatch(/\(\d+%\)/);
  49. expect(out).not.toContain('%');
  50. });
  51. it('--json still carries the raw numeric score for programmatic use', () => {
  52. const parsed = JSON.parse(query(tempDir, ['-l', '5', '--json']));
  53. expect(Array.isArray(parsed)).toBe(true);
  54. expect(parsed.length).toBeGreaterThan(0);
  55. expect(typeof parsed[0].score).toBe('number');
  56. });
  57. });