From 22764eca5e3b13c78a6e3e82eaa5a66a3a3e3493 Mon Sep 17 00:00:00 2001 From: Anton Telyshev Date: Sat, 18 May 2024 16:44:22 +0300 Subject: [PATCH 1/3] useless-assert: support bool ops --- README.md | 2 + .../useless-assert/useless_assert_test.go | 121 +++++++++++------- internal/checkers/useless_assert.go | 27 +++- internal/testgen/gen_useless_assert.go | 19 ++- 4 files changed, 115 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 2877b31..cb7bd86 100644 --- a/README.md +++ b/README.md @@ -584,6 +584,8 @@ Currently the checker guards against assertion of the same variable: ❌ assert.Equal(t, tt.value, tt.value) assert.ElementsMatch(t, users, users) // And so on... + assert.True(t, num > num) + assert.False(t, num == num) ``` More complex cases are [open for contribution](CONTRIBUTING.md#useless-assert). diff --git a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go index ad79e1b..14e0459 100644 --- a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go +++ b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go @@ -13,6 +13,7 @@ func TestUselessAssertChecker(t *testing.T) { var err error var elapsed time.Time var str string + var num int var tc testCase // Invalid. @@ -59,68 +60,92 @@ func TestUselessAssertChecker(t *testing.T) { assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg") // want "useless-assert: asserting of the same variable" assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg with arg %d", 42) // want "useless-assert: asserting of the same variable" assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Contains(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Containsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.ElementsMatch(t, value, value) // want "useless-assert: asserting of the same variable" - assert.ElementsMatchf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Equal(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Equalf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.EqualExportedValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.EqualExportedValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.EqualValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.EqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" - assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.ErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" assert.ErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Greater(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Greaterf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.GreaterOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.GreaterOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Implements(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Implementsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num < num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num != num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" + assert.NotErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" + assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num <= num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num == num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num >= num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num >= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.WithinDuration(t, elapsed, elapsed, time.Second) // want "useless-assert: asserting of the same variable" + assert.WithinDurationf(t, elapsed, elapsed, time.Second, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num <= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num < num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num == num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num > num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num > num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num != num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.YAMLEq(t, str, str) // want "useless-assert: asserting of the same variable" + assert.YAMLEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.InDelta(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" assert.InDeltaf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDeltaSlice(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaSlicef(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InEpsilon(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" - assert.InEpsilonf(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.InEpsilonSlice(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" assert.InEpsilonSlicef(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotEqualValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotEqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Implements(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Implementsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Contains(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Containsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.EqualValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.EqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Same(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Samef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Subset(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Subsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.IsType(t, value, value) // want "useless-assert: asserting of the same variable" assert.IsTypef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.JSONEq(t, str, str) // want "useless-assert: asserting of the same variable" assert.JSONEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Less(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Lessf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.LessOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.LessOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotEqualValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotEqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" - assert.NotErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotRegexp(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotRegexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotSame(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotSamef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Greater(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Greaterf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotSubset(t, value, value) // want "useless-assert: asserting of the same variable" assert.NotSubsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InEpsilon(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" + assert.InEpsilonf(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotSame(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotSamef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotRegexp(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotRegexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Less(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Lessf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDeltaSlice(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaSlicef(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.GreaterOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.GreaterOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.EqualExportedValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.EqualExportedValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Equal(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Equalf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.ElementsMatch(t, value, value) // want "useless-assert: asserting of the same variable" + assert.ElementsMatchf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Regexp(t, value, value) // want "useless-assert: asserting of the same variable" assert.Regexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Same(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Samef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Subset(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Subsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.WithinDuration(t, elapsed, elapsed, time.Second) // want "useless-assert: asserting of the same variable" - assert.WithinDurationf(t, elapsed, elapsed, time.Second, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.YAMLEq(t, str, str) // want "useless-assert: asserting of the same variable" - assert.YAMLEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.LessOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.LessOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" } // Valid. diff --git a/internal/checkers/useless_assert.go b/internal/checkers/useless_assert.go index 669f9d1..6f206d0 100644 --- a/internal/checkers/useless_assert.go +++ b/internal/checkers/useless_assert.go @@ -1,6 +1,8 @@ package checkers import ( + "go/ast" + "golang.org/x/tools/go/analysis" "github.com/Antonboom/testifylint/internal/analysisutil" @@ -13,6 +15,8 @@ import ( // assert.Equal(t, tt.value, tt.value) // assert.ElementsMatch(t, users, users) // ... +// assert.True(t, num > num) +// assert.False(t, num == num) // // 2) Open for contribution... type UselessAssert struct{} @@ -22,6 +26,8 @@ func NewUselessAssert() UselessAssert { return UselessAssert{} } func (UselessAssert) Name() string { return "useless-assert" } func (checker UselessAssert) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { + var first, second ast.Node + switch call.Fn.NameFTrimmed { case "Contains", @@ -55,14 +61,25 @@ func (checker UselessAssert) Check(pass *analysis.Pass, call *CallMeta) *analysi "Subset", "WithinDuration", "YAMLEq": - default: - return nil - } + if len(call.Args) < 2 { + return nil + } + first, second = call.Args[0], call.Args[1] + + case "True", "False": + if len(call.Args) < 1 { + return nil + } - if len(call.Args) < 2 { + be, ok := call.Args[0].(*ast.BinaryExpr) + if !ok { + return nil + } + first, second = be.X, be.Y + + default: return nil } - first, second := call.Args[0], call.Args[1] if analysisutil.NodeString(pass.Fset, first) == analysisutil.NodeString(pass.Fset, second) { return newDiagnostic(checker.Name(), call, "asserting of the same variable", nil) diff --git a/internal/testgen/gen_useless_assert.go b/internal/testgen/gen_useless_assert.go index 4c3cb59..b97605b 100644 --- a/internal/testgen/gen_useless_assert.go +++ b/internal/testgen/gen_useless_assert.go @@ -56,8 +56,24 @@ func (g UselessAssertTestsGenerator) TemplateData() any { twoSideAssertions = append(twoSideAssertions, Assertion{Fn: fn, Argsf: args, ReportMsgf: sameVarReport}) } + + for _, args := range []string{ + "num > num", + "num < num", + "num >= num", + "num <= num", + "num == num", + "num != num", + } { + for _, fn := range []string{"True", "False"} { + twoSideAssertions = append(twoSideAssertions, + Assertion{Fn: fn, Argsf: args, ReportMsgf: sameVarReport}) + } + } + sort.Slice(twoSideAssertions, func(i, j int) bool { - return twoSideAssertions[i].Fn < twoSideAssertions[j].Fn + lhs, rhs := twoSideAssertions[i], twoSideAssertions[j] + return lhs.Fn < rhs.Fn && lhs.Argsf < rhs.Argsf }) return struct { @@ -112,6 +128,7 @@ func {{ .CheckerName.AsTestName }}(t *testing.T) { var err error var elapsed time.Time var str string + var num int var tc testCase // Invalid. From 18b4d229ee19379b3d8d23da8234e48ea73356ab Mon Sep 17 00:00:00 2001 From: Anton Telyshev Date: Sat, 18 May 2024 16:47:29 +0300 Subject: [PATCH 2/3] useless-assert: fix test sort --- .../useless-assert/useless_assert_test.go | 112 +++++++++--------- internal/testgen/gen_useless_assert.go | 5 +- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go index 14e0459..c3efe23 100644 --- a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go +++ b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go @@ -60,92 +60,92 @@ func TestUselessAssertChecker(t *testing.T) { assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg") // want "useless-assert: asserting of the same variable" assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg with arg %d", 42) // want "useless-assert: asserting of the same variable" assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Contains(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Containsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" + assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.ElementsMatch(t, value, value) // want "useless-assert: asserting of the same variable" + assert.ElementsMatchf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Equal(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Equalf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.EqualExportedValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.EqualExportedValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.EqualValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.EqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.ErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" assert.ErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.False(t, num < num) // want "useless-assert: asserting of the same variable" - assert.Falsef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num != num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" assert.NotErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" - assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num < num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num <= num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num == num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num != num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num < num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num <= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.True(t, num == num) // want "useless-assert: asserting of the same variable" assert.Truef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.False(t, num >= num) // want "useless-assert: asserting of the same variable" - assert.Falsef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num >= num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.WithinDuration(t, elapsed, elapsed, time.Second) // want "useless-assert: asserting of the same variable" assert.WithinDurationf(t, elapsed, elapsed, time.Second, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num <= num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num < num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.False(t, num == num) // want "useless-assert: asserting of the same variable" - assert.Falsef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num > num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.True(t, num > num) // want "useless-assert: asserting of the same variable" assert.Truef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num != num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.False(t, num >= num) // want "useless-assert: asserting of the same variable" + assert.Falsef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Greater(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Greaterf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.JSONEq(t, str, str) // want "useless-assert: asserting of the same variable" + assert.JSONEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num >= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.YAMLEq(t, str, str) // want "useless-assert: asserting of the same variable" assert.YAMLEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDelta(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InEpsilonSlice(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" - assert.InEpsilonSlicef(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotEqualValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotEqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.GreaterOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.GreaterOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Implements(t, value, value) // want "useless-assert: asserting of the same variable" assert.Implementsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Contains(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Containsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.EqualValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.EqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Same(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Samef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Subset(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Subsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.IsType(t, value, value) // want "useless-assert: asserting of the same variable" assert.IsTypef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.JSONEq(t, str, str) // want "useless-assert: asserting of the same variable" - assert.JSONEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Greater(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Greaterf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotSubset(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotSubsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Less(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Lessf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.LessOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.LessOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotEqual(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotEqualValues(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotEqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.InEpsilon(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" assert.InEpsilonf(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotSame(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotSamef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDelta(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotRegexp(t, value, value) // want "useless-assert: asserting of the same variable" assert.NotRegexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.NotEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Less(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Lessf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.InDeltaSlice(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" assert.InDeltaSlicef(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.GreaterOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.GreaterOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.EqualExportedValues(t, value, value) // want "useless-assert: asserting of the same variable" - assert.EqualExportedValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Equal(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Equalf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.ElementsMatch(t, value, value) // want "useless-assert: asserting of the same variable" - assert.ElementsMatchf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InEpsilonSlice(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" + assert.InEpsilonSlicef(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotSame(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotSamef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotSubset(t, value, value) // want "useless-assert: asserting of the same variable" + assert.NotSubsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Regexp(t, value, value) // want "useless-assert: asserting of the same variable" assert.Regexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.LessOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" - assert.LessOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Same(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Samef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Subset(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Subsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" } // Valid. diff --git a/internal/testgen/gen_useless_assert.go b/internal/testgen/gen_useless_assert.go index b97605b..de99e8a 100644 --- a/internal/testgen/gen_useless_assert.go +++ b/internal/testgen/gen_useless_assert.go @@ -73,7 +73,10 @@ func (g UselessAssertTestsGenerator) TemplateData() any { sort.Slice(twoSideAssertions, func(i, j int) bool { lhs, rhs := twoSideAssertions[i], twoSideAssertions[j] - return lhs.Fn < rhs.Fn && lhs.Argsf < rhs.Argsf + if lhs.Fn < rhs.Fn { + return true + } + return lhs.Argsf < rhs.Argsf }) return struct { From eed70f0c9d937e83d1d87ae5444a1aec104fcea6 Mon Sep 17 00:00:00 2001 From: Anton Telyshev Date: Sat, 18 May 2024 16:48:39 +0300 Subject: [PATCH 3/3] useless-assert: fix test sort --- .../useless-assert/useless_assert_test.go | 68 +++++++++---------- internal/testgen/gen_useless_assert.go | 6 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go index c3efe23..06952b1 100644 --- a/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go +++ b/analyzer/testdata/src/checkers-default/useless-assert/useless_assert_test.go @@ -62,8 +62,6 @@ func TestUselessAssertChecker(t *testing.T) { assert.IsTypef(t, (*testCase)(nil), (*testCase)(nil), "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Contains(t, value, value) // want "useless-assert: asserting of the same variable" assert.Containsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" - assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.ElementsMatch(t, value, value) // want "useless-assert: asserting of the same variable" assert.ElementsMatchf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Equal(t, value, value) // want "useless-assert: asserting of the same variable" @@ -72,50 +70,44 @@ func TestUselessAssertChecker(t *testing.T) { assert.EqualExportedValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.EqualValues(t, value, value) // want "useless-assert: asserting of the same variable" assert.EqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.ErrorAs(t, err, err) // want "useless-assert: asserting of the same variable" + assert.ErrorAsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.ErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" assert.ErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" + assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num != num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.NotErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" - assert.NotErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num < num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num <= num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.Exactly(t, value, value) // want "useless-assert: asserting of the same variable" - assert.Exactlyf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num == num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num != num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num < num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num <= num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num == num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.WithinDuration(t, elapsed, elapsed, time.Second) // want "useless-assert: asserting of the same variable" - assert.WithinDurationf(t, elapsed, elapsed, time.Second, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num > num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num > num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.False(t, num >= num) // want "useless-assert: asserting of the same variable" assert.Falsef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Greater(t, value, value) // want "useless-assert: asserting of the same variable" assert.Greaterf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.JSONEq(t, str, str) // want "useless-assert: asserting of the same variable" - assert.JSONEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.True(t, num >= num) // want "useless-assert: asserting of the same variable" - assert.Truef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.YAMLEq(t, str, str) // want "useless-assert: asserting of the same variable" - assert.YAMLEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.GreaterOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" assert.GreaterOrEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Implements(t, value, value) // want "useless-assert: asserting of the same variable" assert.Implementsf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDelta(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InDeltaSlice(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" + assert.InDeltaSlicef(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InEpsilon(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" + assert.InEpsilonf(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.InEpsilonSlice(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" + assert.InEpsilonSlicef(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.IsType(t, value, value) // want "useless-assert: asserting of the same variable" assert.IsTypef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.JSONEq(t, str, str) // want "useless-assert: asserting of the same variable" + assert.JSONEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Less(t, value, value) // want "useless-assert: asserting of the same variable" assert.Lessf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.LessOrEqual(t, value, value) // want "useless-assert: asserting of the same variable" @@ -124,18 +116,10 @@ func TestUselessAssertChecker(t *testing.T) { assert.NotEqualf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotEqualValues(t, value, value) // want "useless-assert: asserting of the same variable" assert.NotEqualValuesf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InEpsilon(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" - assert.InEpsilonf(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDelta(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValues(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaMapValuesf(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.NotErrorIs(t, err, err) // want "useless-assert: asserting of the same variable" + assert.NotErrorIsf(t, err, err, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotRegexp(t, value, value) // want "useless-assert: asserting of the same variable" assert.NotRegexpf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InDeltaSlice(t, value, value, 0.01) // want "useless-assert: asserting of the same variable" - assert.InDeltaSlicef(t, value, value, 0.01, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" - assert.InEpsilonSlice(t, value, value, 0.0001) // want "useless-assert: asserting of the same variable" - assert.InEpsilonSlicef(t, value, value, 0.0001, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotSame(t, value, value) // want "useless-assert: asserting of the same variable" assert.NotSamef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.NotSubset(t, value, value) // want "useless-assert: asserting of the same variable" @@ -146,6 +130,22 @@ func TestUselessAssertChecker(t *testing.T) { assert.Samef(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" assert.Subset(t, value, value) // want "useless-assert: asserting of the same variable" assert.Subsetf(t, value, value, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num != num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num != num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num < num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num < num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num <= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num <= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num == num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num == num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num > num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num > num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.True(t, num >= num) // want "useless-assert: asserting of the same variable" + assert.Truef(t, num >= num, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.WithinDuration(t, elapsed, elapsed, time.Second) // want "useless-assert: asserting of the same variable" + assert.WithinDurationf(t, elapsed, elapsed, time.Second, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" + assert.YAMLEq(t, str, str) // want "useless-assert: asserting of the same variable" + assert.YAMLEqf(t, str, str, "msg with args %d %s", 42, "42") // want "useless-assert: asserting of the same variable" } // Valid. diff --git a/internal/testgen/gen_useless_assert.go b/internal/testgen/gen_useless_assert.go index de99e8a..c6a4b58 100644 --- a/internal/testgen/gen_useless_assert.go +++ b/internal/testgen/gen_useless_assert.go @@ -73,10 +73,10 @@ func (g UselessAssertTestsGenerator) TemplateData() any { sort.Slice(twoSideAssertions, func(i, j int) bool { lhs, rhs := twoSideAssertions[i], twoSideAssertions[j] - if lhs.Fn < rhs.Fn { - return true + if lhs.Fn == rhs.Fn { + return lhs.Argsf < rhs.Argsf } - return lhs.Argsf < rhs.Argsf + return lhs.Fn < rhs.Fn }) return struct {