From e5ce7f22d4bcbd9f1c3c9248badf1eca455a90b0 Mon Sep 17 00:00:00 2001 From: MarcoDotIO Date: Wed, 21 Oct 2026 18:46:48 -0400 Subject: [PATCH] fix(web): PR diffs list a `.logic.test.ts` file beside the source it covers The Code tab orders test files by the source they cover, but it stripped one extension too many from the test's name, so `a.logic.test.ts` looked for a source named `a` and fell to the end of the list. Match the longest dotted prefix that names a source file instead, which still pairs `a.browser.test.tsx` with `a.tsx`. Co-Authored-By: Claude Opus 5.5 --- .../pullRequestFileOrder.logic.test.ts | 20 +++++++++++++++++++ .../pullRequest/pullRequestFileOrder.logic.ts | 20 ++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.test.ts b/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.test.ts index 967841af34e62..71ed2bbbaea28 100644 --- a/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.test.ts +++ b/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.test.ts @@ -119,6 +119,26 @@ describe("orderDiffFiles", () => { ]); }); + it("pairs a test with the source whose name carries its own dotted suffix", () => { + expect( + order([ + file("src/c.browser.test.tsx"), + file("src/b.test.ts"), + file("src/a.logic.test.ts"), + file("src/c.tsx"), + file("src/b.ts"), + file("src/a.logic.ts"), + ]), + ).toEqual([ + "src/a.logic.ts", + "src/b.ts", + "src/c.tsx", + "src/a.logic.test.ts", + "src/b.test.ts", + "src/c.browser.test.tsx", + ]); + }); + it("orders the same diff the same way whatever order it arrives in", () => { const files = [ file("src/a.ts", ['import { b } from "./b";']), diff --git a/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.ts b/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.ts index f60a2d8ebdf36..3126bdb8fc1b3 100644 --- a/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.ts +++ b/apps/web/src/components/pullRequest/pullRequestFileOrder.logic.ts @@ -118,8 +118,17 @@ function orderByImports( return ordered; } -function testedBaseName(path: string): string { - return (path.split("/").at(-1) ?? "").replace(/\.(?:test|spec)\..*$/, "").replace(/\.[^.]+$/, ""); +// `a.logic.test.ts` covers `a.logic.ts` while `a.browser.test.ts` covers `a.ts`, so the longest +// dotted prefix that names a source file wins. +function testedSourcePosition(path: string, sourcePositions: ReadonlyMap): number { + let name = (path.split("/").at(-1) ?? "").replace(/\.(?:test|spec)\..*$/, ""); + while (true) { + const position = sourcePositions.get(name); + if (position !== undefined) return position; + const dot = name.lastIndexOf("."); + if (dot <= 0) return Number.MAX_SAFE_INTEGER; + name = name.slice(0, dot); + } } export function orderDiffFiles( @@ -160,9 +169,10 @@ export function orderDiffFiles( const orderedTests = [...byPath.keys()] .filter((path) => tiers.get(path) === "test") .sort((left, right) => { - const leftPosition = sourcePositions.get(testedBaseName(left)) ?? Number.MAX_SAFE_INTEGER; - const rightPosition = sourcePositions.get(testedBaseName(right)) ?? Number.MAX_SAFE_INTEGER; - return leftPosition - rightPosition || left.localeCompare(right); + return ( + testedSourcePosition(left, sourcePositions) - + testedSourcePosition(right, sourcePositions) || left.localeCompare(right) + ); }); const orderedGenerated = [...byPath.keys()]