diff --git a/__tests__/context-ranking.test.ts b/__tests__/context-ranking.test.ts index ec9772086..5e2e63a32 100644 --- a/__tests__/context-ranking.test.ts +++ b/__tests__/context-ranking.test.ts @@ -16,7 +16,7 @@ import * as path from 'path'; import * as os from 'os'; import CodeGraph from '../src/index'; import { LOW_CONFIDENCE_MARKER } from '../src/context'; -import { isDistinctiveIdentifier, scorePathRelevance, deriveProjectNameTokens } from '../src/search/query-utils'; +import { isDistinctiveIdentifier, nameMatchBonus, scorePathRelevance, deriveProjectNameTokens } from '../src/search/query-utils'; describe('isDistinctiveIdentifier', () => { it('treats plain dictionary words as non-distinctive', () => { @@ -39,6 +39,13 @@ describe('isDistinctiveIdentifier', () => { }); }); +describe('nameMatchBonus', () => { + it('does not award a name match bonus for empty or whitespace-only queries', () => { + expect(nameMatchBonus('Anything', '')).toBe(0); + expect(nameMatchBonus('Anything', ' \n\t ')).toBe(0); + }); +}); + // A single PascalCase query word (notably a project name a user naturally // includes) splits into sub-tokens that all match the SAME path segment; summed // per sub-token it boosted that path 4×, burying the rest of the query's stack diff --git a/src/search/query-utils.ts b/src/search/query-utils.ts index 1a7b121fc..74d4afff2 100644 --- a/src/search/query-utils.ts +++ b/src/search/query-utils.ts @@ -343,6 +343,8 @@ function matchesNonProductionDir(lowerPath: string): boolean { export function nameMatchBonus(nodeName: string, query: string): number { const nameLower = nodeName.toLowerCase(); + if (query.trim().length === 0) return 0; + // Split query into word-level terms (handles "CacheBuilder build" → ["cache","builder","build"]) const rawTerms = query .replace(/([a-z])([A-Z])/g, '$1 $2')