Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8fc2103
use testify in the astgen tests
crhntr Sep 29, 2026
cef4971
split TestTypeFormatter into one-behavior subtests
crhntr Sep 29, 2026
2fd1384
use testify in the asteval test
crhntr Sep 29, 2026
8823c41
name the header Args cases and version failures
crhntr Sep 29, 2026
1a4c291
use testify in the generate file and import tests
crhntr Sep 29, 2026
29b5050
use testify in the generate parse tests
crhntr Sep 29, 2026
6afde43
use testify in the generate route and template data tests
crhntr Sep 29, 2026
71ad593
use testify in the generate route function and snapshot tests
crhntr Sep 29, 2026
309087c
use testify in the boolean, delimiters, error and estimate tests
crhntr Sep 29, 2026
50e9556
use testify in the plan, enumerate, mutant and fixture tests
crhntr Sep 29, 2026
f37b00a
use testify in the diff and go test tests
crhntr Sep 29, 2026
5e31391
use testify in the run and runner tests
crhntr Sep 29, 2026
b2d9dd9
use testify in the report and snapshot tests
crhntr Sep 29, 2026
d2c0236
use testify in the scan, source, operand, dot, traverse and walk tests
crhntr Sep 29, 2026
16c1b77
use testify in the call resolution tests
crhntr Sep 29, 2026
0e390a3
use testify in the definition tests
crhntr Sep 29, 2026
f7fd1d6
use testify in the mutant, redirect walk and response state tests
crhntr Sep 29, 2026
0378b43
use testify in the result shape, segment, unmarshal and validation tests
crhntr Sep 29, 2026
127f8cb
use testify in the fakeserver tests
crhntr Sep 29, 2026
a6152b1
use testify in the load package and loadtest tests
crhntr Sep 29, 2026
402b144
use testify in the analysis tests
crhntr Sep 29, 2026
d61a514
use testify in the cli flag and validation tests
crhntr Sep 29, 2026
583b738
use testify in the cli command and file tests
crhntr Sep 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions internal/analysis/analysis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"go/types"
"regexp"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewReferences(t *testing.T) {
Expand Down Expand Up @@ -43,25 +46,16 @@ func TestNewReferences(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
got := names(newReferences("example.com/p", refs(), tt.filter))
if len(got) != len(tt.want) {
t.Fatalf("newReferences() names = %v, want %v", got, tt.want)
}
for i := range got {
if got[i] != tt.want[i] {
t.Fatalf("newReferences() names = %v, want %v", got, tt.want)
}
}
assert.Equal(t, tt.want, got, "newReferences() names")
})
}

t.Run("references are sorted by position and typed", func(t *testing.T) {
got := newReferences("example.com/p", refs(), nil)[1]
if len(got.References) != 2 || got.References[0].Position.Offset != 1 || got.References[1].Position.Offset != 9 {
t.Fatalf("references of b = %+v, want offsets 1 then 9", got.References)
}
if got.References[0].Data != "string" {
t.Errorf("Data = %q, want %q", got.References[0].Data, "string")
}
require.Len(t, got.References, 2, "references of b = %+v, want offsets 1 then 9", got.References)
assert.Equal(t, 1, got.References[0].Position.Offset, "references of b = %+v, want offsets 1 then 9", got.References)
assert.Equal(t, 9, got.References[1].Position.Offset, "references of b = %+v, want offsets 1 then 9", got.References)
assert.Equal(t, "string", got.References[0].Data, "Data")
})
}

Expand All @@ -70,10 +64,11 @@ func TestNewNamedReferencesOrdersKindsAtOnePosition(t *testing.T) {
parse := TemplateReference{Name: "x", Kind: ParseTemplateNode, Position: pos, data: types.Typ[types.Int]}
execute := TemplateReference{Name: "x", Kind: ExecuteTemplateNode, Position: pos, data: types.Typ[types.Int]}
for _, in := range [][]TemplateReference{{parse, execute}, {execute, parse}} {
got := NewNamedReferences("example.com/p", "x", in).References
if len(got) != 2 || got[0].Kind != ExecuteTemplateNode || got[1].Kind != ParseTemplateNode {
t.Errorf("NewNamedReferences(%v) kinds = %v, want execute_template then template", in, got)
var kinds []TemplateReferenceKind
for _, ref := range NewNamedReferences("example.com/p", "x", in).References {
kinds = append(kinds, ref.Kind)
}
assert.Equal(t, []TemplateReferenceKind{ExecuteTemplateNode, ParseTemplateNode}, kinds, "NewNamedReferences(%v) kinds, want execute_template then template", in)
}
}

Expand All @@ -100,9 +95,7 @@ func TestNewNamedReferences(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
got := NewNamedReferences("example.com/p", "x", tt.refs)
if len(got.References) != tt.want {
t.Errorf("NewNamedReferences() has %d references, want %d: %+v", len(got.References), tt.want, got.References)
}
assert.Len(t, got.References, tt.want, "NewNamedReferences() references: %+v", got.References)
})
}
}
74 changes: 26 additions & 48 deletions internal/analysis/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package analysis
import (
"html/template"
"log"
"slices"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/typelate/muxt/internal/muxt"
"github.com/typelate/muxt/internal/source"
)
Expand All @@ -17,9 +19,7 @@ import (
func parseTemplates(t *testing.T, text string) *template.Template {
t.Helper()
ts, err := template.New("set").Parse(text)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
return ts
}

Expand Down Expand Up @@ -73,9 +73,7 @@ func TestFindUnusedTemplates(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
got := findUnusedTemplates(parseTemplates(t, tt.templates), tt.executed)
if !slices.Equal(got, tt.want) {
t.Errorf("findUnusedTemplates = %q, want %q", got, tt.want)
}
assert.Equal(t, tt.want, got, "findUnusedTemplates")
})
}
}
Expand All @@ -86,9 +84,7 @@ func TestFindUnusedTemplates(t *testing.T) {
// template already renders is waiting on that route rather than unused.
func TestPartitionUnusedTemplates(t *testing.T) {
const route = "GET / Home()"
if !muxt.IsRouteDefinitionName(route) {
t.Fatalf("the premise of this test is wrong: %q does not name a route", route)
}
require.True(t, muxt.IsRouteDefinitionName(route), "the premise of this test is wrong: %q does not name a route", route)

for _, tt := range []struct {
name string
Expand Down Expand Up @@ -135,12 +131,8 @@ func TestPartitionUnusedTemplates(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
routes, partials := partitionUnusedTemplates(parseTemplates(t, tt.templates), tt.unused)
if !slices.Equal(routes, tt.wantRoutes) {
t.Errorf("routes = %q, want %q", routes, tt.wantRoutes)
}
if !slices.Equal(partials, tt.wantPartials) {
t.Errorf("partials = %q, want %q", partials, tt.wantPartials)
}
assert.Equal(t, tt.wantRoutes, routes, "routes")
assert.Equal(t, tt.wantPartials, partials, "partials")
})
}
}
Expand Down Expand Up @@ -183,16 +175,12 @@ func TestReportUnusedTemplates(t *testing.T) {
for _, err := range errs {
got = append(got, err.Error())
}
if !slices.Equal(got, tt.wantErrors) {
t.Errorf("errors = %q, want %q", got, tt.wantErrors)
}
if tt.wantSilent && logs.Len() != 0 {
t.Errorf("log = %q, want nothing", logs.String())
assert.Equal(t, tt.wantErrors, got, "errors")
if tt.wantSilent {
assert.Empty(t, logs.String(), "log, want nothing")
}
for _, part := range tt.wantLogParts {
if !strings.Contains(logs.String(), part) {
t.Errorf("log = %q, want containing %q", logs.String(), part)
}
assert.Contains(t, logs.String(), part, "log, want containing %q", part)
}
})
}
Expand All @@ -203,13 +191,9 @@ func TestCollectTemplateReferencesFollowsEveryBranch(t *testing.T) {
seen := make(map[string]bool)
collectTemplateReferences(ts, ts.Lookup("root").Tree.Root, seen)
for _, name := range []string{"in-range", "in-range-else", "in-with", "in-with-else", "loop", "leaf"} {
if !seen[name] {
t.Errorf("collectTemplateReferences did not reach %q; reached %v", name, seen)
}
}
if seen["root"] {
t.Errorf("collectTemplateReferences reached the root template itself")
assert.True(t, seen[name], "collectTemplateReferences did not reach %q; reached %v", name, seen)
}
assert.False(t, seen["root"], "collectTemplateReferences reached the root template itself")
}

// declaredTemplates has a template the set knows by name but that was never
Expand All @@ -219,9 +203,9 @@ func declaredTemplates(t *testing.T) *template.Template {
ts := parseTemplates(t, `{{define "GET / Home()"}}{{template "declared"}}{{template "undefined"}}{{end}}`)
ts.New("declared")
ts.New("GET /bare Bare()")
if ts.Lookup("declared") == nil || ts.Lookup("declared").Tree != nil {
t.Fatal("the premise of this test is wrong: declared should exist without a tree")
}
declared := ts.Lookup("declared")
require.NotNil(t, declared, "the premise of this test is wrong: declared should exist without a tree")
require.Nil(t, declared.Tree, "the premise of this test is wrong: declared should exist without a tree")
return ts
}

Expand All @@ -231,21 +215,17 @@ func TestTemplatesWithoutATreeAreSkipped(t *testing.T) {
t.Run("collectTemplateReferences", func(t *testing.T) {
seen := make(map[string]bool)
collectTemplateReferences(ts, ts.Lookup("GET / Home()").Tree.Root, seen)
if !seen["declared"] || !seen["undefined"] {
t.Errorf("collectTemplateReferences reached %v, want declared and undefined", seen)
}
assert.True(t, seen["declared"], "collectTemplateReferences reached %v, want declared", seen)
assert.True(t, seen["undefined"], "collectTemplateReferences reached %v, want undefined", seen)
})
t.Run("partitionUnusedTemplates", func(t *testing.T) {
routes, partials := partitionUnusedTemplates(ts, []string{"GET / Home()"})
if len(routes) != 1 || len(partials) != 0 {
t.Errorf("partitionUnusedTemplates() = %q, %q, want the route only", routes, partials)
}
assert.Len(t, routes, 1, "partitionUnusedTemplates() routes, want the route only")
assert.Empty(t, partials, "partitionUnusedTemplates() partials, want the route only")
})
t.Run("findUnusedTemplates", func(t *testing.T) {
got := findUnusedTemplates(ts, executed())
if !slices.Equal(got, []string{"GET / Home()"}) {
t.Errorf("findUnusedTemplates() = %q, want only the route", got)
}
assert.Equal(t, []string{"GET / Home()"}, got, "findUnusedTemplates() want only the route")
})
t.Run("executeTemplateTree", func(t *testing.T) {
// A nil global is never touched when there is no tree to walk.
Expand All @@ -256,9 +236,9 @@ func TestTemplatesWithoutATreeAreSkipped(t *testing.T) {

func TestReportDefinitionErrorsIsSilentWithoutErrors(t *testing.T) {
var logs strings.Builder
if err := reportDefinitionErrors(log.New(&logs, "", 0), source.Variable{Set: parseTemplates(t, `{{define "footer"}}x{{end}}`)}); err != nil || logs.Len() != 0 {
t.Errorf("reportDefinitionErrors() = %v with log %q, want neither", err, logs.String())
}
err := reportDefinitionErrors(log.New(&logs, "", 0), source.Variable{Set: parseTemplates(t, `{{define "footer"}}x{{end}}`)})
assert.NoError(t, err, "reportDefinitionErrors()")
assert.Empty(t, logs.String(), "reportDefinitionErrors() log")
}

// TestIsEmptyTemplate states what counts as a template with nothing to
Expand All @@ -278,9 +258,7 @@ func TestIsEmptyTemplate(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
ts := parseTemplates(t, `{{define "t"}}`+tt.template+`{{end}}`)
if got := isEmptyTemplate(ts.Lookup("t").Tree.Root); got != tt.want {
t.Errorf("isEmptyTemplate(%q) = %t, want %t", tt.template, got, tt.want)
}
assert.Equal(t, tt.want, isEmptyTemplate(ts.Lookup("t").Tree.Root), "isEmptyTemplate(%q)", tt.template)
})
}
}
4 changes: 1 addition & 3 deletions internal/analysis/mutants_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ func TestIndent(t *testing.T) {
{in: "a\nb", want: "> a\n> b"},
{in: "a\n", want: "> a\n> "},
} {
if got := indent("> ", tt.in); got != tt.want {
t.Errorf("indent(%q) = %q, want %q", tt.in, got, tt.want)
}
assert.Equal(t, tt.want, indent("> ", tt.in), "indent(%q)", tt.in)
}
}

Expand Down
43 changes: 15 additions & 28 deletions internal/analysis/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/tools/txtar"

"github.com/typelate/muxt/internal/analysis"
Expand Down Expand Up @@ -68,27 +70,21 @@ var templates = template.Must(template.ParseFS(templateFiles, "*.gohtml"))
// written to. Run with -update to rewrite the want/ files, then read the
// diff.
func TestSnapshots(t *testing.T) {
if stray, _ := filepath.Glob(filepath.Join("testdata", "*.txtar")); len(stray) > 0 {
t.Fatalf("%s is not in a command's directory", stray[0])
}
stray, _ := filepath.Glob(filepath.Join("testdata", "*.txtar"))
require.Empty(t, stray, "a testdata archive is not in a command's directory")
directories, err := os.ReadDir("testdata")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
for _, directory := range directories {
if !directory.IsDir() {
continue
}
command := directory.Name()
newConfiguration, ok := commands[command]
if !ok {
t.Errorf("testdata/%s names no command this package snapshots", command)
if !assert.True(t, ok, "testdata/%s names no command this package snapshots", command) {
continue
}
archives, err := filepath.Glob(filepath.Join("testdata", command, "*.txtar"))
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
t.Run(command, func(t *testing.T) {
for _, archivePath := range archives {
runSnapshot(t, archivePath, newConfiguration)
Expand All @@ -112,9 +108,7 @@ func runSnapshot(t *testing.T, archivePath string, newConfiguration func() any)
t.Helper()
t.Run(strings.TrimSuffix(filepath.Base(archivePath), ".txtar"), func(t *testing.T) {
archive, err := txtar.ParseFile(archivePath)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
got := snapshot(t, configuration(t, archive, newConfiguration()), archive)
if *update {
files := slices.DeleteFunc(slices.Clone(archive.Files), func(file txtar.File) bool {
Expand All @@ -124,9 +118,7 @@ func runSnapshot(t *testing.T, archivePath string, newConfiguration func() any)
files = append(files, txtar.File{Name: "want/" + name, Data: []byte(got[name])})
}
archive.Files = files
if err := os.WriteFile(archivePath, txtar.Format(archive), 0o644); err != nil {
t.Fatal(err)
}
require.NoError(t, os.WriteFile(archivePath, txtar.Format(archive), 0o644))
return
}
want := make(map[string]string)
Expand All @@ -136,9 +128,7 @@ func runSnapshot(t *testing.T, archivePath string, newConfiguration func() any)
}
}
for _, name := range sortedKeys(got, want) {
if got[name] != want[name] {
t.Errorf("want/%s differs (run go test -run TestSnapshots -update to rewrite):\n--- got\n%s\n--- want\n%s", name, got[name], want[name])
}
assert.Equal(t, want[name], got[name], "want/%s differs (run go test -run TestSnapshots -update to rewrite)", name)
}
})
}
Expand All @@ -152,12 +142,10 @@ func configuration(t *testing.T, archive *txtar.Archive, config any) any {
if file.Name != "config.json" {
continue
}
if err := json.Unmarshal(file.Data, config, configjson.Options()); err != nil {
t.Fatalf("config.json: %v", err)
}
require.NoError(t, json.Unmarshal(file.Data, config, configjson.Options()), "config.json")
return reflect.ValueOf(config).Elem().Interface()
}
t.Fatal("the archive has no config.json")
require.Fail(t, "the archive has no config.json")
return nil
}

Expand Down Expand Up @@ -226,7 +214,7 @@ func snapshot(t *testing.T, config any, archive *txtar.Archive) map[string]strin
writeTo(t, &stdout, result)
}
default:
t.Fatalf("no analysis runs with a %T", config)
require.Failf(t, "unsupported configuration", "no analysis runs with a %T", config)
}
if stdout.Len() > 0 {
got["stdout.txt"] = relative(stdout.String())
Expand All @@ -243,9 +231,8 @@ func snapshot(t *testing.T, config any, archive *txtar.Archive) map[string]strin

func writeTo(t *testing.T, w io.Writer, result io.WriterTo) {
t.Helper()
if _, err := result.WriteTo(w); err != nil {
t.Fatal(err)
}
_, err := result.WriteTo(w)
require.NoError(t, err)
}

func sortedKeys(maps ...map[string]string) []string {
Expand Down
12 changes: 6 additions & 6 deletions internal/asteval/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import (
"go/token"
"go/types"
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestCheckParses(t *testing.T) {
Expand Down Expand Up @@ -52,12 +53,11 @@ func TestCheckParses(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
err := CheckParses(tt.val, tt.tp)
switch {
case tt.wantErr == "" && err != nil:
t.Errorf("CheckParses(%q, %s) = %v, want no error", tt.val, tt.tp, err)
case tt.wantErr != "" && (err == nil || !strings.Contains(err.Error(), tt.wantErr)):
t.Errorf("CheckParses(%q, %s) = %v, want error containing %q", tt.val, tt.tp, err, tt.wantErr)
if tt.wantErr == "" {
assert.NoError(t, err, "CheckParses(%q, %s)", tt.val, tt.tp)
return
}
assert.ErrorContains(t, err, tt.wantErr, "CheckParses(%q, %s)", tt.val, tt.tp)
})
}
}
Loading
Loading