Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions cli/commands/diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,12 @@ function diffTests(dir, config = {}) {
if (docTests.size === 0 && codeTests.size === 0) return null;

// Glob-aware matching (documented entries are often patterns or basenames).
const codeArr = [...codeTests];
// PERFORMANCE OPTIMIZATION: Pre-compute expensive basenames outside loops and
// use a single-pass iteration with Sets to eliminate O(N*M) array comparisons.
const codeObjects = [...codeTests].map(c => ({ original: c, base: basename(c) }));

// PERFORMANCE OPTIMIZATION: Pre-compile regular expressions to avoid O(N*M)
// instantiation bottlenecks inside the nested .filter and .some loops below.
// instantiation bottlenecks inside loops below.
const docMatchers = [...docTests].map(docEntry => {
const entry = String(docEntry).trim();
const hasSlash = entry.includes('/');
Expand All @@ -363,17 +365,24 @@ function diffTests(dir, config = {}) {
};
});

const matches = (matcher, codeRel) => {
const subject = matcher.hasSlash ? codeRel : basename(codeRel);
return matcher.rx.test(subject);
};
const matchedDocs = new Set();
const matchedCode = new Set();

for (const m of docMatchers) {
for (const c of codeObjects) {
if (m.rx.test(m.hasSlash ? c.original : c.base)) {
matchedDocs.add(m.original);
matchedCode.add(c.original);
}
}
}

return {
title: 'Test Files',
icon: '🧪',
onlyInDocs: docMatchers.filter(m => !codeArr.some(c => matches(m, c))).map(m => m.original),
onlyInCode: codeArr.filter(c => !docMatchers.some(m => matches(m, c))),
matched: docMatchers.filter(m => codeArr.some(c => matches(m, c))).map(m => m.original),
onlyInDocs: docMatchers.filter(m => !matchedDocs.has(m.original)).map(m => m.original),
onlyInCode: codeObjects.filter(c => !matchedCode.has(c.original)).map(c => c.original),
matched: docMatchers.filter(m => matchedDocs.has(m.original)).map(m => m.original),
};
}

Expand Down
25 changes: 17 additions & 8 deletions cli/validators/docs-diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,12 @@ function diffTests(dir, config) {
// bare basenames or full paths. Treat each documented entry as a glob and
// match it against code test paths (or basenames when the entry has no slash).
// Exact-string comparison produced the false "N documented but not found".
const codeArr = [...codeTests];
// PERFORMANCE OPTIMIZATION: Pre-compute expensive basenames outside loops and
// use a single-pass iteration with Sets to eliminate O(N*M) array comparisons.
const codeObjects = [...codeTests].map(c => ({ original: c, base: basename(c) }));

// PERFORMANCE OPTIMIZATION: Pre-compile regular expressions to avoid O(N*M)
// instantiation bottlenecks inside the nested .filter and .some loops below.
// instantiation bottlenecks inside loops below.
const docMatchers = [...docTests].map(docEntry => {
const entry = String(docEntry).trim();
const hasSlash = entry.includes('/');
Expand All @@ -188,15 +190,22 @@ function diffTests(dir, config) {
};
});

const matches = (matcher, codeRel) => {
const subject = matcher.hasSlash ? codeRel : basename(codeRel);
return matcher.rx.test(subject);
};
const matchedDocs = new Set();
const matchedCode = new Set();

for (const m of docMatchers) {
for (const c of codeObjects) {
if (m.rx.test(m.hasSlash ? c.original : c.base)) {
matchedDocs.add(m.original);
matchedCode.add(c.original);
}
}
}

return {
title: 'Test Files',
onlyInDocs: docMatchers.filter(m => !codeArr.some(c => matches(m, c))).map(m => m.original),
onlyInCode: codeArr.filter(c => !docMatchers.some(m => matches(m, c))),
onlyInDocs: docMatchers.filter(m => !matchedDocs.has(m.original)).map(m => m.original),
onlyInCode: codeObjects.filter(c => !matchedCode.has(c.original)).map(c => c.original),
};
}

Expand Down