github.com/patricebensoussan/go/codec@v1.2.99/values_test.go (about) 1 // comment this out // + build testing 2 3 // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved. 4 // Use of this source code is governed by a MIT license found in the LICENSE file. 5 6 package codec 7 8 // This file contains values used by tests and benchmarks. 9 // The benchmarks will test performance against other libraries 10 // (encoding/json, json-iterator, bson, gob, etc). 11 // Consequently, we only use values that will parse well in all engines, 12 // and only leverage features that work across multiple libraries for a truer comparison. 13 // For example, 14 // - JSON/BSON do not like maps with keys that are not strings, 15 // so we only use maps with string keys here. 16 // - _struct options are not honored by other libraries, 17 // so we don't use them in this file. 18 19 import ( 20 "math" 21 "strconv" 22 "strings" 23 ) 24 25 // func init() { 26 // rt := reflect.TypeOf((*TestStruc)(nil)).Elem() 27 // defTypeInfos.get(rt2id(rt), rt) 28 // } 29 30 const numStrUi64T = 32 // use 8, prefer 32, test with 1024 31 32 type wrapSliceUint64 []uint64 33 type wrapSliceString []string 34 type wrapUint64 uint64 35 type wrapString string 36 type wrapUint64Slice []wrapUint64 37 type wrapStringSlice []wrapString 38 39 // some other types 40 41 type stringUint64T struct { 42 S string 43 U uint64 44 } 45 46 type AnonInTestStruc struct { 47 AS string 48 AI64 int64 49 AI16 int16 50 AUi64 uint64 51 ASslice []string 52 AI64slice []int64 53 AUi64slice []uint64 54 AF64slice []float64 55 AF32slice []float32 56 57 AMSS map[string]string 58 // AMI32U32 map[int32]uint32 59 // AMU32F64 map[uint32]float64 // json/bson do not like it 60 AMSU64 map[string]uint64 61 62 AI64arr8 [8]int64 63 64 // use these to test 0-len or nil slices/maps/arrays 65 AI64arr0 [0]int64 66 AI64slice0 []int64 67 AUi64sliceN []uint64 68 AMSU64N map[string]uint64 69 AMSU64E map[string]uint64 70 } 71 72 // testSimpleFields is a sub-set of TestStrucCommon 73 type testSimpleFields struct { 74 S string 75 76 I64 int64 77 I8 int8 78 79 Ui64 uint64 80 Ui8 uint8 81 82 F64 float64 83 F32 float32 84 85 B bool 86 87 Sslice []string 88 I32slice []int32 89 Ui64slice []uint64 90 Ui8slice []uint8 91 Bslice []bool 92 93 Iptrslice []*int64 94 95 WrapSliceInt64 wrapSliceUint64 96 WrapSliceString wrapSliceString 97 98 Msint map[string]int 99 } 100 101 type TestStrucCommon struct { 102 S string 103 104 I64 int64 105 I32 int32 106 I16 int16 107 I8 int8 108 109 I64n int64 110 I32n int32 111 I16n int16 112 I8n int8 113 114 Ui64 uint64 115 Ui32 uint32 116 Ui16 uint16 117 Ui8 uint8 118 119 F64 float64 120 F32 float32 121 122 B bool 123 By uint8 // byte: msgp doesn't like byte 124 125 Sslice []string 126 I64slice []int64 127 I32slice []int32 128 Ui64slice []uint64 129 Ui8slice []uint8 130 Bslice []bool 131 Byslice []byte 132 133 BytesSlice [][]byte 134 135 Iptrslice []*int64 136 137 WrapSliceInt64 wrapSliceUint64 138 WrapSliceString wrapSliceString 139 140 Msint map[string]int 141 142 Msbytes map[string][]byte 143 144 Simplef testSimpleFields 145 146 SstrUi64T []stringUint64T 147 MstrUi64T map[string]*stringUint64T 148 149 AnonInTestStruc 150 151 NotAnon AnonInTestStruc 152 153 // R Raw // Testing Raw must be explicitly turned on, so use standalone test 154 // Rext RawExt // Testing RawExt is tricky, so use standalone test 155 156 Nmap map[string]bool //don't set this, so we can test for nil 157 Nslice []byte //don't set this, so we can test for nil 158 Nint64 *int64 //don't set this, so we can test for nil 159 } 160 161 type TestStruc struct { 162 // _struct struct{} `json:",omitempty"` //set omitempty for every field 163 164 TestStrucCommon 165 166 Mtsptr map[string]*TestStruc 167 Mts map[string]TestStruc 168 Its []*TestStruc 169 Nteststruc *TestStruc 170 } 171 172 func populateTestStrucCommon(ts *TestStrucCommon, n int, bench, useInterface, useStringKeyOnly bool) { 173 var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464 174 175 // if bench, do not use uint64 values > math.MaxInt64, as bson, etc cannot decode them 176 177 var a = AnonInTestStruc{ 178 // There's more leeway in altering this. 179 AS: strRpt(n, "A-String"), 180 AI64: -64646464, 181 AI16: 1616, 182 AUi64: 64646464, 183 // (U+1D11E)G-clef character may be represented in json as "\uD834\uDD1E". 184 // single reverse solidus character may be represented in json as "\u005C". 185 // include these in ASslice below. 186 ASslice: []string{ 187 strRpt(n, "Aone"), 188 strRpt(n, "Atwo"), 189 strRpt(n, "Athree"), 190 strRpt(n, "Afour.reverse_solidus.\u005c"), 191 strRpt(n, "Afive.Gclef.\U0001d11E\"ugorji\"done.")}, 192 AI64slice: []int64{ 193 0, 1, -1, -22, 333, -4444, 55555, -666666, 194 // msgpack ones 195 -48, -32, -24, -8, 32, 127, 192, 255, 196 // standard ones 197 0, -1, 1, 198 math.MaxInt8, math.MaxInt8 + 4, math.MaxInt8 - 4, 199 math.MaxInt16, math.MaxInt16 + 4, math.MaxInt16 - 4, 200 math.MaxInt32, math.MaxInt32 + 4, math.MaxInt32 - 4, 201 math.MaxInt64, math.MaxInt64 - 4, 202 math.MinInt8, math.MinInt8 + 4, math.MinInt8 - 4, 203 math.MinInt16, math.MinInt16 + 4, math.MinInt16 - 4, 204 math.MinInt32, math.MinInt32 + 4, math.MinInt32 - 4, 205 math.MinInt64, math.MinInt64 + 4, 206 }, 207 AUi64slice: []uint64{ 208 0, 1, 22, 333, 4444, 55555, 666666, 209 // standard ones 210 math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4, 211 math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4, 212 math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4, 213 }, 214 AMSU64: map[string]uint64{ 215 strRpt(n, "1"): 1, 216 strRpt(n, "22"): 2, 217 strRpt(n, "333"): 3, 218 strRpt(n, "4444"): 4, 219 }, 220 AMSS: map[string]string{ 221 strRpt(n, "1"): strRpt(n, "1"), 222 strRpt(n, "22"): strRpt(n, "22"), 223 strRpt(n, "333"): strRpt(n, "333"), 224 strRpt(n, "4444"): strRpt(n, "4444"), 225 }, 226 227 AI64arr8: [...]int64{1, 8, 2, 7, 3, 6, 4, 5}, 228 229 // Note: +/- inf, NaN, and other non-representable numbers should not be explicitly tested here 230 231 AF64slice: []float64{ 232 11.11e-11, -11.11e+11, 233 2.222e+12, -2.222e-12, 234 -555.55e-5, 555.55e+5, 235 666.66e-6, -666.66e+6, 236 7777.7777e-7, -7777.7777e-7, 237 -8888.8888e+8, 8888.8888e+8, 238 -99999.9999e+9, 99999.9999e+9, 239 // these below are hairy enough to need strconv.ParseFloat 240 33.33e-33, -33.33e+33, 241 44.44e+44, -44.44e-44, 242 // standard ones 243 0, -1, 1, 244 // math.Inf(1), math.Inf(-1), 245 math.Pi, math.Phi, math.E, 246 math.MaxFloat64, math.SmallestNonzeroFloat64, 247 }, 248 AF32slice: []float32{ 249 11.11e-1, -11.11e+1, 250 2.222e+2, -2.222e-2, 251 -55.55e-5, 55.55e+5, 252 66.66e-6, -66.66e+6, 253 777.777e-7, -777.777e-7, 254 -8.88e+8, 8.88e-8, 255 -99999.9999e+9, 99999.9999e+9, 256 // these below are hairy enough to need strconv.ParseFloat 257 33.33e-33, -33.33e+33, 258 // standard ones 259 0, -1, 1, 260 // math.Float32frombits(0x7FF00000), math.Float32frombits(0xFFF00000), //+inf and -inf 261 math.MaxFloat32, math.SmallestNonzeroFloat32, 262 }, 263 264 AI64slice0: []int64{}, 265 AUi64sliceN: nil, 266 AMSU64N: nil, 267 AMSU64E: map[string]uint64{}, 268 } 269 270 if !bench { 271 a.AUi64slice = append(a.AUi64slice, math.MaxUint64, math.MaxUint64-4) 272 } 273 *ts = TestStrucCommon{ 274 S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `), 275 276 // set the numbers close to the limits 277 I8: math.MaxInt8 * 2 / 3, // 8, 278 I8n: math.MinInt8 * 2 / 3, // 8, 279 I16: math.MaxInt16 * 2 / 3, // 16, 280 I16n: math.MinInt16 * 2 / 3, // 16, 281 I32: math.MaxInt32 * 2 / 3, // 32, 282 I32n: math.MinInt32 * 2 / 3, // 32, 283 I64: math.MaxInt64 * 2 / 3, // 64, 284 I64n: math.MinInt64 * 2 / 3, // 64, 285 286 Ui64: math.MaxUint64 * 2 / 3, // 64 287 Ui32: math.MaxUint32 * 2 / 3, // 32 288 Ui16: math.MaxUint16 * 2 / 3, // 16 289 Ui8: math.MaxUint8 * 2 / 3, // 8 290 291 F32: 3.402823e+38, // max representable float32 without losing precision 292 F64: 3.40281991833838838338e+53, 293 294 B: true, 295 By: 5, 296 297 Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")}, 298 I64slice: []int64{1111, 2222, 3333}, 299 I32slice: []int32{44, 55, 66}, 300 Ui64slice: []uint64{12121212, 34343434, 56565656}, 301 Ui8slice: []uint8{210, 211, 212}, 302 Bslice: []bool{true, false, true, false}, 303 Byslice: []byte{13, 14, 15}, 304 BytesSlice: [][]byte{ 305 []byte(strRpt(n, "one")), 306 []byte(strRpt(n, "two")), 307 []byte(strRpt(n, "\"three\"")), 308 }, 309 Msint: map[string]int{ 310 strRpt(n, "one"): 1, 311 strRpt(n, "two"): 2, 312 strRpt(n, "\"three\""): 3, 313 }, 314 Msbytes: map[string][]byte{ 315 strRpt(n, "one"): []byte(strRpt(n, "one")), 316 strRpt(n, "two"): []byte(strRpt(n, "two")), 317 strRpt(n, "\"three\""): []byte(strRpt(n, "\"three\"")), 318 }, 319 WrapSliceInt64: []uint64{4, 16, 64, 256}, 320 WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")}, 321 322 // R: Raw([]byte("goodbye")), 323 // Rext: RawExt{ 120, []byte("hello"), }, // MARKER: don't set this - it's hard to test 324 325 // make Simplef same as top-level 326 // MARKER: should this have slightly different values??? 327 Simplef: testSimpleFields{ 328 S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `), 329 330 // set the numbers close to the limits 331 I8: math.MaxInt8 * 2 / 3, // 8, 332 I64: math.MaxInt64 * 2 / 3, // 64, 333 334 Ui64: math.MaxUint64 * 2 / 3, // 64 335 Ui8: math.MaxUint8 * 2 / 3, // 8 336 337 F32: 3.402823e+38, // max representable float32 without losing precision 338 F64: 3.40281991833838838338e+53, 339 340 B: true, 341 342 Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")}, 343 I32slice: []int32{44, 55, 66}, 344 Ui64slice: []uint64{12121212, 34343434, 56565656}, 345 Ui8slice: []uint8{210, 211, 212}, 346 Bslice: []bool{true, false, true, false}, 347 348 Msint: map[string]int{ 349 strRpt(n, "one"): 1, 350 strRpt(n, "two"): 2, 351 strRpt(n, "\"three\""): 3, 352 }, 353 354 WrapSliceInt64: []uint64{4, 16, 64, 256}, 355 WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")}, 356 }, 357 358 SstrUi64T: make([]stringUint64T, numStrUi64T), // {{"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}}, 359 MstrUi64T: make(map[string]*stringUint64T, numStrUi64T), 360 AnonInTestStruc: a, 361 NotAnon: a, 362 } 363 364 for i := uint64(0); i < numStrUi64T; i++ { 365 ss := strings.Repeat(strconv.FormatUint(i, 10), int(i)) // 4) 366 ts.SstrUi64T[i] = stringUint64T{S: ss, U: i} 367 ts.MstrUi64T[ss] = &ts.SstrUi64T[i] 368 } 369 370 if bench { 371 ts.Ui64 = math.MaxInt64 * 2 / 3 372 ts.Simplef.Ui64 = ts.Ui64 373 } 374 375 //For benchmarks, some things will not work. 376 if !bench { 377 //json and bson require string keys in maps 378 //ts.M = map[interface{}]interface{}{ 379 // true: "true", 380 // int8(9): false, 381 //} 382 //gob cannot encode nil in element in array (encodeArray: nil element) 383 ts.Iptrslice = []*int64{nil, &i64a, nil, &i64b, nil, &i64c, nil, &i64d, nil} 384 // ts.Iptrslice = nil 385 } 386 if !useStringKeyOnly { 387 var _ byte = 0 // so this empty branch doesn't flag a warning 388 // ts.AnonInTestStruc.AMU32F64 = map[uint32]float64{1: 1, 2: 2, 3: 3} // Json/Bson barf 389 } 390 } 391 392 func newTestStruc(depth, n int, bench, useInterface, useStringKeyOnly bool) (ts *TestStruc) { 393 ts = &TestStruc{} 394 populateTestStrucCommon(&ts.TestStrucCommon, n, bench, useInterface, useStringKeyOnly) 395 if depth > 0 { 396 depth-- 397 if ts.Mtsptr == nil { 398 ts.Mtsptr = make(map[string]*TestStruc) 399 } 400 if ts.Mts == nil { 401 ts.Mts = make(map[string]TestStruc) 402 } 403 ts.Mtsptr[strRpt(n, "0")] = newTestStruc(depth, n, bench, useInterface, useStringKeyOnly) 404 ts.Mts[strRpt(n, "0")] = *(ts.Mtsptr[strRpt(n, "0")]) 405 ts.Its = append(ts.Its, ts.Mtsptr[strRpt(n, "0")]) 406 } 407 return 408 } 409 410 var testStrRptMap = make(map[int]map[string]string) 411 412 func strRpt(n int, s string) string { 413 if false { 414 // fmt.Printf(">>>> calling strings.Repeat on n: %d, key: %s\n", n, s) 415 return strings.Repeat(s, n) 416 } 417 m1, ok := testStrRptMap[n] 418 if !ok { 419 // fmt.Printf(">>>> making new map for n: %v\n", n) 420 m1 = make(map[string]string) 421 testStrRptMap[n] = m1 422 } 423 v1, ok := m1[s] 424 if !ok { 425 // fmt.Printf(">>>> creating new entry for key: %s\n", s) 426 v1 = strings.Repeat(s, n) 427 m1[s] = v1 428 } 429 return v1 430 } 431 432 // func wstrRpt(n int, s string) wrapBytes { 433 // return wrapBytes(bytes.Repeat([]byte(s), n)) 434 // }