scripts/sqlc-unused counts a call from a package covered by a ".*" entry of scripts/deadcode-testonly.txt as a test use, so one list defines the test-support packages for both checks, and the list's header says so. A query that only the kit's builders call now reads TEST-ONLY, not used. The check reads the module in a directory it is given, which lets a test run it over a fixture module. New tests: TestScanCountsATestSupportPackageAsTestUse, over a fixture module whose kit package and app package each call one query, and TestReadSupportTakesTheWholePackageEntries. The other tests, TestCheck and TestReadAllow, are unchanged. The output of go run ./scripts/sqlc-unused equals the baseline taken before step 2 once each line's count of test references is stripped. 2 breaks, each failed the new tests; they have no old side.
122 lines
3.8 KiB
Go
122 lines
3.8 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func queriesOf(qs ...*query) map[string]*query {
|
|
m := map[string]*query{}
|
|
for _, q := range qs {
|
|
m[q.key] = q
|
|
}
|
|
return m
|
|
}
|
|
|
|
func TestCheck(t *testing.T) {
|
|
unused := &query{key: "internal/billing.Gone", name: "Gone"}
|
|
used := &query{key: "internal/billing.Live", name: "Live", prod: []string{"a.go:1"}}
|
|
testOnly := &query{key: "internal/billing.Probe", name: "Probe", tst: []string{"a_test.go:1"}}
|
|
|
|
tests := []struct {
|
|
name string
|
|
queries map[string]*query
|
|
allow map[string]bool
|
|
want []string // a substring of each problem, in order
|
|
}{
|
|
{"nothing unused", queriesOf(used), nil, nil},
|
|
{"unused and not listed fails", queriesOf(unused, used), nil, []string{"internal/billing.Gone is unused and not in"}},
|
|
{"unused and listed passes", queriesOf(unused, used), map[string]bool{"internal/billing.Gone": true}, nil},
|
|
{"listed but used fails as stale", queriesOf(used), map[string]bool{"internal/billing.Live": true}, []string{"internal/billing.Live is listed"}},
|
|
{"listed but test-only fails as stale", queriesOf(testOnly), map[string]bool{"internal/billing.Probe": true}, []string{"internal/billing.Probe is listed"}},
|
|
{"listed but gone fails as stale", queriesOf(used), map[string]bool{"internal/billing.Deleted": true}, []string{"internal/billing.Deleted is listed"}},
|
|
{"test-only never fails", queriesOf(testOnly, used), nil, nil},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := check(tc.queries, tc.allow)
|
|
if len(got) != len(tc.want) {
|
|
t.Fatalf("problems = %q, want %d", got, len(tc.want))
|
|
}
|
|
for i, sub := range tc.want {
|
|
if !strings.Contains(got[i], sub) {
|
|
t.Errorf("problem %d = %q, want it to contain %q", i, got[i], sub)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadAllow(t *testing.T) {
|
|
path := t.TempDir() + "/allow.txt"
|
|
body := "# header\n\ninternal/billing.Gone # reason (owner)\n internal/organization.Other\n"
|
|
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := readAllow(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 2 || !got["internal/billing.Gone"] || !got["internal/organization.Other"] {
|
|
t.Errorf("allow = %v", got)
|
|
}
|
|
}
|
|
|
|
func TestScanCountsATestSupportPackageAsTestUse(t *testing.T) {
|
|
root, err := filepath.Abs(filepath.Join("testdata", "fixture"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
support map[string]bool
|
|
want map[string]string // query key to class
|
|
}{
|
|
{"a kit call is a test use", map[string]bool{"kit": true}, map[string]string{"db.Probe": "test-only", "db.Live": "used", "db.Gone": "unused"}},
|
|
{"an unlisted package's call is a use", nil, map[string]string{"db.Probe": "used", "db.Live": "used", "db.Gone": "unused"}},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
queries, err := scan(root, tc.support)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got := map[string]string{}
|
|
for _, q := range queries {
|
|
switch {
|
|
case q.used():
|
|
got[q.key] = "used"
|
|
case q.testOnly():
|
|
got[q.key] = "test-only"
|
|
default:
|
|
got[q.key] = "unused"
|
|
}
|
|
}
|
|
if !reflect.DeepEqual(got, tc.want) {
|
|
t.Errorf("classes = %v, want %v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadSupportTakesTheWholePackageEntries(t *testing.T) {
|
|
path := t.TempDir() + "/testonly.txt"
|
|
body := "# header\ninternal/testkit.* # kit (permanent)\ninternal/domains.WithEvidenceLookup # seam (permanent)\n.*\n"
|
|
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := readSupport(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if want := map[string]bool{"internal/testkit": true}; !reflect.DeepEqual(got, want) {
|
|
t.Errorf("support = %v, want %v", got, want)
|
|
}
|
|
}
|