values_test.go 11 KB

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