From f0057b2f5332c9a4c8b386496a27dc76f7030d09 Mon Sep 17 00:00:00 2001 From: Emilien Puget Date: Wed, 10 Sep 2025 10:07:07 +0200 Subject: [PATCH] Replace `testify` assertions with custom testing helpers --- accessors_test.go | 1 - conversions_test.go | 2 - fixture_test.go | 1 - go.mod | 10 -- go.sum | 10 -- map_test.go | 2 - mutations_test.go | 2 - security_test.go | 1 - simple_example_test.go | 2 - std_assert_test.go | 240 ++++++++++++++++++++++++++++++++++ tests_test.go | 1 - type_specific_codegen_test.go | 1 - type_specific_test.go | 1 - value_test.go | 1 - 14 files changed, 240 insertions(+), 35 deletions(-) create mode 100644 std_assert_test.go diff --git a/accessors_test.go b/accessors_test.go index 6eaab60..7b6f1a7 100644 --- a/accessors_test.go +++ b/accessors_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) func TestAccessorsAccessGetSingleField(t *testing.T) { diff --git a/conversions_test.go b/conversions_test.go index 5071225..82adac2 100644 --- a/conversions_test.go +++ b/conversions_test.go @@ -5,8 +5,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestConversionJSON(t *testing.T) { diff --git a/fixture_test.go b/fixture_test.go index cefe8cd..e994fee 100644 --- a/fixture_test.go +++ b/fixture_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) var fixtures = []struct { diff --git a/go.mod b/go.mod index 372c055..6817ec2 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,3 @@ module github.com/stretchr/objx go 1.20 - -require github.com/stretchr/testify v1.11.1 - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -exclude github.com/stretchr/testify v1.8.0 diff --git a/go.sum b/go.sum index c4c1710..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/map_test.go b/map_test.go index f2a0794..06eb996 100644 --- a/map_test.go +++ b/map_test.go @@ -4,8 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) var TestMap = objx.Map{ diff --git a/mutations_test.go b/mutations_test.go index 40901ce..ca16901 100644 --- a/mutations_test.go +++ b/mutations_test.go @@ -5,8 +5,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestExclude(t *testing.T) { diff --git a/security_test.go b/security_test.go index 8c623db..7170290 100644 --- a/security_test.go +++ b/security_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) func TestHashWithKey(t *testing.T) { diff --git a/simple_example_test.go b/simple_example_test.go index 403753d..ede2341 100644 --- a/simple_example_test.go +++ b/simple_example_test.go @@ -4,8 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestSimpleExample(t *testing.T) { diff --git a/std_assert_test.go b/std_assert_test.go new file mode 100644 index 0000000..1afdbe0 --- /dev/null +++ b/std_assert_test.go @@ -0,0 +1,240 @@ +// This file provides minimal assert/require helpers built on Go's standard library to +// remove the dependency on github.com/stretchr/testify from objx tests. +package objx_test + +import ( + "fmt" + "reflect" + "testing" +) + +type nonfatal struct{} +type fatal struct{} + +var assert nonfatal +var require fatal + +func (nonfatal) fail(t *testing.T, msg string, msgAndArgs ...interface{}) bool { + t.Helper() + if len(msgAndArgs) > 0 { + msg = fmt.Sprintf(msg, msgAndArgs...) + } + t.Error(msg) + return false +} + +func (fatal) fail(t *testing.T, msg string, msgAndArgs ...interface{}) { + t.Helper() + if len(msgAndArgs) > 0 { + msg = fmt.Sprintf(msg, msgAndArgs...) + } + t.Fatal(msg) +} + +func (a nonfatal) Equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool { + t.Helper() + if !reflect.DeepEqual(expected, actual) { + return a.fail(t, "not equal:\nexpected: %#v\nactual: %#v", expected, actual) + } + return true +} +func (a fatal) Equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) { + t.Helper() + if !reflect.DeepEqual(expected, actual) { + a.fail(t, "not equal:\nexpected: %#v\nactual: %#v", expected, actual) + } +} + +func (a nonfatal) NotEqual(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool { + t.Helper() + if reflect.DeepEqual(expected, actual) { + return a.fail(t, "should not be equal: %#v", actual) + } + return true +} + +func (a fatal) NotEqual(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) { + t.Helper() + if reflect.DeepEqual(expected, actual) { + a.fail(t, "should not be equal: %#v", actual) + } +} + +func isNil(i interface{}) bool { + if i == nil { + return true + } + v := reflect.ValueOf(i) + switch v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + return false +} + +func (a nonfatal) Nil(t *testing.T, object interface{}, msgAndArgs ...interface{}) bool { + t.Helper() + if !isNil(object) { + return a.fail(t, "expected nil, got: %#v", object) + } + return true +} + +func (a fatal) Nil(t *testing.T, object interface{}, msgAndArgs ...interface{}) { + t.Helper() + if !isNil(object) { + a.fail(t, "expected nil, got: %#v", object) + } +} + +func (a nonfatal) NotNil(t *testing.T, object interface{}, msgAndArgs ...interface{}) bool { + t.Helper() + if isNil(object) { + return a.fail(t, "expected not nil") + } + return true +} + +func (a fatal) NotNil(t *testing.T, object interface{}, msgAndArgs ...interface{}) { + t.Helper() + if isNil(object) { + a.fail(t, "expected not nil") + } +} + +func (a nonfatal) True(t *testing.T, value bool, msgAndArgs ...interface{}) bool { + t.Helper() + if !value { + return a.fail(t, "expected true, got false") + } + return true +} +func (a fatal) True(t *testing.T, value bool, msgAndArgs ...interface{}) { + t.Helper() + if !value { + a.fail(t, "expected true, got false") + } +} + +func (a nonfatal) False(t *testing.T, value bool, msgAndArgs ...interface{}) bool { + t.Helper() + if value { + return a.fail(t, "expected false, got true") + } + return true +} +func (a fatal) False(t *testing.T, value bool, msgAndArgs ...interface{}) { + t.Helper() + if value { + a.fail(t, "expected false, got true") + } +} + +func (a nonfatal) NoError(t *testing.T, err error, msgAndArgs ...interface{}) bool { + t.Helper() + if err != nil { + return a.fail(t, "expected no error, got: %v", err) + } + return true +} +func (a fatal) NoError(t *testing.T, err error, msgAndArgs ...interface{}) { + t.Helper() + if err != nil { + a.fail(t, "expected no error, got: %v", err) + } +} + +func (a nonfatal) Error(t *testing.T, err error, msgAndArgs ...interface{}) bool { + t.Helper() + if err == nil { + return a.fail(t, "expected error, got nil") + } + return true +} +func (a fatal) Error(t *testing.T, err error, msgAndArgs ...interface{}) { + t.Helper() + if err == nil { + a.fail(t, "expected error, got nil") + } +} + +func (a nonfatal) Panics(t *testing.T, f func(), msgAndArgs ...interface{}) bool { + t.Helper() + defer func() { + if r := recover(); r == nil { + _ = a.fail(t, "expected panic, but function did not panic") + } + }() + f() + return true +} + +func (a fatal) Panics(t *testing.T, f func(), msgAndArgs ...interface{}) { + t.Helper() + defer func() { + if r := recover(); r == nil { + a.fail(t, "expected panic, but function did not panic") + } + }() + f() +} + +func (a nonfatal) Empty(t *testing.T, object interface{}, msgAndArgs ...interface{}) bool { + t.Helper() + if !isEmpty(object) { + return a.fail(t, "expected empty, got: %#v", object) + } + return true +} + +func (a fatal) Empty(t *testing.T, object interface{}, msgAndArgs ...interface{}) { + t.Helper() + if !isEmpty(object) { + a.fail(t, "expected empty, got: %#v", object) + } +} + +func isEmpty(object interface{}) bool { + if object == nil { + return true + } + v := reflect.ValueOf(object) + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan, reflect.String: + return v.Len() == 0 + case reflect.Ptr, reflect.Interface: + if v.IsNil() { + return true + } + return isEmpty(v.Elem().Interface()) + } + // numbers and structs are never considered empty here + return false +} + +func (a nonfatal) Len(t *testing.T, object interface{}, length int, msgAndArgs ...interface{}) bool { + t.Helper() + v := reflect.ValueOf(object) + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan, reflect.String: + if v.Len() != length { + return a.fail(t, "unexpected length, expected %d got %d", length, v.Len()) + } + return true + default: + return a.fail(t, "Len not supported for kind %s", v.Kind()) + } +} + +func (a fatal) Len(t *testing.T, object interface{}, length int, msgAndArgs ...interface{}) { + t.Helper() + v := reflect.ValueOf(object) + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan, reflect.String: + if v.Len() != length { + a.fail(t, "unexpected length, expected %d got %d", length, v.Len()) + } + default: + a.fail(t, "Len not supported for kind %s", v.Kind()) + } +} diff --git a/tests_test.go b/tests_test.go index 94a8ada..f5579b0 100644 --- a/tests_test.go +++ b/tests_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) func TestHas(t *testing.T) { diff --git a/type_specific_codegen_test.go b/type_specific_codegen_test.go index 575aa85..3fe0892 100644 --- a/type_specific_codegen_test.go +++ b/type_specific_codegen_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) /* diff --git a/type_specific_test.go b/type_specific_test.go index 505e19a..6512bb7 100644 --- a/type_specific_test.go +++ b/type_specific_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) /* diff --git a/value_test.go b/value_test.go index 898a59a..54727f5 100644 --- a/value_test.go +++ b/value_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/objx" - "github.com/stretchr/testify/assert" ) func TestStringTypeString(t *testing.T) {