From a80659927bf93a56733d0bd835066c4d98487c59 Mon Sep 17 00:00:00 2001 From: Anton Telyshev Date: Tue, 7 Nov 2023 22:08:05 +0200 Subject: [PATCH] analysisutil.IsObj: don't use obj.Id() as uniq identifier --- analyzer/analyzer_test.go | 4 ++ .../testdata/src/not-std-funcs/errors/is.go | 5 +++ .../src/not-std-funcs/not_std_funcs_test.go | 40 +++++++++++++++++++ .../not_std_funcs_test.go.golden | 40 +++++++++++++++++++ internal/analysisutil/object.go | 2 +- internal/analysisutil/object_test.go | 15 +++++++ 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 analyzer/testdata/src/not-std-funcs/errors/is.go create mode 100644 analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go create mode 100644 analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go.golden diff --git a/analyzer/analyzer_test.go b/analyzer/analyzer_test.go index 729b8e1b..f6f9171a 100644 --- a/analyzer/analyzer_test.go +++ b/analyzer/analyzer_test.go @@ -38,6 +38,10 @@ func TestTestifyLint(t *testing.T) { }, }, {dir: "ginkgo"}, + { + dir: "not-std-funcs", + flags: map[string]string{"enable-all": "true"}, + }, {dir: "not-test-file"}, // By default, linter checks regular files too. {dir: "not-true-testify"}, // Linter ignores stretchr/testify's forks. {dir: "pkg-alias"}, diff --git a/analyzer/testdata/src/not-std-funcs/errors/is.go b/analyzer/testdata/src/not-std-funcs/errors/is.go new file mode 100644 index 00000000..2fd606c3 --- /dev/null +++ b/analyzer/testdata/src/not-std-funcs/errors/is.go @@ -0,0 +1,5 @@ +package errors + +func Is(err error, v int) bool { + return false +} diff --git a/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go b/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go new file mode 100644 index 00000000..2f6fbba1 --- /dev/null +++ b/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go @@ -0,0 +1,40 @@ +package notstdfuncs + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + myerrors "not-std-funcs/errors" +) + +func TestCustomStuff(t *testing.T) { + var err error + var errSentinel = errors.New("unexpected") + var scores []float64 + + assert.Equal(t, nil, scores) // want "nil-compare: use assert\\.Nil" + + assert.True(t, myerrors.Is(err, 2)) + assert.False(t, Is(err, errSentinel)) + assert.True(t, As(err, &err)) + assert.Equal(t, 3, len(scores)) + + require.True(t, myerrors.Is(err, 3)) + require.False(t, Is(err, errSentinel)) + require.True(t, As(err, &err)) + require.Equal(t, 4, len(scores)) +} + +func Is(err, target error) bool { + return true +} + +func As(err error, target any) bool { + return false +} + +func len[T any](arr T) int { + return 3 +} diff --git a/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go.golden b/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go.golden new file mode 100644 index 00000000..b5b08217 --- /dev/null +++ b/analyzer/testdata/src/not-std-funcs/not_std_funcs_test.go.golden @@ -0,0 +1,40 @@ +package notstdfuncs + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + myerrors "not-std-funcs/errors" +) + +func TestCustomStuff(t *testing.T) { + var err error + var errSentinel = errors.New("unexpected") + var scores []float64 + + assert.Nil(t, scores) // want "nil-compare: use assert\\.Nil" + + assert.True(t, myerrors.Is(err, 2)) + assert.False(t, Is(err, errSentinel)) + assert.True(t, As(err, &err)) + assert.Equal(t, 3, len(scores)) + + require.True(t, myerrors.Is(err, 3)) + require.False(t, Is(err, errSentinel)) + require.True(t, As(err, &err)) + require.Equal(t, 4, len(scores)) +} + +func Is(err, target error) bool { + return true +} + +func As(err error, target any) bool { + return false +} + +func len[T any](arr T) int { + return 3 +} diff --git a/internal/analysisutil/object.go b/internal/analysisutil/object.go index e01fba5c..4e0346d2 100644 --- a/internal/analysisutil/object.go +++ b/internal/analysisutil/object.go @@ -30,5 +30,5 @@ func IsObj(typesInfo *types.Info, expr ast.Expr, expected types.Object) bool { } obj := typesInfo.ObjectOf(id) - return obj.Id() == expected.Id() + return obj == expected } diff --git a/internal/analysisutil/object_test.go b/internal/analysisutil/object_test.go index 69c37cf8..bb16528d 100644 --- a/internal/analysisutil/object_test.go +++ b/internal/analysisutil/object_test.go @@ -114,3 +114,18 @@ func TestIsObj(t *testing.T) { }) } } + +func TestIsObj_NamesakesFromDifferentPackages(t *testing.T) { + lhs := types.NewFunc(token.NoPos, types.NewPackage("errors", "errors"), "Is", nil) + rhs := types.NewFunc(token.NoPos, types.NewPackage("pkg/errors", "errors"), "Is", nil) + + ident := new(ast.Ident) + typesInfo := &types.Info{ + Defs: map[*ast.Ident]types.Object{ + ident: lhs, + }, + } + if analysisutil.IsObj(typesInfo, ident, rhs) { + t.Fatalf("objects should not be equal") + } +}