Files
cgalo5758 254bc4ccb1 Count the test kit's query calls as test uses
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.
2026-10-08 00:52:30 -05:00

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)
}
}