Source file
src/cmp/cmp_test.go
Documentation: cmp
1
2
3
4
5 package cmp_test
6
7 import (
8 "cmp"
9 "fmt"
10 "math"
11 "slices"
12 "sort"
13 "testing"
14 "unsafe"
15 )
16
17 var negzero = math.Copysign(0, -1)
18 var nonnilptr uintptr = uintptr(unsafe.Pointer(&negzero))
19 var nilptr uintptr = uintptr(unsafe.Pointer(nil))
20
21 var tests = []struct {
22 x, y any
23 compare int
24 }{
25 {1, 2, -1},
26 {1, 1, 0},
27 {2, 1, +1},
28 {"a", "aa", -1},
29 {"a", "a", 0},
30 {"aa", "a", +1},
31 {1.0, 1.1, -1},
32 {1.1, 1.1, 0},
33 {1.1, 1.0, +1},
34 {math.Inf(1), math.Inf(1), 0},
35 {math.Inf(-1), math.Inf(-1), 0},
36 {math.Inf(-1), 1.0, -1},
37 {1.0, math.Inf(-1), +1},
38 {math.Inf(1), 1.0, +1},
39 {1.0, math.Inf(1), -1},
40 {math.NaN(), math.NaN(), 0},
41 {0.0, math.NaN(), +1},
42 {math.NaN(), 0.0, -1},
43 {math.NaN(), math.Inf(-1), -1},
44 {math.Inf(-1), math.NaN(), +1},
45 {0.0, 0.0, 0},
46 {negzero, negzero, 0},
47 {negzero, 0.0, 0},
48 {0.0, negzero, 0},
49 {negzero, 1.0, -1},
50 {negzero, -1.0, +1},
51 {nilptr, nonnilptr, -1},
52 {nonnilptr, nilptr, 1},
53 {nonnilptr, nonnilptr, 0},
54 }
55
56 func TestLess(t *testing.T) {
57 for _, test := range tests {
58 var b bool
59 switch test.x.(type) {
60 case int:
61 b = cmp.Less(test.x.(int), test.y.(int))
62 case string:
63 b = cmp.Less(test.x.(string), test.y.(string))
64 case float64:
65 b = cmp.Less(test.x.(float64), test.y.(float64))
66 case uintptr:
67 b = cmp.Less(test.x.(uintptr), test.y.(uintptr))
68 }
69 if b != (test.compare < 0) {
70 t.Errorf("Less(%v, %v) == %t, want %t", test.x, test.y, b, test.compare < 0)
71 }
72 }
73 }
74
75 func TestCompare(t *testing.T) {
76 for _, test := range tests {
77 var c int
78 switch test.x.(type) {
79 case int:
80 c = cmp.Compare(test.x.(int), test.y.(int))
81 case string:
82 c = cmp.Compare(test.x.(string), test.y.(string))
83 case float64:
84 c = cmp.Compare(test.x.(float64), test.y.(float64))
85 case uintptr:
86 c = cmp.Compare(test.x.(uintptr), test.y.(uintptr))
87 }
88 if c != test.compare {
89 t.Errorf("Compare(%v, %v) == %d, want %d", test.x, test.y, c, test.compare)
90 }
91 }
92 }
93
94 func TestSort(t *testing.T) {
95
96
97 input := []float64{1.0, 0.0, negzero, math.Inf(1), math.Inf(-1), math.NaN()}
98 sort.Float64s(input)
99 for i := 0; i < len(input)-1; i++ {
100 if cmp.Less(input[i+1], input[i]) {
101 t.Errorf("Less sort mismatch at %d in %v", i, input)
102 }
103 if cmp.Compare(input[i], input[i+1]) > 0 {
104 t.Errorf("Compare sort mismatch at %d in %v", i, input)
105 }
106 }
107 }
108
109 func TestOr(t *testing.T) {
110 cases := []struct {
111 in []int
112 want int
113 }{
114 {nil, 0},
115 {[]int{0}, 0},
116 {[]int{1}, 1},
117 {[]int{0, 2}, 2},
118 {[]int{3, 0}, 3},
119 {[]int{4, 5}, 4},
120 {[]int{0, 6, 7}, 6},
121 }
122 for _, tc := range cases {
123 if got := cmp.Or(tc.in...); got != tc.want {
124 t.Errorf("cmp.Or(%v) = %v; want %v", tc.in, got, tc.want)
125 }
126 }
127 }
128
129 func ExampleOr() {
130
131
132 userInput1 := ""
133 userInput2 := "some text"
134
135 fmt.Println(cmp.Or(userInput1, "default"))
136 fmt.Println(cmp.Or(userInput2, "default"))
137 fmt.Println(cmp.Or(userInput1, userInput2, "default"))
138
139
140
141
142 }
143
144 func ExampleOr_sort() {
145 type Order struct {
146 Product string
147 Customer string
148 Price float64
149 }
150 orders := []Order{
151 {"foo", "alice", 1.00},
152 {"bar", "bob", 3.00},
153 {"baz", "carol", 4.00},
154 {"foo", "alice", 2.00},
155 {"bar", "carol", 1.00},
156 {"foo", "bob", 4.00},
157 }
158
159 slices.SortFunc(orders, func(a, b Order) int {
160 return cmp.Or(
161 cmp.Compare(a.Customer, b.Customer),
162 cmp.Compare(a.Product, b.Product),
163 cmp.Compare(b.Price, a.Price),
164 )
165 })
166 for _, order := range orders {
167 fmt.Printf("%s %s %.2f\n", order.Product, order.Customer, order.Price)
168 }
169
170
171
172
173
174
175
176
177 }
178
View as plain text