diff --git a/internal/loader/loader.go b/internal/loader/loader.go index e379a1b..2cd187a 100644 --- a/internal/loader/loader.go +++ b/internal/loader/loader.go @@ -44,7 +44,27 @@ func getConfig(root string, opts config.IndexOpts) *packages.Config { } func addImportsToPkgs(pkgLookup PackageLookup, opts *config.IndexOpts, pkg *packages.Package) { - if _, ok := pkgLookup[newtypes.GetID(pkg)]; ok { + // NOTE(id: special-test-handling): When Go code is compiled, tests + // have special support. There are two forms of adding tests: + // + // - Having _test.go files with 'package mypkg' (white-box testing) + // - Having _test.go files with 'package mypkg_test' (black-box testing) + // + // When using the white-box testing approach, the compiler ends up loading + // two different packages, 'mypkg' and 'mypkg.test', with the latter also + // including _test.go files with 'package mypkg'. Hence, if 'mypkg.test' + // exists, then it will have the same PkgPath as 'mypkg', but it may have + // more files. + // + // If it does have more files, then prefer it over the base package. + // Ideally, we would check that we're actually using a '.test' package, + // but the IDs are meant to be treated opaquely, so there is no reasonable + // API to detect this. + // + // Apart from the special "_test" suffix, using different package names within + // the same directory is an error, so we don't need to worry about accidentally + // dropping information if there are unrelated packages at the same path. + if gotPkg, ok := pkgLookup[newtypes.GetID(pkg)]; ok && len(pkg.Syntax) <= len(gotPkg.Syntax) { return } diff --git a/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/cleanup_test.go b/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/cleanup_test.go new file mode 100755 index 0000000..98ed031 --- /dev/null +++ b/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/cleanup_test.go @@ -0,0 +1,27 @@ + package server +// ^^^^^^ reference 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/ + + import "testing" +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ + + func TestStuff(t *testing.T) { +// ^^^^^^^^^ definition 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/TestStuff(). +// documentation +// > ```go +// > func TestStuff(t *T) +// > ``` +// ^ definition local 0 +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ +// ^ reference github.com/golang/go/src go1.22 testing/T# + wd := "hello" +// ^^ definition local 1 + repo := "world" +// ^^^^ definition local 2 + + runCmd(t, wd, "git", "init", repo) +// ^^^^^^ reference 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/runCmd(). +// ^ reference local 0 +// ^^ reference local 1 +// ^^^^ reference local 2 + } + diff --git a/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/server_test.go b/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/server_test.go new file mode 100755 index 0000000..8ee6dda --- /dev/null +++ b/internal/testdata/snapshots/output/sharedtestmodule/cmd/gitserver/server/server_test.go @@ -0,0 +1,33 @@ + package server +// ^^^^^^ reference 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/ + + import "testing" +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ + + func TestExecRequest(t *testing.T) { +// ^^^^^^^^^^^^^^^ definition 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/TestExecRequest(). +// documentation +// > ```go +// > func TestExecRequest(t *T) +// > ``` +// ^ definition local 0 +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ +// ^ reference github.com/golang/go/src go1.22 testing/T# + t.Log("hello world") +// ^ reference local 0 +// ^^^ reference github.com/golang/go/src go1.22 testing/common#Log(). + } + + func runCmd(t *testing.T, dir string, cmd string, arg ...string) {} +// ^^^^^^ definition 0.1.test `sg/sharedtestmodule/cmd/gitserver/server`/runCmd(). +// documentation +// > ```go +// > func runCmd(t *T, dir string, cmd string, arg ...string) +// > ``` +// ^ definition local 1 +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ +// ^ reference github.com/golang/go/src go1.22 testing/T# +// ^^^ definition local 2 +// ^^^ definition local 3 +// ^^^ definition local 4 + diff --git a/internal/testdata/snapshots/output/testdata/conflicting_test_symbols/sandbox_unsupported_test.go b/internal/testdata/snapshots/output/testdata/conflicting_test_symbols/sandbox_unsupported_test.go new file mode 100755 index 0000000..6c1faa8 --- /dev/null +++ b/internal/testdata/snapshots/output/testdata/conflicting_test_symbols/sandbox_unsupported_test.go @@ -0,0 +1,50 @@ + //go:build !linux && !windows && !freebsd + // +build !linux,!windows,!freebsd + + package osl +// ^^^ definition 0.1.test `sg/testdata/conflicting_test_symbols`/ +// documentation +// > package osl + + import ( + "errors" +// ^^^^^^ reference github.com/golang/go/src go1.22 errors/ + "testing" +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ + ) + + var ErrNotImplemented = errors.New("not implemented") +// ^^^^^^^^^^^^^^^^^ definition 0.1.test `sg/testdata/conflicting_test_symbols`/ErrNotImplemented. +// documentation +// > ```go +// > var ErrNotImplemented error +// > ``` +// ^^^^^^ reference github.com/golang/go/src go1.22 errors/ +// ^^^ reference github.com/golang/go/src go1.22 errors/New(). + + func newKey(t *testing.T) (string, error) { +// ^^^^^^ definition 0.1.test `sg/testdata/conflicting_test_symbols`/newKey(). +// documentation +// > ```go +// > func newKey(t *T) (string, error) +// > ``` +// ^ definition local 0 +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ +// ^ reference github.com/golang/go/src go1.22 testing/T# + return "", ErrNotImplemented +// ^^^^^^^^^^^^^^^^^ reference 0.1.test `sg/testdata/conflicting_test_symbols`/ErrNotImplemented. + } + + func verifySandbox(t *testing.T, s string) { +// ^^^^^^^^^^^^^ definition 0.1.test `sg/testdata/conflicting_test_symbols`/verifySandbox(). +// documentation +// > ```go +// > func verifySandbox(t *T, s string) +// > ``` +// ^ definition local 1 +// ^^^^^^^ reference github.com/golang/go/src go1.22 testing/ +// ^ reference github.com/golang/go/src go1.22 testing/T# +// ^ definition local 2 + return + } + diff --git a/internal/testdata/snapshots/output/testspecial/foo_test.go b/internal/testdata/snapshots/output/testspecial/foo_test.go new file mode 100755 index 0000000..98f6eda --- /dev/null +++ b/internal/testdata/snapshots/output/testspecial/foo_test.go @@ -0,0 +1,11 @@ + package testspecial +// ^^^^^^^^^^^ reference 0.1.test `sg/testspecial`/ + + func TestFoo_Whitebox() { Foo() } +// ^^^^^^^^^^^^^^^^ definition 0.1.test `sg/testspecial`/TestFoo_Whitebox(). +// documentation +// > ```go +// > func TestFoo_Whitebox() +// > ``` +// ^^^ reference 0.1.test `sg/testspecial`/Foo(). +