|
- // Copyright 2017, The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE.md file.
-
- package value_test
-
- import (
- "math"
- "reflect"
- "testing"
-
- "github.com/google/go-cmp/cmp"
- "github.com/google/go-cmp/cmp/internal/value"
- )
-
- func TestSortKeys(t *testing.T) {
- type (
- MyString string
- MyArray [2]int
- MyStruct struct {
- A MyString
- B MyArray
- C chan float64
- }
- EmptyStruct struct{}
- )
-
- opts := []cmp.Option{
- cmp.Comparer(func(x, y float64) bool {
- if math.IsNaN(x) && math.IsNaN(y) {
- return true
- }
- return x == y
- }),
- cmp.Comparer(func(x, y complex128) bool {
- rx, ix, ry, iy := real(x), imag(x), real(y), imag(y)
- if math.IsNaN(rx) && math.IsNaN(ry) {
- rx, ry = 0, 0
- }
- if math.IsNaN(ix) && math.IsNaN(iy) {
- ix, iy = 0, 0
- }
- return rx == ry && ix == iy
- }),
- cmp.Comparer(func(x, y chan bool) bool { return true }),
- cmp.Comparer(func(x, y chan int) bool { return true }),
- cmp.Comparer(func(x, y chan float64) bool { return true }),
- cmp.Comparer(func(x, y chan interface{}) bool { return true }),
- cmp.Comparer(func(x, y *int) bool { return true }),
- }
-
- tests := []struct {
- in map[interface{}]bool // Set of keys to sort
- want []interface{}
- }{{
- in: map[interface{}]bool{1: true, 2: true, 3: true},
- want: []interface{}{1, 2, 3},
- }, {
- in: map[interface{}]bool{
- nil: true,
- true: true,
- false: true,
- -5: true,
- -55: true,
- -555: true,
- uint(1): true,
- uint(11): true,
- uint(111): true,
- "abc": true,
- "abcd": true,
- "abcde": true,
- "foo": true,
- "bar": true,
- MyString("abc"): true,
- MyString("abcd"): true,
- MyString("abcde"): true,
- new(int): true,
- new(int): true,
- make(chan bool): true,
- make(chan bool): true,
- make(chan int): true,
- make(chan interface{}): true,
- math.Inf(+1): true,
- math.Inf(-1): true,
- 1.2345: true,
- 12.345: true,
- 123.45: true,
- 1234.5: true,
- 0 + 0i: true,
- 1 + 0i: true,
- 2 + 0i: true,
- 0 + 1i: true,
- 0 + 2i: true,
- 0 + 3i: true,
- [2]int{2, 3}: true,
- [2]int{4, 0}: true,
- [2]int{2, 4}: true,
- MyArray([2]int{2, 4}): true,
- EmptyStruct{}: true,
- MyStruct{
- "bravo", [2]int{2, 3}, make(chan float64),
- }: true,
- MyStruct{
- "alpha", [2]int{3, 3}, make(chan float64),
- }: true,
- },
- want: []interface{}{
- nil, false, true,
- -555, -55, -5, uint(1), uint(11), uint(111),
- math.Inf(-1), 1.2345, 12.345, 123.45, 1234.5, math.Inf(+1),
- (0 + 0i), (0 + 1i), (0 + 2i), (0 + 3i), (1 + 0i), (2 + 0i),
- [2]int{2, 3}, [2]int{2, 4}, [2]int{4, 0}, MyArray([2]int{2, 4}),
- make(chan bool), make(chan bool), make(chan int), make(chan interface{}),
- new(int), new(int),
- "abc", "abcd", "abcde", "bar", "foo",
- MyString("abc"), MyString("abcd"), MyString("abcde"),
- EmptyStruct{},
- MyStruct{"alpha", [2]int{3, 3}, make(chan float64)},
- MyStruct{"bravo", [2]int{2, 3}, make(chan float64)},
- },
- }, {
- // NaN values cannot be properly deduplicated.
- // This is okay since map entries with NaN in the keys cannot be
- // retrieved anyways.
- in: map[interface{}]bool{
- math.NaN(): true,
- math.NaN(): true,
- complex(0, math.NaN()): true,
- complex(0, math.NaN()): true,
- complex(math.NaN(), 0): true,
- complex(math.NaN(), 0): true,
- complex(math.NaN(), math.NaN()): true,
- },
- want: []interface{}{
- math.NaN(),
- complex(math.NaN(), math.NaN()),
- complex(math.NaN(), 0),
- complex(0, math.NaN()),
- },
- }}
-
- for i, tt := range tests {
- // Intentionally pass the map via an unexported field to detect panics.
- // Unfortunately, we cannot actually test the keys without using unsafe.
- v := reflect.ValueOf(struct{ x map[interface{}]bool }{tt.in}).Field(0)
- value.SortKeys(append(v.MapKeys(), v.MapKeys()...))
-
- // Try again, with keys that have read-write access in reflect.
- v = reflect.ValueOf(tt.in)
- keys := append(v.MapKeys(), v.MapKeys()...)
- var got []interface{}
- for _, k := range value.SortKeys(keys) {
- got = append(got, k.Interface())
- }
- if d := cmp.Diff(got, tt.want, opts...); d != "" {
- t.Errorf("test %d, Sort() mismatch (-got +want):\n%s", i, d)
- }
- }
- }
|