forked from torbiak/gopl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
equal_test.go
134 lines (122 loc) · 3.14 KB
/
equal_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package equalish
import (
"bytes"
"fmt"
"testing"
)
func TestEqualish(t *testing.T) {
one, oneAgain, two := 1, 1, 2
type CyclePtr *CyclePtr
var cyclePtr1, cyclePtr2 CyclePtr
cyclePtr1 = &cyclePtr1
cyclePtr2 = &cyclePtr2
type CycleSlice []CycleSlice
var cycleSlice CycleSlice
cycleSlice = append(cycleSlice, cycleSlice)
ch1, ch2 := make(chan int), make(chan int)
var ch1ro <-chan int = ch1
type mystring string
var iface1, iface1Again, iface2 interface{} = &one, &oneAgain, &two
for _, test := range []struct {
x, y interface{}
want bool
}{
// basic types
{0, 0, true},
{1000000000.9999, 1000000000.0, true}, // almost one part in a billion
{1000000001, 1000000000, false}, // one part in a billion
{uint(1000000011), uint(1000000011), true}, // almost one part in a billion
{1, 1, true},
{1, 2, false}, // different values
{1, 1.0, false}, // different types
{"foo", "foo", true},
{"foo", "bar", false},
{mystring("foo"), "foo", false}, // different types
// slices
{[]string{"foo"}, []string{"foo"}, true},
{[]string{"foo"}, []string{"bar"}, false},
{[]string{}, []string(nil), true},
// slice cycles
{cycleSlice, cycleSlice, true},
// maps
{
map[string][]int{"foo": {1, 2, 3}},
map[string][]int{"foo": {1, 2, 3}},
true,
},
{
map[string][]int{"foo": {1, 2, 3}},
map[string][]int{"foo": {1, 2, 3, 4}},
false,
},
{
map[string][]int{},
map[string][]int(nil),
true,
},
// pointers
{&one, &one, true},
{&one, &two, false},
{&one, &oneAgain, true},
{new(bytes.Buffer), new(bytes.Buffer), true},
// pointer cycles
{cyclePtr1, cyclePtr1, true},
{cyclePtr2, cyclePtr2, true},
{cyclePtr1, cyclePtr2, true}, // they're deeply equal
// functions
{(func())(nil), (func())(nil), true},
{(func())(nil), func() {}, false},
{func() {}, func() {}, false},
// arrays
{[...]int{1, 2, 3}, [...]int{1, 2, 3}, true},
{[...]int{1, 2, 3}, [...]int{1, 2, 4}, false},
// channels
{ch1, ch1, true},
{ch1, ch2, false},
{ch1ro, ch1, false}, // NOTE: not equal
// interfaces
{&iface1, &iface1, true},
{&iface1, &iface2, false},
{&iface1Again, &iface1, true},
} {
if Equalish(test.x, test.y) != test.want {
t.Errorf("Equalish(%#v, %#v) = %t",
test.x, test.y, !test.want)
}
}
}
func Example_equal() {
//!+
fmt.Println(Equalish([]int{1, 2, 3}, []int{1, 2, 3})) // "true"
fmt.Println(Equalish([]string{"foo"}, []string{"bar"})) // "false"
fmt.Println(Equalish([]string(nil), []string{})) // "true"
fmt.Println(Equalish(map[string]int(nil), map[string]int{})) // "true"
//!-
// Output:
// true
// false
// true
// true
}
func Example_equalCycle() {
//!+cycle
// Circular linked lists a -> b -> a and c -> c.
type link struct {
value string
tail *link
}
a, b, c := &link{value: "a"}, &link{value: "b"}, &link{value: "c"}
a.tail, b.tail, c.tail = b, a, c
fmt.Println(Equalish(a, a)) // "true"
fmt.Println(Equalish(b, b)) // "true"
fmt.Println(Equalish(c, c)) // "true"
fmt.Println(Equalish(a, b)) // "false"
fmt.Println(Equalish(a, c)) // "false"
//!-cycle
// Output:
// true
// true
// true
// false
// false
}