Repository navigation
Go: codegraph affected never matches *_test.go — the CLI-local isTestFile duplicates and diverges from search/query-utils.ts #1507
Description
Env: codegraph 1.5.0 (win32-x64).
codegraph affected reports no tests for a Go file that has a sibling _test.go. It exits 0 with a plausible message, so it reads as "this code has no test coverage" rather than as a failure.
Repro
Two-file Go project:
// go.mod: module example.com/demo
// math.go
package demo
func Add(a, b int) int { return a + b }
// math_test.go
package demo
import "testing"
func TestAdd(t *testing.T) { if Add(1, 2) != 3 { t.Fatal("boom") } }$ codegraph init .
● 5 nodes, 4 edges in 271ms
$ codegraph affected math.go
ℹ No test files affected by the changed files. # <- expected math_test.go
$ codegraph affected --filter '*_test.go' math.go
Affected test files (1):
math_test.go # <- found, so only the predicate is wrong
The graph itself knows perfectly well:
$ codegraph node Add
**Called by ←** TestAdd (math_test.go:5)
Same shape in TypeScript works with the default glob, which isolates it to the Go naming convention:
# math.ts + math.test.ts
$ codegraph affected math.ts
Affected test files (1):
math.test.ts
Root cause
The affected command defines its own isTestFile inline instead of importing the shared one. In src/bin/codegraph.ts, inside the affected action:
const defaultTestPatterns = [
/\.spec\./, /\.test\./, /\/__tests__\//, /\/tests?\//, /\/e2e\//, /\/spec\//,
];
function isTestFile(filePath) {
if (customFilter) return customFilter.test(filePath);
return defaultTestPatterns.some(p => p.test(filePath));
}All six are JS/TS conventions. Go uses an underscore suffix — math_test.go — which matches none of them (/\.test\./ needs a dot on both sides; Go has _test.).
Meanwhile src/search/query-utils.ts already ships a correct multi-language isTestFile, which is what explore / node / search use:
/[._-](test|tests|spec|specs)\.[a-z0-9]+$/.test(lowerName) // math_test.go, math.test.ts, math-spec.rb
lowerName.startsWith('test_') // test_math.py
/(?:Test|Tests|TestCase|Tester|Spec|Specs)\.[A-Za-z0-9]+$/ // MathTest.kt, MathTests.swiftIts comments name foo_test.go explicitly, and it even guards against false positives like latest.kt / manifest.kt. So affected is the only blind path — it never asks the shared helper.
Probably why this survived: affected is CLI-only (there is no codegraph_affected MCP tool), so agents never exercise it, and agents are the primary consumer.
Secondary: --filter uncovers an unrelated over-reporting problem
On a real-world Go repo (a few hundred files), working around the bug with --filter '*_test.go' swings the other way — the result includes test files from packages with no relationship to the changed file.
--filter only swaps the is-this-a-test predicate; the dependent BFS still runs at the default --depth 5, and five hops of transitive dependents reach most of a Go tree. The broken default glob was masking this, so the two problems cancelled into empty-but-believable output.
Suggested fix
Delete the local defaultTestPatterns / isTestFile in src/bin/codegraph.ts and import isTestFile from src/search/query-utils.ts. That one already covers Go / Python / Java / Kotlin / Swift / C# / Scala, so this is a one-line import rather than a second pattern list to keep in sync.
For the second half, a smaller default --depth for affected — or a note that 5 is very wide for compiled languages where package-level dependents fan out fast — would make the output usable.
Activity
maxmilian commentedon Aug 5, 2026
Confirmed on
upstream/main(c65d56c) — and the fix you describe is already open as #1273, which is probably the most useful thing I can add here.#1273 ("fix(affected): recognize root-level test files", opened 2026-07-13) does exactly what this issue asks for: it deletes the six inline patterns and calls the shared predicate.
It fixes your Go case, but nothing about it says so — the title and tests are about a root-level
tests/Python directory, so this issue and that PR read as unrelated. The Go fix falls out of the shared predicate's separator rule,/[._-](test|tests|spec|specs)\.[a-z0-9]+$/, whichmath_test.gomatches on the_.I ran both predicates against the same inputs at
c65d56crather than reasoning from the regexes:affected)query-utils)math_test.gotests/test_math_utils.pyFooTest.ktmath.test.tsmath.goThree things that adds to the report:
FooTest.kt/BarTests.swift/BazSpec.scala/QuxTestCase.javaall miss too — the inline list has no CamelCase-suffix rule at all. Soaffectedsilently reports "no tests" for most of the JVM and Swift ecosystems, not just Go.tests/test_math_utils.pyfails for a second, independent reason:/\/tests?\//requires slashes on both sides, so a repo-roottests/directory never matches. That is fix(affected): honor custom filter glob semantics #1273's original case, and it is the same one-line-import fix.math.gostays false on both, so swapping the predicate doesn't turn ordinary source files into "tests".So I don't think this needs a second PR — it needs #1273 reviewed. It has been open three weeks with no review, is +26/−28 across one source file and one test file, and closes at least two issues rather than one. @colbymchenry if it helps, the smallest possible check is the table above: the shared predicate is already what
explore/node/searchuse, so this is removing a divergence rather than introducing a rule.One thing #1273 does not carry is a Go regression test — its two new tests are Python. Worth adding
math.go+math_test.goto__tests__/cli-affected-paths.test.tsbefore merge, since Go is the shape reported here. Happy to send that as a follow-up commit to #1273 if @Jseca666 would rather not reopen the branch, or leave it to whoever reviews.(Checked against
upstream/mainatc65d56c; the inlinedefaultTestPatternsblock is still live atsrc/bin/codegraph.ts:2153.)colbymchenry commentedon Sep 8, 2026
Fix landed
Landing PR: #1803 (cherry-picks upstream #1688 by @danusha2345 onto a Forge branch).
Root cause
codegraph affectedkept six inline JS/TS test regexes (.test.,.spec.,/tests/, …) instead of the sharedisTestPathfromsearch/query-utils, so Gomath_test.gonever matched the default predicate.Linux verify (fail → pass)
On Linux (
9181dd1e→bc8ff11e):FAIL (main):
PASS (PR #1803):
Vitest: 36 passed (
cli-affected-test-conventions+ related). Default--depth 5left unchanged — the secondary transitive over-reporting with--filteron large Go trees is residual / out of scope for this fix.Closing as completed. Upstream #1688 will be closed as superseded by #1803.
fix(cli): affected shares the tool's one notion of a test file (#1507) (