values_test.go 11 KB

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