decode_test.go 17 KB

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