Skip to content

Commit c0b6bee

Browse files
authored
fix(mcp): reuse test matcher for branch summaries (#2964)
1 parent fdda351 commit c0b6bee

3 files changed

Lines changed: 12 additions & 12 deletions

File tree

packages/gittensory-mcp/bin/gittensory-mcp.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { delimiter, dirname, join } from "node:path";
66
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
77
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
88
import { z } from "zod";
9-
import { buildBranchAnalysisPayload, collectLocalDiff, collectLocalBranchMetadata, probeLocalScorer, referenceScorePreviewExample, resolveScorePreviewCommand, resolveWorkspaceCwd, sanitizeLocalScorerStatus, setupGuidanceForLocalScorer } from "../lib/local-branch.js";
9+
import { buildBranchAnalysisPayload, collectLocalDiff, collectLocalBranchMetadata, probeLocalScorer, referenceScorePreviewExample, resolveScorePreviewCommand, resolveWorkspaceCwd, sanitizeLocalScorerStatus, setupGuidanceForLocalScorer, isTestFile } from "../lib/local-branch.js";
1010

1111
const defaultApiUrl = "https://gittensory-api.aethereal.dev";
1212
const legacyDefaultApiUrls = new Set(["https://gittensory-api.zeronode.workers.dev"]);
@@ -3585,7 +3585,7 @@ async function analyzeCurrentBranch(input) {
35853585
mergeBaseSha: body.mergeBaseSha,
35863586
remoteTrackingSha: body.remoteTrackingSha,
35873587
changedFileCount: body.changedFiles?.length ?? 0,
3588-
testFileCount: body.changedFiles?.filter((file) => /(^|\/)(test|tests|spec|__tests__)\/|(^|\/)src\/test\/|(^|\/)[^/]+_test\.(go|py|rb)$|(^|\/)[^/]+_spec\.rb$|\.(test|spec)\.(ts|tsx|js|jsx|py|rb|rs)$/i.test(file.path)).length ?? 0,
3588+
testFileCount: body.changedFiles?.filter((file) => isTestFile(file.path)).length ?? 0,
35893589
passedValidationCount: body.validation?.filter((entry) => entry.status === "passed").length ?? 0,
35903590
localScorerStatus: sanitizeLocalScorerStatus(localScorerStatus),
35913591
setupGuidance: setupGuidanceForLocalScorer(localScorerStatus),

packages/gittensory-mcp/lib/local-branch.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,16 +601,16 @@ export function isTestFile(file) {
601601
/(^|\/)[^/]+_spec\.rb$/i.test(file) ||
602602
/\.(test|spec)\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs)$/i.test(file) ||
603603
/(^|\/)[^/]+\.(cy|e2e)\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(file) ||
604-
// JVM / C# / Swift `SomethingTest(s)`/`SomethingSpec` class-suffix convention (JUnit, Kotlin/ScalaTest,
605-
// Spock, xUnit/NUnit, XCTest). Case-sensitive on the PascalCase suffix so it can't false-positive on words
606-
// that merely end in "test"/"spec" (Latest.java, Contest.cs, manifest.scala).
607-
/(^|\/)\w*(Tests?|Spec)\.(java|kt|kts|scala|cs|swift|groovy)$/.test(file) ||
604+
// JVM / C# / Swift / PHP `SomethingTest(s)`/`SomethingSpec` class-suffix convention (JUnit, Kotlin/ScalaTest,
605+
// Spock, xUnit/NUnit, XCTest, PHPUnit/PHPSpec). Case-sensitive on the PascalCase suffix so it can't false-positive on words
606+
// that merely end in "test"/"spec" (Latest.java, Contest.cs, manifest.scala, Latest.php).
607+
/(^|\/)\w*(Tests?|Spec)\.(java|kt|kts|scala|cs|swift|groovy|php)$/.test(file) ||
608608
/(^|\/)__snapshots__\//i.test(file)
609609
);
610610
}
611611

612612
export function isCodeFile(file) {
613-
return /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy)$/i.test(file) && !isTestFile(file);
613+
return /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy|php)$/i.test(file) && !isTestFile(file);
614614
}
615615

616616
function numberValue(value) {

test/unit/local-branch.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,15 +1762,15 @@ describe("local MCP git metadata collection", () => {
17621762
expect(isTestFile(file)).toBe(true);
17631763
expect(isCodeFile(file)).toBe(false);
17641764
}
1765-
// #2666 + #2743 parity: the pytest `test_*.py` prefix and the JVM/C#/Swift `SomethingTest(s)`/`Spec`
1765+
// #2666 + #2743 parity: the pytest `test_*.py` prefix and the JVM/C#/Swift/PHP `SomethingTest(s)`/`Spec`
17661766
// class-suffix conventions were added to the server isTestPath but not this MCP copy — so the local
1767-
// predictor wrongly counted Java/Kotlin/Scala/C#/Swift tests and pytest-prefixed files as SOURCE.
1768-
for (const file of ["tests/test_utils.py", "test_api.py", "app/FooTests.java", "src/BarSpec.kt", "core/BazTest.scala", "svc/QuuxTests.cs", "ios/CorgeSpec.swift", "build/GraultTest.groovy"]) {
1767+
// predictor wrongly counted Java/Kotlin/Scala/C#/Swift/PHP tests and pytest-prefixed files as SOURCE.
1768+
for (const file of ["tests/test_utils.py", "test_api.py", "app/FooTests.java", "src/BarSpec.kt", "core/BazTest.scala", "svc/QuuxTests.cs", "ios/CorgeSpec.swift", "build/GraultTest.groovy", "lib/WaldoSpec.php"]) {
17691769
expect(isTestFile(file)).toBe(true);
17701770
expect(isCodeFile(file)).toBe(false);
17711771
}
1772-
// Case-sensitive on the PascalCase suffix: a JVM source merely ENDING in "test"/"spec" stays source.
1773-
for (const file of ["src/Latest.java", "core/manifest.scala", "app/MyService.kt"]) {
1772+
// Case-sensitive on the PascalCase suffix: a JVM/PHP source merely ENDING in "test"/"spec" stays source.
1773+
for (const file of ["src/Latest.java", "core/manifest.scala", "app/MyService.kt", "web/Latest.php"]) {
17741774
expect(isTestFile(file)).toBe(false);
17751775
expect(isCodeFile(file)).toBe(true);
17761776
}

0 commit comments

Comments
 (0)