Skip to content

Commit

Permalink
empty: added empty and zero length detection (#109)
Browse files Browse the repository at this point in the history
Fixes #108

Co-authored-by: Anton Telyshev <[email protected]>
  • Loading branch information
ccoVeille and Antonboom authored Jun 8, 2024
1 parent 309888d commit 1164965
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 3 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,15 @@ assert.Less(t, len(arr), 0)
assert.Greater(t, 0, len(arr))
assert.Less(t, len(arr), 1)
assert.Greater(t, 1, len(arr))
assert.Zero(t, len(arr))
assert.Empty(t, len(arr))

assert.NotEqual(t, 0, len(arr))
assert.NotEqualValues(t, 0, len(arr))
assert.Less(t, 0, len(arr))
assert.Greater(t, len(arr), 0)
assert.NotZero(t, len(arr))
assert.NotEmpty(t, len(arr))

assert.Empty(t, arr)
Expand Down
8 changes: 8 additions & 0 deletions analyzer/testdata/src/checkers-default/empty/empty_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ func TestEmptyChecker(t *testing.T) {
assert.Emptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.Emptyf"
assert.Empty(t, elems) // want "empty: use assert\\.Empty"
assert.Emptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.Emptyf"
assert.Empty(t, elems) // want "empty: use assert\\.Empty"
assert.Emptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.Emptyf"
assert.Empty(t, elems) // want "empty: use assert\\.Empty"
assert.Emptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.Emptyf"

// Valid.
assert.Empty(t, elems)
Expand All @@ -65,6 +69,10 @@ func TestEmptyChecker(t *testing.T) {
assert.NotEmptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.NotEmptyf"
assert.NotEmpty(t, elems) // want "empty: use assert\\.NotEmpty"
assert.NotEmptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.NotEmptyf"
assert.NotEmpty(t, elems) // want "empty: use assert\\.NotEmpty"
assert.NotEmptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.NotEmptyf"
assert.NotEmpty(t, elems) // want "empty: use assert\\.NotEmpty"
assert.NotEmptyf(t, elems, "msg with args %d %s", 42, "42") // want "empty: use assert\\.NotEmptyf"

// Valid.
assert.NotEmpty(t, elems)
Expand Down
34 changes: 32 additions & 2 deletions internal/checkers/empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ import (
// assert.Greater(t, 0, len(arr))
// assert.Less(t, len(arr), 1)
// assert.Greater(t, 1, len(arr))
// assert.Zero(t, len(arr))
// assert.Empty(t, len(arr))
//
// assert.NotEqual(t, 0, len(arr))
// assert.NotEqualValues(t, 0, len(arr))
// assert.Less(t, 0, len(arr))
// assert.Greater(t, len(arr), 0)
// assert.NotZero(t, len(arr))
// assert.NotEmpty(t, len(arr))
//
// and requires
//
Expand Down Expand Up @@ -56,10 +60,23 @@ func (checker Empty) checkEmpty(pass *analysis.Pass, call *CallMeta) *analysis.D
)
}

if len(call.Args) == 0 {
return nil
}

a := call.Args[0]
switch call.Fn.NameFTrimmed {
case "Zero", "Empty":
lenArg, ok := isBuiltinLenCall(pass, a)
if ok {
return newUseEmptyDiagnostic(a.Pos(), a.End(), lenArg)
}
}

if len(call.Args) < 2 {
return nil
}
a, b := call.Args[0], call.Args[1]
b := call.Args[1]

switch call.Fn.NameFTrimmed {
case "Len":
Expand Down Expand Up @@ -110,10 +127,23 @@ func (checker Empty) checkNotEmpty(pass *analysis.Pass, call *CallMeta) *analysi
)
}

if len(call.Args) == 0 {
return nil
}

a := call.Args[0]
switch call.Fn.NameFTrimmed {
case "NotZero", "NotEmpty":
lenArg, ok := isBuiltinLenCall(pass, a)
if ok {
return newUseNotEmptyDiagnostic(a.Pos(), a.End(), lenArg)
}
}

if len(call.Args) < 2 {
return nil
}
a, b := call.Args[0], call.Args[1]
b := call.Args[1]

switch call.Fn.NameFTrimmed {
case "NotEqual", "NotEqualValues":
Expand Down
6 changes: 5 additions & 1 deletion internal/testgen/gen_empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func (g EmptyTestsGenerator) TemplateData() any {
{Fn: "GreaterOrEqual", Argsf: "0, len(elems)", ReportMsgf: report, ProposedFn: "Empty", ProposedArgsf: "elems"},
{Fn: "Less", Argsf: "len(elems), 1", ReportMsgf: report, ProposedFn: "Empty", ProposedArgsf: "elems"},
{Fn: "Greater", Argsf: "1, len(elems)", ReportMsgf: report, ProposedFn: "Empty", ProposedArgsf: "elems"},
{Fn: "Zero", Argsf: "len(elems)", ReportMsgf: report, ProposedFn: "Empty", ProposedArgsf: "elems"},
{Fn: "Empty", Argsf: "len(elems)", ReportMsgf: report, ProposedFn: "Empty", ProposedArgsf: "elems"},

// Bullshit, but supported by the checker:
// n < 0, n <= 0
Expand All @@ -84,6 +86,8 @@ func (g EmptyTestsGenerator) TemplateData() any {
{Fn: "NotEqualValues", Argsf: "0, len(elems)", ReportMsgf: report, ProposedFn: "NotEmpty", ProposedArgsf: "elems"},
{Fn: "Greater", Argsf: "len(elems), 0", ReportMsgf: report, ProposedFn: "NotEmpty", ProposedArgsf: "elems"},
{Fn: "Less", Argsf: "0, len(elems)", ReportMsgf: report, ProposedFn: "NotEmpty", ProposedArgsf: "elems"},
{Fn: "NotZero", Argsf: "len(elems)", ReportMsgf: report, ProposedFn: "NotEmpty", ProposedArgsf: "elems"},
{Fn: "NotEmpty", Argsf: "len(elems)", ReportMsgf: report, ProposedFn: "NotEmpty", ProposedArgsf: "elems"},
},
ValidAssertions: []Assertion{
{Fn: "NotEmpty", Argsf: "elems"},
Expand Down Expand Up @@ -161,7 +165,7 @@ func {{ .CheckerName.AsTestName }}(t *testing.T) {
{{- range $ai, $assrn := $test.InvalidAssertions }}
{{ NewAssertionExpander.Expand $assrn "assert" "t" nil }}
{{- end }}
// Valid.
{{- range $ai, $assrn := $test.ValidAssertions }}
{{ NewAssertionExpander.Expand $assrn "assert" "t" nil }}
Expand Down

0 comments on commit 1164965

Please sign in to comment.