Files
codeql/go/extractor/extractor_test.go
Arieh Schneier aa1d322fe7 Address PR feedback
Changes based on code review:

1. Remove redundant strings.Contains check in isExactTestPackage
   The equality check on the next line handles both cases, making
   the early return unnecessary.

2. Extract package selection logic into selectBestPackages function
   This reduces code duplication and allows the test to call the
   actual implementation rather than copying the logic.

3. Add TestSelectBestPackages to test the new function
   Comprehensive test covering single packages, test vs production,
   exact vs nested tests, and multiple packages.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-11 21:07:39 +10:00

344 lines
9.5 KiB
Go

package extractor
import (
"go/ast"
"testing"
"golang.org/x/tools/go/packages"
)
func TestIsExactTestPackage(t *testing.T) {
tests := []struct {
name string
pkgID string
pkgPath string
expected bool
}{
{
name: "exact test package",
pkgID: "github.com/foo/bar [github.com/foo/bar.test]",
pkgPath: "github.com/foo/bar",
expected: true,
},
{
name: "nested test package",
pkgID: "github.com/foo/bar [github.com/foo/bar/nested.test]",
pkgPath: "github.com/foo/bar",
expected: false,
},
{
name: "deeply nested test package",
pkgID: "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/format/packfile.test]",
pkgPath: "github.com/go-git/go-git/v6",
expected: false,
},
{
name: "exact test package with version",
pkgID: "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]",
pkgPath: "github.com/go-git/go-git/v6",
expected: true,
},
{
name: "non-test package",
pkgID: "github.com/foo/bar",
pkgPath: "github.com/foo/bar",
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pkg := &packages.Package{
ID: tt.pkgID,
PkgPath: tt.pkgPath,
}
result := isExactTestPackage(pkg)
if result != tt.expected {
t.Errorf("isExactTestPackage(%q) = %v, want %v", tt.pkgID, result, tt.expected)
}
})
}
}
func TestIsBetterPackage(t *testing.T) {
// Helper to create a package with specified properties
makePkg := func(id, path string, syntaxCount int) *packages.Package {
syntax := make([]*ast.File, syntaxCount)
return &packages.Package{
ID: id,
PkgPath: path,
Syntax: syntax,
}
}
tests := []struct {
name string
pkg *packages.Package
current *packages.Package
expected bool // true if pkg is better than current
}{
{
name: "exact test package beats nested test package",
pkg: makePkg(
"github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]",
"github.com/go-git/go-git/v6",
39, // 19 production + 20 test files
),
current: makePkg(
"github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/format/packfile.test]",
"github.com/go-git/go-git/v6",
19, // production files only
),
expected: true,
},
{
name: "nested test package loses to exact test package",
pkg: makePkg(
"github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/format/packfile.test]",
"github.com/go-git/go-git/v6",
19,
),
current: makePkg(
"github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]",
"github.com/go-git/go-git/v6",
39,
),
expected: false,
},
{
name: "more syntax nodes wins when both are exact tests",
pkg: makePkg(
"github.com/foo/bar [github.com/foo/bar.test]",
"github.com/foo/bar",
50,
),
current: makePkg(
"github.com/foo/bar [github.com/foo/bar.test]",
"github.com/foo/bar",
30,
),
expected: true,
},
{
name: "fewer syntax nodes loses when both are exact tests",
pkg: makePkg(
"github.com/foo/bar [github.com/foo/bar.test]",
"github.com/foo/bar",
30,
),
current: makePkg(
"github.com/foo/bar [github.com/foo/bar.test]",
"github.com/foo/bar",
50,
),
expected: false,
},
{
name: "more syntax nodes wins when both are nested tests",
pkg: makePkg(
"github.com/foo/bar [github.com/foo/bar/pkg1.test]",
"github.com/foo/bar",
25,
),
current: makePkg(
"github.com/foo/bar [github.com/foo/bar/pkg2.test]",
"github.com/foo/bar",
20,
),
expected: true,
},
{
name: "longer ID wins when same syntax count",
pkg: makePkg(
"github.com/foo/bar [github.com/foo/bar/verylongpackagename.test]",
"github.com/foo/bar",
20,
),
current: makePkg(
"github.com/foo/bar [github.com/foo/bar/short.test]",
"github.com/foo/bar",
20,
),
expected: true,
},
{
name: "test package beats non-test with same syntax count",
pkg: makePkg(
"github.com/foo/bar [github.com/foo/bar.test]",
"github.com/foo/bar",
20,
),
current: makePkg(
"github.com/foo/bar",
"github.com/foo/bar",
20,
),
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := isBetterPackage(tt.pkg, tt.current)
if result != tt.expected {
t.Errorf("isBetterPackage() = %v, want %v\n pkg: %q (%d syntax nodes)\n current: %q (%d syntax nodes)",
result, tt.expected,
tt.pkg.ID, len(tt.pkg.Syntax),
tt.current.ID, len(tt.current.Syntax))
}
})
}
}
// TestSelectBestPackages tests the selectBestPackages function
func TestSelectBestPackages(t *testing.T) {
// Helper to create a package with specified properties
makePkg := func(id, path string, syntaxCount int) *packages.Package {
syntax := make([]*ast.File, syntaxCount)
return &packages.Package{
ID: id,
PkgPath: path,
Syntax: syntax,
}
}
tests := []struct {
name string
pkgs []*packages.Package
expectedPkgIDs map[string]string // pkgPath -> expected selected ID
}{
{
name: "single package",
pkgs: []*packages.Package{
makePkg("example.com/pkg", "example.com/pkg", 10),
},
expectedPkgIDs: map[string]string{
"example.com/pkg": "example.com/pkg",
},
},
{
name: "test package preferred over production",
pkgs: []*packages.Package{
makePkg("example.com/pkg", "example.com/pkg", 10),
makePkg("example.com/pkg [example.com/pkg.test]", "example.com/pkg", 15),
},
expectedPkgIDs: map[string]string{
"example.com/pkg": "example.com/pkg [example.com/pkg.test]",
},
},
{
name: "exact test preferred over nested test",
pkgs: []*packages.Package{
makePkg("example.com/pkg [example.com/pkg.test]", "example.com/pkg", 20),
makePkg("example.com/pkg [example.com/pkg/nested.test]", "example.com/pkg", 15),
},
expectedPkgIDs: map[string]string{
"example.com/pkg": "example.com/pkg [example.com/pkg.test]",
},
},
{
name: "multiple packages with different paths",
pkgs: []*packages.Package{
makePkg("example.com/pkg1", "example.com/pkg1", 10),
makePkg("example.com/pkg1 [example.com/pkg1.test]", "example.com/pkg1", 15),
makePkg("example.com/pkg2", "example.com/pkg2", 8),
makePkg("example.com/pkg2 [example.com/pkg2.test]", "example.com/pkg2", 12),
},
expectedPkgIDs: map[string]string{
"example.com/pkg1": "example.com/pkg1 [example.com/pkg1.test]",
"example.com/pkg2": "example.com/pkg2 [example.com/pkg2.test]",
},
},
{
name: "more syntax nodes wins among nested tests",
pkgs: []*packages.Package{
makePkg("example.com/pkg [example.com/pkg/a.test]", "example.com/pkg", 10),
makePkg("example.com/pkg [example.com/pkg/b.test]", "example.com/pkg", 20),
},
expectedPkgIDs: map[string]string{
"example.com/pkg": "example.com/pkg [example.com/pkg/b.test]",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := selectBestPackages(tt.pkgs)
// Check that all expected packages are present
for pkgPath, expectedID := range tt.expectedPkgIDs {
selected, found := result[pkgPath]
if !found {
t.Errorf("Expected package path %q not found in result", pkgPath)
continue
}
if selected.ID != expectedID {
t.Errorf("For package path %q: got ID %q, want %q",
pkgPath, selected.ID, expectedID)
}
}
// Check that no unexpected packages are present
if len(result) != len(tt.expectedPkgIDs) {
t.Errorf("Expected %d packages in result, got %d",
len(tt.expectedPkgIDs), len(result))
}
})
}
}
// TestPackageSelectionRealWorld simulates the real-world go-git scenario
func TestPackageSelectionRealWorld(t *testing.T) {
// Simulate the actual packages.Load result for go-git repository
// when EXTRACT_TESTS=true
pkgs := []*packages.Package{
// Production package only
{
ID: "github.com/go-git/go-git/v6",
PkgPath: "github.com/go-git/go-git/v6",
Syntax: make([]*ast.File, 19), // 19 production files
},
// Root test package - this is what we want!
{
ID: "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]",
PkgPath: "github.com/go-git/go-git/v6",
Syntax: make([]*ast.File, 39), // 19 production + 20 test files
},
// Nested test dependency 1
{
ID: "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/format/packfile.test]",
PkgPath: "github.com/go-git/go-git/v6",
Syntax: make([]*ast.File, 19), // production files only (dependency)
},
// Nested test dependency 2
{
ID: "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/object.test]",
PkgPath: "github.com/go-git/go-git/v6",
Syntax: make([]*ast.File, 19), // production files only (dependency)
},
}
// Use the actual selection logic from the extractor
bestPackageIds := selectBestPackages(pkgs)
// Verify the correct package was selected
selected := bestPackageIds["github.com/go-git/go-git/v6"]
expectedID := "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]"
expectedSyntaxCount := 39
if selected.ID != expectedID {
t.Errorf("Wrong package selected!\n got: %q (%d syntax nodes)\n want: %q (%d syntax nodes)",
selected.ID, len(selected.Syntax),
expectedID, expectedSyntaxCount)
}
if len(selected.Syntax) != expectedSyntaxCount {
t.Errorf("Wrong syntax count: got %d, want %d", len(selected.Syntax), expectedSyntaxCount)
}
// Verify it's recognized as an exact test package
if !isExactTestPackage(selected) {
t.Errorf("Selected package %q should be recognized as exact test package", selected.ID)
}
}