github.com/mitranim/gg@v0.1.17/grepr/grepr_test.go (about) 1 package grepr_test 2 3 import ( 4 "fmt" 5 "math" 6 r "reflect" 7 "testing" 8 "unicode/utf8" 9 10 "github.com/mitranim/gg" 11 "github.com/mitranim/gg/grepr" 12 "github.com/mitranim/gg/gtest" 13 ) 14 15 type ( 16 Bool bool 17 Byte uint8 18 Uint16 uint16 19 Uint32 uint32 20 Uint64 uint64 21 Uint uint 22 Int8 int8 23 Int16 int16 24 Int32 int32 25 Int64 int64 26 Int int 27 Float32 float32 28 Float64 float64 29 Complex64 complex64 30 Complex128 complex128 31 Str string 32 ) 33 34 type Struct0 struct{} 35 36 type Struct1 struct{ A int } 37 38 type Struct2 struct { 39 A int 40 B int 41 } 42 43 type Struct1Any struct{ Val any } 44 45 type Outer struct { 46 OuterId int 47 OuterName string 48 Embed 49 Inner *Inner 50 } 51 52 type Embed struct { 53 EmbedId int 54 EmbedName string 55 } 56 57 type Inner struct { 58 InnerId *int 59 InnerName *string 60 } 61 62 type Cyclic struct { 63 Id int 64 Cyclic *Cyclic 65 } 66 67 type GoStringer struct{} 68 69 func (GoStringer) GoString() string { return `MakeGoStringer()` } 70 71 var testInner = Inner{ 72 InnerId: gg.Ptr(30), 73 InnerName: gg.Ptr(`inner`), 74 } 75 76 var testEmbed = Embed{EmbedId: 20} 77 78 var testOuter = Outer{ 79 OuterName: `outer`, 80 Embed: testEmbed, 81 Inner: &testInner, 82 } 83 84 var testOuterStringZero = "grepr_test.Outer{OuterName: `outer`, Embed: grepr_test.Embed{EmbedId: 20}, Inner: &grepr_test.Inner{InnerId: gg.Ptr(30), InnerName: gg.Ptr(`inner`)}}" 85 86 var testOuterStringDef = `grepr_test.Outer{ 87 OuterName: ` + "`outer`" + `, 88 Embed: grepr_test.Embed{EmbedId: 20}, 89 Inner: &grepr_test.Inner{ 90 InnerId: gg.Ptr(30), 91 InnerName: gg.Ptr(` + "`inner`" + `), 92 }, 93 }` 94 95 var testOuterStringDefPkgStrip = `Outer{ 96 OuterName: ` + "`outer`" + `, 97 Embed: Embed{EmbedId: 20}, 98 Inner: &Inner{ 99 InnerId: gg.Ptr(30), 100 InnerName: gg.Ptr(` + "`inner`" + `), 101 }, 102 }` 103 104 /* 105 Replacement for `gtest.Eq` just for this test. `gtest` uses `grepr` to print 106 values. Since we're testing `grepr`, we can't trust it. 107 */ 108 func strEq(act, exp string) { 109 if act != exp { 110 panic(gtest.ErrAt(1, gg.JoinLinesOpt( 111 `unexpected difference`, 112 gtest.Msg(`actual:`, act), 113 gtest.Msg(`expected:`, exp), 114 ))) 115 } 116 } 117 118 func testReprZero[A any](src A, exp string) { 119 testReprC(grepr.Conf{}, src, exp) 120 } 121 122 func testReprDef[A any](src A, exp string) { 123 strEq(grepr.String(src), exp) 124 } 125 126 func testReprC[A any](conf grepr.Conf, src A, exp string) { 127 strEq(grepr.StringC(conf, src), exp) 128 } 129 130 func Test_nil_top(t *testing.T) { 131 defer gtest.Catch(t) 132 133 testReprZero[any](nil, `nil`) 134 testReprZero[*any](nil, `nil`) 135 testReprZero[fmt.Stringer](nil, `nil`) 136 testReprZero[func()](nil, `nil`) 137 testReprZero[[]byte](nil, `nil`) 138 testReprZero[*string](nil, `nil`) 139 testReprZero[map[int]bool](nil, `nil`) 140 } 141 142 func Test_nil_inner(t *testing.T) { 143 defer gtest.Catch(t) 144 145 testReprZero([]any{nil}, `[]any{nil}`) 146 testReprZero([]any{(*any)(nil)}, `[]any{(*any)(nil)}`) 147 testReprZero([]any{(*string)(nil)}, `[]any{(*string)(nil)}`) 148 testReprZero([]any{(func())(nil)}, `[]any{(func())(nil)}`) 149 testReprZero([]any{[]byte(nil)}, `[]any{[]byte(nil)}`) 150 testReprZero([]any{map[int]bool(nil)}, `[]any{map[int]bool(nil)}`) 151 testReprZero([]fmt.Stringer{nil}, `[]fmt.Stringer{nil}`) 152 testReprZero([]fmt.Stringer{(*gg.ErrStr)(nil)}, `[]fmt.Stringer{(*gg.ErrStr)(nil)}`) 153 testReprZero([]func(){nil}, `[]func(){nil}`) 154 testReprZero([][]byte{nil}, `[][]byte{nil}`) 155 } 156 157 func Test_primitives(t *testing.T) { 158 defer gtest.Catch(t) 159 160 { 161 testBoolTop[bool]() 162 testBoolTop[Bool]() 163 164 // `bool` is default type for boolean literals. 165 testReprZero([1]any{false}, `[1]any{false}`) 166 testReprZero([1]any{true}, `[1]any{true}`) 167 168 testReprZero([1]any{Bool(false)}, `[1]any{grepr_test.Bool(false)}`) 169 testReprZero([1]any{Bool(true)}, `[1]any{grepr_test.Bool(true)}`) 170 } 171 172 testByte[uint8](`byte`) 173 testByte[Byte](`grepr_test.Byte`) 174 175 testUint[uint16]() 176 testUint[Uint16]() 177 testUint[uint32]() 178 testUint[Uint32]() 179 testUint[uint64]() 180 testUint[Uint64]() 181 testUint[uint]() 182 testUint[Uint]() 183 184 testSint[int16]() 185 testSint[Int16]() 186 testSint[int32]() 187 testSint[Int32]() 188 testSint[int64]() 189 testSint[Int64]() 190 191 { 192 testSintTop[int]() 193 testSintTop[Int]() 194 testSignedInner[Int]() 195 196 // `int` is default type for integer literals. 197 testReprZero([1]any{0}, `[1]any{0}`) 198 testReprZero([1]any{127}, `[1]any{127}`) 199 testReprZero([1]any{-128}, `[1]any{-128}`) 200 } 201 202 testFloat[float32]() 203 testFloat[Float32]() 204 testFloat[float64]() 205 testFloat[Float64]() 206 207 testComplex[complex64]() 208 testComplex[Complex64]() 209 210 { 211 testComplexTop[complex128]() 212 testComplex[Complex128]() 213 214 // `complex128` is default type for complex literals. 215 testReprZero([1]any{0i}, `[1]any{(0i)}`) 216 testReprZero([1]any{10i + 20}, `[1]any{(20+10i)}`) 217 } 218 219 { 220 testStringTop[string]() 221 testStringTop[Str]() 222 223 // `string` is default type for string literals. 224 testReprZero([1]any{``}, "[1]any{``}") 225 testReprZero([1]any{`str`}, "[1]any{`str`}") 226 227 testReprZero([1]any{Str(``)}, "[1]any{grepr_test.Str(``)}") 228 testReprZero([1]any{Str(`str`)}, "[1]any{grepr_test.Str(`str`)}") 229 } 230 } 231 232 func testBoolTop[A ~bool]() { 233 testReprZero[A](false, `false`) 234 testReprZero[A](true, `true`) 235 } 236 237 func testByte[A ~byte](name string) { 238 testByteTop[A]() 239 testByteInner[A](name) 240 } 241 242 func testByteTop[A ~byte]() { 243 testReprZero[A](0, `0x00`) 244 testReprZero[A](10, `0x0a`) 245 testReprZero[A](15, `0x0f`) 246 testReprZero[A](16, `0x10`) 247 testReprZero[A](17, `0x11`) 248 testReprZero[A](255, `0xff`) 249 } 250 251 func testByteInner[A ~byte](name string) { 252 testReprZero([1]any{A(0)}, `[1]any{`+name+`(0x00)}`) 253 testReprZero([1]any{A(255)}, `[1]any{`+name+`(0xff)}`) 254 } 255 256 func testUint[A gg.Uint]() { 257 testUintTop[A]() 258 testUintInner[A]() 259 } 260 261 func testUintTop[A gg.Uint]() { 262 testReprZero[A](0, `0`) 263 testReprZero[A](10, `10`) 264 testReprZero[A](16, `16`) 265 testReprZero[A](255, `255`) 266 } 267 268 func testUintInner[A gg.Uint]() { 269 name := gg.Type[A]().String() 270 271 testReprZero([1]any{A(0)}, `[1]any{`+name+`(0)}`) 272 testReprZero([1]any{A(255)}, `[1]any{`+name+`(255)}`) 273 } 274 275 func testSint[A gg.Sint]() { 276 testSintTop[A]() 277 testSignedInner[A]() 278 } 279 280 func testSintTop[A gg.Sint]() { 281 testReprZero[A](0, `0`) 282 testReprZero[A](10, `10`) 283 testReprZero[A](16, `16`) 284 testReprZero[A](127, `127`) 285 testReprZero[A](-10, `-10`) 286 testReprZero[A](-16, `-16`) 287 testReprZero[A](-128, `-128`) 288 } 289 290 func testSignedInner[A gg.Signed]() { 291 name := gg.Type[A]().String() 292 293 testReprZero([1]any{A(0)}, `[1]any{`+name+`(0)}`) 294 testReprZero([1]any{A(127)}, `[1]any{`+name+`(127)}`) 295 testReprZero([1]any{A(-128)}, `[1]any{`+name+`(-128)}`) 296 } 297 298 func testFloat[A gg.Float]() { 299 testFloatTop[A]() 300 testSignedInner[A]() 301 } 302 303 func testFloatTop[A gg.Float]() { 304 testReprZero[A](0, `0`) 305 testReprZero[A](-10, `-10`) 306 testReprZero[A](-10.5, `-10.5`) 307 testReprZero[A](10, `10`) 308 testReprZero[A](10.5, `10.5`) 309 testReprZero[A](A(math.NaN()), `math.NaN()`) 310 testReprZero[A](A(math.Inf(0)), `math.Inf(0)`) 311 testReprZero[A](A(math.Inf(1)), `math.Inf(0)`) 312 testReprZero[A](A(math.Inf(-1)), `math.Inf(-1)`) 313 } 314 315 func testComplex[A gg.Complex]() { 316 testComplexTop[A]() 317 testComplexInner[A]() 318 } 319 320 func testComplexTop[A gg.Complex]() { 321 testReprZero[A](10i, `(10i)`) 322 testReprZero[A](-10i, `(-10i)`) 323 testReprZero[A](10i+20, `(20+10i)`) 324 testReprZero[A](-10i+20, `(20-10i)`) 325 testReprZero[A](10i-20, `(-20+10i)`) 326 testReprZero[A](-10i-20, `(-20-10i)`) 327 testReprZero[A](10+20i, `(10+20i)`) 328 testReprZero[A](-10+20i, `(-10+20i)`) 329 testReprZero[A](10-20i, `(10-20i)`) 330 testReprZero[A](-10-20i, `(-10-20i)`) 331 } 332 333 func testComplexInner[A gg.Complex]() { 334 name := gg.Type[A]().String() 335 336 testReprZero([1]any{A(0i)}, `[1]any{`+name+`(0i)}`) 337 testReprZero([1]any{A(10i + 20)}, `[1]any{`+name+`(20+10i)}`) 338 } 339 340 func testStringTop[A ~string]() { 341 testReprZero[A](``, "``") 342 testReprDef[A](``, "``") 343 testString(testReprZero[A], testReprDef[A]) 344 } 345 346 func testString[A gg.Text](testZero, testDef func(A, string)) { 347 testStringPrintable(testZero, testDef) 348 testStringNewlines(testZero, testDef) 349 } 350 351 func testStringPrintable[A gg.Text](testZero, testDef func(A, string)) { 352 testZero(A(`one`), "`one`") 353 testDef(A(`one`), "`one`") 354 355 testZero(A(`one`), "`one`") 356 testDef(A(`one`), "`one`") 357 358 testZero(A(`"one"`), "`\"one\"`") 359 testDef(A(`"one"`), "`\"one\"`") 360 361 testZero(A("`one`"), "\"`one`\"") 362 testDef(A("`one`"), "\"`one`\"") 363 } 364 365 func testStringNewlines[A gg.Text](testZero, testDef func(A, string)) { 366 testZero(A("\n"), `"\n"`) 367 testDef(A("\n"), "`\n`") 368 369 testZero(A("\r"), `"\r"`) 370 testDef(A("\r"), `"\r"`) 371 372 testZero(A("\r\n"), `"\r\n"`) 373 testDef(A("\r\n"), `"\r\n"`) 374 375 testZero(A("one\ntwo"), `"one\ntwo"`) 376 testDef(A("one\ntwo"), "`one\ntwo`") 377 378 testZero(A("one\rtwo"), `"one\rtwo"`) 379 testDef(A("one\rtwo"), `"one\rtwo"`) 380 381 testZero(A("one\r\ntwo"), `"one\r\ntwo"`) 382 testDef(A("one\r\ntwo"), `"one\r\ntwo"`) 383 } 384 385 func Test_bytes(t *testing.T) { 386 defer gtest.Catch(t) 387 388 t.Run(`empty`, func(t *testing.T) { 389 defer gtest.Catch(t) 390 391 testReprZero([]byte(nil), `nil`) 392 testReprZero([]byte{}, `[]byte{}`) 393 }) 394 395 t.Run(`text`, func(t *testing.T) { 396 defer gtest.Catch(t) 397 398 testZero := func(src []byte, exp string) { testReprZero(src, `[]byte(`+exp+`)`) } 399 testDef := func(src []byte, exp string) { testReprDef(src, `[]byte(`+exp+`)`) } 400 testString(testZero, testDef) 401 }) 402 403 t.Run(`unprintable`, func(t *testing.T) { 404 defer gtest.Catch(t) 405 406 testReprZero( 407 []byte(`printable `+"\xff"), 408 `[]byte{0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0xff}`, 409 ) 410 411 testReprZero( 412 []byte(`printable `+"\ufeff"), 413 `[]byte{0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0xef, 0xbb, 0xbf}`, 414 ) 415 416 testReprZero( 417 []byte(`printable `+string(utf8.RuneError)), 418 `[]byte{0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0xef, 0xbf, 0xbd}`, 419 ) 420 }) 421 422 t.Run(`typedef`, func(t *testing.T) { 423 defer gtest.Catch(t) 424 425 testReprZero(gg.Buf(nil), `nil`) 426 testReprZero(gg.Buf{}, `gg.Buf{}`) 427 testReprZero(gg.Buf(`str`), "gg.Buf(`str`)") 428 }) 429 } 430 431 func Benchmark_bytes_hex(b *testing.B) { 432 defer gtest.Catch(b) 433 434 src := []byte{0xf5, 0x92, 0x93, 0xec, 0x38, 0x8f, 0x21, 0xd3, 0x52, 0x5a, 0x09, 0x40, 0xb0, 0x72, 0x97, 0x90, 0x38, 0x4d, 0x1f, 0x52, 0x90, 0x4a, 0xe5, 0x33, 0x06, 0xf2, 0x8b, 0xb1, 0xbd, 0x94, 0xfc, 0x42, 0xf0, 0xdd, 0xcb, 0x77, 0xc5, 0x4f, 0xc9, 0x27, 0x84, 0xca, 0x1b, 0xad, 0xd3, 0x40, 0x3f, 0xf5, 0xcd, 0x0e, 0x6f, 0x43, 0x71, 0x9e, 0xb2, 0x66, 0x2f, 0x8e, 0x0c, 0x00, 0xe3, 0xdc, 0x47, 0x83, 0x65, 0x0f, 0x68, 0xbf, 0xb7, 0x0f, 0x5f, 0x01, 0x25, 0x35, 0x1b, 0xfd, 0xa6, 0xdc, 0x75, 0x63, 0xbf, 0xed, 0xc9, 0x52, 0x6e, 0x4e, 0x0b, 0xb1, 0xa3, 0xb0, 0x89, 0x38, 0xd5, 0x3e, 0xc8, 0xe9, 0x6f, 0x07, 0xf0, 0x11, 0x6e, 0x4a, 0x3a, 0x1f, 0xb7, 0x75, 0xcb, 0x64, 0xb9, 0x2f, 0xc2, 0x23, 0xbe, 0x09, 0x12, 0x67, 0xaf, 0xfa, 0xbb, 0xae, 0x8b, 0x25, 0x6e, 0x4a, 0x53, 0xb4, 0x9e, 0x08, 0xa0, 0x0c, 0x41, 0xfc, 0x7e, 0x8f, 0x57, 0x44, 0xbd, 0x93, 0x04, 0xa3, 0x36, 0xa3, 0x16, 0xf8, 0x9a, 0x1c, 0xd2, 0x01, 0x5b, 0x16, 0x0f, 0x11, 0x82, 0xc8, 0xc0, 0x25, 0xe5, 0x32, 0x3b, 0x63, 0xc0, 0x02, 0x30, 0x10, 0xf5, 0x35, 0x51, 0x80, 0x87, 0x39, 0x7d, 0x73, 0xbe, 0xca, 0xc0, 0x84, 0xcc, 0x69, 0x95, 0x1d, 0xcf, 0x59, 0x53, 0x3d, 0xf4, 0x60, 0x79, 0x44, 0xd2, 0xb4, 0x95, 0x82, 0x81, 0x3e, 0xe6, 0x11, 0xc1, 0xba, 0x85, 0xeb, 0x90, 0xb6, 0x78, 0x7f, 0xd1, 0x56, 0x99, 0xbe, 0xa1, 0xe9, 0x9c, 0xb8, 0x56, 0xc0, 0xd4, 0xcc, 0x16, 0x5a, 0x7e, 0xf2, 0x90, 0xc0, 0x26, 0x05, 0x49, 0x47, 0xf5, 0x49, 0x19, 0x68, 0x96, 0x6e, 0xe9, 0xe1, 0x60, 0x3d, 0x28, 0x18, 0x47, 0xc8, 0x90, 0x95, 0x19, 0xf2, 0xa8, 0xcf, 0x8b, 0x66, 0x51, 0xbe, 0xeb, 0xe7, 0x04, 0x61, 0x71, 0xd8, 0xa3, 0x6c, 0x59, 0x2e, 0xcc, 0x4c, 0xcc, 0xbf, 0xfd, 0x99, 0x26, 0x41, 0x28, 0x15, 0xb6, 0x76, 0x33, 0xad, 0x9f, 0x9d, 0xbc, 0x65, 0xef, 0x1f, 0x2d, 0x92, 0x07, 0xb5, 0x02, 0x52, 0x07, 0xd5, 0x2d, 0x98, 0x86, 0x22, 0x25, 0xd9, 0xae, 0x35, 0x91, 0xae, 0x59, 0x7c, 0xf8, 0xb4, 0xaa, 0xb2, 0xfa, 0xc2, 0xa1, 0x7d, 0x00, 0xea, 0x5d, 0x76, 0xff, 0xb2, 0xa8, 0xa2, 0x93, 0xa0, 0x24, 0xc3, 0xa9, 0x68, 0x84, 0x18, 0xc3, 0x5b, 0x85, 0xd5, 0x57, 0x73, 0xe0, 0xb0, 0xa1, 0xaa, 0xfd, 0xda, 0xb4, 0x5d, 0xb1, 0x3f, 0x0c, 0x3f, 0x8a, 0x80, 0x1c, 0xfe, 0x76, 0x89, 0x6e, 0xa1, 0x7e, 0xa7, 0x94, 0x69, 0x34, 0x54, 0x5a, 0x6f, 0x7a, 0x57, 0x89, 0x72, 0x76, 0x42, 0xc2, 0xa8, 0x1a, 0xda, 0xb9, 0xfc, 0x87, 0xe9, 0x14, 0x3e, 0xda, 0xf0, 0x73, 0x0e, 0xf5, 0xb0, 0x56, 0xf3, 0xd8, 0x89, 0x62, 0x63, 0x50, 0x48, 0x8f, 0xc5, 0x9c, 0x9f, 0x25, 0x92, 0x53, 0xca, 0x6d, 0x14, 0x7c, 0xfc, 0x32, 0x0c, 0x7a, 0x2b, 0x67, 0xd1, 0x0f, 0xc2, 0xcf, 0x97, 0x18, 0xd1, 0xe5, 0x1e, 0x7c, 0xf6, 0xe6, 0x52, 0x33, 0x50, 0xb2, 0xdf, 0xc4, 0x81, 0xcc, 0x3b, 0x20, 0xf7, 0x8b, 0x87, 0xa7, 0x9d, 0x18, 0xf9, 0xa4, 0x6c, 0x4e, 0xab, 0x20, 0xc5, 0x6d, 0x40, 0x22, 0xd9, 0x0a, 0x84, 0xec, 0x70, 0x38, 0x8a, 0x9a, 0x73, 0x95, 0xed, 0xb6, 0xef, 0x85, 0x47, 0x3d, 0x18, 0x9a, 0x3f, 0xab, 0x96, 0x45, 0x86, 0x2b, 0xe7, 0xc4, 0x14, 0x40, 0x92, 0x51, 0x67, 0x2a, 0x9d, 0x87, 0xda, 0x0b, 0x4b, 0xfc, 0x84, 0xfc, 0xe0, 0xb1, 0x3b, 0xb4, 0xf0, 0xbc, 0x67, 0xc3, 0xf1, 0x57, 0x4d, 0xb0, 0xf6, 0xe5, 0x10, 0xa7, 0x10, 0xa0, 0x1e, 0x55, 0xcd, 0x1d, 0x08, 0x3f, 0xe1, 0x19, 0x47, 0xa6, 0x84, 0x1e, 0x4a, 0xec, 0x03, 0xf5, 0x63, 0x59, 0xd8, 0x77, 0xaa, 0x26, 0x54, 0x05, 0xce, 0x50, 0x7d, 0x09, 0x7f, 0x7d, 0xe8, 0xa2, 0xe6, 0xb2, 0x84, 0xaa, 0x59, 0xbe, 0x57, 0x8a, 0xea, 0xd4, 0x97, 0x78, 0xf7, 0xfd, 0x26, 0x17, 0x41, 0x0c, 0x78, 0xae, 0xa2, 0x14, 0x6f, 0xe6, 0x09, 0x36, 0xc8, 0xe4, 0xdf, 0x45, 0x5a, 0x7e, 0x41, 0x82, 0x95, 0x47, 0x9e, 0xb4, 0x38, 0x8f, 0xcb, 0x09, 0xbc, 0xd4, 0x85, 0x96, 0x3c, 0xd3, 0xc0, 0x4f, 0xc5, 0xf1, 0x9c, 0x13, 0xfb, 0x23, 0x39, 0x23, 0x34, 0x40, 0x98, 0x21, 0x22, 0x48, 0x74, 0x7f, 0xb5, 0x4f, 0x41, 0x14, 0x76, 0xfb, 0x81, 0x75, 0x13, 0xcb, 0x3d, 0xfa, 0x8e, 0x7d, 0xa1, 0x36, 0x6a, 0x3f, 0x6b, 0xf2, 0xc8, 0xeb, 0x97, 0x29, 0x0b, 0xa9, 0x8d, 0x06, 0xa8, 0xad, 0x91, 0x66, 0x4a, 0x6d, 0x7a, 0x45, 0x92, 0x1c, 0x07, 0x8a, 0xe2, 0x16, 0x7d, 0xbb, 0xce, 0xec, 0x87, 0xf9, 0x42, 0xa6, 0xf1, 0xce, 0xa7, 0x80, 0xd7, 0x1e, 0xc4, 0x83, 0x14, 0x8f, 0xb3, 0xe7, 0x40, 0x04, 0x26, 0x7c, 0xec, 0x8a, 0x36, 0xad, 0x7b, 0x23, 0x4b, 0xdf, 0x8c, 0xd8, 0x45, 0xcd, 0x07, 0x39, 0x35, 0xf7, 0x2b, 0x98, 0xb2, 0xf9, 0xcc, 0xda, 0x60, 0xb3, 0x86, 0xa8, 0xee, 0xda, 0xbd, 0x5a, 0xc0, 0x50, 0x5a, 0x92, 0xf1, 0x9d, 0xc2, 0x6b, 0x85, 0xa6, 0x65, 0xe5, 0x25, 0xb8, 0xcb, 0xca, 0x72, 0x6a, 0x1a, 0x33, 0x1d, 0x2b, 0x73, 0xf2, 0xe9, 0xa9, 0x20, 0x85, 0x16, 0x46, 0xe2, 0x21, 0x9c, 0xe2, 0x2d, 0x77, 0xec, 0x98, 0x51, 0x9d, 0x91, 0x9d, 0xf9, 0x0a, 0xb0, 0xd4, 0x76, 0xd2, 0xb4, 0xa2, 0x26, 0x34, 0x6f, 0x40, 0xad, 0xd9, 0x23, 0xb8, 0x2d, 0xa9, 0x12, 0x00, 0xfe, 0x37, 0x2b, 0xc4, 0x78, 0x81, 0xa8, 0xfe, 0x0e, 0x0d, 0xe5, 0x00, 0x9b, 0xc0, 0x71, 0x46, 0x24, 0xe4, 0xc8, 0x39, 0x28, 0xad, 0x9c, 0xeb, 0x84, 0xb4, 0x47, 0x56, 0xe9, 0xa5, 0x9b, 0x60, 0x02, 0xb9, 0x90, 0x45, 0x70, 0x49, 0x18, 0x8c, 0x38, 0xce, 0xc7, 0x0b, 0xb5, 0xf3, 0xc5, 0xcb, 0xba, 0x8f, 0xe6, 0xb2, 0xb7, 0xb5, 0xc1, 0x53, 0x3d, 0x9c, 0x51, 0x10, 0x7e, 0xc5, 0xd7, 0x3a, 0x8e, 0x2a, 0xad, 0xbb, 0x4a, 0x8f, 0x76, 0x80, 0x7c, 0x9d, 0x5c, 0x94, 0x54, 0xf9, 0x6c, 0x4c, 0xbb, 0x25, 0x29, 0x3c, 0x85, 0xc6, 0x6f, 0xc7, 0x5e, 0xb0, 0x77, 0x22, 0x94, 0xc8, 0x91, 0x56, 0xdd, 0x04, 0x31, 0x90, 0x68, 0xdc, 0x20, 0x5a, 0xd8, 0xc1, 0xf3, 0x19, 0x88, 0xd9, 0x44, 0x27, 0x82, 0xd3, 0xe5, 0x5b, 0xd2, 0x0c, 0x06, 0x6c, 0xc4, 0xdd, 0xd5, 0x65, 0xd1, 0x22, 0xa1, 0x03, 0x51, 0x1c, 0x9a, 0xf1, 0x41, 0x2c, 0x3a, 0x30, 0x03, 0x8e, 0x57, 0x5d, 0x37, 0x9f, 0x56, 0x0d, 0xc0, 0xbf, 0xd5, 0x18, 0xe1, 0xef, 0xae, 0xa6, 0xf8, 0x3c, 0x92, 0xc3, 0x7d, 0x47, 0xa5, 0x45, 0x9f, 0xf2, 0x02, 0xda, 0xa4, 0xfe, 0xdc, 0x59, 0x2c, 0x15, 0xdc, 0x06, 0x3c, 0xbf, 0x01, 0x82, 0x72, 0x45, 0xc2, 0xa6, 0x26, 0x8a, 0xa0, 0xea, 0xe5, 0xf2, 0x5c, 0xd9, 0xac, 0xb0, 0x60, 0x66, 0x60, 0x25, 0xad, 0xc5, 0x75, 0x05, 0x9a, 0x85, 0x34, 0x0e, 0xac, 0x2e, 0xd2, 0x0f, 0xcb, 0xea, 0x35, 0x4f, 0xe8, 0x13, 0x0b, 0x0d, 0xfe, 0x48, 0x44, 0x48, 0x25, 0xea, 0x31, 0x56, 0x2d, 0x16, 0x4d, 0x2d, 0xc8, 0xd6, 0x8e, 0xeb, 0xb8, 0x74, 0x9e, 0x6d, 0x5f, 0x0a, 0x10, 0x70, 0x72, 0xb9, 0xec, 0x6e, 0x58, 0xc9, 0x43, 0xde, 0x5c, 0xa6, 0xf0, 0x1f, 0x78, 0x23, 0x3e, 0x3f, 0xe5, 0xbd, 0xf0, 0xb2, 0x6d, 0xa5, 0x1f, 0x90, 0x9a, 0x77, 0x48, 0x58, 0xa3, 0x8b, 0x34, 0x61, 0x75, 0x67, 0x52, 0x9f, 0x36, 0x1e, 0xa8, 0x52, 0x77, 0xbb, 0x05, 0x1c, 0xe9, 0xd1, 0xf7, 0x75, 0xae, 0xd5, 0xd2, 0xf7, 0x32, 0x5a, 0xa7, 0xa5, 0x8b, 0xc7, 0xda, 0x50, 0x8c, 0x33, 0x07, 0x80, 0xb5, 0xeb, 0xb3, 0xed, 0x17, 0xe2, 0x44, 0x65, 0x2a, 0x5c, 0x20, 0xe8, 0x45, 0xfd, 0x03, 0x06, 0xd8, 0xd9, 0x98, 0xc8, 0x04, 0x1a, 0xcb, 0x25, 0x8e, 0xa6, 0xb5, 0x0b, 0xa8, 0xcb, 0x2b, 0x56, 0xea, 0x08, 0x86, 0xf2, 0x4c, 0x60, 0xc9, 0x90, 0x9d, 0x2f, 0x31, 0x54, 0x87, 0xe6, 0xfb, 0x20, 0x8e, 0x3c, 0x4e, 0x46, 0x8a, 0xdd, 0x2e, 0xe3, 0x75, 0xad, 0x79, 0x43, 0x6e, 0x23, 0xc0, 0xde, 0x0e, 0x98, 0xab, 0x5e, 0x5a, 0x28, 0xd1, 0x16, 0x72, 0xb6, 0xfd, 0x91, 0xf0, 0x76, 0x50, 0xbc, 0x44, 0xbb, 0x63, 0x5d, 0xb5, 0x43, 0x21, 0xe5, 0x1f, 0xd8, 0x0f, 0x75, 0x48, 0x4a, 0xd8, 0xeb, 0x6b, 0xec, 0x6c, 0xa8, 0xa6, 0xb7, 0x32, 0x65, 0x61, 0xd6, 0xa1, 0xc0, 0x4e, 0x26, 0x4a, 0xf5, 0x44, 0x78, 0x5b, 0xeb, 0xc6, 0xc3, 0xb6, 0x80, 0x6e, 0x4a, 0x9c, 0x76, 0x10, 0x76, 0x1d, 0xf7, 0xfc, 0x24, 0x2f, 0x77, 0x91, 0xd0, 0xc7, 0xaa, 0xda, 0x10, 0xa2, 0xdf, 0x50, 0x75, 0x8e, 0x7d, 0x6b, 0xe4, 0x75, 0xf4, 0x9c, 0x7f, 0x71, 0x1f, 0x39, 0x19, 0x6a, 0x13, 0x8d, 0x1b, 0xcd, 0xc9, 0xb2, 0xac, 0x83, 0xfd, 0x80, 0xc8, 0xfa, 0x62, 0xa0, 0x17, 0xe2, 0x42, 0x91, 0xfe, 0x0d, 0x42, 0x8c, 0x46, 0x04, 0x33, 0x0c, 0xa2, 0x76, 0x92, 0x8d, 0xf7, 0xb6, 0xd9, 0x1c, 0xba, 0x94, 0xa2, 0xe5, 0xea, 0x51, 0x57, 0xd7, 0xef, 0x1b, 0xbf, 0xf7, 0x5b, 0x4c, 0x5b, 0xb4, 0x00, 0x49, 0x73, 0x48, 0x4f, 0xd2, 0x20, 0xc4, 0xd6, 0xe8, 0x81, 0xad, 0xfa, 0x9d, 0x43, 0x86, 0x91, 0xb8, 0xc2, 0xf2, 0xd4, 0x1a, 0x0c, 0xf5, 0x98, 0x73, 0x8b, 0x40, 0x8a, 0xe5, 0xdf, 0xea, 0x81, 0xfb, 0x89, 0xf8, 0xae, 0xbe, 0xd5, 0xc4, 0xf3, 0xb1, 0x90, 0x85, 0x68, 0x6c, 0xbb, 0xf7, 0xcd, 0x42, 0xd5, 0x60, 0x39, 0x53, 0xa7, 0xb4, 0xc6, 0x27, 0x19, 0x5b, 0xeb, 0x0e, 0x7f, 0xc0, 0xfd, 0xbf, 0xc8, 0x9a, 0x89, 0x28, 0x79, 0xd8, 0xea, 0xff, 0x2c, 0x83, 0x64, 0xbb, 0x8d, 0x35, 0x7b, 0xb9, 0xf6, 0xe7, 0x84, 0x5f, 0x3c, 0x24, 0xdc, 0x15, 0x1e, 0x1b, 0xc6, 0x11, 0x23, 0x0c, 0x0e, 0x6e, 0x40, 0x53, 0x20, 0xd2, 0xe7, 0x45, 0x9c, 0x6e, 0x68, 0xd1, 0x18, 0xd1, 0x2c, 0xc0, 0xd6, 0xbf, 0x06, 0x62, 0xad, 0x19, 0x89, 0x87, 0x2c, 0xf1, 0xad, 0x90, 0xcb, 0x07, 0x9f, 0xe1, 0x5a, 0x60, 0x77, 0x49, 0xac, 0x39, 0x07, 0x2d, 0x27, 0x26, 0xc6, 0x3e, 0x9b, 0x4c, 0x82, 0xa4, 0xeb, 0x4f, 0x62, 0x6d, 0xff, 0xa3, 0xe1, 0x26, 0xe0, 0x0f, 0xb9, 0xd6, 0x3c, 0x8e, 0xd8, 0x60, 0xc4, 0x7a, 0xc5, 0x06, 0xa8, 0x53, 0x49, 0x0d, 0x3b, 0xf8, 0xf6, 0xbe, 0xba, 0x9a, 0xbc, 0x7e, 0x86, 0x60, 0x81, 0xc1, 0x1c, 0xd2, 0xb9, 0xce, 0xa2, 0x08, 0x41, 0x5c, 0xcd, 0xdd, 0xa4, 0x89, 0x61, 0x1d, 0x27, 0x45, 0xd8, 0x27, 0x13, 0xfe, 0x9a, 0x93, 0xf4, 0xfb, 0x4b, 0x31, 0xb5, 0x39, 0x71, 0x17, 0x9d, 0xe9, 0x5c, 0x5d, 0x17, 0x8f, 0x86, 0x99, 0x2e, 0xbf, 0x97, 0xda, 0xff, 0xb6, 0xd3, 0x27, 0xbe, 0x3e, 0x79, 0xf0, 0xe1, 0xb7, 0x75, 0xc3, 0xa6, 0x8c, 0x0c, 0xfb, 0x38, 0x88, 0x21, 0x97, 0xdd, 0x3f, 0x48, 0x96, 0xb0, 0xcc, 0x37, 0xad, 0x43, 0x30, 0x40, 0x43, 0x37, 0xb8, 0x0d, 0x7d, 0xfa, 0xd1, 0x5d, 0x80, 0xc1, 0x77, 0xc1, 0xdb, 0x0e, 0x00, 0xa0, 0xe8, 0x3f, 0x09, 0x96, 0xa9, 0xc2, 0xd3, 0x2f, 0x02, 0xf7, 0x89, 0x2e, 0x0a, 0x50, 0x51, 0xc1, 0xba, 0x70, 0x14, 0x9f, 0xba, 0xec, 0x97, 0x11, 0x30, 0xe1, 0xb8, 0x9b, 0x2c, 0x3c, 0x59, 0x1b, 0x25, 0xf1, 0x73, 0xea, 0x43, 0x53, 0x44, 0x04, 0x4b, 0x7b, 0x87, 0x62, 0xe3, 0x95, 0xfe, 0x57, 0x5c, 0xaf, 0xf2, 0xfd, 0x49, 0x05, 0xdf, 0xa6, 0x7c, 0x44, 0xf7, 0x00, 0xf6, 0xf5, 0x35, 0x34, 0x26, 0x70, 0xe4, 0x4a, 0xf4, 0x85, 0x4d, 0x76, 0x58, 0xb9, 0x2d, 0x3c, 0x2f, 0x30, 0xe5, 0x9f, 0xd5, 0xca, 0xfe, 0x17, 0xae, 0x09, 0x7f, 0x4d, 0x37, 0xab, 0x35, 0xa8, 0xbc, 0x80, 0x73, 0x8b, 0x25, 0x24, 0x75, 0xc4, 0x2e, 0x41, 0x2a, 0xc0, 0xa0, 0x67, 0x1e, 0xcb, 0x6e, 0x0a, 0x4e, 0xfc, 0xc5, 0xe7, 0x2f, 0xf8, 0x90, 0xfb, 0x0b, 0xd6, 0xce, 0xf1, 0xa2, 0xd1, 0xb5, 0x47, 0x0e, 0x47, 0xdd, 0x5c, 0x84, 0x50, 0x28, 0x07, 0xf8, 0x5c, 0x91, 0xc9, 0x5c, 0xe4, 0xf4, 0xa8, 0x2e, 0x7a, 0x2a, 0x88, 0xfb, 0xd0, 0xfa, 0x51, 0x5f, 0xb6, 0x82, 0x65, 0x6d, 0x11, 0xce, 0xc9, 0xa2, 0x4b, 0x1b, 0xdd, 0xa8, 0xc7, 0x31, 0x2c, 0xad, 0x95, 0x31, 0xb2, 0xdb, 0xc0, 0x98, 0x6b, 0xc4, 0xf1, 0x73, 0xba, 0x51, 0x9f, 0xa9, 0xd2, 0x39, 0xed, 0xd6, 0xa1, 0xc6, 0x97, 0x7f, 0x57, 0xa5, 0xf4, 0x54, 0x49, 0xd8, 0xd9, 0x85, 0x76, 0x4c, 0x89, 0xea, 0xb0, 0x8a, 0xd1, 0x06, 0x90, 0x7c, 0xb1, 0xa4, 0x2b, 0xe0, 0x85, 0xb2, 0x53, 0x4e, 0x56, 0x5b, 0x42, 0x0e, 0x85, 0x3d, 0xe7, 0x5b, 0x58, 0x06, 0x1f, 0x4f, 0xaa, 0x45, 0xf5, 0x58, 0xef, 0xba, 0x14, 0x87, 0xda, 0x2d, 0xf5, 0xc8, 0x74, 0x24, 0x82, 0xa4, 0x5d, 0xe4, 0x12, 0x0a, 0x0e, 0x1f, 0x24, 0x37, 0xf5, 0x60, 0xe8, 0x70, 0x6e, 0xd0, 0xad, 0x69, 0x23, 0xd8, 0x79, 0xbd, 0xb2, 0x3e, 0xbe, 0x4d, 0x20, 0x32, 0x63, 0x2f, 0x6a, 0x2a, 0x93, 0xc4, 0x26, 0x4c, 0xd6, 0xf0, 0x6a, 0x08, 0x47, 0x84, 0x34, 0xff, 0xb9, 0x80, 0x32, 0xb1, 0xf8, 0x0e, 0x8b, 0x9f, 0x43, 0x87, 0x0e, 0x48, 0x4f, 0x89, 0x47, 0x71, 0x5c, 0x6f, 0x78, 0xd4, 0x5c, 0xc9, 0x0a, 0xf6, 0x58, 0x3a, 0xdb, 0x4f, 0xc1, 0x34, 0xe9, 0xce, 0x1c, 0x26, 0x16, 0xdb, 0x42, 0x23, 0x37, 0x12, 0x4f, 0xf6, 0x7c, 0x4b, 0x23, 0x65, 0xbb, 0x0f, 0x6f, 0x6d, 0x2c, 0x57, 0x61, 0xfc, 0x27, 0x78, 0x8d, 0xba, 0xc3, 0xba, 0x81, 0x79, 0xfe, 0xb0, 0x4b, 0x1a, 0x27, 0x48, 0xaa, 0x54, 0x23, 0x81, 0xd2, 0x63, 0x64, 0xfe, 0x0b, 0x88, 0xe5, 0x3a, 0x84, 0x50, 0xbd, 0x28, 0x31, 0x18, 0x93, 0x9a, 0xef, 0xc7, 0xad, 0x5c, 0x2d, 0x83, 0x39, 0x3b, 0x26, 0x03, 0x71, 0x31, 0x0b, 0x0c, 0xda, 0x57, 0x22, 0x02, 0x2c, 0x97, 0x8c, 0x16, 0xe4, 0x17, 0x87, 0x29, 0x11, 0xa4, 0xa3, 0x67, 0x15, 0xf5, 0xee, 0x05, 0xcb, 0x13, 0x33, 0x90, 0xc1, 0x36, 0xea, 0xd4, 0xe8, 0x08, 0x82, 0xa3, 0xb1, 0x8d, 0xe5, 0x48, 0x4e, 0x24, 0xe6, 0x3b, 0x52, 0x81, 0x78, 0x7d, 0xd0, 0x1c, 0xae, 0xb5, 0xa6, 0xa9, 0x3b, 0x28, 0x55, 0x2f, 0x75, 0x5b, 0x7c, 0xd8, 0x56, 0x9c, 0x66, 0xc2, 0x33, 0x2d, 0xe9, 0x49, 0x51, 0x06, 0x62, 0x73, 0xda, 0xde, 0x69, 0x97, 0xc7, 0x8d, 0x8f, 0x87, 0x3a, 0x2f, 0xae, 0xb0, 0xe8, 0xb9, 0x2a, 0x9f, 0x12, 0x24, 0xb5, 0x4d, 0x80, 0xc3, 0x43, 0xf6, 0xb9, 0x9f, 0xb1, 0x67, 0xc5, 0xb2, 0x74, 0x09, 0x9b, 0x4b, 0x95, 0xe9, 0x46, 0xb1, 0x48, 0xa9, 0x3b, 0xd5, 0xb7, 0xc8, 0x13, 0xf8, 0xac, 0x65, 0x4a, 0xe9, 0xc0, 0x30, 0x80, 0x5e, 0x30, 0x2e, 0xda, 0xc8, 0x69, 0x71, 0xd0, 0x28, 0x98, 0xcc, 0x9f, 0xb6, 0x0a, 0xcb, 0x80, 0x5a, 0x62, 0x13, 0x9e, 0xa0, 0x54, 0x1b, 0x15, 0xc3, 0xea, 0x74, 0xd7, 0x2b, 0xbc, 0xd6, 0x7d, 0x7b, 0x8e, 0xd7, 0x19, 0x7b, 0x8a, 0xf9, 0x46, 0x1c, 0xf6, 0x04, 0x76, 0xed, 0x7f, 0xa6, 0xe9, 0xbc, 0xfd, 0x07, 0x7d, 0x06, 0x7c, 0x4a, 0x26, 0xb4, 0xa5, 0x36, 0xee, 0x18, 0x24, 0x93, 0x56, 0x0f, 0x6d, 0xb8, 0xb1, 0x08, 0x0c, 0x6b, 0xb4, 0x60, 0x80, 0xea, 0x73, 0xee, 0x47, 0x0f, 0x08, 0x52, 0xf4, 0x83, 0x44, 0x22, 0x30, 0x8d, 0x5c, 0x1e, 0xf1, 0x2b, 0x3e, 0xbd, 0xb4, 0xda, 0x37, 0xed, 0x0a, 0xf9, 0xb1, 0x01, 0x81, 0xfe, 0x52, 0x49, 0x49, 0x4f, 0x20, 0x7c, 0x73, 0x02, 0x93, 0x94, 0x3d, 0x1f, 0x5d, 0xa4, 0x85, 0xb9, 0xcd, 0x19, 0xe5, 0x84, 0x1d, 0xc4, 0x4d, 0x7a, 0x9c, 0x09, 0x8c, 0xf0, 0x12, 0xdc, 0xfa, 0xee, 0xb9, 0x5a, 0x2e, 0x60, 0x67, 0x84, 0x14, 0xc8, 0xdf, 0x34, 0x3c, 0x35, 0x0b, 0x42, 0x18, 0x24, 0x9a, 0xdc, 0x99, 0x76, 0x15, 0xf9, 0xd0, 0x12, 0x3b, 0x97, 0xa8, 0x31, 0xda, 0x5f, 0xbc, 0xb0, 0xca, 0x32, 0xfc, 0x5b, 0x67, 0x5e, 0xd0, 0xd5, 0xba, 0xed, 0x2e, 0x9c, 0x35, 0x1e, 0x2e, 0x22, 0x83, 0xb7, 0x72, 0xab, 0x1c, 0x2c, 0x2d, 0x23, 0x4f, 0x3a, 0xd8, 0xe1, 0x28, 0xbd, 0x28, 0xf1, 0x04, 0x14, 0x34, 0x54, 0x5c, 0xcc, 0xf0, 0xed, 0xe3, 0x0f, 0x9f, 0x11, 0x60, 0x0f, 0x5b, 0xfd, 0x4b, 0x39, 0xd6, 0xcd, 0x2f, 0x42, 0x82, 0xa9, 0xb5, 0x0a, 0x02, 0x22, 0xe8, 0x07, 0x55, 0xed, 0x1c, 0x31, 0x35, 0xc6, 0x60, 0x4d, 0xb6, 0xac, 0x42, 0x30, 0x0c, 0xc5, 0x97, 0x21, 0xee, 0xa2, 0xb2, 0x5d, 0x8a, 0x7b, 0xc3, 0xd6, 0x90, 0xd4, 0xd1, 0x25, 0x50, 0xeb, 0x32, 0x82, 0xe8, 0xcc, 0xa0, 0x31, 0xef, 0x7e, 0x19, 0xdc, 0x25, 0x72, 0xd6, 0xec, 0x0a, 0x94, 0xab, 0xd2, 0x10, 0x60, 0xe3, 0x1f, 0xbd, 0xc7, 0x94, 0x6a, 0xfa, 0x82, 0x0c, 0xff, 0x27, 0xdd, 0x59, 0x70, 0x12, 0xa0, 0x5e, 0x9e, 0xe1, 0x9c, 0xc7, 0xc8, 0x4b, 0x10, 0xf2, 0x3a, 0x20, 0xd2, 0x9c, 0x66, 0xa5, 0xf1, 0x3d, 0x48, 0x26, 0x7b, 0xa2, 0xd1, 0xbc, 0x24, 0x73, 0x0b, 0x02, 0x36, 0xd6, 0x8d, 0xe0, 0x0f, 0x69, 0x6f, 0x8d, 0xef, 0x48, 0x31, 0xf7, 0x35, 0x14, 0xa2, 0x47, 0x0b, 0x1e, 0x8f, 0x5e, 0xe1, 0x3a, 0x21, 0xd1, 0x64, 0x85, 0x2b, 0xa2, 0x62, 0x2d, 0x6e, 0xc1, 0x14, 0x5c, 0x0f, 0x0f, 0xed, 0x84, 0xa6, 0x25, 0x72, 0xb8, 0x9f, 0x5a, 0xcb, 0x58, 0x9f, 0xd9, 0xdd, 0x4a, 0xb2, 0xda, 0xf1, 0x45, 0x4d, 0x1d, 0xc0, 0x52, 0x75, 0xc6, 0x73, 0xd9, 0x87, 0x80, 0xc4, 0x6f, 0xfc, 0x61, 0xb7, 0xa1, 0x93, 0x91, 0x15, 0xb8, 0x00, 0x65, 0x5f, 0x5c, 0xa5, 0x3d, 0x9f, 0x27, 0xe3, 0x37, 0x2c, 0x94, 0x51, 0xdd, 0x08, 0x74, 0x8d, 0x3d, 0x12, 0x05, 0xcd, 0xa6, 0x26, 0x46, 0x20, 0xcd, 0x84, 0xe3, 0x64, 0x07, 0x7a, 0x04, 0x5e, 0xc4, 0x33, 0xb1, 0xd0, 0x62, 0xa6, 0x67, 0x3a, 0x18, 0x1f, 0x3a, 0xf5, 0x0d, 0xc5, 0x6b, 0x51, 0xa0, 0x33, 0x19, 0x88, 0x91, 0x1e, 0xf2, 0x63, 0x07, 0x8c, 0x96, 0xa6, 0xbd, 0xc7, 0xd3, 0x18, 0x64, 0xa7, 0x8b, 0x19, 0x11, 0xbc, 0xb0, 0x06, 0x56, 0x98, 0xf0, 0x58, 0xdc, 0x85, 0xc8, 0xed, 0x4e, 0x19, 0x3b, 0x01, 0xb1, 0xf5, 0xad, 0x3d, 0x54, 0xcd, 0xde, 0xd1, 0x1a, 0x30, 0x60, 0x34, 0xd5, 0xa4, 0xab, 0x43, 0x61, 0x74, 0x02, 0xf9, 0xe9, 0x16, 0x42, 0x54, 0xd7, 0x50, 0x84, 0xd0, 0xdc, 0xe2, 0x45, 0xe3, 0xc6, 0xac, 0xe6, 0x7b, 0x93, 0x7e, 0x66, 0x84, 0x9a, 0x72, 0xa7, 0xf6, 0x86, 0xae, 0x42, 0xb1, 0xa5, 0xeb, 0xb9, 0xa2, 0xb8, 0x3f, 0xd3, 0xfd, 0x50, 0xe3, 0xc8, 0x1a, 0xe4, 0x66, 0x67, 0xec, 0xa1, 0x05, 0xa6, 0x71, 0x9e, 0xf6, 0x93, 0xff, 0xfe, 0x4f, 0x8e, 0x08, 0xe5, 0x0a, 0x90, 0x8e, 0x39, 0xa8, 0xaf, 0x06, 0x46, 0xdb, 0x85, 0xa9, 0xe4, 0xef, 0x28, 0x8d, 0x6a, 0x81, 0x8c, 0xa5, 0x17, 0x8c, 0xcf, 0xa2, 0xda, 0x5a, 0x8d, 0xbd, 0xeb, 0x76, 0x9f, 0x78, 0x5f, 0x07, 0xd0, 0x68, 0xf3, 0x2c, 0x92, 0x92, 0x09, 0x95, 0xb0, 0xf0, 0x5f, 0xc4, 0x59, 0xe5, 0xd9, 0x37, 0x56, 0x22, 0xdb, 0x9d, 0xd5, 0xfa, 0x26, 0x77, 0x58, 0x9c, 0x2f, 0xc6, 0xb1, 0x1a, 0x7d, 0xc5, 0x6f, 0x28, 0x7b, 0xad, 0xd9, 0x81, 0x99, 0x61, 0x6a, 0xb7, 0x3f, 0xe4, 0x84, 0x50, 0xcb, 0x3e, 0x9c, 0x79, 0xbb, 0x22, 0x01, 0xfa, 0x39, 0xc3, 0x8c, 0x61, 0x3c, 0x1d, 0xa7, 0x4c, 0x6a, 0xbf, 0x7f, 0x8b, 0x7b, 0x8d, 0x4c, 0xa9, 0x5b, 0x3a, 0x24, 0x50, 0x44, 0x19, 0x86, 0x42, 0x48, 0x4d, 0xf6, 0x47, 0x10, 0x68, 0x39, 0x42, 0x46, 0x68, 0xff, 0x12, 0x0f, 0x9d, 0xe3, 0xde, 0x1e, 0x9f, 0x5f, 0xa1, 0x16, 0x7e, 0x09, 0xff, 0xc9, 0x68, 0x8f, 0xaf, 0x30, 0xc3, 0x89, 0xb5, 0xdf, 0x45, 0x94, 0xf9, 0x32, 0x5c, 0x51, 0x41, 0x88, 0x78, 0xe1, 0x02, 0x1b, 0xac, 0xde, 0xbb, 0xa6, 0x32, 0x86, 0xc1, 0xd5, 0xf6, 0x5b, 0xef, 0x7a, 0x6e, 0x26, 0x56, 0xe0, 0x0f, 0x2b, 0x01, 0x10, 0x99, 0xb7, 0x77, 0x7d, 0xe9, 0x49, 0x13, 0x40, 0x96, 0x82, 0xec, 0x30, 0x9c, 0xa2, 0xff, 0x2c, 0x60, 0xa8, 0xb8, 0x46, 0x84, 0xe0, 0xa3, 0xd2, 0x5e, 0x8f, 0xf0, 0x8a, 0x44, 0x4f, 0x98, 0xdf, 0x60, 0x0a, 0x3a, 0xc2, 0x2c, 0xab, 0x6e, 0xc8, 0x32, 0xb8, 0x80, 0xdd, 0xc9, 0x96, 0xe1, 0x4c, 0x68, 0xd9, 0xbd, 0x15, 0xcf, 0xae, 0xd3, 0xaf, 0xac, 0x92, 0x1c, 0x33, 0xe8, 0xab, 0x87, 0x27, 0x6b, 0x39, 0x20, 0x69, 0x39, 0xf8, 0x35, 0xb1, 0xde, 0x1a, 0xbf, 0x10, 0x8e, 0x6f, 0x50, 0x1f, 0x85, 0x5d, 0x5a, 0x78, 0xd8, 0x17, 0x17, 0x40, 0xda, 0x54, 0xa2, 0xb4, 0xb2, 0xdc, 0xe8, 0x84, 0x62, 0xba, 0x7f, 0xb6, 0x3f, 0x17, 0x52, 0x1d, 0xce, 0x15, 0x66, 0x98, 0xd0, 0x95, 0xc6, 0x19, 0x51, 0x10, 0xbd, 0xa7, 0x66, 0x94, 0x1a, 0xa0, 0xa3, 0x62, 0x19, 0xa6, 0xb2, 0xba, 0xff, 0x06, 0xd6, 0x7e, 0x5a, 0x35, 0xbe, 0x67, 0x34, 0xfb, 0xdf, 0xda, 0x7c, 0x93, 0xfa, 0x80, 0x99, 0xdd, 0x24, 0x8f, 0xf5, 0xaa, 0xa6, 0xa5, 0x72, 0x1b, 0xb1, 0xa1, 0xf2, 0x34, 0xb0, 0x30, 0x14, 0x9d, 0x1b, 0xad, 0x57, 0xff, 0xce, 0x63, 0x28, 0x0e, 0xb8, 0xf8, 0xb5, 0x36, 0xda, 0x8e, 0xd3, 0x64, 0x77, 0x83, 0x8b, 0xe4, 0x42, 0xb8, 0x30, 0x4f, 0x52, 0x4e, 0x2e, 0x74, 0x3c, 0xdc, 0xbd, 0x3b, 0x22, 0x2d, 0xe4, 0x3a, 0xee, 0xfe, 0x9c, 0x40, 0xf2, 0xe6, 0xcb, 0xd6, 0x6b, 0xf9, 0x2e, 0x28, 0x87, 0x85, 0xb8, 0x88, 0x55, 0x63, 0x3e, 0x56, 0x0d, 0x4d, 0x4a, 0xcc, 0xf1, 0x41, 0xe1, 0xa8, 0x10, 0xe8, 0x0a, 0xdc, 0x33, 0xe1, 0xff, 0xc3, 0x59, 0xfb, 0x8a, 0x1e, 0x22, 0x3e, 0x76, 0xa9, 0xe8, 0x46, 0x7d, 0xf0, 0x0f, 0x3c, 0x1d, 0xa3, 0x58, 0x7d, 0xfb, 0x3d, 0xd8, 0x46, 0xdb, 0xcc, 0xab, 0xac, 0xd0, 0xd2, 0xd6, 0x13, 0x0f, 0x50, 0x18, 0xa4, 0x48, 0xd0, 0xc9, 0x47, 0xda, 0x77, 0x11, 0x63, 0x80, 0x22, 0x1d, 0xfd, 0x8a, 0x2e, 0x5b, 0x31, 0x1d, 0xec, 0xcb, 0xc4, 0x11, 0x93, 0xae, 0x32, 0x53, 0x0c, 0x4e, 0xad, 0x99, 0xbc, 0xb0, 0x74, 0x4b, 0xd9, 0xe6, 0xdd, 0x25, 0x56, 0x39, 0xdb, 0x93, 0x0f, 0x71, 0x32, 0xb9, 0xd3, 0x41, 0x45, 0xdc, 0xc7, 0x72, 0x8d, 0x6a, 0x1e, 0xab, 0x3e, 0x02, 0x95, 0x8d, 0xa4, 0x81, 0x73, 0x6f, 0x65, 0x19, 0x23, 0xd8, 0xf1, 0xc5, 0xba, 0x28, 0x11, 0xb3, 0xfe, 0x12, 0xad, 0x88, 0xfe, 0xa4, 0xfa, 0x0d, 0x95, 0xd2, 0x4d, 0x09, 0x7b, 0x95, 0x71, 0x36, 0xff, 0x7d, 0x32, 0x89, 0xf1, 0xc3, 0x86, 0x79, 0x6e, 0xef, 0x0b, 0x46, 0x5f, 0x32, 0x4b, 0x23, 0x7d, 0x0e, 0xf0, 0x1f, 0x55, 0x35, 0x87, 0x01, 0x03, 0x4f, 0x65, 0xcc, 0x49, 0x9b, 0x11, 0xe6, 0x59, 0x03, 0x6d, 0xbc, 0x8f, 0x8f, 0x1f, 0xa0, 0x25, 0x14, 0x6c, 0x7d, 0x75, 0xbe, 0xd4, 0x75, 0xdb, 0x74, 0xa3, 0x0c, 0xd9, 0x8f, 0x5c, 0x29, 0xa5, 0xd4, 0x05, 0xd0, 0x28, 0xba, 0x21, 0xf9, 0x60, 0x08, 0x28, 0xd1, 0xd5, 0x57, 0x16, 0x4d, 0xae, 0xa6, 0xfe, 0xe5, 0x61, 0x60, 0x72, 0xfc, 0xc2, 0x7b, 0xe9, 0xf0, 0x50, 0xab, 0x62, 0xbe, 0x4e, 0xfb, 0xdf, 0xf6, 0x82, 0x09, 0x4b, 0xb4, 0xc7, 0xb5, 0x2b, 0x6e, 0x8a, 0x31, 0xa1, 0xce, 0xc5, 0x1a, 0x81, 0x9e, 0xd0, 0x04, 0x2c, 0x52, 0x21, 0xc2, 0xde, 0xbf, 0xeb, 0xfb, 0x91, 0xa9, 0xff, 0x41, 0xd5, 0x4e, 0xb3, 0xf1, 0xc7, 0xb5, 0xf9, 0x00, 0x9c, 0x68, 0x61, 0xfc, 0xc5, 0x4f, 0x1c, 0x0e, 0xd1, 0xe8, 0xcb, 0x68, 0xec, 0x38, 0x66, 0x3c, 0x2f, 0x14, 0xc1, 0xa5, 0x5d, 0xe2, 0xe8, 0x3f, 0xe5, 0xe2, 0xef, 0x17, 0xf1, 0x18, 0x45, 0x6a, 0xe4, 0xea, 0xaa, 0x92, 0x86, 0x2b, 0x92, 0x8c, 0x63, 0x94, 0xf8, 0x5f, 0x58, 0x84, 0x5c, 0xf3, 0xc4, 0x31, 0xd2, 0x77, 0xa4, 0xaa, 0x63, 0xb5, 0x60, 0xde, 0x52, 0xa8, 0x39, 0x99, 0x08, 0x59, 0x6b, 0x09, 0xbc, 0x1b, 0x51, 0xc7, 0x4d, 0xf5, 0x1b, 0xe5, 0x84, 0xa1, 0xc1, 0x4c, 0xc4, 0xba, 0xbc, 0x75, 0x4a, 0x13, 0xef, 0x3f, 0x5f, 0x65, 0x56, 0x33, 0x4b, 0x24, 0x5c, 0x91, 0xb5, 0xb6, 0x69, 0x0c, 0x4c, 0x9d, 0xd2, 0xa4, 0xd8, 0x29, 0xf9, 0x7e, 0x84, 0xec, 0x07, 0xe0, 0x92, 0xae, 0x61, 0x1d, 0xd4, 0xe0, 0x9f, 0xd7, 0xc6, 0x96, 0x8d, 0x37, 0x7d, 0xe8, 0x64, 0x11, 0x30, 0x0f, 0x50, 0x16, 0x9e, 0xcd, 0x62, 0xbe, 0x93, 0x03, 0xdb, 0x1b, 0xd0, 0xba, 0xd3, 0x77, 0x91, 0x8b, 0x35, 0x70, 0xa1, 0x46, 0xd1, 0x2a, 0x68, 0x82, 0x7e, 0x19, 0x3d, 0xa8, 0x42, 0xf8, 0x9b, 0x72, 0xf7, 0x7d, 0xa2, 0xcb, 0xe8, 0x9a, 0x7b, 0x87, 0x14, 0xe7, 0x18, 0x2b, 0xc3, 0xba, 0x47, 0xad, 0xdb, 0xa6, 0x1a, 0x00, 0x0b, 0x73, 0x67, 0x32, 0x8c, 0x28, 0x94, 0x66, 0x71, 0xed, 0x57, 0x27, 0x59, 0xf8, 0xac, 0x67, 0x91, 0x25, 0x02, 0xfe, 0xe9, 0x37, 0xc0, 0x1e, 0x14, 0xee, 0x8b, 0x4d, 0x7f, 0x97, 0xfe, 0x5a, 0x1f, 0x80, 0x44, 0xde, 0x21, 0x8a, 0x20, 0xb3, 0xa1, 0x81, 0x53, 0x73, 0xa2, 0x2a, 0xad, 0x3e, 0x31, 0x50, 0x82, 0xcd, 0xb5, 0x78, 0x5d, 0xf6, 0xf9, 0x97, 0xd6, 0x51, 0xd2, 0x14, 0x6d, 0xc8, 0xcf, 0xca, 0x2a, 0x85, 0xd9, 0x35, 0x19, 0xe4, 0x6b, 0x70, 0xef, 0x76, 0xf8, 0xaa, 0x92, 0xa1, 0xe2, 0x74, 0x52, 0x71, 0x75, 0x10, 0xf1, 0xca, 0x72, 0x0a, 0xbf, 0x52, 0x30, 0x44, 0xf2, 0x1b, 0xee, 0x53, 0x7c, 0x34, 0x43, 0xb9, 0xfb, 0x06, 0x96, 0x5e, 0xe6, 0x79, 0x10, 0xea, 0xd5, 0x2a, 0xe4, 0x90, 0x24, 0x20, 0x53, 0x32, 0xb2, 0x19, 0xe8, 0x58, 0x0a, 0xd1, 0x8a, 0x7a, 0xac, 0x09, 0xb1, 0x8e, 0x50, 0xc9, 0xa9, 0x28, 0x97, 0x88, 0x25, 0x18, 0x73, 0x55, 0x1c, 0xb3, 0xdb, 0x40, 0x01, 0xe5, 0x24, 0x9d, 0x85, 0xa3, 0xb3, 0xac, 0x3d, 0x44, 0x50, 0xe5, 0x0d, 0xa3, 0xfd, 0x2f, 0x5f, 0x59, 0x25, 0x2c, 0x03, 0x57, 0x35, 0x02, 0x28, 0x4d, 0xa0, 0x99, 0xb3, 0xeb, 0x6f, 0x4c, 0x4d, 0x87, 0x87, 0x9a, 0x18, 0x8a, 0xaf, 0xcc, 0x85, 0x73, 0x05, 0xa6, 0x70, 0x25, 0x51, 0x4b, 0xd1, 0xa0, 0x18, 0x44, 0x02, 0xaa, 0xc4, 0x78, 0xf0, 0x56, 0x8e, 0x16, 0x3a, 0x06, 0xd7, 0x80, 0xda, 0x62, 0x57, 0xfe, 0xd5, 0x2b, 0xb4, 0xbb, 0x53, 0xfd, 0x20, 0x49, 0xcb, 0xd6, 0x2a, 0xd6, 0xe7, 0x13, 0xc4, 0xe4, 0x6b, 0x72, 0x74, 0xa5, 0xf2, 0xdd, 0x16, 0x71, 0xb3, 0xe7, 0xf6, 0x9a, 0x8e, 0x50, 0xa7, 0x40, 0x9b, 0xff, 0x8f, 0x31, 0x15, 0xf4, 0x0b, 0xb0, 0x99, 0x80, 0xb5, 0x98, 0xff, 0x17, 0xc4, 0x1f, 0x4b, 0xc9, 0xc9, 0xb8, 0xfd, 0xe6, 0xd5, 0x7d, 0xc2, 0x9b, 0x8b, 0x7d, 0x1e, 0x42, 0xdd, 0x81, 0x77, 0xbf, 0xa8, 0x56, 0x30, 0x27, 0x2a, 0xdb, 0x5a, 0x1a, 0x20, 0x03, 0x10, 0xae, 0x83, 0x72, 0xe2, 0xe0, 0xf3, 0xa9, 0x2b, 0x16, 0x82, 0x0b, 0x93, 0x7a, 0x68, 0xf1, 0xcd, 0xd5, 0xc8, 0x7b, 0xff, 0x13, 0x72, 0xa5, 0xc4, 0xb5, 0x0c, 0x52, 0x1a, 0xc6, 0xfc, 0xf1, 0x55, 0x9d, 0xb4, 0x19, 0x2e, 0xcb, 0x24, 0xe5, 0xf4, 0x76, 0x25, 0xa1, 0xe3, 0x22, 0xfb, 0xc8, 0x3b, 0xb8, 0x65, 0x07, 0xf7, 0x68, 0x03, 0x40, 0x02, 0xfe, 0x2f, 0x34, 0xad, 0x02, 0xbf, 0x60, 0xfb, 0x6b, 0xa7, 0xa3, 0xd0, 0x9e, 0x56, 0x24, 0xa3, 0xdc, 0xca, 0xf5, 0x75, 0xf3, 0xd6, 0x49, 0xd1, 0xed, 0x3a, 0x7c, 0x6e, 0x44, 0x80, 0x0c, 0xba, 0xef, 0x77, 0x0c, 0x53, 0x58, 0xba, 0x0d, 0xf2, 0xe2, 0x64, 0x8c, 0x0c, 0x2b, 0x49, 0xbb, 0x70, 0x9e, 0x5f, 0x6f, 0xcc, 0x74, 0x78, 0x32, 0xda, 0x78, 0x82, 0x82, 0x34, 0x18, 0x38, 0x2e, 0xd0, 0xc4, 0x58, 0x80, 0x6e, 0x8a, 0x57, 0x57, 0xd2, 0x3f, 0xb5, 0xc9, 0xea, 0xcc, 0xab, 0xca, 0x68, 0xc9, 0x6e, 0xb9, 0x42, 0xc4, 0x87, 0x4f, 0x49, 0x0c, 0x3e, 0xb5, 0x35, 0x85, 0xce, 0xcb, 0xe3, 0xa2, 0xae, 0x1e, 0xa5, 0x78, 0xbd, 0x1e, 0xdd, 0x34, 0x50, 0x59, 0x86, 0xb1, 0x93, 0x05, 0x5a, 0x84, 0x68, 0x24, 0xb2, 0x90, 0xe6, 0x66, 0xef, 0x78, 0xef, 0x83, 0x79, 0x34, 0xf6, 0x2e, 0x26, 0x8d, 0x3c, 0x00, 0xef, 0x60, 0x6f, 0x34, 0x93, 0x0a, 0xd4, 0x4a, 0x8d, 0x92, 0x4b, 0x81, 0x14, 0x34, 0x76, 0xc8, 0x87, 0x53, 0x3f, 0x06, 0xa7, 0xe5, 0xfe, 0x46, 0x59, 0xf4, 0x6a, 0xd3, 0x5a, 0x52, 0x5a, 0xf4, 0xe8, 0x6f, 0xf4, 0x57, 0x41, 0x0d, 0x8d, 0xec, 0x21, 0x5a, 0xd5, 0x7d, 0xae, 0x85, 0xc3, 0xa1, 0x2c, 0x47, 0x7d, 0xf4, 0x92, 0xe6, 0x2a, 0x86, 0xd9, 0x82, 0x5f, 0xe8, 0xfb, 0xa0, 0xf7, 0xf2, 0x20, 0x71, 0xcd, 0x47, 0x1c, 0xa7, 0xb0, 0x47, 0x59, 0x20, 0x5c, 0x35, 0x0d, 0x42, 0x2c, 0xb4, 0xce, 0x81, 0xc0, 0xf5, 0x67, 0x14, 0xe7, 0xcf, 0x87, 0xf6, 0xea, 0xdd, 0x14, 0xf2, 0x6b, 0xdc, 0xc1, 0x9c, 0x3e, 0x6f, 0xff, 0xd1, 0x84, 0x45, 0x38, 0xf6, 0x5d, 0x54, 0xda, 0xc8, 0xd1, 0xfe, 0x6a, 0x4d, 0xa1, 0x5f, 0xec, 0xaf, 0x24, 0xef, 0x89, 0x98, 0x70, 0xae, 0x38, 0x04, 0x8b, 0x16, 0x93, 0xa2, 0x73, 0xe2, 0x33, 0x5e, 0x4c, 0x94, 0x9e, 0x32, 0x57, 0xab, 0x19, 0xea, 0x1d, 0x83, 0xb2, 0xa8, 0x8f, 0x41, 0xd9, 0xc0, 0xc9, 0x20, 0x00, 0x2e, 0xf9, 0x7a, 0x1a, 0x01, 0xa6, 0xd9, 0xa7, 0x5f, 0x41, 0xf9, 0xdc, 0x42, 0x0c, 0x3a, 0x0e, 0x92, 0xf0, 0xe9, 0xdd, 0x5a, 0x60, 0xfd, 0xe9, 0x81} 435 var conf grepr.Conf 436 437 for ind := 0; ind < b.N; ind++ { 438 grepr.StringC(conf, src) 439 } 440 } 441 442 func Test_slices(t *testing.T) { 443 defer gtest.Catch(t) 444 445 testReprZero([]int(nil), `nil`) 446 testReprZero([]int{}, `[]int{}`) 447 testReprZero([]int{10, 20, 30}, `[]int{10, 20, 30}`) 448 449 testReprDef([]int(nil), `nil`) 450 testReprDef([]int{}, `[]int{}`) 451 testReprDef([]int{10, 20, 30}, `[]int{ 452 10, 453 20, 454 30, 455 }`) 456 457 testReprZero([]any(nil), `nil`) 458 testReprZero([]any{}, `[]any{}`) 459 testReprZero([]any{true, 10}, `[]any{true, 10}`) 460 testReprZero([]any{Bool(true), Int(10)}, `[]any{grepr_test.Bool(true), grepr_test.Int(10)}`) 461 462 testReprDef([]any(nil), `nil`) 463 testReprDef([]any{}, `[]any{}`) 464 testReprDef([]any{true, 10}, `[]any{ 465 true, 466 10, 467 }`) 468 testReprDef([]any{Bool(true), Int(10)}, `[]any{ 469 grepr_test.Bool(true), 470 grepr_test.Int(10), 471 }`) 472 473 testReprZero([]string(nil), `nil`) 474 testReprDef([]string(nil), `nil`) 475 476 testReprZero([]string{}, `[]string{}`) 477 testReprDef([]string{}, `[]string{}`) 478 479 testReprZero([]string{`one`}, "[]string{`one`}") 480 testReprDef([]string{`one`}, `[]string{ 481 `+"`one`"+`, 482 }`) 483 484 testReprZero([]string{`one`, `two`}, "[]string{`one`, `two`}") 485 testReprDef([]string{`one`, `two`}, `[]string{ 486 `+"`one`"+`, 487 `+"`two`"+`, 488 }`) 489 } 490 491 func Test_slice_type_elision(t *testing.T) { 492 defer gtest.Catch(t) 493 494 t.Run(`in_slice_literals`, func(t *testing.T) { 495 defer gtest.Catch(t) 496 497 testReprZero( 498 [][]int{nil, {}, {10, 20}, {30, 40, 50}}, 499 `[][]int{nil, {}, {10, 20}, {30, 40, 50}}`, 500 ) 501 502 testReprDef( 503 [][]int{nil, {}, {10, 20}, {30, 40, 50}}, 504 `[][]int{ 505 nil, 506 {}, 507 { 508 10, 509 20, 510 }, 511 { 512 30, 513 40, 514 50, 515 }, 516 }`) 517 518 testReprZero( 519 [][][]int{nil, {nil}, {{10, 20}}, {{30, 40, 50}}}, 520 `[][][]int{nil, {nil}, {{10, 20}}, {{30, 40, 50}}}`, 521 ) 522 }) 523 524 t.Run(`in_map_literals`, func(t *testing.T) { 525 defer gtest.Catch(t) 526 527 testReprZero(map[int][]int{10: {20, 30}}, `map[int][]int{10: {20, 30}}`) 528 529 testReprDef( 530 map[int][]int{10: {20, 30}}, 531 `map[int][]int{ 532 10: { 533 20, 534 30, 535 }, 536 }`) 537 538 t.Run(`interface_values`, func(t *testing.T) { 539 defer gtest.Catch(t) 540 testReprZero(map[int]any{10: []int{20, 30}}, `map[int]any{10: []int{20, 30}}`) 541 542 testReprDef( 543 map[int][]int{10: {20, 30}}, 544 `map[int][]int{ 545 10: { 546 20, 547 30, 548 }, 549 }`) 550 }) 551 552 }) 553 554 t.Run(`in_struct_literals`, func(t *testing.T) { 555 defer gtest.Catch(t) 556 557 type Tar struct{ Val []int } 558 559 testReprZero(Tar{[]int{10, 20, 30}}, `grepr_test.Tar{[]int{10, 20, 30}}`) 560 }) 561 } 562 563 func Test_arrays(t *testing.T) { 564 defer gtest.Catch(t) 565 566 testReprZero([0]any{}, `[0]any{}`) 567 testReprZero([1]any{nil}, `[1]any{}`) 568 testReprZero([2]any{nil, nil}, `[2]any{}`) 569 testReprZero([2]any{10, 20}, `[2]any{10, 20}`) 570 571 testReprZero([0]func(){}, `[0]func(){}`) 572 testReprZero([1]func(){nil}, `[1]func(){}`) 573 testReprZero([2]func(){nil, nil}, `[2]func(){}`) 574 575 testReprZero([3]int{}, `[3]int{}`) 576 testReprZero([3]int{10, 20, 30}, `[3]int{10, 20, 30}`) 577 } 578 579 func Test_structs(t *testing.T) { 580 defer gtest.Catch(t) 581 582 testReprDef(Struct0{}, `grepr_test.Struct0{}`) 583 584 testReprDef(Struct1{}, `grepr_test.Struct1{}`) 585 testReprDef(Struct1{10}, `grepr_test.Struct1{10}`) 586 587 testReprDef(Struct2{}, `grepr_test.Struct2{}`) 588 testReprDef(Struct2{A: 10}, `grepr_test.Struct2{A: 10}`) 589 testReprDef(Struct2{B: 20}, `grepr_test.Struct2{B: 20}`) 590 testReprDef(Struct2{A: 10, B: 20}, `grepr_test.Struct2{ 591 A: 10, 592 B: 20, 593 }`) 594 595 testReprDef(testOuter, testOuterStringDef) 596 testReprZero(testOuter, testOuterStringZero) 597 598 testReprDef(Struct1Any{}, `grepr_test.Struct1Any{}`) 599 600 testReprDef(Struct1Any{true}, `grepr_test.Struct1Any{true}`) 601 testReprDef(Struct1Any{Bool(true)}, `grepr_test.Struct1Any{grepr_test.Bool(true)}`) 602 603 testReprDef(Struct1Any{10}, `grepr_test.Struct1Any{10}`) 604 testReprDef(Struct1Any{gg.TimeMicro(10)}, `grepr_test.Struct1Any{gg.TimeMicro(10)}`) 605 606 testReprDef(Struct1Any{`one`}, `grepr_test.Struct1Any{`+"`one`"+`}`) 607 testReprDef(Struct1Any{gg.ErrStr(`one`)}, `grepr_test.Struct1Any{gg.ErrStr(`+"`one`"+`)}`) 608 } 609 610 func Test_structs_embed_GoStringer(t *testing.T) { 611 t.Skip(`not yet implemented`) 612 613 defer gtest.Catch(t) 614 615 type Tar1 struct{ GoStringer } 616 617 fmt.Println(`gg.Type[Tar1]().Implements(gg.Type[fmt.GoStringer]()):`, gg.Type[Tar1]().Implements(gg.Type[fmt.GoStringer]())) 618 619 testReprZero(Tar1{}, `grepr_test.Tar1{MakeGoStringer()}`) 620 testReprDef(Tar1{}, `grepr_test.Tar1{MakeGoStringer()}`) 621 622 type Tar2 struct { 623 GoStringer 624 Id int 625 } 626 627 testReprZero(Tar2{}, `grepr_test.Tar2{GoStringer: MakeGoStringer()}`) 628 629 testReprDef(Tar2{}, `grepr_test.Tar2{ 630 GoStringer: MakeGoStringer(), 631 }`) 632 633 testReprZero(Tar2{Id: 10}, `grepr_test.Tar2{GoStringer: MakeGoStringer(), Id: 10}`) 634 635 testReprDef(Tar2{Id: 10}, `grepr_test.Tar2{ 636 GoStringer: MakeGoStringer(), 637 Id: 10, 638 }`) 639 } 640 641 /* 642 This test is limited because Go iterates maps in random order, and our 643 pretty-printer doesn't bother to sort keys. 644 */ 645 func Test_maps(t *testing.T) { 646 defer gtest.Catch(t) 647 648 testReprZero(map[int]bool(nil), `nil`) 649 testReprDef(map[int]bool(nil), `nil`) 650 651 testReprZero(map[int]bool{}, `map[int]bool{}`) 652 testReprDef(map[int]bool{}, `map[int]bool{}`) 653 654 testReprZero(map[int]bool{10: true}, `map[int]bool{10: true}`) 655 testReprZero(map[int]bool{10: false}, `map[int]bool{10: false}`) 656 657 testReprDef( 658 map[int]bool{10: true}, 659 `map[int]bool{ 660 10: true, 661 }`, 662 ) 663 } 664 665 func Test_map_type_elision(t *testing.T) { 666 defer gtest.Catch(t) 667 668 t.Run(`in_slice_literals`, func(t *testing.T) { 669 defer gtest.Catch(t) 670 671 testReprZero([]map[int]bool{{10: true}}, `[]map[int]bool{{10: true}}`) 672 673 testReprDef([]map[int]bool{{10: true}, {20: false}}, `[]map[int]bool{ 674 { 675 10: true, 676 }, 677 { 678 20: false, 679 }, 680 }`) 681 }) 682 683 t.Run(`in_map_literals`, func(t *testing.T) { 684 defer gtest.Catch(t) 685 686 testReprZero( 687 map[int]map[int]bool{10: {20: true}}, 688 `map[int]map[int]bool{10: {20: true}}`, 689 ) 690 691 testReprDef( 692 map[int]map[int]bool{10: {20: true}}, 693 `map[int]map[int]bool{ 694 10: { 695 20: true, 696 }, 697 }`) 698 }) 699 700 t.Run(`in_struct_literals`, func(t *testing.T) { 701 defer gtest.Catch(t) 702 703 type Tar struct{ Val map[int]bool } 704 705 testReprZero( 706 Tar{map[int]bool{10: true}}, 707 `grepr_test.Tar{map[int]bool{10: true}}`, 708 ) 709 }) 710 } 711 712 func Test_interfaces(t *testing.T) { 713 defer gtest.Catch(t) 714 715 testReprDef(any(10), `10`) 716 717 testReprDef(any(`str`), "`str`") 718 719 testReprDef([]any{10, 20}, `[]any{ 720 10, 721 20, 722 }`) 723 724 testReprDef( 725 []any{gg.TimeMilli(10), gg.TimeMicro(20)}, 726 `[]any{ 727 gg.TimeMilli(10), 728 gg.TimeMicro(20), 729 }`, 730 ) 731 732 testReprDef([]any{true, false}, `[]any{ 733 true, 734 false, 735 }`) 736 737 testReprDef( 738 []any{Bool(true), Bool(false)}, 739 `[]any{ 740 grepr_test.Bool(true), 741 grepr_test.Bool(false), 742 }`, 743 ) 744 745 testReprDef([]any{`one`, `two`}, `[]any{ 746 `+"`one`"+`, 747 `+"`two`"+`, 748 }`) 749 750 testReprDef( 751 []any{gg.ErrStr(`one`), Str(`two`)}, 752 `[]any{ 753 gg.ErrStr(`+"`one`"+`), 754 grepr_test.Str(`+"`two`"+`), 755 }`, 756 ) 757 758 testReprDef([]any{Struct1{10}, Struct2{20, 30}}, `[]any{ 759 grepr_test.Struct1{10}, 760 grepr_test.Struct2{ 761 A: 20, 762 B: 30, 763 }, 764 }`) 765 766 testReprZero[r.Type](nil, `nil`) 767 testReprZero[r.Type](gg.Type[int](), `gg.Type[int]()`) 768 testReprZero[r.Type](gg.Type[string](), `gg.Type[string]()`) 769 } 770 771 func Test_pkg_names(t *testing.T) { 772 defer gtest.Catch(t) 773 774 { 775 type Tar []gg.Buf 776 777 testReprDef( 778 Tar{gg.Buf(`one`), gg.Buf(`two`), gg.Buf(`three`)}, 779 `grepr_test.Tar{ 780 gg.Buf(`+"`one`"+`), 781 gg.Buf(`+"`two`"+`), 782 gg.Buf(`+"`three`"+`), 783 }`, 784 ) 785 } 786 787 { 788 type Tar []any 789 790 testReprDef( 791 Tar{gg.TimeMilli(10), gg.TimeMicro(20)}, 792 `grepr_test.Tar{ 793 gg.TimeMilli(10), 794 gg.TimeMicro(20), 795 }`, 796 ) 797 } 798 } 799 800 func TestConf_pkg_names_strip(t *testing.T) { 801 defer gtest.Catch(t) 802 803 { 804 conf := grepr.ConfDefault 805 conf.Pkg = `grepr_test` 806 807 testReprC(conf, testOuter, testOuterStringDefPkgStrip) 808 809 testReprC( 810 conf, 811 Struct1Any{gg.TimeMicro(10)}, 812 `Struct1Any{gg.TimeMicro(10)}`, 813 ) 814 } 815 816 { 817 conf := grepr.ConfDefault 818 conf.Pkg = `gg` 819 820 testReprC(conf, testOuter, `grepr_test.Outer{ 821 OuterName: `+"`outer`"+`, 822 Embed: grepr_test.Embed{EmbedId: 20}, 823 Inner: &grepr_test.Inner{ 824 InnerId: Ptr(30), 825 InnerName: Ptr(`+"`inner`"+`), 826 }, 827 }`) 828 829 testReprC( 830 conf, 831 Struct1Any{gg.TimeMicro(10)}, 832 `grepr_test.Struct1Any{TimeMicro(10)}`, 833 ) 834 } 835 836 // Not fully implemented. 837 // TODO either implement properly, or drop `Conf.Pkg`. 838 // 839 // { 840 // var conf grepr.Conf 841 // testReprC(conf, []Struct0{{}}, `[]grepr_test.Struct0{{}}`) 842 // conf.Pkg = `grepr_test` 843 // testReprC(conf, []Struct0{{}}, `[]Struct0{{}}`) 844 // } 845 } 846 847 func ExampleString() { 848 fmt.Println(grepr.String(testOuter)) 849 // Output: 850 // grepr_test.Outer{ 851 // OuterName: `outer`, 852 // Embed: grepr_test.Embed{EmbedId: 20}, 853 // Inner: &grepr_test.Inner{ 854 // InnerId: gg.Ptr(30), 855 // InnerName: gg.Ptr(`inner`), 856 // }, 857 // } 858 } 859 860 func BenchmarkString_num(b *testing.B) { 861 for ind := 0; ind < b.N; ind++ { 862 gg.Nop1(grepr.String(10)) 863 } 864 } 865 866 func BenchmarkString_str(b *testing.B) { 867 for ind := 0; ind < b.N; ind++ { 868 gg.Nop1(grepr.String(`str`)) 869 } 870 } 871 872 func BenchmarkString_struct_flat(b *testing.B) { 873 for ind := 0; ind < b.N; ind++ { 874 gg.Nop1(grepr.String(testEmbed)) 875 } 876 } 877 878 func BenchmarkString_struct_nested_fmt(b *testing.B) { 879 for ind := 0; ind < b.N; ind++ { 880 gg.Nop1(gg.GoString(testOuter)) 881 } 882 } 883 884 func BenchmarkString_struct_nested_grepr(b *testing.B) { 885 for ind := 0; ind < b.N; ind++ { 886 gg.Nop1(grepr.String(testOuter)) 887 } 888 } 889 890 func BenchmarkString_struct_nested_grepr_elide_pkg(b *testing.B) { 891 conf := grepr.ConfDefault 892 conf.Pkg = `grepr_test` 893 894 for ind := 0; ind < b.N; ind++ { 895 gg.Nop1(grepr.StringC(conf, testOuter)) 896 } 897 } 898 899 func BenchmarkString_fmt_GoStringer(b *testing.B) { 900 src := gg.Set[int]{} 901 gg.Nop1(fmt.GoStringer(src)) 902 strEq(grepr.String(src), `gg.Set[int]{}`) 903 904 b.ResetTimer() 905 906 for ind := 0; ind < b.N; ind++ { 907 gg.Nop1(grepr.String(src)) 908 } 909 } 910 911 func Test_cyclic_1(t *testing.T) { 912 defer gtest.Catch(t) 913 914 cyclic := Cyclic{Id: 10} 915 cyclic.Cyclic = &cyclic 916 917 gtest.Is(&cyclic, cyclic.Cyclic) 918 testCyclic(&cyclic) 919 } 920 921 func Test_cyclic_2(t *testing.T) { 922 defer gtest.Catch(t) 923 924 cyclic0 := Cyclic{Id: 10} 925 cyclic1 := Cyclic{Id: 20} 926 927 cyclic0.Cyclic = &cyclic1 928 cyclic1.Cyclic = &cyclic0 929 930 gtest.Is(&cyclic0, cyclic1.Cyclic) 931 gtest.Is(&cyclic1, cyclic0.Cyclic) 932 933 testCyclic(&cyclic0) 934 } 935 936 /* 937 For now, this verifies the following: 938 939 * We eventually terminate. 940 * We mark visited references. 941 942 TODO verify the exact output structure. It can be broken by unsafe hacks such as 943 `gg.AnyNoEscUnsafe`. 944 */ 945 func testCyclic[A any](src A) { 946 gtest.TextHas(grepr.String(src), `/* visited */ (*`) 947 } 948 949 func BenchmarkString_cyclic(b *testing.B) { 950 cyclic0 := Cyclic{Id: 10} 951 cyclic1 := Cyclic{Id: 20} 952 953 cyclic0.Cyclic = &cyclic1 954 cyclic1.Cyclic = &cyclic0 955 956 for ind := 0; ind < b.N; ind++ { 957 gg.Nop1(grepr.String(&cyclic0)) 958 } 959 }