values_test.go 13 KB

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