values_test.go 12 KB

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