values_test.go 11 KB

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