github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sortx/intersort_test.go (about) 1 package sortx 2 3 import ( 4 "fmt" 5 "math" 6 "math/rand" 7 "sort" 8 "strings" 9 "testing" 10 ) 11 12 func TestSingleType(t *testing.T) { 13 ptrArray := [2]int{2, 1} 14 chanArray := [2]chan int{make(chan int), make(chan int)} 15 16 tests := []struct { 17 desc string 18 orig interface{} 19 sorted interface{} 20 }{ 21 { 22 // "When applicable, nil compares low" 23 desc: "Nil", 24 orig: []*int{&ptrArray[0], (*int)(nil)}, 25 sorted: []*int{nil, &ptrArray[0]}, 26 }, 27 { 28 // "ints, floats, and strings order by <" 29 desc: "Ints", 30 orig: []int{3, 2, 1}, 31 sorted: []int{1, 2, 3}, 32 }, 33 { 34 // "ints, floats, and strings order by <" 35 desc: "Floats", 36 orig: []float64{3.1, 2.1, 1.1}, 37 sorted: []float64{1.1, 2.1, 3.1}, 38 }, 39 { 40 // "ints, floats, and strings order by <" 41 desc: "Strings", 42 orig: []string{"c", "b", "a"}, 43 sorted: []string{"a", "b", "c"}, 44 }, 45 { 46 // "NaN compares less than non-NaN floats" 47 desc: "NaN", 48 orig: []float64{3.1, 2.1, math.NaN()}, 49 sorted: []float64{math.NaN(), 2.1, 3.1}, 50 }, 51 { 52 // "bool compares false before true" 53 desc: "Bool", 54 orig: []bool{true, false}, 55 sorted: []bool{false, true}, 56 }, 57 { 58 // "Complex compares real, then imaginary" 59 desc: "Complex", 60 orig: []complex128{2 + 1i, 1 + 2i}, 61 sorted: []complex128{1 + 2i, 2 + 1i}, 62 }, 63 { 64 // "Pointers compare by machine address" 65 desc: "Pointers", 66 orig: []*int{&ptrArray[1], &ptrArray[0]}, 67 sorted: []*int{&ptrArray[0], &ptrArray[1]}, 68 }, 69 { 70 // "Channel values compare by machine address" 71 desc: "Channel", 72 orig: []chan int{chanArray[1], chanArray[0]}, 73 sorted: []chan int{chanArray[0], chanArray[1]}, 74 }, 75 { 76 // "Structs compare each field in turn" 77 desc: "Structs", 78 orig: []struct{ x, y int }{{1, 0}, {0, 1}}, 79 sorted: []struct{ x, y int }{{0, 1}, {1, 0}}, 80 }, 81 { 82 // "Arrays compare each element in turn" 83 desc: "Arrays", 84 orig: [][2]int{{1, 0}, {0, 1}}, 85 sorted: [][2]int{{0, 1}, {1, 0}}, 86 }, 87 } 88 for _, test := range tests { 89 t.Run(test.desc, func(t *testing.T) { 90 Sort(test.orig) 91 // can't use reflect.DeepEqual, since NaN != NaN 92 if fmt.Sprint(test.orig) != fmt.Sprint(test.sorted) { 93 t.Fatalf("expected %#v, got %#v", test.sorted, test.orig) 94 } 95 }) 96 } 97 } 98 99 // "Interface values compare first by reflect.Type describing the 100 // concrete type and then by concrete value as described in the 101 // previous rules." 102 func TestMultiType(t *testing.T) { 103 ptrArray := [2]int{2, 1} 104 chanArray := [2]chan int{make(chan int), make(chan int)} 105 106 // Unfortunately, sorting is unpredictable because it compares the machine 107 // addresses of the *reflect.rtype pointers. But we can at least assert that 108 // the result contains all sorted subgroups. 109 groups := [][]interface{}{ 110 {(*int)(nil), &ptrArray[0], &ptrArray[1]}, 111 {1, 2, 3}, 112 {"a", "b", "c"}, 113 {false, true}, 114 {1 + 2i, 2 + 1i}, 115 {chanArray[0], chanArray[1]}, 116 {struct{ x, y int }{0, 1}, struct{ x, y int }{1, 0}}, 117 {[2]int{0, 1}, [2]int{1, 0}}, 118 } 119 120 var elems Slice 121 for _, g := range groups { 122 elems = append(elems, g...) 123 } 124 rand.Shuffle(len(elems), elems.Swap) // nice 125 126 sort.Sort(elems) 127 str := fmt.Sprint(elems) 128 for _, g := range groups { 129 exp := strings.TrimSpace(fmt.Sprintln(g...)) 130 if !strings.Contains(str, exp) { 131 t.Errorf("sorted map should contain %q", exp) 132 } 133 } 134 }