github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/testing/checkers/deepequal_test.go (about) 1 // Copied with small adaptations from the reflect package in the 2 // Go source tree. We use testing rather than gocheck to preserve 3 // as much source equivalence as possible. 4 5 // TODO tests for error messages 6 7 // Copyright 2009 The Go Authors. All rights reserved. 8 // Use of this source code is governed by a BSD-style 9 // license that can be found in the LICENSE file. 10 11 package checkers_test 12 13 import ( 14 "regexp" 15 "testing" 16 17 "launchpad.net/juju-core/testing/checkers" 18 ) 19 20 func deepEqual(a1, a2 interface{}) bool { 21 ok, _ := checkers.DeepEqual(a1, a2) 22 return ok 23 } 24 25 type Basic struct { 26 x int 27 y float32 28 } 29 30 type NotBasic Basic 31 32 type DeepEqualTest struct { 33 a, b interface{} 34 eq bool 35 msg string 36 } 37 38 // Simple functions for DeepEqual tests. 39 var ( 40 fn1 func() // nil. 41 fn2 func() // nil. 42 fn3 = func() { fn1() } // Not nil. 43 ) 44 45 var deepEqualTests = []DeepEqualTest{ 46 // Equalities 47 {nil, nil, true, ""}, 48 {1, 1, true, ""}, 49 {int32(1), int32(1), true, ""}, 50 {0.5, 0.5, true, ""}, 51 {float32(0.5), float32(0.5), true, ""}, 52 {"hello", "hello", true, ""}, 53 {make([]int, 10), make([]int, 10), true, ""}, 54 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true, ""}, 55 {Basic{1, 0.5}, Basic{1, 0.5}, true, ""}, 56 {error(nil), error(nil), true, ""}, 57 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true, ""}, 58 {fn1, fn2, true, ""}, 59 60 // Inequalities 61 {1, 2, false, `mismatch at top level: unequal; obtained 1; expected 2`}, 62 {int32(1), int32(2), false, `mismatch at top level: unequal; obtained 1; expected 2`}, 63 {0.5, 0.6, false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`}, 64 {float32(0.5), float32(0.6), false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`}, 65 {"hello", "hey", false, `mismatch at top level: unequal; obtained "hello"; expected "hey"`}, 66 {make([]int, 10), make([]int, 11), false, `mismatch at top level: length mismatch, 10 vs 11; obtained \[\]int\{0, 0, 0, 0, 0, 0, 0, 0, 0, 0\}; expected \[\]int\{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\}`}, 67 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false, `mismatch at \(\*\)\[2\]: unequal; obtained 3; expected 4`}, 68 {Basic{1, 0.5}, Basic{1, 0.6}, false, `mismatch at \.y: unequal; obtained 0\.5; expected 0\.6`}, 69 {Basic{1, 0}, Basic{2, 0}, false, `mismatch at \.x: unequal; obtained 1; expected 2`}, 70 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at \[3\]: validity mismatch; obtained "two"; expected <nil>`}, 71 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at \[2\]: unequal; obtained "txo"; expected "two"`}, 72 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at top level: length mismatch, 1 vs 2; obtained map\[int\]string\{1:"one"\}; expected map\[int\]string\{2:"two", 1:"one"\}`}, 73 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false, `mismatch at top level: length mismatch, 2 vs 1; obtained map\[int\]string\{2:"two", 1:"one"\}; expected map\[int\]string\{1:"one"\}`}, 74 {nil, 1, false, `mismatch at top level: nil vs non-nil mismatch; obtained <nil>; expected 1`}, 75 {1, nil, false, `mismatch at top level: nil vs non-nil mismatch; obtained 1; expected <nil>`}, 76 {fn1, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(nil\); expected \(func\(\)\)\(0x[0-9a-f]+\)`}, 77 {fn3, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(0x[0-9a-f]+\); expected \(func\(\)\)\(0x[0-9a-f]+\)`}, 78 79 // Nil vs empty: they're the same (difference from normal DeepEqual) 80 {[]int{}, []int(nil), true, ""}, 81 {[]int{}, []int{}, true, ""}, 82 {[]int(nil), []int(nil), true, ""}, 83 84 // Mismatched types 85 {1, 1.0, false, `mismatch at top level: type mismatch int vs float64; obtained 1; expected 1`}, 86 {int32(1), int64(1), false, `mismatch at top level: type mismatch int32 vs int64; obtained 1; expected 1`}, 87 {0.5, "hello", false, `mismatch at top level: type mismatch float64 vs string; obtained 0\.5; expected "hello"`}, 88 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false, `mismatch at top level: type mismatch \[\]int vs \[3\]int; obtained \[\]int\{1, 2, 3\}; expected \[3\]int\{1, 2, 3\}`}, 89 {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false, `mismatch at \(\*\)\[2\]: type mismatch int vs string; obtained 4; expected "s"`}, 90 {Basic{1, 0.5}, NotBasic{1, 0.5}, false, `mismatch at top level: type mismatch checkers_test\.Basic vs checkers_test\.NotBasic; obtained checkers_test\.Basic\{x:1, y:0\.5\}; expected checkers_test\.NotBasic\{x:1, y:0\.5\}`}, 91 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at top level: type mismatch map\[uint\]string vs map\[int\]string; obtained map\[uint\]string\{0x1:"one", 0x2:"two"\}; expected map\[int\]string\{2:"two", 1:"one"\}`}, 92 } 93 94 func TestDeepEqual(t *testing.T) { 95 for _, test := range deepEqualTests { 96 r, err := checkers.DeepEqual(test.a, test.b) 97 if r != test.eq { 98 t.Errorf("deepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq) 99 } 100 if test.eq { 101 if err != nil { 102 t.Errorf("deepEqual(%v, %v): unexpected error message %q when equal", test.a, test.b, err) 103 } 104 } else { 105 if ok, _ := regexp.MatchString(test.msg, err.Error()); !ok { 106 t.Errorf("deepEqual(%v, %v); unexpected error %q, want %q", test.a, test.b, err.Error(), test.msg) 107 } 108 } 109 } 110 } 111 112 type Recursive struct { 113 x int 114 r *Recursive 115 } 116 117 func TestDeepEqualRecursiveStruct(t *testing.T) { 118 a, b := new(Recursive), new(Recursive) 119 *a = Recursive{12, a} 120 *b = Recursive{12, b} 121 if !deepEqual(a, b) { 122 t.Error("deepEqual(recursive same) = false, want true") 123 } 124 } 125 126 type _Complex struct { 127 a int 128 b [3]*_Complex 129 c *string 130 d map[float64]float64 131 } 132 133 func TestDeepEqualComplexStruct(t *testing.T) { 134 m := make(map[float64]float64) 135 stra, strb := "hello", "hello" 136 a, b := new(_Complex), new(_Complex) 137 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} 138 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} 139 if !deepEqual(a, b) { 140 t.Error("deepEqual(complex same) = false, want true") 141 } 142 } 143 144 func TestDeepEqualComplexStructInequality(t *testing.T) { 145 m := make(map[float64]float64) 146 stra, strb := "hello", "helloo" // Difference is here 147 a, b := new(_Complex), new(_Complex) 148 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} 149 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} 150 if deepEqual(a, b) { 151 t.Error("deepEqual(complex different) = true, want false") 152 } 153 } 154 155 type UnexpT struct { 156 m map[int]int 157 } 158 159 func TestDeepEqualUnexportedMap(t *testing.T) { 160 // Check that DeepEqual can look at unexported fields. 161 x1 := UnexpT{map[int]int{1: 2}} 162 x2 := UnexpT{map[int]int{1: 2}} 163 if !deepEqual(&x1, &x2) { 164 t.Error("deepEqual(x1, x2) = false, want true") 165 } 166 167 y1 := UnexpT{map[int]int{2: 3}} 168 if deepEqual(&x1, &y1) { 169 t.Error("deepEqual(x1, y1) = true, want false") 170 } 171 }