Add testifylint
linter (#4103)
This commit is contained in:
parent
823f02dc35
commit
2d5d29f505
@ -1886,6 +1886,35 @@ linters-settings:
|
|||||||
# Default: false
|
# Default: false
|
||||||
all: false
|
all: false
|
||||||
|
|
||||||
|
testifylint:
|
||||||
|
# Enable all checkers.
|
||||||
|
# Default: false
|
||||||
|
enable-all: true
|
||||||
|
# Enable specific checkers.
|
||||||
|
# https://github.com/Antonboom/testifylint#checkers
|
||||||
|
# Default: ["bool-compare", "compares", "empty", "error-is-as", "error-nil", "expected-actual", "float-compare", "len", "require-error", "suite-dont-use-pkg", "suite-extra-assert-call"]
|
||||||
|
enable:
|
||||||
|
- bool-compare
|
||||||
|
- compares
|
||||||
|
- empty
|
||||||
|
- error-is-as
|
||||||
|
- error-nil
|
||||||
|
- expected-actual
|
||||||
|
- float-compare
|
||||||
|
- len
|
||||||
|
- require-error
|
||||||
|
- suite-dont-use-pkg
|
||||||
|
- suite-extra-assert-call
|
||||||
|
- suite-thelper
|
||||||
|
expected-actual:
|
||||||
|
# Regexp for expected variable name.
|
||||||
|
# Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)
|
||||||
|
pattern: ^expected
|
||||||
|
suite-extra-assert-call:
|
||||||
|
# To require or remove extra Assert() call?
|
||||||
|
# Default: remove
|
||||||
|
mode: require
|
||||||
|
|
||||||
testpackage:
|
testpackage:
|
||||||
# Regexp pattern to skip files.
|
# Regexp pattern to skip files.
|
||||||
# Default: "(export|internal)_test\\.go"
|
# Default: "(export|internal)_test\\.go"
|
||||||
@ -2246,6 +2275,7 @@ linters:
|
|||||||
- tagliatelle
|
- tagliatelle
|
||||||
- tenv
|
- tenv
|
||||||
- testableexamples
|
- testableexamples
|
||||||
|
- testifylint
|
||||||
- testpackage
|
- testpackage
|
||||||
- thelper
|
- thelper
|
||||||
- tparallel
|
- tparallel
|
||||||
@ -2360,6 +2390,7 @@ linters:
|
|||||||
- tagliatelle
|
- tagliatelle
|
||||||
- tenv
|
- tenv
|
||||||
- testableexamples
|
- testableexamples
|
||||||
|
- testifylint
|
||||||
- testpackage
|
- testpackage
|
||||||
- thelper
|
- thelper
|
||||||
- tparallel
|
- tparallel
|
||||||
|
1
go.mod
1
go.mod
@ -9,6 +9,7 @@ require (
|
|||||||
github.com/Abirdcfly/dupword v0.0.13
|
github.com/Abirdcfly/dupword v0.0.13
|
||||||
github.com/Antonboom/errname v0.1.12
|
github.com/Antonboom/errname v0.1.12
|
||||||
github.com/Antonboom/nilnil v0.1.7
|
github.com/Antonboom/nilnil v0.1.7
|
||||||
|
github.com/Antonboom/testifylint v0.2.3
|
||||||
github.com/BurntSushi/toml v1.3.2
|
github.com/BurntSushi/toml v1.3.2
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
||||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0
|
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0
|
||||||
|
2
go.sum
generated
2
go.sum
generated
@ -48,6 +48,8 @@ github.com/Antonboom/errname v0.1.12 h1:oh9ak2zUtsLp5oaEd/erjB4GPu9w19NyoIskZClD
|
|||||||
github.com/Antonboom/errname v0.1.12/go.mod h1:bK7todrzvlaZoQagP1orKzWXv59X/x0W0Io2XT1Ssro=
|
github.com/Antonboom/errname v0.1.12/go.mod h1:bK7todrzvlaZoQagP1orKzWXv59X/x0W0Io2XT1Ssro=
|
||||||
github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTow=
|
github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTow=
|
||||||
github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ=
|
github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ=
|
||||||
|
github.com/Antonboom/testifylint v0.2.3 h1:MFq9zyL+rIVpsvLX4vDPLojgN7qODzWsrnftNX2Qh60=
|
||||||
|
github.com/Antonboom/testifylint v0.2.3/go.mod h1:IYaXaOX9NbfAyO+Y04nfjGI8wDemC1rUyM/cYolz018=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
@ -218,6 +218,7 @@ type LintersSettings struct {
|
|||||||
Stylecheck StaticCheckSettings
|
Stylecheck StaticCheckSettings
|
||||||
TagAlign TagAlignSettings
|
TagAlign TagAlignSettings
|
||||||
Tagliatelle TagliatelleSettings
|
Tagliatelle TagliatelleSettings
|
||||||
|
Testifylint TestifylintSettings
|
||||||
Tenv TenvSettings
|
Tenv TenvSettings
|
||||||
Testpackage TestpackageSettings
|
Testpackage TestpackageSettings
|
||||||
Thelper ThelperSettings
|
Thelper ThelperSettings
|
||||||
@ -738,6 +739,19 @@ type TagliatelleSettings struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TestifylintSettings struct {
|
||||||
|
EnableAll bool `mapstructure:"enable-all"`
|
||||||
|
EnabledCheckers []string `mapstructure:"enable"`
|
||||||
|
|
||||||
|
ExpectedActual struct {
|
||||||
|
ExpVarPattern string `mapstructure:"pattern"`
|
||||||
|
} `mapstructure:"expected-actual"`
|
||||||
|
|
||||||
|
SuiteExtraAssertCall struct {
|
||||||
|
Mode string `mapstructure:"mode"`
|
||||||
|
} `mapstructure:"suite-extra-assert-call"`
|
||||||
|
}
|
||||||
|
|
||||||
type TestpackageSettings struct {
|
type TestpackageSettings struct {
|
||||||
SkipRegexp string `mapstructure:"skip-regexp"`
|
SkipRegexp string `mapstructure:"skip-regexp"`
|
||||||
AllowPackages []string `mapstructure:"allow-packages"`
|
AllowPackages []string `mapstructure:"allow-packages"`
|
||||||
|
36
pkg/golinters/testifylint.go
Normal file
36
pkg/golinters/testifylint.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Antonboom/testifylint/analyzer"
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
|
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTestifylint(settings *config.TestifylintSettings) *goanalysis.Linter {
|
||||||
|
a := analyzer.New()
|
||||||
|
|
||||||
|
cfg := make(map[string]map[string]any)
|
||||||
|
if settings != nil {
|
||||||
|
cfg[a.Name] = map[string]any{
|
||||||
|
"enable-all": settings.EnableAll,
|
||||||
|
}
|
||||||
|
if len(settings.EnabledCheckers) > 0 {
|
||||||
|
cfg[a.Name]["enable"] = settings.EnabledCheckers
|
||||||
|
}
|
||||||
|
if p := settings.ExpectedActual.ExpVarPattern; p != "" {
|
||||||
|
cfg[a.Name]["expected-actual.pattern"] = p
|
||||||
|
}
|
||||||
|
if m := settings.SuiteExtraAssertCall.Mode; m != "" {
|
||||||
|
cfg[a.Name]["suite-extra-assert-call.mode"] = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return goanalysis.NewLinter(
|
||||||
|
a.Name,
|
||||||
|
a.Doc,
|
||||||
|
[]*analysis.Analyzer{a},
|
||||||
|
cfg,
|
||||||
|
).WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||||
|
}
|
@ -133,6 +133,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
tagalignCfg *config.TagAlignSettings
|
tagalignCfg *config.TagAlignSettings
|
||||||
tagliatelleCfg *config.TagliatelleSettings
|
tagliatelleCfg *config.TagliatelleSettings
|
||||||
tenvCfg *config.TenvSettings
|
tenvCfg *config.TenvSettings
|
||||||
|
testifylintCfg *config.TestifylintSettings
|
||||||
testpackageCfg *config.TestpackageSettings
|
testpackageCfg *config.TestpackageSettings
|
||||||
thelperCfg *config.ThelperSettings
|
thelperCfg *config.ThelperSettings
|
||||||
unparamCfg *config.UnparamSettings
|
unparamCfg *config.UnparamSettings
|
||||||
@ -213,6 +214,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
tagalignCfg = &m.cfg.LintersSettings.TagAlign
|
tagalignCfg = &m.cfg.LintersSettings.TagAlign
|
||||||
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
|
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
|
||||||
tenvCfg = &m.cfg.LintersSettings.Tenv
|
tenvCfg = &m.cfg.LintersSettings.Tenv
|
||||||
|
testifylintCfg = &m.cfg.LintersSettings.Testifylint
|
||||||
testpackageCfg = &m.cfg.LintersSettings.Testpackage
|
testpackageCfg = &m.cfg.LintersSettings.Testpackage
|
||||||
thelperCfg = &m.cfg.LintersSettings.Thelper
|
thelperCfg = &m.cfg.LintersSettings.Thelper
|
||||||
unparamCfg = &m.cfg.LintersSettings.Unparam
|
unparamCfg = &m.cfg.LintersSettings.Unparam
|
||||||
@ -788,6 +790,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
WithPresets(linter.PresetTest).
|
WithPresets(linter.PresetTest).
|
||||||
WithURL("https://github.com/maratori/testableexamples"),
|
WithURL("https://github.com/maratori/testableexamples"),
|
||||||
|
|
||||||
|
linter.NewConfig(golinters.NewTestifylint(testifylintCfg)).
|
||||||
|
WithSince("v1.55.0").
|
||||||
|
WithPresets(linter.PresetTest, linter.PresetBugs).
|
||||||
|
WithLoadForGoAnalysis().
|
||||||
|
WithURL("https://github.com/Antonboom/testifylint"),
|
||||||
|
|
||||||
linter.NewConfig(golinters.NewTestpackage(testpackageCfg)).
|
linter.NewConfig(golinters.NewTestpackage(testpackageCfg)).
|
||||||
WithSince("v1.25.0").
|
WithSince("v1.25.0").
|
||||||
WithPresets(linter.PresetStyle, linter.PresetTest).
|
WithPresets(linter.PresetStyle, linter.PresetTest).
|
||||||
|
62
test/testdata/testifylint.go
vendored
Normal file
62
test/testdata/testifylint.go
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//golangcitest:args -Etestifylint
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestifylint(t *testing.T) {
|
||||||
|
var (
|
||||||
|
predicate bool
|
||||||
|
resultInt int
|
||||||
|
resultFloat float64
|
||||||
|
arr []string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Equal(t, predicate, true) // want "bool-compare: use assert\\.True"
|
||||||
|
assert.True(t, resultInt == 1) // want "compares: use assert\\.Equal"
|
||||||
|
assert.Equal(t, len(arr), 0) // want "empty: use assert\\.Empty"
|
||||||
|
assert.Error(t, err, io.EOF) // want "error-is-as: invalid usage of assert\\.Error, use assert\\.ErrorIs instead"
|
||||||
|
assert.Nil(t, err) // want "error-nil: use assert\\.NoError"
|
||||||
|
assert.Equal(t, resultInt, 42) // want "expected-actual: need to reverse actual and expected values"
|
||||||
|
assert.Equal(t, resultFloat, 42.42) // want "float-compare: use assert\\.InEpsilon \\(or InDelta\\)"
|
||||||
|
assert.Equal(t, len(arr), 10) // want "len: use assert\\.Len"
|
||||||
|
|
||||||
|
assert.True(t, predicate)
|
||||||
|
assert.Equal(t, resultInt, 1) // want "expected-actual: need to reverse actual and expected values"
|
||||||
|
assert.Empty(t, arr)
|
||||||
|
assert.ErrorIs(t, err, io.EOF) // want "require-error: for error assertions use require"
|
||||||
|
assert.NoError(t, err) // want "require-error: for error assertions use require"
|
||||||
|
assert.Equal(t, 42, resultInt)
|
||||||
|
assert.InEpsilon(t, 42.42, resultFloat, 0.0001)
|
||||||
|
assert.Len(t, arr, 10)
|
||||||
|
|
||||||
|
require.ErrorIs(t, err, io.EOF)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("formatted", func(t *testing.T) {
|
||||||
|
assert.Equal(t, predicate, true, "message") // want "bool-compare: use assert\\.True"
|
||||||
|
assert.Equal(t, predicate, true, "message %d", 42) // want "bool-compare: use assert\\.True"
|
||||||
|
assert.Equalf(t, predicate, true, "message") // want "bool-compare: use assert\\.Truef"
|
||||||
|
assert.Equalf(t, predicate, true, "message %d", 42) // want "bool-compare: use assert\\.Truef"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type SuiteExample struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSuiteExample(t *testing.T) {
|
||||||
|
suite.Run(t, new(SuiteExample))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SuiteExample) TestAll() {
|
||||||
|
var b bool
|
||||||
|
s.Assert().True(b) // want "suite-extra-assert-call: need to simplify the assertion to s\\.True"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user