Skip to content

Commit cc919ca

Browse files
authored
[feature] add deep equal methods and remove unneeded assertion methods (#13)
* removed EqualSlice, NotEqualSlice, EqualMap, NotEqualMap as DeepEqual can achieve the same * improved SimilarSlice and NotSimilarSlice to work with any type
1 parent 719b0e5 commit cc919ca

File tree

4 files changed

+359
-353
lines changed

4 files changed

+359
-353
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,8 @@ func Test_1Plus1ShouldEqual2(t *testing.T) {
4343
* `NotEqual` - asserts two values are not equal. Values must be comparable
4444
* `Nil` - asserts the value is nil
4545
* `NotNil` - asserts the value is not nil
46-
* `EqualSlice` - asserts two slices have the same values in the same order. The elements must be comparable
47-
* `NotEqualSlice` - asserts two slices do not have the same values in the same order. The elements must be comparable
4846
* `SimilarSlice` - asserts two slices have the same values in any order. The elements must be comparable
4947
* `NotSimilarSlice` - asserts two slices do not have the same values. The elements must be comparable
50-
* `EqualMap` - asserts two maps have same key-value pairs. The values must be comparable
51-
* `NotEqualMap` - asserts two maps do not have same key-value pairs. The values must be comparable
5248

5349
### Collection
5450
* `EmptySlice` - asserts the slice is empty. The assertion will fail if the slice is nil

assert_equality.go

Lines changed: 39 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -28,82 +28,68 @@ func NotEqual[K comparable](t testing.TB, expected K, actual K) {
2828
}
2929

3030
/*
31-
Asserts that the given value is nil
31+
Asserts that the two given valus are deeply equal. Internally uses reflect.DeepEqual.
32+
The equality of arrays, slices and maps can be asserted with this method
3233
*/
33-
func Nil(t testing.TB, actual interface{}) {
34+
func DeepEqual[T any](t testing.TB, expected T, actual T) {
3435
t.Helper()
3536

36-
if !isNil(actual) {
37-
t.Error(inequalityMsg(nil, actual))
37+
if !reflect.DeepEqual(expected, actual) {
38+
t.Error(inequalityMsg(expected, actual))
3839
}
3940
}
4041

4142
/*
42-
Asserts that the given value is not nil
43+
Asserts that the two given valus are not deeply equal. Internally uses reflect.DeepEqual.
44+
The inequality of arrays, slices and maps can be asserted with this method
4345
*/
44-
func NotNil(t testing.TB, actual interface{}) {
46+
func NotDeepEqual[T any](t testing.TB, expected T, actual T) {
4547
t.Helper()
4648

47-
if isNil(actual) {
48-
t.Error(equalityMsg("nil"))
49-
}
50-
}
51-
52-
func isNil(value interface{}) bool {
53-
if value == nil {
54-
return true
55-
}
56-
57-
switch reflect.TypeOf(value).Kind() {
58-
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan, reflect.Func:
59-
return reflect.ValueOf(value).IsNil()
49+
if reflect.DeepEqual(expected, actual) {
50+
t.Error(equalityMsg(expected))
6051
}
61-
62-
return false
6352
}
6453

6554
/*
66-
Asserts that the two given slices have the same elements in the same order. The elements must be [comparable]
55+
Asserts that the given value is nil
6756
*/
68-
func EqualSlice[K comparable](t testing.TB, expected []K, actual []K) {
57+
func Nil(t testing.TB, actual interface{}) {
6958
t.Helper()
7059

71-
if !areEqualSlices(expected, actual) {
72-
t.Error(inequalityMsg(expected, actual))
60+
if !isNil(actual) {
61+
t.Error(inequalityMsg(nil, actual))
7362
}
7463
}
7564

7665
/*
77-
Asserts that the two given slices does not have the same elements in the same order. The elements must be [comparable]
66+
Asserts that the given value is not nil
7867
*/
79-
func NotEqualSlice[K comparable](t testing.TB, expected []K, actual []K) {
68+
func NotNil(t testing.TB, actual interface{}) {
8069
t.Helper()
8170

82-
if areEqualSlices(expected, actual) {
83-
t.Error(equalityMsg(expected))
71+
if isNil(actual) {
72+
t.Error(equalityMsg("nil"))
8473
}
8574
}
8675

87-
func areEqualSlices[K comparable](expected []K, actual []K) bool {
88-
expectedLength := len(expected)
89-
actualLength := len(actual)
90-
if actualLength != expectedLength {
91-
return false
76+
func isNil(value interface{}) bool {
77+
if value == nil {
78+
return true
9279
}
9380

94-
for i := 0; i < expectedLength; i++ {
95-
if actual[i] != expected[i] {
96-
return false
97-
}
81+
switch reflect.TypeOf(value).Kind() {
82+
case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Chan, reflect.Func:
83+
return reflect.ValueOf(value).IsNil()
9884
}
9985

100-
return true
86+
return false
10187
}
10288

10389
/*
10490
Asserts that the two given slices have the same values in any order. The elements must be [comparable]
10591
*/
106-
func SimilarSlice[K comparable](t testing.TB, expected []K, actual []K) {
92+
func SimilarSlice[T any](t testing.TB, expected []T, actual []T) {
10793
t.Helper()
10894

10995
if !areSimilarSlices(expected, actual) {
@@ -114,69 +100,34 @@ func SimilarSlice[K comparable](t testing.TB, expected []K, actual []K) {
114100
/*
115101
Asserts that the two given slices does not have the same values. The elements must be [comparable]
116102
*/
117-
func NotSimilarSlice[K comparable](t testing.TB, expected []K, actual []K) {
103+
func NotSimilarSlice[T any](t testing.TB, expected []T, actual []T) {
118104
t.Helper()
119105

120106
if areSimilarSlices(expected, actual) {
121107
t.Error(equalityMsg(expected))
122108
}
123109
}
124110

125-
func areSimilarSlices[K comparable](expected []K, actual []K) bool {
111+
func areSimilarSlices[T any](expected []T, actual []T) bool {
126112
expectedLength := len(expected)
127113
actualLength := len(actual)
128114
if actualLength != expectedLength {
129115
return false
130116
}
131117

132-
expectedElementsMap := make(map[K]int, expectedLength)
133-
for _, v := range expected {
134-
expectedElementsMap[v] += 1
135-
}
136-
137-
actualElementsMap := make(map[K]int, actualLength)
138-
for _, v := range actual {
139-
actualElementsMap[v] += 1
140-
}
141-
142-
return isEqualMap(expectedElementsMap, actualElementsMap)
143-
}
144-
145-
/*
146-
Asserts that the two given maps have the same key-value pairs. The values must be [comparable]
147-
*/
148-
func EqualMap[K, V comparable](t testing.TB, expected map[K]V, actual map[K]V) {
149-
t.Helper()
150-
151-
if !isEqualMap(expected, actual) {
152-
t.Error(inequalityMsg(expected, actual))
153-
}
154-
}
155-
156-
/*
157-
Asserts that the two given maps does not have the same key-value pairs. The values must be [comparable]
158-
*/
159-
func NotEqualMap[K, V comparable](t testing.TB, expected map[K]V, actual map[K]V) {
160-
t.Helper()
161-
162-
if isEqualMap(expected, actual) {
163-
t.Error(equalityMsg(expected))
164-
}
165-
}
166-
167-
func isEqualMap[K, V comparable](expected map[K]V, actual map[K]V) bool {
168-
expectedLength := len(expected)
169-
actualLength := len(actual)
170-
if actualLength != expectedLength {
171-
return false
172-
}
118+
matchedIndexMap := make(map[int]interface{}, expectedLength)
119+
for _, expectedValue := range expected {
120+
for j, actualValue := range actual {
121+
if !reflect.DeepEqual(expectedValue, actualValue) {
122+
continue
123+
}
173124

174-
for actualKey, actualValue := range actual {
175-
expectedValue, found := expected[actualKey]
176-
if !found || actualValue != expectedValue {
177-
return false
125+
if _, alreadyMatched := matchedIndexMap[j]; !alreadyMatched {
126+
matchedIndexMap[j] = nil
127+
break
128+
}
178129
}
179130
}
180131

181-
return true
132+
return len(matchedIndexMap) == expectedLength
182133
}

0 commit comments

Comments
 (0)