decode_test.go 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. package yaml_test
  2. import (
  3. "errors"
  4. "math"
  5. "net"
  6. "reflect"
  7. "strings"
  8. "time"
  9. . "gopkg.in/check.v1"
  10. "gopkg.in/yaml.v2"
  11. )
  12. var unmarshalIntTest = 123
  13. var unmarshalTests = []struct {
  14. data string
  15. value interface{}
  16. }{
  17. {
  18. "",
  19. &struct{}{},
  20. }, {
  21. "{}", &struct{}{},
  22. }, {
  23. "v: hi",
  24. map[string]string{"v": "hi"},
  25. }, {
  26. "v: hi", map[string]interface{}{"v": "hi"},
  27. }, {
  28. "v: true",
  29. map[string]string{"v": "true"},
  30. }, {
  31. "v: true",
  32. map[string]interface{}{"v": true},
  33. }, {
  34. "v: 10",
  35. map[string]interface{}{"v": 10},
  36. }, {
  37. "v: 0b10",
  38. map[string]interface{}{"v": 2},
  39. }, {
  40. "v: 0xA",
  41. map[string]interface{}{"v": 10},
  42. }, {
  43. "v: 4294967296",
  44. map[string]int64{"v": 4294967296},
  45. }, {
  46. "v: 0.1",
  47. map[string]interface{}{"v": 0.1},
  48. }, {
  49. "v: .1",
  50. map[string]interface{}{"v": 0.1},
  51. }, {
  52. "v: .Inf",
  53. map[string]interface{}{"v": math.Inf(+1)},
  54. }, {
  55. "v: -.Inf",
  56. map[string]interface{}{"v": math.Inf(-1)},
  57. }, {
  58. "v: -10",
  59. map[string]interface{}{"v": -10},
  60. }, {
  61. "v: -.1",
  62. map[string]interface{}{"v": -0.1},
  63. },
  64. // Simple values.
  65. {
  66. "123",
  67. &unmarshalIntTest,
  68. },
  69. // Floats from spec
  70. {
  71. "canonical: 6.8523e+5",
  72. map[string]interface{}{"canonical": 6.8523e+5},
  73. }, {
  74. "expo: 685.230_15e+03",
  75. map[string]interface{}{"expo": 685.23015e+03},
  76. }, {
  77. "fixed: 685_230.15",
  78. map[string]interface{}{"fixed": 685230.15},
  79. }, {
  80. "neginf: -.inf",
  81. map[string]interface{}{"neginf": math.Inf(-1)},
  82. }, {
  83. "fixed: 685_230.15",
  84. map[string]float64{"fixed": 685230.15},
  85. },
  86. //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
  87. //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
  88. // Bools from spec
  89. {
  90. "canonical: y",
  91. map[string]interface{}{"canonical": true},
  92. }, {
  93. "answer: NO",
  94. map[string]interface{}{"answer": false},
  95. }, {
  96. "logical: True",
  97. map[string]interface{}{"logical": true},
  98. }, {
  99. "option: on",
  100. map[string]interface{}{"option": true},
  101. }, {
  102. "option: on",
  103. map[string]bool{"option": true},
  104. },
  105. // Ints from spec
  106. {
  107. "canonical: 685230",
  108. map[string]interface{}{"canonical": 685230},
  109. }, {
  110. "decimal: +685_230",
  111. map[string]interface{}{"decimal": 685230},
  112. }, {
  113. "octal: 02472256",
  114. map[string]interface{}{"octal": 685230},
  115. }, {
  116. "hexa: 0x_0A_74_AE",
  117. map[string]interface{}{"hexa": 685230},
  118. }, {
  119. "bin: 0b1010_0111_0100_1010_1110",
  120. map[string]interface{}{"bin": 685230},
  121. }, {
  122. "bin: -0b101010",
  123. map[string]interface{}{"bin": -42},
  124. }, {
  125. "decimal: +685_230",
  126. map[string]int{"decimal": 685230},
  127. },
  128. //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
  129. // Nulls from spec
  130. {
  131. "empty:",
  132. map[string]interface{}{"empty": nil},
  133. }, {
  134. "canonical: ~",
  135. map[string]interface{}{"canonical": nil},
  136. }, {
  137. "english: null",
  138. map[string]interface{}{"english": nil},
  139. }, {
  140. "~: null key",
  141. map[interface{}]string{nil: "null key"},
  142. }, {
  143. "empty:",
  144. map[string]*bool{"empty": nil},
  145. },
  146. // Flow sequence
  147. {
  148. "seq: [A,B]",
  149. map[string]interface{}{"seq": []interface{}{"A", "B"}},
  150. }, {
  151. "seq: [A,B,C,]",
  152. map[string][]string{"seq": []string{"A", "B", "C"}},
  153. }, {
  154. "seq: [A,1,C]",
  155. map[string][]string{"seq": []string{"A", "1", "C"}},
  156. }, {
  157. "seq: [A,1,C]",
  158. map[string][]int{"seq": []int{1}},
  159. }, {
  160. "seq: [A,1,C]",
  161. map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
  162. },
  163. // Block sequence
  164. {
  165. "seq:\n - A\n - B",
  166. map[string]interface{}{"seq": []interface{}{"A", "B"}},
  167. }, {
  168. "seq:\n - A\n - B\n - C",
  169. map[string][]string{"seq": []string{"A", "B", "C"}},
  170. }, {
  171. "seq:\n - A\n - 1\n - C",
  172. map[string][]string{"seq": []string{"A", "1", "C"}},
  173. }, {
  174. "seq:\n - A\n - 1\n - C",
  175. map[string][]int{"seq": []int{1}},
  176. }, {
  177. "seq:\n - A\n - 1\n - C",
  178. map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
  179. },
  180. // Literal block scalar
  181. {
  182. "scalar: | # Comment\n\n literal\n\n \ttext\n\n",
  183. map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
  184. },
  185. // Folded block scalar
  186. {
  187. "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n",
  188. map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
  189. },
  190. // Map inside interface with no type hints.
  191. {
  192. "a: {b: c}",
  193. map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
  194. },
  195. // Structs and type conversions.
  196. {
  197. "hello: world",
  198. &struct{ Hello string }{"world"},
  199. }, {
  200. "a: {b: c}",
  201. &struct{ A struct{ B string } }{struct{ B string }{"c"}},
  202. }, {
  203. "a: {b: c}",
  204. &struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
  205. }, {
  206. "a: {b: c}",
  207. &struct{ A map[string]string }{map[string]string{"b": "c"}},
  208. }, {
  209. "a: {b: c}",
  210. &struct{ A *map[string]string }{&map[string]string{"b": "c"}},
  211. }, {
  212. "a:",
  213. &struct{ A map[string]string }{},
  214. }, {
  215. "a: 1",
  216. &struct{ A int }{1},
  217. }, {
  218. "a: 1",
  219. &struct{ A float64 }{1},
  220. }, {
  221. "a: 1.0",
  222. &struct{ A int }{1},
  223. }, {
  224. "a: 1.0",
  225. &struct{ A uint }{1},
  226. }, {
  227. "a: [1, 2]",
  228. &struct{ A []int }{[]int{1, 2}},
  229. }, {
  230. "a: 1",
  231. &struct{ B int }{0},
  232. }, {
  233. "a: 1",
  234. &struct {
  235. B int "a"
  236. }{1},
  237. }, {
  238. "a: y",
  239. &struct{ A bool }{true},
  240. },
  241. // Some cross type conversions
  242. {
  243. "v: 42",
  244. map[string]uint{"v": 42},
  245. }, {
  246. "v: -42",
  247. map[string]uint{},
  248. }, {
  249. "v: 4294967296",
  250. map[string]uint64{"v": 4294967296},
  251. }, {
  252. "v: -4294967296",
  253. map[string]uint64{},
  254. },
  255. // int
  256. {
  257. "int_max: 2147483647",
  258. map[string]int{"int_max": math.MaxInt32},
  259. },
  260. {
  261. "int_min: -2147483648",
  262. map[string]int{"int_min": math.MinInt32},
  263. },
  264. {
  265. "int_overflow: 9223372036854775808", // math.MaxInt64 + 1
  266. map[string]int{},
  267. },
  268. // int64
  269. {
  270. "int64_max: 9223372036854775807",
  271. map[string]int64{"int64_max": math.MaxInt64},
  272. },
  273. {
  274. "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
  275. map[string]int64{"int64_max_base2": math.MaxInt64},
  276. },
  277. {
  278. "int64_min: -9223372036854775808",
  279. map[string]int64{"int64_min": math.MinInt64},
  280. },
  281. {
  282. "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
  283. map[string]int64{"int64_neg_base2": -math.MaxInt64},
  284. },
  285. {
  286. "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
  287. map[string]int64{},
  288. },
  289. // uint
  290. {
  291. "uint_min: 0",
  292. map[string]uint{"uint_min": 0},
  293. },
  294. {
  295. "uint_max: 4294967295",
  296. map[string]uint{"uint_max": math.MaxUint32},
  297. },
  298. {
  299. "uint_underflow: -1",
  300. map[string]uint{},
  301. },
  302. // uint64
  303. {
  304. "uint64_min: 0",
  305. map[string]uint{"uint64_min": 0},
  306. },
  307. {
  308. "uint64_max: 18446744073709551615",
  309. map[string]uint64{"uint64_max": math.MaxUint64},
  310. },
  311. {
  312. "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
  313. map[string]uint64{"uint64_max_base2": math.MaxUint64},
  314. },
  315. {
  316. "uint64_maxint64: 9223372036854775807",
  317. map[string]uint64{"uint64_maxint64": math.MaxInt64},
  318. },
  319. {
  320. "uint64_underflow: -1",
  321. map[string]uint64{},
  322. },
  323. // float32
  324. {
  325. "float32_max: 3.40282346638528859811704183484516925440e+38",
  326. map[string]float32{"float32_max": math.MaxFloat32},
  327. },
  328. {
  329. "float32_nonzero: 1.401298464324817070923729583289916131280e-45",
  330. map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
  331. },
  332. {
  333. "float32_maxuint64: 18446744073709551615",
  334. map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
  335. },
  336. {
  337. "float32_maxuint64+1: 18446744073709551616",
  338. map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
  339. },
  340. // float64
  341. {
  342. "float64_max: 1.797693134862315708145274237317043567981e+308",
  343. map[string]float64{"float64_max": math.MaxFloat64},
  344. },
  345. {
  346. "float64_nonzero: 4.940656458412465441765687928682213723651e-324",
  347. map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
  348. },
  349. {
  350. "float64_maxuint64: 18446744073709551615",
  351. map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
  352. },
  353. {
  354. "float64_maxuint64+1: 18446744073709551616",
  355. map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
  356. },
  357. // Overflow cases.
  358. {
  359. "v: 4294967297",
  360. map[string]int32{},
  361. }, {
  362. "v: 128",
  363. map[string]int8{},
  364. },
  365. // Quoted values.
  366. {
  367. "'1': '\"2\"'",
  368. map[interface{}]interface{}{"1": "\"2\""},
  369. }, {
  370. "v:\n- A\n- 'B\n\n C'\n",
  371. map[string][]string{"v": []string{"A", "B\nC"}},
  372. },
  373. // Explicit tags.
  374. {
  375. "v: !!float '1.1'",
  376. map[string]interface{}{"v": 1.1},
  377. }, {
  378. "v: !!null ''",
  379. map[string]interface{}{"v": nil},
  380. }, {
  381. "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
  382. map[string]interface{}{"v": 1},
  383. },
  384. // Non-specific tag (Issue #75)
  385. {
  386. "v: ! test",
  387. map[string]interface{}{"v": "test"},
  388. },
  389. // Anchors and aliases.
  390. {
  391. "a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
  392. &struct{ A, B, C, D int }{1, 2, 1, 2},
  393. }, {
  394. "a: &a {c: 1}\nb: *a",
  395. &struct {
  396. A, B struct {
  397. C int
  398. }
  399. }{struct{ C int }{1}, struct{ C int }{1}},
  400. }, {
  401. "a: &a [1, 2]\nb: *a",
  402. &struct{ B []int }{[]int{1, 2}},
  403. },
  404. // Bug #1133337
  405. {
  406. "foo: ''",
  407. map[string]*string{"foo": new(string)},
  408. }, {
  409. "foo: null",
  410. map[string]*string{"foo": nil},
  411. }, {
  412. "foo: null",
  413. map[string]string{"foo": ""},
  414. }, {
  415. "foo: null",
  416. map[string]interface{}{"foo": nil},
  417. },
  418. // Support for ~
  419. {
  420. "foo: ~",
  421. map[string]*string{"foo": nil},
  422. }, {
  423. "foo: ~",
  424. map[string]string{"foo": ""},
  425. }, {
  426. "foo: ~",
  427. map[string]interface{}{"foo": nil},
  428. },
  429. // Ignored field
  430. {
  431. "a: 1\nb: 2\n",
  432. &struct {
  433. A int
  434. B int "-"
  435. }{1, 0},
  436. },
  437. // Bug #1191981
  438. {
  439. "" +
  440. "%YAML 1.1\n" +
  441. "--- !!str\n" +
  442. `"Generic line break (no glyph)\n\` + "\n" +
  443. ` Generic line break (glyphed)\n\` + "\n" +
  444. ` Line separator\u2028\` + "\n" +
  445. ` Paragraph separator\u2029"` + "\n",
  446. "" +
  447. "Generic line break (no glyph)\n" +
  448. "Generic line break (glyphed)\n" +
  449. "Line separator\u2028Paragraph separator\u2029",
  450. },
  451. // Struct inlining
  452. {
  453. "a: 1\nb: 2\nc: 3\n",
  454. &struct {
  455. A int
  456. C inlineB `yaml:",inline"`
  457. }{1, inlineB{2, inlineC{3}}},
  458. },
  459. // Map inlining
  460. {
  461. "a: 1\nb: 2\nc: 3\n",
  462. &struct {
  463. A int
  464. C map[string]int `yaml:",inline"`
  465. }{1, map[string]int{"b": 2, "c": 3}},
  466. },
  467. // bug 1243827
  468. {
  469. "a: -b_c",
  470. map[string]interface{}{"a": "-b_c"},
  471. },
  472. {
  473. "a: +b_c",
  474. map[string]interface{}{"a": "+b_c"},
  475. },
  476. {
  477. "a: 50cent_of_dollar",
  478. map[string]interface{}{"a": "50cent_of_dollar"},
  479. },
  480. // Duration
  481. {
  482. "a: 3s",
  483. map[string]time.Duration{"a": 3 * time.Second},
  484. },
  485. // Issue #24.
  486. {
  487. "a: <foo>",
  488. map[string]string{"a": "<foo>"},
  489. },
  490. // Base 60 floats are obsolete and unsupported.
  491. {
  492. "a: 1:1\n",
  493. map[string]string{"a": "1:1"},
  494. },
  495. // Binary data.
  496. {
  497. "a: !!binary gIGC\n",
  498. map[string]string{"a": "\x80\x81\x82"},
  499. }, {
  500. "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
  501. map[string]string{"a": strings.Repeat("\x90", 54)},
  502. }, {
  503. "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n",
  504. map[string]string{"a": strings.Repeat("\x00", 52)},
  505. },
  506. // Ordered maps.
  507. {
  508. "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
  509. &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
  510. },
  511. // Issue #39.
  512. {
  513. "a:\n b:\n c: d\n",
  514. map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
  515. },
  516. // Custom map type.
  517. {
  518. "a: {b: c}",
  519. M{"a": M{"b": "c"}},
  520. },
  521. // Support encoding.TextUnmarshaler.
  522. {
  523. "a: 1.2.3.4\n",
  524. map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
  525. },
  526. {
  527. "a: 2015-02-24T18:19:39Z\n",
  528. map[string]time.Time{"a": time.Unix(1424801979, 0).In(time.UTC)},
  529. },
  530. // Encode empty lists as zero-length slices.
  531. {
  532. "a: []",
  533. &struct{ A []int }{[]int{}},
  534. },
  535. // UTF-16-LE
  536. {
  537. "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
  538. M{"ñoño": "very yes"},
  539. },
  540. // UTF-16-LE with surrogate.
  541. {
  542. "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
  543. M{"ñoño": "very yes 🟔"},
  544. },
  545. // UTF-16-BE
  546. {
  547. "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
  548. M{"ñoño": "very yes"},
  549. },
  550. // UTF-16-BE with surrogate.
  551. {
  552. "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
  553. M{"ñoño": "very yes 🟔"},
  554. },
  555. // YAML Float regex shouldn't match this
  556. {
  557. "a: 123456e1\n",
  558. M{"a": "123456e1"},
  559. }, {
  560. "a: 123456E1\n",
  561. M{"a": "123456E1"},
  562. },
  563. // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
  564. {
  565. "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
  566. map[interface{}]interface{}{
  567. "Reuse anchor": "Bar",
  568. "First occurrence": "Foo",
  569. "Second occurrence": "Foo",
  570. "Override anchor": "Bar",
  571. },
  572. },
  573. }
  574. type M map[interface{}]interface{}
  575. type inlineB struct {
  576. B int
  577. inlineC `yaml:",inline"`
  578. }
  579. type inlineC struct {
  580. C int
  581. }
  582. func (s *S) TestUnmarshal(c *C) {
  583. for i, item := range unmarshalTests {
  584. c.Logf("test %d: %q", i, item.data)
  585. t := reflect.ValueOf(item.value).Type()
  586. var value interface{}
  587. switch t.Kind() {
  588. case reflect.Map:
  589. value = reflect.MakeMap(t).Interface()
  590. case reflect.String:
  591. value = reflect.New(t).Interface()
  592. case reflect.Ptr:
  593. value = reflect.New(t.Elem()).Interface()
  594. default:
  595. c.Fatalf("missing case for %s", t)
  596. }
  597. err := yaml.Unmarshal([]byte(item.data), value)
  598. if _, ok := err.(*yaml.TypeError); !ok {
  599. c.Assert(err, IsNil)
  600. }
  601. if t.Kind() == reflect.String {
  602. c.Assert(*value.(*string), Equals, item.value)
  603. } else {
  604. c.Assert(value, DeepEquals, item.value)
  605. }
  606. }
  607. }
  608. func (s *S) TestUnmarshalNaN(c *C) {
  609. value := map[string]interface{}{}
  610. err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
  611. c.Assert(err, IsNil)
  612. c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
  613. }
  614. var unmarshalErrorTests = []struct {
  615. data, error string
  616. }{
  617. {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
  618. {"v: [A,", "yaml: line 1: did not find expected node content"},
  619. {"v:\n- [A,", "yaml: line 2: did not find expected node content"},
  620. {"a: *b\n", "yaml: unknown anchor 'b' referenced"},
  621. {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"},
  622. {"value: -", "yaml: block sequence entries are not allowed in this context"},
  623. {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
  624. {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
  625. {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
  626. {"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
  627. {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
  628. }
  629. func (s *S) TestUnmarshalErrors(c *C) {
  630. for _, item := range unmarshalErrorTests {
  631. var value interface{}
  632. err := yaml.Unmarshal([]byte(item.data), &value)
  633. c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
  634. }
  635. }
  636. var unmarshalerTests = []struct {
  637. data, tag string
  638. value interface{}
  639. }{
  640. {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
  641. {"_: [1,A]", "!!seq", []interface{}{1, "A"}},
  642. {"_: 10", "!!int", 10},
  643. {"_: null", "!!null", nil},
  644. {`_: BAR!`, "!!str", "BAR!"},
  645. {`_: "BAR!"`, "!!str", "BAR!"},
  646. {"_: !!foo 'BAR!'", "!!foo", "BAR!"},
  647. {`_: ""`, "!!str", ""},
  648. }
  649. var unmarshalerResult = map[int]error{}
  650. type unmarshalerType struct {
  651. value interface{}
  652. }
  653. func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
  654. if err := unmarshal(&o.value); err != nil {
  655. return err
  656. }
  657. if i, ok := o.value.(int); ok {
  658. if result, ok := unmarshalerResult[i]; ok {
  659. return result
  660. }
  661. }
  662. return nil
  663. }
  664. type unmarshalerPointer struct {
  665. Field *unmarshalerType "_"
  666. }
  667. type unmarshalerValue struct {
  668. Field unmarshalerType "_"
  669. }
  670. func (s *S) TestUnmarshalerPointerField(c *C) {
  671. for _, item := range unmarshalerTests {
  672. obj := &unmarshalerPointer{}
  673. err := yaml.Unmarshal([]byte(item.data), obj)
  674. c.Assert(err, IsNil)
  675. if item.value == nil {
  676. c.Assert(obj.Field, IsNil)
  677. } else {
  678. c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  679. c.Assert(obj.Field.value, DeepEquals, item.value)
  680. }
  681. }
  682. }
  683. func (s *S) TestUnmarshalerValueField(c *C) {
  684. for _, item := range unmarshalerTests {
  685. obj := &unmarshalerValue{}
  686. err := yaml.Unmarshal([]byte(item.data), obj)
  687. c.Assert(err, IsNil)
  688. c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  689. c.Assert(obj.Field.value, DeepEquals, item.value)
  690. }
  691. }
  692. func (s *S) TestUnmarshalerWholeDocument(c *C) {
  693. obj := &unmarshalerType{}
  694. err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
  695. c.Assert(err, IsNil)
  696. value, ok := obj.value.(map[interface{}]interface{})
  697. c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
  698. c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
  699. }
  700. func (s *S) TestUnmarshalerTypeError(c *C) {
  701. unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
  702. unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
  703. defer func() {
  704. delete(unmarshalerResult, 2)
  705. delete(unmarshalerResult, 4)
  706. }()
  707. type T struct {
  708. Before int
  709. After int
  710. M map[string]*unmarshalerType
  711. }
  712. var v T
  713. data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
  714. err := yaml.Unmarshal([]byte(data), &v)
  715. c.Assert(err, ErrorMatches, ""+
  716. "yaml: unmarshal errors:\n"+
  717. " line 1: cannot unmarshal !!str `A` into int\n"+
  718. " foo\n"+
  719. " bar\n"+
  720. " line 1: cannot unmarshal !!str `B` into int")
  721. c.Assert(v.M["abc"], NotNil)
  722. c.Assert(v.M["def"], IsNil)
  723. c.Assert(v.M["ghi"], NotNil)
  724. c.Assert(v.M["jkl"], IsNil)
  725. c.Assert(v.M["abc"].value, Equals, 1)
  726. c.Assert(v.M["ghi"].value, Equals, 3)
  727. }
  728. type proxyTypeError struct{}
  729. func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
  730. var s string
  731. var a int32
  732. var b int64
  733. if err := unmarshal(&s); err != nil {
  734. panic(err)
  735. }
  736. if s == "a" {
  737. if err := unmarshal(&b); err == nil {
  738. panic("should have failed")
  739. }
  740. return unmarshal(&a)
  741. }
  742. if err := unmarshal(&a); err == nil {
  743. panic("should have failed")
  744. }
  745. return unmarshal(&b)
  746. }
  747. func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
  748. type T struct {
  749. Before int
  750. After int
  751. M map[string]*proxyTypeError
  752. }
  753. var v T
  754. data := `{before: A, m: {abc: a, def: b}, after: B}`
  755. err := yaml.Unmarshal([]byte(data), &v)
  756. c.Assert(err, ErrorMatches, ""+
  757. "yaml: unmarshal errors:\n"+
  758. " line 1: cannot unmarshal !!str `A` into int\n"+
  759. " line 1: cannot unmarshal !!str `a` into int32\n"+
  760. " line 1: cannot unmarshal !!str `b` into int64\n"+
  761. " line 1: cannot unmarshal !!str `B` into int")
  762. }
  763. type failingUnmarshaler struct{}
  764. var failingErr = errors.New("failingErr")
  765. func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  766. return failingErr
  767. }
  768. func (s *S) TestUnmarshalerError(c *C) {
  769. err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
  770. c.Assert(err, Equals, failingErr)
  771. }
  772. type sliceUnmarshaler []int
  773. func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  774. var slice []int
  775. err := unmarshal(&slice)
  776. if err == nil {
  777. *su = slice
  778. return nil
  779. }
  780. var intVal int
  781. err = unmarshal(&intVal)
  782. if err == nil {
  783. *su = []int{intVal}
  784. return nil
  785. }
  786. return err
  787. }
  788. func (s *S) TestUnmarshalerRetry(c *C) {
  789. var su sliceUnmarshaler
  790. err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  791. c.Assert(err, IsNil)
  792. c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
  793. err = yaml.Unmarshal([]byte("1"), &su)
  794. c.Assert(err, IsNil)
  795. c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
  796. }
  797. // From http://yaml.org/type/merge.html
  798. var mergeTests = `
  799. anchors:
  800. list:
  801. - &CENTER { "x": 1, "y": 2 }
  802. - &LEFT { "x": 0, "y": 2 }
  803. - &BIG { "r": 10 }
  804. - &SMALL { "r": 1 }
  805. # All the following maps are equal:
  806. plain:
  807. # Explicit keys
  808. "x": 1
  809. "y": 2
  810. "r": 10
  811. label: center/big
  812. mergeOne:
  813. # Merge one map
  814. << : *CENTER
  815. "r": 10
  816. label: center/big
  817. mergeMultiple:
  818. # Merge multiple maps
  819. << : [ *CENTER, *BIG ]
  820. label: center/big
  821. override:
  822. # Override
  823. << : [ *BIG, *LEFT, *SMALL ]
  824. "x": 1
  825. label: center/big
  826. shortTag:
  827. # Explicit short merge tag
  828. !!merge "<<" : [ *CENTER, *BIG ]
  829. label: center/big
  830. longTag:
  831. # Explicit merge long tag
  832. !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
  833. label: center/big
  834. inlineMap:
  835. # Inlined map
  836. << : {"x": 1, "y": 2, "r": 10}
  837. label: center/big
  838. inlineSequenceMap:
  839. # Inlined map in sequence
  840. << : [ *CENTER, {"r": 10} ]
  841. label: center/big
  842. `
  843. func (s *S) TestMerge(c *C) {
  844. var want = map[interface{}]interface{}{
  845. "x": 1,
  846. "y": 2,
  847. "r": 10,
  848. "label": "center/big",
  849. }
  850. var m map[interface{}]interface{}
  851. err := yaml.Unmarshal([]byte(mergeTests), &m)
  852. c.Assert(err, IsNil)
  853. for name, test := range m {
  854. if name == "anchors" {
  855. continue
  856. }
  857. c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
  858. }
  859. }
  860. func (s *S) TestMergeStruct(c *C) {
  861. type Data struct {
  862. X, Y, R int
  863. Label string
  864. }
  865. want := Data{1, 2, 10, "center/big"}
  866. var m map[string]Data
  867. err := yaml.Unmarshal([]byte(mergeTests), &m)
  868. c.Assert(err, IsNil)
  869. for name, test := range m {
  870. if name == "anchors" {
  871. continue
  872. }
  873. c.Assert(test, Equals, want, Commentf("test %q failed", name))
  874. }
  875. }
  876. var unmarshalNullTests = []func() interface{}{
  877. func() interface{} { var v interface{}; v = "v"; return &v },
  878. func() interface{} { var s = "s"; return &s },
  879. func() interface{} { var s = "s"; sptr := &s; return &sptr },
  880. func() interface{} { var i = 1; return &i },
  881. func() interface{} { var i = 1; iptr := &i; return &iptr },
  882. func() interface{} { m := map[string]int{"s": 1}; return &m },
  883. func() interface{} { m := map[string]int{"s": 1}; return m },
  884. }
  885. func (s *S) TestUnmarshalNull(c *C) {
  886. for _, test := range unmarshalNullTests {
  887. item := test()
  888. zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
  889. err := yaml.Unmarshal([]byte("null"), item)
  890. c.Assert(err, IsNil)
  891. if reflect.TypeOf(item).Kind() == reflect.Map {
  892. c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
  893. } else {
  894. c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
  895. }
  896. }
  897. }
  898. func (s *S) TestUnmarshalSliceOnPreset(c *C) {
  899. // Issue #48.
  900. v := struct{ A []int }{[]int{1}}
  901. yaml.Unmarshal([]byte("a: [2]"), &v)
  902. c.Assert(v.A, DeepEquals, []int{2})
  903. }
  904. func (s *S) TestUnmarshalStrict(c *C) {
  905. v := struct{ A, B int }{}
  906. err := yaml.UnmarshalStrict([]byte("a: 1\nb: 2"), &v)
  907. c.Check(err, IsNil)
  908. err = yaml.Unmarshal([]byte("a: 1\nb: 2\nc: 3"), &v)
  909. c.Check(err, IsNil)
  910. err = yaml.UnmarshalStrict([]byte("a: 1\nb: 2\nc: 3"), &v)
  911. c.Check(err, ErrorMatches, "yaml: unmarshal errors:\n line 3: field c not found in struct struct { A int; B int }")
  912. }
  913. //var data []byte
  914. //func init() {
  915. // var err error
  916. // data, err = ioutil.ReadFile("/tmp/file.yaml")
  917. // if err != nil {
  918. // panic(err)
  919. // }
  920. //}
  921. //
  922. //func (s *S) BenchmarkUnmarshal(c *C) {
  923. // var err error
  924. // for i := 0; i < c.N; i++ {
  925. // var v map[string]interface{}
  926. // err = yaml.Unmarshal(data, &v)
  927. // }
  928. // if err != nil {
  929. // panic(err)
  930. // }
  931. //}
  932. //
  933. //func (s *S) BenchmarkMarshal(c *C) {
  934. // var v map[string]interface{}
  935. // yaml.Unmarshal(data, &v)
  936. // c.ResetTimer()
  937. // for i := 0; i < c.N; i++ {
  938. // yaml.Marshal(&v)
  939. // }
  940. //}