github.com/jmigpin/editor@v1.6.0/core/godebug/debug/stringify_test.go (about) 1 package debug 2 3 import ( 4 "regexp" 5 "testing" 6 "unsafe" 7 ) 8 9 func TestStringify(t *testing.T) { 10 a := int(1) 11 runTest1(t, a, "1") 12 13 b := int(1) 14 //runTest1(t, &b, "@0x.*") 15 runTest1(t, &b, "&1") 16 17 var c *int 18 runTest1(t, c, "nil") 19 runTest1(t, &c, "&nil") 20 } 21 22 func TestStringifyPtr2(t *testing.T) { 23 type St1 struct { 24 a int 25 B int 26 } 27 var a St1 28 runTest1(t, &a, "&St1{0 0}") 29 //runTest1(t, &a, "&{0 0}") 30 } 31 32 func TestStringifyPtr3(t *testing.T) { 33 type St1 struct { 34 a int 35 B int 36 } 37 var v1 *St1 38 runTest1(t, v1, "nil") 39 40 v2 := &St1{2, 3} 41 runTest1(t, v2, "&St1{2 3}") 42 //runTest1(t, v2, "&{2 3}") 43 44 v3 := &v2 45 //runTest1(t, &v3, "@0x.*") 46 runTest1(t, &v3, "&&&St1{2 3}") 47 //runTest1(t, &v3, "&&&{2 3}") 48 } 49 50 func TestStringifyUintptr(t *testing.T) { 51 type Handle uintptr 52 a := Handle(0) 53 runTest1(t, a, "0x0") 54 b := Handle(1) 55 runTest1(t, b, "0x1") 56 } 57 58 func TestStringifyMap(t *testing.T) { 59 //a := map[string]int{"a": 1, "b": 2} 60 //runTest1(t, a, "map[\"a\":1 \"b\":2]") // TODO: key order 61 } 62 63 func TestStringifySlice(t *testing.T) { 64 type S1 struct { 65 a int 66 B int 67 } 68 a := []*S1{{1, 2}, {3, 4}, {5, 6}} 69 runTest1(t, a, "[&{1 2} &{3 4} &{5 6}]") 70 runTest1(t, a[1:1], "[]") 71 runTest1(t, a[1:2], "[&{3 4}]") 72 73 b := []*S1{nil, nil} 74 runTest1(t, b, "[nil nil]") 75 } 76 77 func TestStringifySlice2(t *testing.T) { 78 type S1 struct { 79 a int 80 B int 81 c interface{} 82 } 83 a := []*S1{{1, 2, 10}, {3, 4, true}} 84 runTest1(t, a, "[&{1 2 10} &{3 4 true}]") 85 86 type S2 struct{ b bool } 87 b := []*S1{{1, 2, S2{true}}, {3, 4, &S2{false}}} 88 //runTest1(t, b, "@\\[&{1 2 S2{true}} &{3 4 0x.*]") 89 //runTest2(t, b, "@\\[&{1 2 S2{true}} &{3 4 0x.*]", 150, 5) 90 runTest2(t, b, "@\\[&{1 2 S2{true}} &{3 4 &S2{...}}]", 100, 5) 91 runTest2(t, b, "[&{1 2 S2{true}} &{3 4 &S2{false}}]", 50, 10) 92 93 c := []*S1{{c: &S1{c: &S2{true}}}} 94 //runTest1(t, c, "@\\[&{0 0 0x.*}]") 95 runTest2(t, c, "[&{0 0 &S1{...}}]", 100, 4) 96 runTest2(t, c, "[&{0 0 &S1{0 0 &S2{true}}}]", 50, 10) 97 } 98 99 func TestStringifyArray(t *testing.T) { 100 type S1 struct { 101 a int 102 B int 103 } 104 a := [...]*S1{{1, 2}, {3, 4}, {5, 6}} 105 runTest1(t, a, "[&{1 2} &{3 4} &{5 6}]") 106 } 107 108 func TestStringifyInterface(t *testing.T) { 109 type S1 struct { 110 a int 111 B int 112 c interface{} 113 } 114 var a interface{} = &S1{1, 2, 3} 115 runTest1(t, a, "&S1{1 2 3}") 116 runTest1(t, &a, "&&S1{1 2 3}") 117 var c = &S1{1, 2, 3} 118 runTest1(t, c, "&S1{1 2 3}") 119 120 var b interface{} = &a 121 runTest1(t, b, "&&S1{1 2 3}") 122 } 123 124 func TestStringifyChan(t *testing.T) { 125 a := make(chan int) 126 runTest1(t, a, "@0x.*") 127 var b chan int 128 runTest1(t, &b, "&0x0") 129 var c *chan int 130 runTest1(t, c, "nil") 131 var d *chan int 132 runTest1(t, &d, "&nil") 133 } 134 135 func TestStringifyUnsafePointer(t *testing.T) { 136 a := 5 137 b := unsafe.Pointer(&a) 138 runTest1(t, b, "@0x.*") 139 } 140 141 func TestStringifyBytes(t *testing.T) { 142 a := []byte("abc") 143 runTest1(t, a, "[97 98 99]") 144 145 a2 := []byte{} 146 runTest1(t, a2, "[]") 147 148 b := []byte{1, 2, 3, 'a'} 149 runTest1(t, b, "[1 2 3 97]") 150 //runTest2(t, b, "[1 2 ...]", 2, 3) 151 runTest2(t, b, "[1 2 ...]", 4, 3) 152 153 type S1 struct { 154 a []byte 155 } 156 c := &S1{[]byte{1, 2, 3}} 157 runTest1(t, c, "&S1{[1 2 3]}") 158 159 //d := []byte{1, 2, 3} 160 //println(d) 161 //fmt.Printf("%v\n", d) 162 //fmt.Printf("%s\n", d) 163 } 164 165 func TestStringifyBytes2(t *testing.T) { 166 b := []byte{'a', 'b', 'c'} 167 for i := 0; i < 10; i++ { 168 b = append(b, b...) 169 } 170 runTest3(t, b, "\"abcabcabc...\"", 10, 5, true) 171 } 172 173 func TestStringifyBytes3(t *testing.T) { 174 type t1 struct { 175 b []byte 176 } 177 v1 := &t1{} 178 runTest3(t, v1, "&t1{\"\"}", 100, 55, true) 179 180 v2 := &t1{b: []byte("abc")} 181 runTest3(t, v2, "&t1{\"abc\"}", 100, 55, true) 182 } 183 184 func TestStringifyBytes4(t *testing.T) { 185 type t3 []byte 186 type t2 struct { 187 t3 t3 188 } 189 type t1 struct { 190 b []byte 191 t2 t2 192 } 193 v1 := &t1{} 194 runTest3(t, v1, "&t1{\"\" {\"\"}}", 100, 55, true) 195 } 196 197 func TestStringifyString(t *testing.T) { 198 b := []byte{'a', 'b', 'c'} 199 for i := 0; i < 10; i++ { 200 b = append(b, b...) 201 } 202 c := string(b) 203 runTest2(t, c, "\"abcabcabc...\"", 10, 5) 204 } 205 206 func TestStringifyRunes(t *testing.T) { 207 b := []byte{'a', 'b', 'c'} 208 for i := 0; i < 10; i++ { 209 b = append(b, b...) 210 } 211 c := []rune(string(b)) 212 runTest3(t, c, "\"abcabcabc...\"", 10, 5, true) 213 } 214 215 func TestStringifyNilReceiver(t *testing.T) { 216 var p *Dummy1 217 runTest1(t, p, "nil") 218 219 a := uintptr(0) 220 var b *Dummy1 = (*Dummy1)(unsafe.Pointer(a)) 221 runTest1(t, b, "nil") 222 223 a = uintptr(1) 224 b = (*Dummy1)(unsafe.Pointer(a)) 225 //runTest1(t, b, "(PANIC:String())") 226 runTest1(t, b, "&Dummy1{\"\"PANIC}") 227 } 228 229 func TestStringifyStringError(t *testing.T) { 230 v1 := &Dummy1{"aa"} 231 runTest1(t, v1, "&Dummy1{\"aa\"}") 232 233 v2 := &Dummy2{"bb"} 234 runTest1(t, v2, "&Dummy2{\"bb\"}") 235 } 236 237 func TestStringifyNil(t *testing.T) { 238 a := interface{}(nil) 239 runTest1(t, a, "nil") 240 runTest1(t, &a, "&nil") 241 } 242 243 //---------- 244 245 //func TestSliceCut(t *testing.T) { 246 // b1 := []interface{}{} 247 // for i := 0; i < 50; i++ { 248 // b1 = append(b1, i) 249 // } 250 // t.Logf("%0.5v\n", b1) // not trimmed 251 // t.Logf("%0.5q\n", b1) 252 // t.Logf("%0.5x\n", b1) 253 // t.Logf("%0.5s\n", b1) 254 // t.Logf("%0.2v\n", true) 255 //} 256 257 //---------- 258 259 func runTest1(t *testing.T, v interface{}, out string) { 260 t.Helper() 261 runTest2(t, v, out, 0, 0) 262 } 263 func runTest2(t *testing.T, v interface{}, out string, max, maxDepth int) { 264 t.Helper() 265 runTest3(t, v, out, max, maxDepth, false) 266 } 267 func runTest3(t *testing.T, v interface{}, out string, max, maxDepth int, sbr bool) { 268 t.Helper() 269 s2 := "" 270 if max == 0 && maxDepth == 0 { 271 // use production values 272 s2 = stringifyV3(v) 273 } else { 274 p := newPrint3(max, maxDepth, sbr) 275 p.do(v) 276 s2 = p.ToString() 277 } 278 279 // support regular expression match if starting with @ 280 res := false 281 if len(out) > 0 && out[0] == '@' { 282 out = out[1:] 283 m, err := regexp.MatchString("^"+out+"$", s2) 284 if err != nil { 285 panic(err) 286 } 287 res = m 288 } else { 289 res = s2 == out 290 } 291 292 if !res { 293 t.Fatalf("got %q expecting %q", s2, out) 294 } 295 } 296 297 //---------- 298 299 type Dummy1 struct{ s string } 300 301 func (d *Dummy1) String() string { return d.s } 302 303 type Dummy2 struct{ s string } 304 305 func (d *Dummy2) Error() string { return d.s }