PageRenderTime 43ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/gopkg.in/yaml.v1/decode_test.go

https://gitlab.com/rpi-romlinch/drone
Go | 648 lines | 546 code | 48 blank | 54 comment | 17 complexity | d29035d58d06318cf246257a42acbb50 MD5 | raw file
  1. package yaml_test
  2. import (
  3. . "gopkg.in/check.v1"
  4. "gopkg.in/yaml.v1"
  5. "math"
  6. "reflect"
  7. "time"
  8. )
  9. var unmarshalIntTest = 123
  10. var unmarshalTests = []struct {
  11. data string
  12. value interface{}
  13. }{
  14. {
  15. "",
  16. &struct{}{},
  17. }, {
  18. "{}", &struct{}{},
  19. }, {
  20. "v: hi",
  21. map[string]string{"v": "hi"},
  22. }, {
  23. "v: hi", map[string]interface{}{"v": "hi"},
  24. }, {
  25. "v: true",
  26. map[string]string{"v": "true"},
  27. }, {
  28. "v: true",
  29. map[string]interface{}{"v": true},
  30. }, {
  31. "v: 10",
  32. map[string]interface{}{"v": 10},
  33. }, {
  34. "v: 0b10",
  35. map[string]interface{}{"v": 2},
  36. }, {
  37. "v: 0xA",
  38. map[string]interface{}{"v": 10},
  39. }, {
  40. "v: 4294967296",
  41. map[string]int64{"v": 4294967296},
  42. }, {
  43. "v: 0.1",
  44. map[string]interface{}{"v": 0.1},
  45. }, {
  46. "v: .1",
  47. map[string]interface{}{"v": 0.1},
  48. }, {
  49. "v: .Inf",
  50. map[string]interface{}{"v": math.Inf(+1)},
  51. }, {
  52. "v: -.Inf",
  53. map[string]interface{}{"v": math.Inf(-1)},
  54. }, {
  55. "v: -10",
  56. map[string]interface{}{"v": -10},
  57. }, {
  58. "v: -.1",
  59. map[string]interface{}{"v": -0.1},
  60. },
  61. // Simple values.
  62. {
  63. "123",
  64. &unmarshalIntTest,
  65. },
  66. // Floats from spec
  67. {
  68. "canonical: 6.8523e+5",
  69. map[string]interface{}{"canonical": 6.8523e+5},
  70. }, {
  71. "expo: 685.230_15e+03",
  72. map[string]interface{}{"expo": 685.23015e+03},
  73. }, {
  74. "fixed: 685_230.15",
  75. map[string]interface{}{"fixed": 685230.15},
  76. }, {
  77. "neginf: -.inf",
  78. map[string]interface{}{"neginf": math.Inf(-1)},
  79. }, {
  80. "fixed: 685_230.15",
  81. map[string]float64{"fixed": 685230.15},
  82. },
  83. //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
  84. //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
  85. // Bools from spec
  86. {
  87. "canonical: y",
  88. map[string]interface{}{"canonical": true},
  89. }, {
  90. "answer: NO",
  91. map[string]interface{}{"answer": false},
  92. }, {
  93. "logical: True",
  94. map[string]interface{}{"logical": true},
  95. }, {
  96. "option: on",
  97. map[string]interface{}{"option": true},
  98. }, {
  99. "option: on",
  100. map[string]bool{"option": true},
  101. },
  102. // Ints from spec
  103. {
  104. "canonical: 685230",
  105. map[string]interface{}{"canonical": 685230},
  106. }, {
  107. "decimal: +685_230",
  108. map[string]interface{}{"decimal": 685230},
  109. }, {
  110. "octal: 02472256",
  111. map[string]interface{}{"octal": 685230},
  112. }, {
  113. "hexa: 0x_0A_74_AE",
  114. map[string]interface{}{"hexa": 685230},
  115. }, {
  116. "bin: 0b1010_0111_0100_1010_1110",
  117. map[string]interface{}{"bin": 685230},
  118. }, {
  119. "bin: -0b101010",
  120. map[string]interface{}{"bin": -42},
  121. }, {
  122. "decimal: +685_230",
  123. map[string]int{"decimal": 685230},
  124. },
  125. //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
  126. // Nulls from spec
  127. {
  128. "empty:",
  129. map[string]interface{}{"empty": nil},
  130. }, {
  131. "canonical: ~",
  132. map[string]interface{}{"canonical": nil},
  133. }, {
  134. "english: null",
  135. map[string]interface{}{"english": nil},
  136. }, {
  137. "~: null key",
  138. map[interface{}]string{nil: "null key"},
  139. }, {
  140. "empty:",
  141. map[string]*bool{"empty": nil},
  142. },
  143. // Flow sequence
  144. {
  145. "seq: [A,B]",
  146. map[string]interface{}{"seq": []interface{}{"A", "B"}},
  147. }, {
  148. "seq: [A,B,C,]",
  149. map[string][]string{"seq": []string{"A", "B", "C"}},
  150. }, {
  151. "seq: [A,1,C]",
  152. map[string][]string{"seq": []string{"A", "1", "C"}},
  153. }, {
  154. "seq: [A,1,C]",
  155. map[string][]int{"seq": []int{1}},
  156. }, {
  157. "seq: [A,1,C]",
  158. map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
  159. },
  160. // Block sequence
  161. {
  162. "seq:\n - A\n - B",
  163. map[string]interface{}{"seq": []interface{}{"A", "B"}},
  164. }, {
  165. "seq:\n - A\n - B\n - C",
  166. map[string][]string{"seq": []string{"A", "B", "C"}},
  167. }, {
  168. "seq:\n - A\n - 1\n - C",
  169. map[string][]string{"seq": []string{"A", "1", "C"}},
  170. }, {
  171. "seq:\n - A\n - 1\n - C",
  172. map[string][]int{"seq": []int{1}},
  173. }, {
  174. "seq:\n - A\n - 1\n - C",
  175. map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
  176. },
  177. // Literal block scalar
  178. {
  179. "scalar: | # Comment\n\n literal\n\n \ttext\n\n",
  180. map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
  181. },
  182. // Folded block scalar
  183. {
  184. "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n",
  185. map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
  186. },
  187. // Map inside interface with no type hints.
  188. {
  189. "a: {b: c}",
  190. map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
  191. },
  192. // Structs and type conversions.
  193. {
  194. "hello: world",
  195. &struct{ Hello string }{"world"},
  196. }, {
  197. "a: {b: c}",
  198. &struct{ A struct{ B string } }{struct{ B string }{"c"}},
  199. }, {
  200. "a: {b: c}",
  201. &struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
  202. }, {
  203. "a: {b: c}",
  204. &struct{ A map[string]string }{map[string]string{"b": "c"}},
  205. }, {
  206. "a: {b: c}",
  207. &struct{ A *map[string]string }{&map[string]string{"b": "c"}},
  208. }, {
  209. "a:",
  210. &struct{ A map[string]string }{},
  211. }, {
  212. "a: 1",
  213. &struct{ A int }{1},
  214. }, {
  215. "a: 1",
  216. &struct{ A float64 }{1},
  217. }, {
  218. "a: 1.0",
  219. &struct{ A int }{1},
  220. }, {
  221. "a: 1.0",
  222. &struct{ A uint }{1},
  223. }, {
  224. "a: [1, 2]",
  225. &struct{ A []int }{[]int{1, 2}},
  226. }, {
  227. "a: 1",
  228. &struct{ B int }{0},
  229. }, {
  230. "a: 1",
  231. &struct {
  232. B int "a"
  233. }{1},
  234. }, {
  235. "a: y",
  236. &struct{ A bool }{true},
  237. },
  238. // Some cross type conversions
  239. {
  240. "v: 42",
  241. map[string]uint{"v": 42},
  242. }, {
  243. "v: -42",
  244. map[string]uint{},
  245. }, {
  246. "v: 4294967296",
  247. map[string]uint64{"v": 4294967296},
  248. }, {
  249. "v: -4294967296",
  250. map[string]uint64{},
  251. },
  252. // Overflow cases.
  253. {
  254. "v: 4294967297",
  255. map[string]int32{},
  256. }, {
  257. "v: 128",
  258. map[string]int8{},
  259. },
  260. // Quoted values.
  261. {
  262. "'1': '\"2\"'",
  263. map[interface{}]interface{}{"1": "\"2\""},
  264. }, {
  265. "v:\n- A\n- 'B\n\n C'\n",
  266. map[string][]string{"v": []string{"A", "B\nC"}},
  267. },
  268. // Explicit tags.
  269. {
  270. "v: !!float '1.1'",
  271. map[string]interface{}{"v": 1.1},
  272. }, {
  273. "v: !!null ''",
  274. map[string]interface{}{"v": nil},
  275. }, {
  276. "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
  277. map[string]interface{}{"v": 1},
  278. },
  279. // Anchors and aliases.
  280. {
  281. "a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
  282. &struct{ A, B, C, D int }{1, 2, 1, 2},
  283. }, {
  284. "a: &a {c: 1}\nb: *a",
  285. &struct {
  286. A, B struct {
  287. C int
  288. }
  289. }{struct{ C int }{1}, struct{ C int }{1}},
  290. }, {
  291. "a: &a [1, 2]\nb: *a",
  292. &struct{ B []int }{[]int{1, 2}},
  293. },
  294. // Bug #1133337
  295. {
  296. "foo: ''",
  297. map[string]*string{"foo": new(string)},
  298. }, {
  299. "foo: null",
  300. map[string]string{},
  301. },
  302. // Ignored field
  303. {
  304. "a: 1\nb: 2\n",
  305. &struct {
  306. A int
  307. B int "-"
  308. }{1, 0},
  309. },
  310. // Bug #1191981
  311. {
  312. "" +
  313. "%YAML 1.1\n" +
  314. "--- !!str\n" +
  315. `"Generic line break (no glyph)\n\` + "\n" +
  316. ` Generic line break (glyphed)\n\` + "\n" +
  317. ` Line separator\u2028\` + "\n" +
  318. ` Paragraph separator\u2029"` + "\n",
  319. "" +
  320. "Generic line break (no glyph)\n" +
  321. "Generic line break (glyphed)\n" +
  322. "Line separator\u2028Paragraph separator\u2029",
  323. },
  324. // Struct inlining
  325. {
  326. "a: 1\nb: 2\nc: 3\n",
  327. &struct {
  328. A int
  329. C inlineB `yaml:",inline"`
  330. }{1, inlineB{2, inlineC{3}}},
  331. },
  332. // bug 1243827
  333. {
  334. "a: -b_c",
  335. map[string]interface{}{"a": "-b_c"},
  336. },
  337. {
  338. "a: +b_c",
  339. map[string]interface{}{"a": "+b_c"},
  340. },
  341. {
  342. "a: 50cent_of_dollar",
  343. map[string]interface{}{"a": "50cent_of_dollar"},
  344. },
  345. // Duration
  346. {
  347. "a: 3s",
  348. map[string]time.Duration{"a": 3 * time.Second},
  349. },
  350. }
  351. type inlineB struct {
  352. B int
  353. inlineC `yaml:",inline"`
  354. }
  355. type inlineC struct {
  356. C int
  357. }
  358. func (s *S) TestUnmarshal(c *C) {
  359. for i, item := range unmarshalTests {
  360. t := reflect.ValueOf(item.value).Type()
  361. var value interface{}
  362. switch t.Kind() {
  363. case reflect.Map:
  364. value = reflect.MakeMap(t).Interface()
  365. case reflect.String:
  366. t := reflect.ValueOf(item.value).Type()
  367. v := reflect.New(t)
  368. value = v.Interface()
  369. default:
  370. pt := reflect.ValueOf(item.value).Type()
  371. pv := reflect.New(pt.Elem())
  372. value = pv.Interface()
  373. }
  374. err := yaml.Unmarshal([]byte(item.data), value)
  375. c.Assert(err, IsNil, Commentf("Item #%d", i))
  376. if t.Kind() == reflect.String {
  377. c.Assert(*value.(*string), Equals, item.value, Commentf("Item #%d", i))
  378. } else {
  379. c.Assert(value, DeepEquals, item.value, Commentf("Item #%d", i))
  380. }
  381. }
  382. }
  383. func (s *S) TestUnmarshalNaN(c *C) {
  384. value := map[string]interface{}{}
  385. err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
  386. c.Assert(err, IsNil)
  387. c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
  388. }
  389. var unmarshalErrorTests = []struct {
  390. data, error string
  391. }{
  392. {"v: !!float 'error'", "YAML error: Can't decode !!str 'error' as a !!float"},
  393. {"v: [A,", "YAML error: line 1: did not find expected node content"},
  394. {"v:\n- [A,", "YAML error: line 2: did not find expected node content"},
  395. {"a: *b\n", "YAML error: Unknown anchor 'b' referenced"},
  396. {"a: &a\n b: *a\n", "YAML error: Anchor 'a' value contains itself"},
  397. {"value: -", "YAML error: block sequence entries are not allowed in this context"},
  398. }
  399. func (s *S) TestUnmarshalErrors(c *C) {
  400. for _, item := range unmarshalErrorTests {
  401. var value interface{}
  402. err := yaml.Unmarshal([]byte(item.data), &value)
  403. c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
  404. }
  405. }
  406. var setterTests = []struct {
  407. data, tag string
  408. value interface{}
  409. }{
  410. {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
  411. {"_: [1,A]", "!!seq", []interface{}{1, "A"}},
  412. {"_: 10", "!!int", 10},
  413. {"_: null", "!!null", nil},
  414. {`_: BAR!`, "!!str", "BAR!"},
  415. {`_: "BAR!"`, "!!str", "BAR!"},
  416. {"_: !!foo 'BAR!'", "!!foo", "BAR!"},
  417. }
  418. var setterResult = map[int]bool{}
  419. type typeWithSetter struct {
  420. tag string
  421. value interface{}
  422. }
  423. func (o *typeWithSetter) SetYAML(tag string, value interface{}) (ok bool) {
  424. o.tag = tag
  425. o.value = value
  426. if i, ok := value.(int); ok {
  427. if result, ok := setterResult[i]; ok {
  428. return result
  429. }
  430. }
  431. return true
  432. }
  433. type setterPointerType struct {
  434. Field *typeWithSetter "_"
  435. }
  436. type setterValueType struct {
  437. Field typeWithSetter "_"
  438. }
  439. func (s *S) TestUnmarshalWithPointerSetter(c *C) {
  440. for _, item := range setterTests {
  441. obj := &setterPointerType{}
  442. err := yaml.Unmarshal([]byte(item.data), obj)
  443. c.Assert(err, IsNil)
  444. c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  445. c.Assert(obj.Field.tag, Equals, item.tag)
  446. c.Assert(obj.Field.value, DeepEquals, item.value)
  447. }
  448. }
  449. func (s *S) TestUnmarshalWithValueSetter(c *C) {
  450. for _, item := range setterTests {
  451. obj := &setterValueType{}
  452. err := yaml.Unmarshal([]byte(item.data), obj)
  453. c.Assert(err, IsNil)
  454. c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  455. c.Assert(obj.Field.tag, Equals, item.tag)
  456. c.Assert(obj.Field.value, DeepEquals, item.value)
  457. }
  458. }
  459. func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) {
  460. obj := &typeWithSetter{}
  461. err := yaml.Unmarshal([]byte(setterTests[0].data), obj)
  462. c.Assert(err, IsNil)
  463. c.Assert(obj.tag, Equals, setterTests[0].tag)
  464. value, ok := obj.value.(map[interface{}]interface{})
  465. c.Assert(ok, Equals, true)
  466. c.Assert(value["_"], DeepEquals, setterTests[0].value)
  467. }
  468. func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
  469. setterResult[2] = false
  470. setterResult[4] = false
  471. defer func() {
  472. delete(setterResult, 2)
  473. delete(setterResult, 4)
  474. }()
  475. m := map[string]*typeWithSetter{}
  476. data := `{abc: 1, def: 2, ghi: 3, jkl: 4}`
  477. err := yaml.Unmarshal([]byte(data), m)
  478. c.Assert(err, IsNil)
  479. c.Assert(m["abc"], NotNil)
  480. c.Assert(m["def"], IsNil)
  481. c.Assert(m["ghi"], NotNil)
  482. c.Assert(m["jkl"], IsNil)
  483. c.Assert(m["abc"].value, Equals, 1)
  484. c.Assert(m["ghi"].value, Equals, 3)
  485. }
  486. // From http://yaml.org/type/merge.html
  487. var mergeTests = `
  488. anchors:
  489. - &CENTER { "x": 1, "y": 2 }
  490. - &LEFT { "x": 0, "y": 2 }
  491. - &BIG { "r": 10 }
  492. - &SMALL { "r": 1 }
  493. # All the following maps are equal:
  494. plain:
  495. # Explicit keys
  496. "x": 1
  497. "y": 2
  498. "r": 10
  499. label: center/big
  500. mergeOne:
  501. # Merge one map
  502. << : *CENTER
  503. "r": 10
  504. label: center/big
  505. mergeMultiple:
  506. # Merge multiple maps
  507. << : [ *CENTER, *BIG ]
  508. label: center/big
  509. override:
  510. # Override
  511. << : [ *BIG, *LEFT, *SMALL ]
  512. "x": 1
  513. label: center/big
  514. shortTag:
  515. # Explicit short merge tag
  516. !!merge "<<" : [ *CENTER, *BIG ]
  517. label: center/big
  518. longTag:
  519. # Explicit merge long tag
  520. !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
  521. label: center/big
  522. inlineMap:
  523. # Inlined map
  524. << : {"x": 1, "y": 2, "r": 10}
  525. label: center/big
  526. inlineSequenceMap:
  527. # Inlined map in sequence
  528. << : [ *CENTER, {"r": 10} ]
  529. label: center/big
  530. `
  531. func (s *S) TestMerge(c *C) {
  532. var want = map[interface{}]interface{}{
  533. "x": 1,
  534. "y": 2,
  535. "r": 10,
  536. "label": "center/big",
  537. }
  538. var m map[string]interface{}
  539. err := yaml.Unmarshal([]byte(mergeTests), &m)
  540. c.Assert(err, IsNil)
  541. for name, test := range m {
  542. if name == "anchors" {
  543. continue
  544. }
  545. c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
  546. }
  547. }
  548. func (s *S) TestMergeStruct(c *C) {
  549. type Data struct {
  550. X, Y, R int
  551. Label string
  552. }
  553. want := Data{1, 2, 10, "center/big"}
  554. var m map[string]Data
  555. err := yaml.Unmarshal([]byte(mergeTests), &m)
  556. c.Assert(err, IsNil)
  557. for name, test := range m {
  558. if name == "anchors" {
  559. continue
  560. }
  561. c.Assert(test, Equals, want, Commentf("test %q failed", name))
  562. }
  563. }
  564. //var data []byte
  565. //func init() {
  566. // var err error
  567. // data, err = ioutil.ReadFile("/tmp/file.yaml")
  568. // if err != nil {
  569. // panic(err)
  570. // }
  571. //}
  572. //
  573. //func (s *S) BenchmarkUnmarshal(c *C) {
  574. // var err error
  575. // for i := 0; i < c.N; i++ {
  576. // var v map[string]interface{}
  577. // err = yaml.Unmarshal(data, &v)
  578. // }
  579. // if err != nil {
  580. // panic(err)
  581. // }
  582. //}
  583. //
  584. //func (s *S) BenchmarkMarshal(c *C) {
  585. // var v map[string]interface{}
  586. // yaml.Unmarshal(data, &v)
  587. // c.ResetTimer()
  588. // for i := 0; i < c.N; i++ {
  589. // yaml.Marshal(&v)
  590. // }
  591. //}