diff --git a/testifycheck/README.md b/testifycheck/README.md new file mode 100644 index 0000000..ef68d19 --- /dev/null +++ b/testifycheck/README.md @@ -0,0 +1,8 @@ +# testifycheck + +Напишите линтер, который находит неправильные использование функции `{require,assert}.(Not)?Nil` из пакета `testify`. + +Линтер должен смотреть на тип аргумента, который передаётся в функцию `require.NotNil`. Если тот является `error`, +то линтер должен предлагать заменить вызов на `require.NoError`. + +Полный список ситуаций, смотрите в тестовом файле `testdata/srcs/tests/errors_test.go`. diff --git a/testifycheck/testdata/src/github.com/stretchr/testify/assert/assert.go b/testifycheck/testdata/src/github.com/stretchr/testify/assert/assert.go new file mode 100644 index 0000000..92c6ca9 --- /dev/null +++ b/testifycheck/testdata/src/github.com/stretchr/testify/assert/assert.go @@ -0,0 +1,75 @@ +package assert + +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func NoError(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func Error(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { + panic("not implemented") +} + +type Assertions struct{} + +func New(t TestingT) *Assertions { + return nil +} + +func (*Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) NoError(object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) NoErrorf(object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) Error(object interface{}, msgAndArgs ...interface{}) bool { + panic("not implemented") +} + +func (*Assertions) Errorf(object interface{}, msg string, args ...interface{}) bool { + panic("not implemented") +} diff --git a/testifycheck/testdata/src/github.com/stretchr/testify/require/require.go b/testifycheck/testdata/src/github.com/stretchr/testify/require/require.go new file mode 100644 index 0000000..37e58cb --- /dev/null +++ b/testifycheck/testdata/src/github.com/stretchr/testify/require/require.go @@ -0,0 +1,75 @@ +package require + +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} + +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} + +func NoError(t TestingT, object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { + panic("not implemented") +} + +func Error(t TestingT, object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func Errorf(t TestingT, err error, msg string, args ...interface{}) { + panic("not implemented") +} + +type Assertions struct{} + +func New(t TestingT) *Assertions { + return nil +} + +func (*Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func (*Assertions) NotNilf(object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} + +func (*Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func (*Assertions) Nilf(object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} + +func (*Assertions) NoError(object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func (*Assertions) NoErrorf(object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} + +func (*Assertions) Error(object interface{}, msgAndArgs ...interface{}) { + panic("not implemented") +} + +func (*Assertions) Errorf(object interface{}, msg string, args ...interface{}) { + panic("not implemented") +} diff --git a/testifycheck/testdata/src/tests/errors_test.go b/testifycheck/testdata/src/tests/errors_test.go new file mode 100644 index 0000000..d2628ca --- /dev/null +++ b/testifycheck/testdata/src/tests/errors_test.go @@ -0,0 +1,67 @@ +package tests + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func errorFunc() error { + panic("implement me") +} + +func TestFunctions(t *testing.T) { + err := errorFunc() + + require.Nil(t, err) // want `use require.NoError instead of comparing error to nil` + require.NotNil(t, err) // want `use require.Error instead of comparing error to nil` + assert.Nil(t, err) // want `use assert.NoError instead of comparing error to nil` + assert.NotNil(t, err) // want `use assert.Error instead of comparing error to nil` + + require.Nilf(t, err, "%s", "a") // want `use require.NoErrorf instead of comparing error to nil` + require.NotNilf(t, err, "%s", "a") // want `use require.Errorf instead of comparing error to nil` + assert.Nilf(t, err, "%s", "a") // want `use assert.NoErrorf instead of comparing error to nil` + assert.NotNilf(t, err, "%s", "a") // want `use assert.Errorf instead of comparing error to nil` + + p := new(int) + + require.Nil(t, p) + require.NotNil(t, p) + assert.Nil(t, p) + assert.NotNil(t, p) + + require.Nilf(t, p, "%s", "a") + require.NotNilf(t, p, "%s", "a") + assert.Nilf(t, p, "%s", "a") + assert.NotNilf(t, p, "%s", "a") +} + +func TestAssertions(t *testing.T) { + err := errorFunc() + + assert := assert.New(t) + require := require.New(t) + + require.Nil(err) // want `use require.NoError instead of comparing error to nil` + require.NotNil(err) // want `use require.Error instead of comparing error to nil` + assert.Nil(err) // want `use assert.NoError instead of comparing error to nil` + assert.NotNil(err) // want `use assert.Error instead of comparing error to nil` + + require.Nilf(err, "%s", "a") // want `use require.NoErrorf instead of comparing error to nil` + require.NotNilf(err, "%s", "a") // want `use require.Errorf instead of comparing error to nil` + assert.Nilf(err, "%s", "a") // want `use assert.NoErrorf instead of comparing error to nil` + assert.NotNilf(err, "%s", "a") // want `use assert.Errorf instead of comparing error to nil` + + p := new(int) + + require.Nil(p) + require.NotNil(p) + assert.Nil(p) + assert.NotNil(p) + + require.Nilf(p, "%s", "a") + require.NotNilf(p, "%s", "a") + assert.Nilf(p, "%s", "a") + assert.NotNilf(p, "%s", "a") +} diff --git a/testifycheck/testifycheck.go b/testifycheck/testifycheck.go new file mode 100644 index 0000000..829c1ec --- /dev/null +++ b/testifycheck/testifycheck.go @@ -0,0 +1,3 @@ +// +build !solution + +package testifycheck diff --git a/testifycheck/testifycheck_test.go b/testifycheck/testifycheck_test.go new file mode 100644 index 0000000..6abb9ac --- /dev/null +++ b/testifycheck/testifycheck_test.go @@ -0,0 +1,12 @@ +package testifycheck + +import ( + "testing" + + "golang.org/x/tools/go/analysis/analysistest" +) + +func Test(t *testing.T) { + testdata := analysistest.TestData() + analysistest.Run(t, testdata, Analyzer, "tests/...") +}