Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TMPDIR ?= /tmp
# Setup default go-make installation flags.
INSTALL_FLAGS ?= -mod=readonly -buildvcs=auto
# Setup go-make version to use desired build and config scripts.
GOMAKE_DEP ?= github.com/tkrop/go-make@v0.0.159
GOMAKE_DEP ?= github.com/tkrop/go-make@v0.0.164
# Request targets from go-make show-targets target.
TARGETS := $(shell command -v $(GOBIN)/go-make >/dev/null || \
$(GO) install $(INSTALL_FLAGS) $(GOMAKE_DEP) >&2 && \
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.45
0.0.46
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/tkrop/go-testing

go 1.25.4
go 1.25.5

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
Expand All @@ -10,13 +10,13 @@ require (
github.com/stretchr/testify v1.11.1
go.uber.org/mock v0.6.0
golang.org/x/text v0.30.0
golang.org/x/tools v0.38.0
golang.org/x/tools v0.40.0
)

require (
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/sync v0.19.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
24 changes: 17 additions & 7 deletions test/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ type DeepCopyParams struct {

// typeToTestName converts a reflect.Type into a human readable test case name.
// The name is derived from the base (non-pointer) type's CamelCase identifier
// converted to a space separated lower-case string. For unnamed types the
// converted to a hyphen-separated lower-case string. For unnamed types the
// string representation of the type is used as a fallback.
func typeToTestName(typ reflect.Type) string {
raw := typ.Name()
Expand All @@ -191,14 +191,20 @@ func typeToTestName(typ reflect.Type) string {
}
runes := []rune(raw)

last := byte('-')
var b strings.Builder
for i, r := range runes {
if i > 0 && unicode.IsUpper(r) && (unicode.IsLower(runes[i-1]) ||
(i+1 < len(runes) && unicode.IsLower(runes[i+1]))) {
b.WriteByte(' ')
(i+1 < len(runes) && unicode.IsLower(runes[i+1]))) &&
(unicode.IsLetter(runes[i-1]) || unicode.IsDigit(runes[i-1])) {
b.WriteByte('-')
}
b.WriteRune(unicode.ToLower(r))
if r == ' ' {
last = byte(' ')
}
}
b.WriteByte(last)
return b.String()
}

Expand Down Expand Up @@ -226,10 +232,10 @@ func DeepCopyTestCases(
ptrType := reflect.PointerTo(base)
nilPtr := reflect.Zero(ptrType).Interface()

cases[name+" nil"] = DeepCopyParams{
cases[name+"nil"] = DeepCopyParams{
Value: nilPtr,
}
cases[name+" value"] = DeepCopyParams{
cases[name+"value"] = DeepCopyParams{
Value: random.Random(nilPtr),
}
}
Expand Down Expand Up @@ -273,8 +279,12 @@ func DeepCopy(t Test, p DeepCopyParams) {
}

// Then
if !reflect.ValueOf(value).IsNil() {
assert.NotSame(t, value, result)
rv := reflect.ValueOf(value)
if !rv.IsNil() {
// Only check NotSame for pointer types
if rv.Kind() == reflect.Ptr {
assert.NotSame(t, value, result)
}
assert.Equal(t, value, result)
} else {
assert.Nil(t, result)
Expand Down
168 changes: 130 additions & 38 deletions test/pattern_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,30 +518,66 @@ func TestMainUnexpected(t *testing.T) {
test.Param(t, test.MainParams{}).RunSeq(test.Main(main))
}

type deepCopy struct {
type (
noCopySlice []int
deepCopySlice []int
)

func (d deepCopySlice) DeepCopy() deepCopySlice {
if d == nil {
return nil
}

copied := make(deepCopySlice, len(d))
copy(copied, d)

return copied
}

type (
noCopyMap map[string]int
deepCopyMap map[string]int
)

func (d deepCopyMap) DeepCopy() deepCopyMap {
if d == nil {
return nil
}

copied := make(deepCopyMap)
for k, v := range d {
copied[k] = v
}

return copied
}

type noCopyStruct struct {
Value int
}

type deepCopyStruct struct {
Value int
}

func (d *deepCopy) DeepCopy() *deepCopy {
if d != nil {
return &deepCopy{Value: d.Value}
func (d *deepCopyStruct) DeepCopy() *deepCopyStruct {
if d == nil {
return nil
}
return nil

return &deepCopyStruct{Value: d.Value}
}

type deepCopyObject struct {
Value int
}

func (d *deepCopyObject) DeepCopyObject() *deepCopyObject {
if d != nil {
return &deepCopyObject{Value: d.Value}
if d == nil {
return nil
}
return nil
}

type noCopyMethod struct {
Value int
return &deepCopyObject{Value: d.Value}
}

// DeepCopyCasesParams defines parameters for testing DeepCopyTestCases.
Expand All @@ -552,35 +588,71 @@ type DeepCopyCasesParams struct {

var deepCopyTestCasesTestCases = map[string]DeepCopyCasesParams{
"struct types": {
args: []any{&deepCopy{}, &deepCopyObject{}, &noCopyMethod{}},
args: []any{
&noCopySlice{},
&deepCopySlice{},
&noCopyMap{},
&deepCopyMap{},
&noCopyStruct{},
&deepCopyStruct{},
&deepCopyObject{},
},
expect: map[string]test.DeepCopyParams{
"deep copy nil": {
Value: (*deepCopy)(nil),
"no-copy-slice-nil": {
Value: (*noCopySlice)(nil),
},
"deep copy value": {
Value: &deepCopy{Value: 6},
"no-copy-slice-value": {
Value: &noCopySlice{8, 9, 1},
},
"deep copy object nil": {
Value: (*deepCopyObject)(nil),
"deep-copy-slice-nil": {
Value: (*deepCopySlice)(nil),
},
"deep copy object value": {
Value: &deepCopyObject{Value: 8},
"deep-copy-slice-value": {
Value: &deepCopySlice{6, 8},
},
"no-copy-map-nil": {
Value: (*noCopyMap)(nil),
},
"no-copy-map-value": {
Value: &noCopyMap{
"6jif9": 5,
"g21qrot5": 10,
"hbl": 6,
},
},
"deep-copy-map-nil": {
Value: (*deepCopyMap)(nil),
},
"deep-copy-map-value": {
Value: &deepCopyMap{"5srwst": 3},
},
"no copy method nil": {
Value: (*noCopyMethod)(nil),
"no-copy-struct-nil": {
Value: (*noCopyStruct)(nil),
},
"no copy method value": {
Value: &noCopyMethod{Value: 9},
"no-copy-struct-value": {
Value: &noCopyStruct{Value: 8},
},
"deep-copy-struct-nil": {
Value: (*deepCopyStruct)(nil),
},
"deep-copy-struct-value": {
Value: &deepCopyStruct{Value: 6},
},
"deep-copy-object-nil": {
Value: (*deepCopyObject)(nil),
},
"deep-copy-object-value": {
Value: &deepCopyObject{Value: 8},
},
},
},
"anonymous struct type": {
args: []any{&struct{ Value int }{}},
expect: map[string]test.DeepCopyParams{
"struct { value int } nil": {
"struct { value int } nil": {
Value: (*struct{ Value int })(nil),
},
"struct { value int } value": {
"struct { value int } value": {
Value: &struct{ Value int }{Value: 6},
},
},
Expand All @@ -604,47 +676,67 @@ type DeepCopyParams struct {
}

var deepCopyTestCases = map[string]DeepCopyParams{
"deep copy nil": {
"deep-copy-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: (*deepCopy)(nil),
Value: (*deepCopyStruct)(nil),
},
},
"deep-copy value": {
"deep-copy-value": {
DeepCopyParams: test.DeepCopyParams{
Value: &deepCopy{Value: 2},
Value: &deepCopyStruct{Value: 2},
},
},
"deep copy object nil": {
"deep-copy-object-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: (*deepCopyObject)(nil),
},
},
"deep copy object value": {
"deep-copy-object-value": {
DeepCopyParams: test.DeepCopyParams{
Value: &deepCopyObject{Value: 4},
},
},
"no copy method nil": {
"deep-copy-slice-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: deepCopySlice(nil),
},
},
"deep-copy-slice-value": {
DeepCopyParams: test.DeepCopyParams{
Value: deepCopySlice{1, 2, 3},
},
},
"deep-copy-map-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: deepCopyMap(nil),
},
},
"deep-copy-map-value": {
DeepCopyParams: test.DeepCopyParams{
Value: deepCopyMap{"key": 42},
},
},
"no-copy-method-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: nil,
},
setup: test.Fatalf("no deep copy method [%T]", nil),
},
"no copy method value": {
"no-copy-method-value": {
DeepCopyParams: test.DeepCopyParams{
Value: &noCopyMethod{Value: 6},
Value: &noCopyStruct{Value: 6},
},
setup: test.Fatalf("no deep copy method [%T]",
&noCopyMethod{Value: 6}),
&noCopyStruct{Value: 6}),
},
"anonymous struct nil": {
"anonymous-struct-nil": {
DeepCopyParams: test.DeepCopyParams{
Value: (*struct{ Value int })(nil),
},
setup: test.Fatalf("no deep copy method [%T]",
(*struct{ Value int })(nil)),
},
"anonymous struct value": {
"anonymous-struct-value": {
DeepCopyParams: test.DeepCopyParams{
Value: &struct{ Value int }{Value: 8},
},
Expand Down
Loading