...

Source file src/github.com/google/go-cmp/cmp/internal/value/sort_test.go

Documentation: github.com/google/go-cmp/cmp/internal/value

     1  // Copyright 2017, The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     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 // Set of keys to sort
    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  		// NaN values cannot be properly deduplicated.
   123  		// This is okay since map entries with NaN in the keys cannot be
   124  		// retrieved anyways.
   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  		// Intentionally pass the map via an unexported field to detect panics.
   144  		// Unfortunately, we cannot actually test the keys without using unsafe.
   145  		v := reflect.ValueOf(struct{ x map[interface{}]bool }{tt.in}).Field(0)
   146  		value.SortKeys(append(v.MapKeys(), v.MapKeys()...))
   147  
   148  		// Try again, with keys that have read-write access in reflect.
   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