Skip to content

Commit bee68cf

Browse files
benibenjCopilot
andcommitted
Extract command suggestion helper and test it
Move the inlined helper out of main.ts into util.ts, split into a `levenshtein` distance function and a `findSimilar` selection function so both can be unit tested. Adds src/test/similarity.test.ts covering three layers: the distance function against a textbook full matrix reference, the selection rule against a reference implementation, and the actual `vsce <typo>` output so the wiring in main.ts is covered too. Includes a guard that fails if the registered command list drifts from what the tests assume. Selection behaviour is unchanged from the inlined version, verified by a differential run over 189k inputs covering mutated commands, unicode, surrogate pairs, ties and degenerate candidate sets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f3174c5 commit bee68cf

3 files changed

Lines changed: 688 additions & 23 deletions

File tree

‎src/main.ts‎

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,12 @@ import { show } from './show';
55
import { search } from './search';
66
import { listPublishers, deletePublisher, loginPublisher, logoutPublisher, verifyPat } from './store';
77
import { getLatestVersion } from './npm';
8-
import { CancellationToken, log } from './util';
8+
import { CancellationToken, findSimilar, log } from './util';
99
import * as semver from 'semver';
1010
import { isatty } from 'tty';
1111

1212
const pkg = require('../package.json');
1313

14-
function findSimilar(target: string, candidates: Iterable<string>): string | undefined {
15-
let best: string | undefined;
16-
let bestDistance = Math.ceil(target.length * 0.4);
17-
for (const candidate of candidates) {
18-
const row = Array.from({ length: candidate.length + 1 }, (_, j) => j);
19-
for (let i = 1; i <= target.length; i++) {
20-
let diag = row[0];
21-
row[0] = i;
22-
for (let j = 1; j <= candidate.length; j++) {
23-
const tmp = row[j];
24-
row[j] = Math.min(row[j - 1] + 1, tmp + 1, diag + (target[i - 1] === candidate[j - 1] ? 0 : 1));
25-
diag = tmp;
26-
}
27-
}
28-
if (row[candidate.length] < bestDistance) {
29-
best = candidate;
30-
bestDistance = row[candidate.length];
31-
}
32-
}
33-
return best;
34-
}
35-
3614
function fatal(message: any, ...args: any[]): void {
3715
if (message instanceof Error) {
3816
if (process.env['VSCE_DEBUG']) {

0 commit comments

Comments
 (0)