1 
2 //          Copyright Ferdinand Majerech 2011.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module dyaml.test.constructor;
8 
9 
10 version(unittest)
11 {
12 
13 import std.datetime;
14 import std.exception;
15 import std.path;
16 import std..string;
17 import std.typecons;
18 
19 import dyaml.test.common;
20 
21 
22 ///Expected results of loading test inputs.
23 Node[][string] expected;
24 
25 ///Initialize expected.
26 static this() @safe
27 {
28     expected["aliases-cdumper-bug"]         = constructAliasesCDumperBug();
29     expected["construct-binary"]            = constructBinary();
30     expected["construct-bool"]              = constructBool();
31     expected["construct-custom"]            = constructCustom();
32     expected["construct-float"]             = constructFloat();
33     expected["construct-int"]               = constructInt();
34     expected["construct-map"]               = constructMap();
35     expected["construct-merge"]             = constructMerge();
36     expected["construct-null"]              = constructNull();
37     expected["construct-omap"]              = constructOMap();
38     expected["construct-pairs"]             = constructPairs();
39     expected["construct-seq"]               = constructSeq();
40     expected["construct-set"]               = constructSet();
41     expected["construct-str-ascii"]         = constructStrASCII();
42     expected["construct-str"]               = constructStr();
43     expected["construct-str-utf8"]          = constructStrUTF8();
44     expected["construct-timestamp"]         = constructTimestamp();
45     expected["construct-value"]             = constructValue();
46     expected["duplicate-merge-key"]         = duplicateMergeKey();
47     expected["float-representer-2.3-bug"]   = floatRepresenterBug();
48     expected["invalid-single-quote-bug"]    = invalidSingleQuoteBug();
49     expected["more-floats"]                 = moreFloats();
50     expected["negative-float-bug"]          = negativeFloatBug();
51     expected["single-dot-is-not-float-bug"] = singleDotFloatBug();
52     expected["timestamp-bugs"]              = timestampBugs();
53     expected["utf16be"]                     = utf16be();
54     expected["utf16le"]                     = utf16le();
55     expected["utf8"]                        = utf8();
56     expected["utf8-implicit"]               = utf8implicit();
57 }
58 
59 ///Construct a pair of nodes with specified values.
60 Node.Pair pair(A, B)(A a, B b)
61 {
62     return Node.Pair(a,b);
63 }
64 
65 ///Test cases:
66 
67 Node[] constructAliasesCDumperBug() @safe
68 {
69     return [
70         Node(
71             [
72                 Node("today", "tag:yaml.org,2002:str"),
73                 Node("today", "tag:yaml.org,2002:str")
74             ],
75         "tag:yaml.org,2002:seq")
76     ];
77 }
78 
79 Node[] constructBinary() @safe
80 {
81     auto canonical   = "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;".representation.dup;
82     auto generic     = "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;".representation.dup;
83     auto description = "The binary value above is a tiny arrow encoded as a gif image.";
84 
85     return [
86         Node(
87             [
88                 pair(
89                     Node("canonical", "tag:yaml.org,2002:str"),
90                     Node(canonical, "tag:yaml.org,2002:binary")
91                 ),
92                 pair(
93                     Node("generic", "tag:yaml.org,2002:str"),
94                     Node(generic, "tag:yaml.org,2002:binary")
95                 ),
96                 pair(
97                     Node("description", "tag:yaml.org,2002:str"),
98                     Node(description, "tag:yaml.org,2002:str")
99                 )
100             ],
101         "tag:yaml.org,2002:map")
102     ];
103 }
104 
105 Node[] constructBool() @safe
106 {
107     const(bool) a = true;
108     immutable(bool) b = true;
109     const bool aa = true;
110     immutable bool bb = true;
111     return [
112         Node(
113             [
114                 pair(
115                     Node("canonical", "tag:yaml.org,2002:str"),
116                     Node(true, "tag:yaml.org,2002:bool")
117                 ),
118                 pair(
119                     Node("answer", "tag:yaml.org,2002:str"),
120                     Node(false, "tag:yaml.org,2002:bool")
121                 ),
122                 pair(
123                     Node("logical", "tag:yaml.org,2002:str"),
124                     Node(true, "tag:yaml.org,2002:bool")
125                 ),
126                 pair(
127                     Node("option", "tag:yaml.org,2002:str"),
128                     Node(true, "tag:yaml.org,2002:bool")
129                 ),
130                 pair(
131                     Node("constbool", "tag:yaml.org,2002:str"),
132                     Node(a, "tag:yaml.org,2002:bool")
133                 ),
134                 pair(
135                     Node("imutbool", "tag:yaml.org,2002:str"),
136                     Node(b, "tag:yaml.org,2002:bool")
137                 ),
138                 pair(
139                     Node("const_bool", "tag:yaml.org,2002:str"),
140                     Node(aa, "tag:yaml.org,2002:bool")
141                 ),
142                 pair(
143                     Node("imut_bool", "tag:yaml.org,2002:str"),
144                     Node(bb, "tag:yaml.org,2002:bool")
145                 ),
146                 pair(
147                     Node("but", "tag:yaml.org,2002:str"),
148                     Node(
149                             [
150                             pair(
151                                 Node("y", "tag:yaml.org,2002:str"),
152                                 Node("is a string", "tag:yaml.org,2002:str")
153                             ),
154                             pair(
155                                 Node("n", "tag:yaml.org,2002:str"),
156                                 Node("is a string", "tag:yaml.org,2002:str")
157                             )
158                         ],
159                     "tag:yaml.org,2002:map")
160                 )
161             ],
162         "tag:yaml.org,2002:map")
163     ];
164 }
165 
166 Node[] constructCustom() @safe
167 {
168     return [
169         Node(
170             [
171                 Node(new TestClass(1, 2, 3)),
172                 Node(TestStruct(10))
173             ],
174         "tag:yaml.org,2002:seq")
175     ];
176 }
177 
178 Node[] constructFloat() @safe
179 {
180     return [
181         Node(
182             [
183                 pair(
184                     Node("canonical", "tag:yaml.org,2002:str"),
185                     Node(685230.15L, "tag:yaml.org,2002:float")
186                 ),
187                 pair(
188                     Node("exponential", "tag:yaml.org,2002:str"),
189                     Node(685230.15L, "tag:yaml.org,2002:float")
190                 ),
191                 pair(
192                     Node("fixed", "tag:yaml.org,2002:str"),
193                     Node(685230.15L, "tag:yaml.org,2002:float")
194                 ),
195                 pair(
196                     Node("sexagesimal", "tag:yaml.org,2002:str"),
197                     Node(685230.15L, "tag:yaml.org,2002:float")
198                 ),
199                 pair(
200                     Node("negative infinity", "tag:yaml.org,2002:str"),
201                     Node(-real.infinity, "tag:yaml.org,2002:float")
202                 ),
203                 pair(
204                     Node("not a number", "tag:yaml.org,2002:str"),
205                     Node(real.nan, "tag:yaml.org,2002:float")
206                 )
207             ],
208         "tag:yaml.org,2002:map")
209     ];
210 }
211 
212 Node[] constructInt() @safe
213 {
214     return [
215         Node(
216             [
217                 pair(
218                     Node("canonical", "tag:yaml.org,2002:str"),
219                     Node(685230L, "tag:yaml.org,2002:int")
220                 ),
221                 pair(
222                     Node("decimal", "tag:yaml.org,2002:str"),
223                     Node(685230L, "tag:yaml.org,2002:int")
224                 ),
225                 pair(
226                     Node("octal", "tag:yaml.org,2002:str"),
227                     Node(685230L, "tag:yaml.org,2002:int")
228                 ),
229                 pair(
230                     Node("hexadecimal", "tag:yaml.org,2002:str"),
231                     Node(685230L, "tag:yaml.org,2002:int")
232                 ),
233                 pair(
234                     Node("binary", "tag:yaml.org,2002:str"),
235                     Node(685230L, "tag:yaml.org,2002:int")
236                 ),
237                 pair(
238                     Node("sexagesimal", "tag:yaml.org,2002:str"),
239                     Node(685230L, "tag:yaml.org,2002:int")
240                 )
241             ],
242         "tag:yaml.org,2002:map")
243     ];
244 }
245 
246 Node[] constructMap() @safe
247 {
248     return [
249         Node(
250             [
251                 pair(
252                     Node("Block style", "tag:yaml.org,2002:str"),
253                     Node(
254                         [
255                             pair(
256                                 Node("Clark", "tag:yaml.org,2002:str"),
257                                 Node("Evans", "tag:yaml.org,2002:str")
258                             ),
259                             pair(
260                                 Node("Brian", "tag:yaml.org,2002:str"),
261                                 Node("Ingerson", "tag:yaml.org,2002:str")
262                             ),
263                             pair(
264                                 Node("Oren", "tag:yaml.org,2002:str"),
265                                 Node("Ben-Kiki", "tag:yaml.org,2002:str")
266                             )
267                         ],
268                     "tag:yaml.org,2002:map")
269                 ),
270                 pair(
271                     Node("Flow style", "tag:yaml.org,2002:str"),
272                     Node(
273                         [
274                             pair(
275                                 Node("Clark", "tag:yaml.org,2002:str"),
276                                 Node("Evans", "tag:yaml.org,2002:str")
277                             ),
278                             pair(
279                                 Node("Brian", "tag:yaml.org,2002:str"),
280                                 Node("Ingerson", "tag:yaml.org,2002:str")
281                             ),
282                             pair(
283                                 Node("Oren", "tag:yaml.org,2002:str"),
284                                 Node("Ben-Kiki", "tag:yaml.org,2002:str")
285                             )
286                         ],
287                     "tag:yaml.org,2002:map")
288                 )
289             ],
290         "tag:yaml.org,2002:map")
291     ];
292 }
293 
294 Node[] constructMerge() @safe
295 {
296     return [
297         Node(
298             [
299                 Node(
300                     [
301                         pair(
302                             Node("x", "tag:yaml.org,2002:str"),
303                             Node(1L, "tag:yaml.org,2002:int")
304                         ),
305                         pair(
306                             Node("y", "tag:yaml.org,2002:str"),
307                             Node(2L, "tag:yaml.org,2002:int")
308                         )
309                     ],
310                 "tag:yaml.org,2002:map"),
311                 Node(
312                     [
313                         pair(
314                             Node("x", "tag:yaml.org,2002:str"),
315                             Node(0L, "tag:yaml.org,2002:int")
316                         ),
317                         pair(
318                             Node("y", "tag:yaml.org,2002:str"),
319                             Node(2L, "tag:yaml.org,2002:int")
320                         )
321                     ],
322                 "tag:yaml.org,2002:map"),
323                 Node(
324                     [
325                         pair(
326                             Node("r", "tag:yaml.org,2002:str"),
327                             Node(10L, "tag:yaml.org,2002:int")
328                         )
329                     ],
330                 "tag:yaml.org,2002:map"),
331                 Node(
332                     [
333                         pair(
334                             Node("r", "tag:yaml.org,2002:str"),
335                             Node(1L, "tag:yaml.org,2002:int")
336                         )
337                     ],
338                 "tag:yaml.org,2002:map"),
339                 Node(
340                     [
341                         pair(
342                             Node("x", "tag:yaml.org,2002:str"),
343                             Node(1L, "tag:yaml.org,2002:int")
344                         ),
345                         pair(
346                             Node("y", "tag:yaml.org,2002:str"),
347                             Node(2L, "tag:yaml.org,2002:int")
348                         ),
349                         pair(
350                             Node("r", "tag:yaml.org,2002:str"),
351                             Node(10L, "tag:yaml.org,2002:int")
352                         ),
353                         pair(
354                             Node("label", "tag:yaml.org,2002:str"),
355                             Node("center/big", "tag:yaml.org,2002:str")
356                         )
357                     ],
358                 "tag:yaml.org,2002:map"),
359                 Node(
360                     [
361                         pair(
362                             Node("r", "tag:yaml.org,2002:str"),
363                             Node(10L, "tag:yaml.org,2002:int")
364                         ),
365                         pair(
366                             Node("label", "tag:yaml.org,2002:str"),
367                             Node("center/big", "tag:yaml.org,2002:str")
368                         ),
369                         pair(
370                             Node("x", "tag:yaml.org,2002:str"),
371                             Node(1L, "tag:yaml.org,2002:int")
372                         ),
373                         pair(
374                             Node("y", "tag:yaml.org,2002:str"),
375                             Node(2L, "tag:yaml.org,2002:int")
376                         )
377                     ],
378                 "tag:yaml.org,2002:map"),
379                 Node(
380                     [
381                         pair(
382                             Node("label", "tag:yaml.org,2002:str"),
383                             Node("center/big", "tag:yaml.org,2002:str")
384                         ),
385                         pair(
386                             Node("x", "tag:yaml.org,2002:str"),
387                             Node(1L, "tag:yaml.org,2002:int")
388                         ),
389                         pair(
390                             Node("y", "tag:yaml.org,2002:str"),
391                             Node(2L, "tag:yaml.org,2002:int")
392                         ),
393                         pair(
394                             Node("r", "tag:yaml.org,2002:str"),
395                             Node(10L, "tag:yaml.org,2002:int")
396                         )
397                     ],
398                 "tag:yaml.org,2002:map"),
399                 Node(
400                     [
401                         pair(
402                             Node("x", "tag:yaml.org,2002:str"),
403                             Node(1L, "tag:yaml.org,2002:int")
404                         ),
405                         pair(
406                             Node("label", "tag:yaml.org,2002:str"),
407                             Node("center/big", "tag:yaml.org,2002:str")
408                         ),
409                         pair(
410                             Node("r", "tag:yaml.org,2002:str"),
411                             Node(10L, "tag:yaml.org,2002:int")
412                         ),
413                         pair(
414                             Node("y", "tag:yaml.org,2002:str"),
415                             Node(2L, "tag:yaml.org,2002:int")
416                         )
417                     ],
418                 "tag:yaml.org,2002:map")
419             ],
420         "tag:yaml.org,2002:seq")
421     ];
422 }
423 
424 Node[] constructNull() @safe
425 {
426     return [
427         Node(YAMLNull(), "tag:yaml.org,2002:null"),
428         Node(
429             [
430                 pair(
431                     Node("empty", "tag:yaml.org,2002:str"),
432                     Node(YAMLNull(), "tag:yaml.org,2002:null")
433                 ),
434                 pair(
435                     Node("canonical", "tag:yaml.org,2002:str"),
436                     Node(YAMLNull(), "tag:yaml.org,2002:null")
437                 ),
438                 pair(
439                     Node("english", "tag:yaml.org,2002:str"),
440                     Node(YAMLNull(), "tag:yaml.org,2002:null")
441                 ),
442                 pair(
443                     Node(YAMLNull(), "tag:yaml.org,2002:null"),
444                     Node("null key", "tag:yaml.org,2002:str")
445                 )
446             ],
447         "tag:yaml.org,2002:map"),
448         Node(
449             [
450                 pair(
451                     Node("sparse", "tag:yaml.org,2002:str"),
452                     Node(
453                         [
454                             Node(YAMLNull(), "tag:yaml.org,2002:null"),
455                             Node("2nd entry", "tag:yaml.org,2002:str"),
456                             Node(YAMLNull(), "tag:yaml.org,2002:null"),
457                             Node("4th entry", "tag:yaml.org,2002:str"),
458                             Node(YAMLNull(), "tag:yaml.org,2002:null")
459                         ],
460                     "tag:yaml.org,2002:seq")
461                 )
462             ],
463         "tag:yaml.org,2002:map")
464     ];
465 }
466 
467 Node[] constructOMap() @safe
468 {
469     return [
470         Node(
471             [
472                 pair(
473                     Node("Bestiary", "tag:yaml.org,2002:str"),
474                     Node(
475                         [
476                             pair(
477                                 Node("aardvark", "tag:yaml.org,2002:str"),
478                                 Node("African pig-like ant eater. Ugly.", "tag:yaml.org,2002:str")
479                             ),
480                             pair(
481                                 Node("anteater", "tag:yaml.org,2002:str"),
482                                 Node("South-American ant eater. Two species.", "tag:yaml.org,2002:str")
483                             ),
484                             pair(
485                                 Node("anaconda", "tag:yaml.org,2002:str"),
486                                 Node("South-American constrictor snake. Scaly.", "tag:yaml.org,2002:str")
487                             )
488                         ],
489                     "tag:yaml.org,2002:omap")
490                 ),
491                 pair(
492                     Node("Numbers", "tag:yaml.org,2002:str"),
493                     Node(
494                         [
495                             pair(
496                                 Node("one", "tag:yaml.org,2002:str"),
497                                 Node(1L, "tag:yaml.org,2002:int")
498                             ),
499                             pair(
500                                 Node("two", "tag:yaml.org,2002:str"),
501                                 Node(2L, "tag:yaml.org,2002:int")
502                             ),
503                             pair(
504                                 Node("three", "tag:yaml.org,2002:str"),
505                                 Node(3L, "tag:yaml.org,2002:int")
506                             )
507                         ],
508                     "tag:yaml.org,2002:omap")
509                 )
510             ],
511         "tag:yaml.org,2002:map")
512     ];
513 }
514 
515 Node[] constructPairs() @safe
516 {
517     return [
518         Node(
519             [
520                 pair(
521                     Node("Block tasks", "tag:yaml.org,2002:str"),
522                     Node(
523                         [
524                             pair(Node("meeting", "tag:yaml.org,2002:str"), Node("with team.", "tag:yaml.org,2002:str")),
525                             pair(Node("meeting", "tag:yaml.org,2002:str"), Node("with boss.", "tag:yaml.org,2002:str")),
526                             pair(Node("break", "tag:yaml.org,2002:str"), Node("lunch.", "tag:yaml.org,2002:str")),
527                             pair(Node("meeting", "tag:yaml.org,2002:str"), Node("with client.", "tag:yaml.org,2002:str"))
528                         ],
529                     "tag:yaml.org,2002:pairs")
530                 ),
531                 pair(
532                     Node("Flow tasks", "tag:yaml.org,2002:str"),
533                     Node(
534                         [
535                             pair(Node("meeting", "tag:yaml.org,2002:str"), Node("with team", "tag:yaml.org,2002:str")),
536                             pair(Node("meeting", "tag:yaml.org,2002:str"), Node("with boss", "tag:yaml.org,2002:str"))
537                         ],
538                     "tag:yaml.org,2002:pairs")
539                 )
540             ],
541         "tag:yaml.org,2002:map")
542     ];
543 }
544 
545 Node[] constructSeq() @safe
546 {
547     return [
548         Node(
549             [
550                 pair(
551                     Node("Block style", "tag:yaml.org,2002:str"),
552                     Node([
553                           Node("Mercury", "tag:yaml.org,2002:str"),
554                           Node("Venus", "tag:yaml.org,2002:str"),
555                           Node("Earth", "tag:yaml.org,2002:str"),
556                           Node("Mars", "tag:yaml.org,2002:str"),
557                           Node("Jupiter", "tag:yaml.org,2002:str"),
558                           Node("Saturn", "tag:yaml.org,2002:str"),
559                           Node("Uranus", "tag:yaml.org,2002:str"),
560                           Node("Neptune", "tag:yaml.org,2002:str"),
561                           Node("Pluto", "tag:yaml.org,2002:str")
562                     ], "tag:yaml.org,2002:seq")
563                 ),
564                 pair(
565                     Node("Flow style", "tag:yaml.org,2002:str"),
566                     Node([
567                         Node("Mercury", "tag:yaml.org,2002:str"),
568                         Node("Venus", "tag:yaml.org,2002:str"),
569                         Node("Earth", "tag:yaml.org,2002:str"),
570                         Node("Mars", "tag:yaml.org,2002:str"),
571                         Node("Jupiter", "tag:yaml.org,2002:str"),
572                         Node("Saturn", "tag:yaml.org,2002:str"),
573                         Node("Uranus", "tag:yaml.org,2002:str"),
574                         Node("Neptune", "tag:yaml.org,2002:str"),
575                         Node("Pluto", "tag:yaml.org,2002:str")
576                     ], "tag:yaml.org,2002:seq")
577                 )
578             ],
579         "tag:yaml.org,2002:map")
580     ];
581 }
582 
583 Node[] constructSet() @safe
584 {
585     return [
586         Node(
587             [
588                 pair(
589                     Node("baseball players", "tag:yaml.org,2002:str"),
590                     Node(
591                         [
592                             Node("Mark McGwire", "tag:yaml.org,2002:str"),
593                             Node("Sammy Sosa", "tag:yaml.org,2002:str"),
594                             Node("Ken Griffey", "tag:yaml.org,2002:str")
595                         ],
596                     "tag:yaml.org,2002:set")
597                 ),
598                 pair(
599                     Node("baseball teams", "tag:yaml.org,2002:str"),
600                     Node(
601                             [
602                             Node("Boston Red Sox", "tag:yaml.org,2002:str"),
603                             Node("Detroit Tigers", "tag:yaml.org,2002:str"),
604                             Node("New York Yankees", "tag:yaml.org,2002:str")
605                         ],
606                     "tag:yaml.org,2002:set")
607                 )
608             ],
609         "tag:yaml.org,2002:map")
610     ];
611 }
612 
613 Node[] constructStrASCII() @safe
614 {
615     return [
616         Node("ascii string", "tag:yaml.org,2002:str")
617     ];
618 }
619 
620 Node[] constructStr() @safe
621 {
622     return [
623         Node(
624             [
625                 pair(
626                     Node("string", "tag:yaml.org,2002:str"),
627                     Node("abcd", "tag:yaml.org,2002:str")
628                 )
629             ],
630         "tag:yaml.org,2002:map")
631     ];
632 }
633 
634 Node[] constructStrUTF8() @safe
635 {
636     return [
637         Node("\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430", "tag:yaml.org,2002:str")
638     ];
639 }
640 
641 Node[] constructTimestamp() @safe
642 {
643     return [
644         Node(
645             [
646                 pair(
647                     Node("canonical", "tag:yaml.org,2002:str"),
648                     Node(SysTime(DateTime(2001, 12, 15, 2, 59, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp")
649                 ),
650                 pair(
651                     Node("valid iso8601", "tag:yaml.org,2002:str"),
652                     Node(SysTime(DateTime(2001, 12, 15, 2, 59, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp")
653                 ),
654                 pair(
655                     Node("space separated", "tag:yaml.org,2002:str"),
656                     Node(SysTime(DateTime(2001, 12, 15, 2, 59, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp")
657                 ),
658                 pair(
659                     Node("no time zone (Z)", "tag:yaml.org,2002:str"),
660                     Node(SysTime(DateTime(2001, 12, 15, 2, 59, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp")
661                 ),
662                 pair(
663                     Node("date (00:00:00Z)", "tag:yaml.org,2002:str"),
664                     Node(SysTime(DateTime(2002, 12, 14), UTC()), "tag:yaml.org,2002:timestamp")
665                 )
666             ],
667         "tag:yaml.org,2002:map")
668     ];
669 }
670 
671 Node[] constructValue() @safe
672 {
673     return [
674         Node(
675             [
676                 pair(
677                     Node("link with", "tag:yaml.org,2002:str"),
678                     Node(
679                         [
680                             Node("library1.dll", "tag:yaml.org,2002:str"),
681                             Node("library2.dll", "tag:yaml.org,2002:str")
682                         ],
683                     "tag:yaml.org,2002:seq")
684                 )
685             ],
686         "tag:yaml.org,2002:map"),
687         Node(
688             [
689                 pair(
690                     Node("link with", "tag:yaml.org,2002:str"),
691                     Node(
692                         [
693                             Node(
694                                 [
695                                     pair(
696                                         Node("=", "tag:yaml.org,2002:value"),
697                                         Node("library1.dll", "tag:yaml.org,2002:str")
698                                     ),
699                                     pair(
700                                         Node("version", "tag:yaml.org,2002:str"),
701                                         Node(1.2L, "tag:yaml.org,2002:float")
702                                     )
703                                 ],
704                             "tag:yaml.org,2002:map"),
705                             Node(
706                                 [
707                                     pair(
708                                         Node("=", "tag:yaml.org,2002:value"),
709                                         Node("library2.dll", "tag:yaml.org,2002:str")
710                                     ),
711                                     pair(
712                                         Node("version", "tag:yaml.org,2002:str"),
713                                         Node(2.3L, "tag:yaml.org,2002:float")
714                                     )
715                                 ],
716                             "tag:yaml.org,2002:map")
717                         ],
718                     "tag:yaml.org,2002:seq")
719                 )
720             ],
721         "tag:yaml.org,2002:map")
722     ];
723 }
724 
725 Node[] duplicateMergeKey() @safe
726 {
727     return [
728         Node(
729             [
730                 pair(
731                     Node("foo", "tag:yaml.org,2002:str"),
732                     Node("bar", "tag:yaml.org,2002:str")
733                 ),
734                 pair(
735                     Node("x", "tag:yaml.org,2002:str"),
736                     Node(1L, "tag:yaml.org,2002:int")
737                 ),
738                 pair(
739                     Node("y", "tag:yaml.org,2002:str"),
740                     Node(2L, "tag:yaml.org,2002:int")
741                 ),
742                 pair(
743                     Node("z", "tag:yaml.org,2002:str"),
744                     Node(3L, "tag:yaml.org,2002:int")
745                 ),
746                 pair(
747                     Node("t", "tag:yaml.org,2002:str"),
748                     Node(4L, "tag:yaml.org,2002:int")
749                 )
750             ],
751         "tag:yaml.org,2002:map")
752     ];
753 }
754 
755 Node[] floatRepresenterBug() @safe
756 {
757     return [
758         Node(
759             [
760                 pair(
761                     Node(1.0L, "tag:yaml.org,2002:float"),
762                     Node(1L, "tag:yaml.org,2002:int")
763                 ),
764                 pair(
765                     Node(real.infinity, "tag:yaml.org,2002:float"),
766                     Node(10L, "tag:yaml.org,2002:int")
767                 ),
768                 pair(
769                     Node(-real.infinity, "tag:yaml.org,2002:float"),
770                     Node(-10L, "tag:yaml.org,2002:int")
771                 ),
772                 pair(
773                     Node(real.nan, "tag:yaml.org,2002:float"),
774                     Node(100L, "tag:yaml.org,2002:int")
775                 )
776             ],
777         "tag:yaml.org,2002:map")
778     ];
779 }
780 
781 Node[] invalidSingleQuoteBug() @safe
782 {
783     return [
784         Node(
785             [
786                 Node("foo \'bar\'", "tag:yaml.org,2002:str"),
787                 Node("foo\n\'bar\'", "tag:yaml.org,2002:str")
788             ],
789         "tag:yaml.org,2002:seq")
790     ];
791 }
792 
793 Node[] moreFloats() @safe
794 {
795     return [
796         Node(
797             [
798                 Node(0.0L, "tag:yaml.org,2002:float"),
799                 Node(1.0L, "tag:yaml.org,2002:float"),
800                 Node(-1.0L, "tag:yaml.org,2002:float"),
801                 Node(real.infinity, "tag:yaml.org,2002:float"),
802                 Node(-real.infinity, "tag:yaml.org,2002:float"),
803                 Node(real.nan, "tag:yaml.org,2002:float"),
804                 Node(real.nan, "tag:yaml.org,2002:float")
805             ],
806         "tag:yaml.org,2002:seq")
807     ];
808 }
809 
810 Node[] negativeFloatBug() @safe
811 {
812     return [
813         Node(-1.0L, "tag:yaml.org,2002:float")
814     ];
815 }
816 
817 Node[] singleDotFloatBug() @safe
818 {
819     return [
820         Node(".", "tag:yaml.org,2002:str")
821     ];
822 }
823 
824 Node[] timestampBugs() @safe
825 {
826     return [
827         Node(
828             [
829                 Node(SysTime(DateTime(2001, 12, 15, 3, 29, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp"),
830                 Node(SysTime(DateTime(2001, 12, 14, 16, 29, 43), 1000000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp"),
831                 Node(SysTime(DateTime(2001, 12, 14, 21, 59, 43), 10100.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp"),
832                 Node(SysTime(DateTime(2001, 12, 14, 21, 59, 43), new immutable SimpleTimeZone(60.dur!"minutes")), "tag:yaml.org,2002:timestamp"),
833                 Node(SysTime(DateTime(2001, 12, 14, 21, 59, 43), new immutable SimpleTimeZone(-90.dur!"minutes")), "tag:yaml.org,2002:timestamp"),
834                 Node(SysTime(DateTime(2005, 7, 8, 17, 35, 4), 5176000.dur!"hnsecs", UTC()), "tag:yaml.org,2002:timestamp")
835             ],
836         "tag:yaml.org,2002:seq")
837     ];
838 }
839 
840 Node[] utf16be() @safe
841 {
842     return [
843         Node("UTF-16-BE", "tag:yaml.org,2002:str")
844     ];
845 }
846 
847 Node[] utf16le() @safe
848 {
849     return [
850         Node("UTF-16-LE", "tag:yaml.org,2002:str")
851     ];
852 }
853 
854 Node[] utf8() @safe
855 {
856     return [
857         Node("UTF-8", "tag:yaml.org,2002:str")
858     ];
859 }
860 
861 Node[] utf8implicit() @safe
862 {
863     return [
864         Node("implicit UTF-8", "tag:yaml.org,2002:str")
865     ];
866 }
867 
868 ///Testing custom YAML class type.
869 class TestClass
870 {
871     int x, y, z;
872 
873     this(int x, int y, int z) @safe
874     {
875         this.x = x;
876         this.y = y;
877         this.z = z;
878     }
879 
880     Node opCast(T: Node)() @safe
881     {
882         return Node(
883             [
884                 Node.Pair(
885                     Node("x", "tag:yaml.org,2002:str"),
886                     Node(x, "tag:yaml.org,2002:int")
887                 ),
888                 Node.Pair(
889                     Node("y", "tag:yaml.org,2002:str"),
890                     Node(y, "tag:yaml.org,2002:int")
891                 ),
892                 Node.Pair(
893                     Node("z", "tag:yaml.org,2002:str"),
894                     Node(z, "tag:yaml.org,2002:int")
895                 )
896             ],
897         "!tag1");
898     }
899 }
900 
901 ///Testing custom YAML struct type.
902 struct TestStruct
903 {
904     int value;
905 
906     this (int x) @safe
907     {
908         value = x;
909     }
910 
911     ///Constructor function for TestStruct.
912     this(ref Node node) @safe
913     {
914         value = node.as!string.to!int;
915     }
916 
917     ///Representer function for TestStruct.
918     Node opCast(T: Node)() @safe
919     {
920         return Node(value.to!string, "!tag2");
921     }
922 }
923 
924 /**
925  * Constructor unittest.
926  *
927  * Params:  dataFilename = File name to read from.
928  *          codeDummy    = Dummy .code filename, used to determine that
929  *                         .data file with the same name should be used in this test.
930  */
931 void testConstructor(string dataFilename, string codeDummy) @safe
932 {
933     string base = dataFilename.baseName.stripExtension;
934     enforce((base in expected) !is null,
935             new Exception("Unimplemented constructor test: " ~ base));
936 
937     auto loader        = Loader.fromFile(dataFilename);
938 
939     Node[] exp = expected[base];
940 
941     //Compare with expected results document by document.
942     size_t i;
943     foreach(node; loader)
944     {
945         if(node != exp[i])
946         {
947             static if(verbose)
948             {
949                 writeln("Expected value:");
950                 writeln(exp[i].debugString);
951                 writeln("\n");
952                 writeln("Actual value:");
953                 writeln(node.debugString);
954             }
955             assert(false);
956         }
957         ++i;
958     }
959     assert(i == exp.length);
960 }
961 
962 
963 @safe unittest
964 {
965     printProgress("D:YAML Constructor unittest");
966     run("testConstructor", &testConstructor, ["data", "code"]);
967 }
968 
969 } // version(unittest)