1
2
3
4
5 package value_test
6
7 import (
8 "math"
9 "reflect"
10 "testing"
11
12 "github.com/google/go-cmp/cmp"
13 "github.com/google/go-cmp/cmp/internal/value"
14 )
15
16 func TestSortKeys(t *testing.T) {
17 type (
18 MyString string
19 MyArray [2]int
20 MyStruct struct {
21 A MyString
22 B MyArray
23 C chan float64
24 }
25 EmptyStruct struct{}
26 )
27
28 opts := []cmp.Option{
29 cmp.Comparer(func(x, y float64) bool {
30 if math.IsNaN(x) && math.IsNaN(y) {
31 return true
32 }
33 return x == y
34 }),
35 cmp.Comparer(func(x, y complex128) bool {
36 rx, ix, ry, iy := real(x), imag(x), real(y), imag(y)
37 if math.IsNaN(rx) && math.IsNaN(ry) {
38 rx, ry = 0, 0
39 }
40 if math.IsNaN(ix) && math.IsNaN(iy) {
41 ix, iy = 0, 0
42 }
43 return rx == ry && ix == iy
44 }),
45 cmp.Comparer(func(x, y chan bool) bool { return true }),
46 cmp.Comparer(func(x, y chan int) bool { return true }),
47 cmp.Comparer(func(x, y chan float64) bool { return true }),
48 cmp.Comparer(func(x, y chan interface{}) bool { return true }),
49 cmp.Comparer(func(x, y *int) bool { return true }),
50 }
51
52 tests := []struct {
53 in map[interface{}]bool
54 want []interface{}
55 }{{
56 in: map[interface{}]bool{1: true, 2: true, 3: true},
57 want: []interface{}{1, 2, 3},
58 }, {
59 in: map[interface{}]bool{
60 nil: true,
61 true: true,
62 false: true,
63 -5: true,
64 -55: true,
65 -555: true,
66 uint(1): true,
67 uint(11): true,
68 uint(111): true,
69 "abc": true,
70 "abcd": true,
71 "abcde": true,
72 "foo": true,
73 "bar": true,
74 MyString("abc"): true,
75 MyString("abcd"): true,
76 MyString("abcde"): true,
77 new(int): true,
78 new(int): true,
79 make(chan bool): true,
80 make(chan bool): true,
81 make(chan int): true,
82 make(chan interface{}): true,
83 math.Inf(+1): true,
84 math.Inf(-1): true,
85 1.2345: true,
86 12.345: true,
87 123.45: true,
88 1234.5: true,
89 0 + 0i: true,
90 1 + 0i: true,
91 2 + 0i: true,
92 0 + 1i: true,
93 0 + 2i: true,
94 0 + 3i: true,
95 [2]int{2, 3}: true,
96 [2]int{4, 0}: true,
97 [2]int{2, 4}: true,
98 MyArray([2]int{2, 4}): true,
99 EmptyStruct{}: true,
100 MyStruct{
101 "bravo", [2]int{2, 3}, make(chan float64),
102 }: true,
103 MyStruct{
104 "alpha", [2]int{3, 3}, make(chan float64),
105 }: true,
106 },
107 want: []interface{}{
108 nil, false, true,
109 -555, -55, -5, uint(1), uint(11), uint(111),
110 math.Inf(-1), 1.2345, 12.345, 123.45, 1234.5, math.Inf(+1),
111 (0 + 0i), (0 + 1i), (0 + 2i), (0 + 3i), (1 + 0i), (2 + 0i),
112 [2]int{2, 3}, [2]int{2, 4}, [2]int{4, 0}, MyArray([2]int{2, 4}),
113 make(chan bool), make(chan bool), make(chan int), make(chan interface{}),
114 new(int), new(int),
115 "abc", "abcd", "abcde", "bar", "foo",
116 MyString("abc"), MyString("abcd"), MyString("abcde"),
117 EmptyStruct{},
118 MyStruct{"alpha", [2]int{3, 3}, make(chan float64)},
119 MyStruct{"bravo", [2]int{2, 3}, make(chan float64)},
120 },
121 }, {
122
123
124
125 in: map[interface{}]bool{
126 math.NaN(): true,
127 math.NaN(): true,
128 complex(0, math.NaN()): true,
129 complex(0, math.NaN()): true,
130 complex(math.NaN(), 0): true,
131 complex(math.NaN(), 0): true,
132 complex(math.NaN(), math.NaN()): true,
133 },
134 want: []interface{}{
135 math.NaN(),
136 complex(math.NaN(), math.NaN()),
137 complex(math.NaN(), 0),
138 complex(0, math.NaN()),
139 },
140 }}
141
142 for i, tt := range tests {
143
144
145 v := reflect.ValueOf(struct{ x map[interface{}]bool }{tt.in}).Field(0)
146 value.SortKeys(append(v.MapKeys(), v.MapKeys()...))
147
148
149 v = reflect.ValueOf(tt.in)
150 keys := append(v.MapKeys(), v.MapKeys()...)
151 var got []interface{}
152 for _, k := range value.SortKeys(keys) {
153 got = append(got, k.Interface())
154 }
155 if d := cmp.Diff(got, tt.want, opts...); d != "" {
156 t.Errorf("test %d, Sort() mismatch (-got +want):\n%s", i, d)
157 }
158 }
159 }
160
View as plain text