values_test.go 11 KB

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