values_test.go 12 KB

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