values_test.go 11 KB

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