values_test.go 9.7 KB

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