OSDN Git Service

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