Yaffs site version 1.1
[yaffs-website] / vendor / symfony / yaml / Tests / ParserTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Yaml\Tests;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Yaml\Yaml;
16 use Symfony\Component\Yaml\Parser;
17
18 class ParserTest extends TestCase
19 {
20     /** @var Parser */
21     protected $parser;
22
23     protected function setUp()
24     {
25         $this->parser = new Parser();
26     }
27
28     protected function tearDown()
29     {
30         $this->parser = null;
31     }
32
33     /**
34      * @dataProvider getDataFormSpecifications
35      */
36     public function testSpecifications($file, $expected, $yaml, $comment)
37     {
38         $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
39     }
40
41     public function getDataFormSpecifications()
42     {
43         $parser = new Parser();
44         $path = __DIR__.'/Fixtures';
45
46         $tests = array();
47         $files = $parser->parse(file_get_contents($path.'/index.yml'));
48         foreach ($files as $file) {
49             $yamls = file_get_contents($path.'/'.$file.'.yml');
50
51             // split YAMLs documents
52             foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
53                 if (!$yaml) {
54                     continue;
55                 }
56
57                 $test = $parser->parse($yaml);
58                 if (isset($test['todo']) && $test['todo']) {
59                     // TODO
60                 } else {
61                     eval('$expected = '.trim($test['php']).';');
62
63                     $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']);
64                 }
65             }
66         }
67
68         return $tests;
69     }
70
71     public function testTabsInYaml()
72     {
73         // test tabs in YAML
74         $yamls = array(
75             "foo:\n     bar",
76             "foo:\n     bar",
77             "foo:\n      bar",
78             "foo:\n      bar",
79         );
80
81         foreach ($yamls as $yaml) {
82             try {
83                 $content = $this->parser->parse($yaml);
84
85                 $this->fail('YAML files must not contain tabs');
86             } catch (\Exception $e) {
87                 $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
88                 $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
89             }
90         }
91     }
92
93     public function testEndOfTheDocumentMarker()
94     {
95         $yaml = <<<'EOF'
96 --- %YAML:1.0
97 foo
98 ...
99 EOF;
100
101         $this->assertEquals('foo', $this->parser->parse($yaml));
102     }
103
104     public function getBlockChompingTests()
105     {
106         $tests = array();
107
108         $yaml = <<<'EOF'
109 foo: |-
110     one
111     two
112 bar: |-
113     one
114     two
115
116 EOF;
117         $expected = array(
118             'foo' => "one\ntwo",
119             'bar' => "one\ntwo",
120         );
121         $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);
122
123         $yaml = <<<'EOF'
124 foo: |-
125     one
126     two
127
128 bar: |-
129     one
130     two
131
132
133 EOF;
134         $expected = array(
135             'foo' => "one\ntwo",
136             'bar' => "one\ntwo",
137         );
138         $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
139
140         $yaml = <<<'EOF'
141 {}
142
143
144 EOF;
145         $expected = array();
146         $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);
147
148         $yaml = <<<'EOF'
149 foo: |-
150     one
151     two
152 bar: |-
153     one
154     two
155 EOF;
156         $expected = array(
157             'foo' => "one\ntwo",
158             'bar' => "one\ntwo",
159         );
160         $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);
161
162         $yaml = <<<'EOF'
163 foo: |
164     one
165     two
166 bar: |
167     one
168     two
169
170 EOF;
171         $expected = array(
172             'foo' => "one\ntwo\n",
173             'bar' => "one\ntwo\n",
174         );
175         $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);
176
177         $yaml = <<<'EOF'
178 foo: |
179     one
180     two
181
182 bar: |
183     one
184     two
185
186
187 EOF;
188         $expected = array(
189             'foo' => "one\ntwo\n",
190             'bar' => "one\ntwo\n",
191         );
192         $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
193
194         $yaml = <<<'EOF'
195 foo:
196 - bar: |
197     one
198
199     two
200 EOF;
201         $expected = array(
202             'foo' => array(
203                 array(
204                     'bar' => "one\n\ntwo",
205                 ),
206             ),
207         );
208         $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml);
209
210         $yaml = <<<'EOF'
211 foo: |
212     one
213     two
214 bar: |
215     one
216     two
217 EOF;
218         $expected = array(
219             'foo' => "one\ntwo\n",
220             'bar' => "one\ntwo",
221         );
222         $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);
223
224         $yaml = <<<'EOF'
225 foo: |+
226     one
227     two
228 bar: |+
229     one
230     two
231
232 EOF;
233         $expected = array(
234             'foo' => "one\ntwo\n",
235             'bar' => "one\ntwo\n",
236         );
237         $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);
238
239         $yaml = <<<'EOF'
240 foo: |+
241     one
242     two
243
244 bar: |+
245     one
246     two
247
248
249 EOF;
250         $expected = array(
251             'foo' => "one\ntwo\n\n",
252             'bar' => "one\ntwo\n\n",
253         );
254         $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
255
256         $yaml = <<<'EOF'
257 foo: |+
258     one
259     two
260 bar: |+
261     one
262     two
263 EOF;
264         $expected = array(
265             'foo' => "one\ntwo\n",
266             'bar' => "one\ntwo",
267         );
268         $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);
269
270         $yaml = <<<'EOF'
271 foo: >-
272     one
273     two
274 bar: >-
275     one
276     two
277
278 EOF;
279         $expected = array(
280             'foo' => 'one two',
281             'bar' => 'one two',
282         );
283         $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);
284
285         $yaml = <<<'EOF'
286 foo: >-
287     one
288     two
289
290 bar: >-
291     one
292     two
293
294
295 EOF;
296         $expected = array(
297             'foo' => 'one two',
298             'bar' => 'one two',
299         );
300         $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
301
302         $yaml = <<<'EOF'
303 foo: >-
304     one
305     two
306 bar: >-
307     one
308     two
309 EOF;
310         $expected = array(
311             'foo' => 'one two',
312             'bar' => 'one two',
313         );
314         $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);
315
316         $yaml = <<<'EOF'
317 foo: >
318     one
319     two
320 bar: >
321     one
322     two
323
324 EOF;
325         $expected = array(
326             'foo' => "one two\n",
327             'bar' => "one two\n",
328         );
329         $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);
330
331         $yaml = <<<'EOF'
332 foo: >
333     one
334     two
335
336 bar: >
337     one
338     two
339
340
341 EOF;
342         $expected = array(
343             'foo' => "one two\n",
344             'bar' => "one two\n",
345         );
346         $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
347
348         $yaml = <<<'EOF'
349 foo: >
350     one
351     two
352 bar: >
353     one
354     two
355 EOF;
356         $expected = array(
357             'foo' => "one two\n",
358             'bar' => 'one two',
359         );
360         $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);
361
362         $yaml = <<<'EOF'
363 foo: >+
364     one
365     two
366 bar: >+
367     one
368     two
369
370 EOF;
371         $expected = array(
372             'foo' => "one two\n",
373             'bar' => "one two\n",
374         );
375         $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);
376
377         $yaml = <<<'EOF'
378 foo: >+
379     one
380     two
381
382 bar: >+
383     one
384     two
385
386
387 EOF;
388         $expected = array(
389             'foo' => "one two\n\n",
390             'bar' => "one two\n\n",
391         );
392         $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
393
394         $yaml = <<<'EOF'
395 foo: >+
396     one
397     two
398 bar: >+
399     one
400     two
401 EOF;
402         $expected = array(
403             'foo' => "one two\n",
404             'bar' => 'one two',
405         );
406         $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);
407
408         return $tests;
409     }
410
411     /**
412      * @dataProvider getBlockChompingTests
413      */
414     public function testBlockChomping($expected, $yaml)
415     {
416         $this->assertSame($expected, $this->parser->parse($yaml));
417     }
418
419     /**
420      * Regression test for issue #7989.
421      *
422      * @see https://github.com/symfony/symfony/issues/7989
423      */
424     public function testBlockLiteralWithLeadingNewlines()
425     {
426         $yaml = <<<'EOF'
427 foo: |-
428
429
430     bar
431
432 EOF;
433         $expected = array(
434             'foo' => "\n\nbar",
435         );
436
437         $this->assertSame($expected, $this->parser->parse($yaml));
438     }
439
440     public function testObjectSupportEnabled()
441     {
442         $input = <<<'EOF'
443 foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
444 bar: 1
445 EOF;
446         $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
447
448         $input = <<<'EOF'
449 foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
450 bar: 1
451 EOF;
452         $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
453     }
454
455     /**
456      * @dataProvider invalidDumpedObjectProvider
457      */
458     public function testObjectSupportDisabledButNoExceptions($input)
459     {
460         $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
461     }
462
463     /**
464      * @dataProvider getObjectForMapTests
465      */
466     public function testObjectForMap($yaml, $expected)
467     {
468         $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true));
469     }
470
471     public function getObjectForMapTests()
472     {
473         $tests = array();
474
475         $yaml = <<<'EOF'
476 foo:
477     fiz: [cat]
478 EOF;
479         $expected = new \stdClass();
480         $expected->foo = new \stdClass();
481         $expected->foo->fiz = array('cat');
482         $tests['mapping'] = array($yaml, $expected);
483
484         $yaml = '{ "foo": "bar", "fiz": "cat" }';
485         $expected = new \stdClass();
486         $expected->foo = 'bar';
487         $expected->fiz = 'cat';
488         $tests['inline-mapping'] = array($yaml, $expected);
489
490         $yaml = "foo: bar\nbaz: foobar";
491         $expected = new \stdClass();
492         $expected->foo = 'bar';
493         $expected->baz = 'foobar';
494         $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected);
495
496         $yaml = <<<'EOT'
497 array:
498   - key: one
499   - key: two
500 EOT;
501         $expected = new \stdClass();
502         $expected->array = array();
503         $expected->array[0] = new \stdClass();
504         $expected->array[0]->key = 'one';
505         $expected->array[1] = new \stdClass();
506         $expected->array[1]->key = 'two';
507         $tests['nest-map-and-sequence'] = array($yaml, $expected);
508
509         $yaml = <<<'YAML'
510 map:
511   1: one
512   2: two
513 YAML;
514         $expected = new \stdClass();
515         $expected->map = new \stdClass();
516         $expected->map->{1} = 'one';
517         $expected->map->{2} = 'two';
518         $tests['numeric-keys'] = array($yaml, $expected);
519
520         $yaml = <<<'YAML'
521 map:
522   0: one
523   1: two
524 YAML;
525         $expected = new \stdClass();
526         $expected->map = new \stdClass();
527         $expected->map->{0} = 'one';
528         $expected->map->{1} = 'two';
529         $tests['zero-indexed-numeric-keys'] = array($yaml, $expected);
530
531         return $tests;
532     }
533
534     /**
535      * @dataProvider invalidDumpedObjectProvider
536      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
537      */
538     public function testObjectsSupportDisabledWithExceptions($yaml)
539     {
540         $this->parser->parse($yaml, true, false);
541     }
542
543     public function invalidDumpedObjectProvider()
544     {
545         $yamlTag = <<<'EOF'
546 foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
547 bar: 1
548 EOF;
549         $localTag = <<<'EOF'
550 foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
551 bar: 1
552 EOF;
553
554         return array(
555             'yaml-tag' => array($yamlTag),
556             'local-tag' => array($localTag),
557         );
558     }
559
560     /**
561      * @requires extension iconv
562      */
563     public function testNonUtf8Exception()
564     {
565         $yamls = array(
566             iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
567             iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
568             iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
569         );
570
571         foreach ($yamls as $yaml) {
572             try {
573                 $this->parser->parse($yaml);
574
575                 $this->fail('charsets other than UTF-8 are rejected.');
576             } catch (\Exception $e) {
577                 $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
578             }
579         }
580     }
581
582     /**
583      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
584      */
585     public function testUnindentedCollectionException()
586     {
587         $yaml = <<<'EOF'
588
589 collection:
590 -item1
591 -item2
592 -item3
593
594 EOF;
595
596         $this->parser->parse($yaml);
597     }
598
599     /**
600      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
601      */
602     public function testShortcutKeyUnindentedCollectionException()
603     {
604         $yaml = <<<'EOF'
605
606 collection:
607 -  key: foo
608   foo: bar
609
610 EOF;
611
612         $this->parser->parse($yaml);
613     }
614
615     /**
616      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
617      * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
618      */
619     public function testMultipleDocumentsNotSupportedException()
620     {
621         Yaml::parse(<<<'EOL'
622 # Ranking of 1998 home runs
623 ---
624 - Mark McGwire
625 - Sammy Sosa
626 - Ken Griffey
627
628 # Team ranking
629 ---
630 - Chicago Cubs
631 - St Louis Cardinals
632 EOL
633         );
634     }
635
636     /**
637      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
638      */
639     public function testSequenceInAMapping()
640     {
641         Yaml::parse(<<<'EOF'
642 yaml:
643   hash: me
644   - array stuff
645 EOF
646         );
647     }
648
649     public function testSequenceInMappingStartedBySingleDashLine()
650     {
651         $yaml = <<<'EOT'
652 a:
653 -
654   b:
655   -
656     bar: baz
657 - foo
658 d: e
659 EOT;
660         $expected = array(
661             'a' => array(
662                 array(
663                     'b' => array(
664                         array(
665                             'bar' => 'baz',
666                         ),
667                     ),
668                 ),
669                 'foo',
670             ),
671             'd' => 'e',
672         );
673
674         $this->assertSame($expected, $this->parser->parse($yaml));
675     }
676
677     public function testSequenceFollowedByCommentEmbeddedInMapping()
678     {
679         $yaml = <<<'EOT'
680 a:
681     b:
682         - c
683 # comment
684     d: e
685 EOT;
686         $expected = array(
687             'a' => array(
688                 'b' => array('c'),
689                 'd' => 'e',
690             ),
691         );
692
693         $this->assertSame($expected, $this->parser->parse($yaml));
694     }
695
696     /**
697      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
698      */
699     public function testMappingInASequence()
700     {
701         Yaml::parse(<<<'EOF'
702 yaml:
703   - array stuff
704   hash: me
705 EOF
706         );
707     }
708
709     /**
710      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
711      * @expectedExceptionMessage missing colon
712      */
713     public function testScalarInSequence()
714     {
715         Yaml::parse(<<<'EOF'
716 foo:
717     - bar
718 "missing colon"
719     foo: bar
720 EOF
721         );
722     }
723
724     /**
725      * > It is an error for two equal keys to appear in the same mapping node.
726      * > In such a case the YAML processor may continue, ignoring the second
727      * > `key: value` pair and issuing an appropriate warning. This strategy
728      * > preserves a consistent information model for one-pass and random access
729      * > applications.
730      *
731      * @see http://yaml.org/spec/1.2/spec.html#id2759572
732      * @see http://yaml.org/spec/1.1/#id932806
733      */
734     public function testMappingDuplicateKeyBlock()
735     {
736         $input = <<<'EOD'
737 parent:
738     child: first
739     child: duplicate
740 parent:
741     child: duplicate
742     child: duplicate
743 EOD;
744         $expected = array(
745             'parent' => array(
746                 'child' => 'first',
747             ),
748         );
749         $this->assertSame($expected, Yaml::parse($input));
750     }
751
752     public function testMappingDuplicateKeyFlow()
753     {
754         $input = <<<'EOD'
755 parent: { child: first, child: duplicate }
756 parent: { child: duplicate, child: duplicate }
757 EOD;
758         $expected = array(
759             'parent' => array(
760                 'child' => 'first',
761             ),
762         );
763         $this->assertSame($expected, Yaml::parse($input));
764     }
765
766     public function testEmptyValue()
767     {
768         $input = <<<'EOF'
769 hash:
770 EOF;
771
772         $this->assertEquals(array('hash' => null), Yaml::parse($input));
773     }
774
775     public function testCommentAtTheRootIndent()
776     {
777         $this->assertEquals(array(
778             'services' => array(
779                 'app.foo_service' => array(
780                     'class' => 'Foo',
781                 ),
782                 'app/bar_service' => array(
783                     'class' => 'Bar',
784                 ),
785             ),
786         ), Yaml::parse(<<<'EOF'
787 # comment 1
788 services:
789 # comment 2
790     # comment 3
791     app.foo_service:
792         class: Foo
793 # comment 4
794     # comment 5
795     app/bar_service:
796         class: Bar
797 EOF
798         ));
799     }
800
801     public function testStringBlockWithComments()
802     {
803         $this->assertEquals(array('content' => <<<'EOT'
804 # comment 1
805 header
806
807     # comment 2
808     <body>
809         <h1>title</h1>
810     </body>
811
812 footer # comment3
813 EOT
814         ), Yaml::parse(<<<'EOF'
815 content: |
816     # comment 1
817     header
818
819         # comment 2
820         <body>
821             <h1>title</h1>
822         </body>
823
824     footer # comment3
825 EOF
826         ));
827     }
828
829     public function testFoldedStringBlockWithComments()
830     {
831         $this->assertEquals(array(array('content' => <<<'EOT'
832 # comment 1
833 header
834
835     # comment 2
836     <body>
837         <h1>title</h1>
838     </body>
839
840 footer # comment3
841 EOT
842         )), Yaml::parse(<<<'EOF'
843 -
844     content: |
845         # comment 1
846         header
847
848             # comment 2
849             <body>
850                 <h1>title</h1>
851             </body>
852
853         footer # comment3
854 EOF
855         ));
856     }
857
858     public function testNestedFoldedStringBlockWithComments()
859     {
860         $this->assertEquals(array(array(
861             'title' => 'some title',
862             'content' => <<<'EOT'
863 # comment 1
864 header
865
866     # comment 2
867     <body>
868         <h1>title</h1>
869     </body>
870
871 footer # comment3
872 EOT
873         )), Yaml::parse(<<<'EOF'
874 -
875     title: some title
876     content: |
877         # comment 1
878         header
879
880             # comment 2
881             <body>
882                 <h1>title</h1>
883             </body>
884
885         footer # comment3
886 EOF
887         ));
888     }
889
890     public function testReferenceResolvingInInlineStrings()
891     {
892         $this->assertEquals(array(
893             'var' => 'var-value',
894             'scalar' => 'var-value',
895             'list' => array('var-value'),
896             'list_in_list' => array(array('var-value')),
897             'map_in_list' => array(array('key' => 'var-value')),
898             'embedded_mapping' => array(array('key' => 'var-value')),
899             'map' => array('key' => 'var-value'),
900             'list_in_map' => array('key' => array('var-value')),
901             'map_in_map' => array('foo' => array('bar' => 'var-value')),
902         ), Yaml::parse(<<<'EOF'
903 var:  &var var-value
904 scalar: *var
905 list: [ *var ]
906 list_in_list: [[ *var ]]
907 map_in_list: [ { key: *var } ]
908 embedded_mapping: [ key: *var ]
909 map: { key: *var }
910 list_in_map: { key: [*var] }
911 map_in_map: { foo: { bar: *var } }
912 EOF
913         ));
914     }
915
916     public function testYamlDirective()
917     {
918         $yaml = <<<'EOF'
919 %YAML 1.2
920 ---
921 foo: 1
922 bar: 2
923 EOF;
924         $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
925     }
926
927     public function testFloatKeys()
928     {
929         $yaml = <<<'EOF'
930 foo:
931     1.2: "bar"
932     1.3: "baz"
933 EOF;
934
935         $expected = array(
936             'foo' => array(
937                 '1.2' => 'bar',
938                 '1.3' => 'baz',
939             ),
940         );
941
942         $this->assertEquals($expected, $this->parser->parse($yaml));
943     }
944
945     /**
946      * @group legacy
947      * @expectedDeprecation Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.
948      * throw ParseException in Symfony 3.0
949      */
950     public function testColonInMappingValueException()
951     {
952         $yaml = <<<'EOF'
953 foo: bar: baz
954 EOF;
955
956         $this->parser->parse($yaml);
957     }
958
959     public function testColonInMappingValueExceptionNotTriggeredByColonInComment()
960     {
961         $yaml = <<<'EOT'
962 foo:
963     bar: foobar # Note: a comment after a colon
964 EOT;
965
966         $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
967     }
968
969     /**
970      * @dataProvider getCommentLikeStringInScalarBlockData
971      */
972     public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
973     {
974         $this->assertSame($expectedParserResult, $this->parser->parse($yaml));
975     }
976
977     public function getCommentLikeStringInScalarBlockData()
978     {
979         $tests = array();
980
981         $yaml = <<<'EOT'
982 pages:
983     -
984         title: some title
985         content: |
986             # comment 1
987             header
988
989                 # comment 2
990                 <body>
991                     <h1>title</h1>
992                 </body>
993
994             footer # comment3
995 EOT;
996         $expected = array(
997             'pages' => array(
998                 array(
999                     'title' => 'some title',
1000                     'content' => <<<'EOT'
1001 # comment 1
1002 header
1003
1004     # comment 2
1005     <body>
1006         <h1>title</h1>
1007     </body>
1008
1009 footer # comment3
1010 EOT
1011                     ,
1012                 ),
1013             ),
1014         );
1015         $tests[] = array($yaml, $expected);
1016
1017         $yaml = <<<'EOT'
1018 test: |
1019     foo
1020     # bar
1021     baz
1022 collection:
1023     - one: |
1024         foo
1025         # bar
1026         baz
1027     - two: |
1028         foo
1029         # bar
1030         baz
1031 EOT;
1032         $expected = array(
1033             'test' => <<<'EOT'
1034 foo
1035 # bar
1036 baz
1037
1038 EOT
1039             ,
1040             'collection' => array(
1041                 array(
1042                     'one' => <<<'EOT'
1043 foo
1044 # bar
1045 baz
1046
1047 EOT
1048                     ,
1049                 ),
1050                 array(
1051                     'two' => <<<'EOT'
1052 foo
1053 # bar
1054 baz
1055 EOT
1056                     ,
1057                 ),
1058             ),
1059         );
1060         $tests[] = array($yaml, $expected);
1061
1062         $yaml = <<<'EOT'
1063 foo:
1064   bar:
1065     scalar-block: >
1066       line1
1067       line2>
1068   baz:
1069 # comment
1070     foobar: ~
1071 EOT;
1072         $expected = array(
1073             'foo' => array(
1074                 'bar' => array(
1075                     'scalar-block' => "line1 line2>\n",
1076                 ),
1077                 'baz' => array(
1078                     'foobar' => null,
1079                 ),
1080             ),
1081         );
1082         $tests[] = array($yaml, $expected);
1083
1084         $yaml = <<<'EOT'
1085 a:
1086     b: hello
1087 #    c: |
1088 #        first row
1089 #        second row
1090     d: hello
1091 EOT;
1092         $expected = array(
1093             'a' => array(
1094                 'b' => 'hello',
1095                 'd' => 'hello',
1096             ),
1097         );
1098         $tests[] = array($yaml, $expected);
1099
1100         return $tests;
1101     }
1102
1103     public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
1104     {
1105         $yaml = <<<'EOT'
1106 test: >
1107     <h2>A heading</h2>
1108
1109     <ul>
1110     <li>a list</li>
1111     <li>may be a good example</li>
1112     </ul>
1113 EOT;
1114
1115         $this->assertSame(
1116             array(
1117                 'test' => <<<'EOT'
1118 <h2>A heading</h2>
1119 <ul> <li>a list</li> <li>may be a good example</li> </ul>
1120 EOT
1121                 ,
1122             ),
1123             $this->parser->parse($yaml)
1124         );
1125     }
1126
1127     public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
1128     {
1129         $yaml = <<<'EOT'
1130 test: >
1131     <h2>A heading</h2>
1132
1133     <ul>
1134       <li>a list</li>
1135       <li>may be a good example</li>
1136     </ul>
1137 EOT;
1138
1139         $this->assertSame(
1140             array(
1141                 'test' => <<<'EOT'
1142 <h2>A heading</h2>
1143 <ul>
1144   <li>a list</li>
1145   <li>may be a good example</li>
1146 </ul>
1147 EOT
1148                 ,
1149             ),
1150             $this->parser->parse($yaml)
1151         );
1152     }
1153
1154     /**
1155      * @param $lineNumber
1156      * @param $yaml
1157      * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider
1158      */
1159     public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml)
1160     {
1161         if (method_exists($this, 'expectException')) {
1162             $this->expectException('\Symfony\Component\Yaml\Exception\ParseException');
1163             $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
1164         } else {
1165             $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
1166         }
1167
1168         $this->parser->parse($yaml);
1169     }
1170
1171     public function parserThrowsExceptionWithCorrectLineNumberProvider()
1172     {
1173         return array(
1174             array(
1175                 4,
1176                 <<<'YAML'
1177 foo:
1178     -
1179         # bar
1180         bar: "123",
1181 YAML
1182             ),
1183             array(
1184                 5,
1185                 <<<'YAML'
1186 foo:
1187     -
1188         # bar
1189         # bar
1190         bar: "123",
1191 YAML
1192             ),
1193             array(
1194                 8,
1195                 <<<'YAML'
1196 foo:
1197     -
1198         # foobar
1199         baz: 123
1200 bar:
1201     -
1202         # bar
1203         bar: "123",
1204 YAML
1205             ),
1206             array(
1207                 10,
1208                 <<<'YAML'
1209 foo:
1210     -
1211         # foobar
1212         # foobar
1213         baz: 123
1214 bar:
1215     -
1216         # bar
1217         # bar
1218         bar: "123",
1219 YAML
1220             ),
1221         );
1222     }
1223
1224     public function testCanParseVeryLongValue()
1225     {
1226         $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000);
1227         $trickyVal = array('x' => $longStringWithSpaces);
1228
1229         $yamlString = Yaml::dump($trickyVal);
1230         $arrayFromYaml = $this->parser->parse($yamlString);
1231
1232         $this->assertEquals($trickyVal, $arrayFromYaml);
1233     }
1234
1235     /**
1236      * @expectedException \Symfony\Component\Yaml\Exception\ParseException
1237      * @expectedExceptionMessage Reference "foo" does not exist at line 2
1238      */
1239     public function testParserCleansUpReferencesBetweenRuns()
1240     {
1241         $yaml = <<<YAML
1242 foo: &foo
1243     baz: foobar
1244 bar:
1245     <<: *foo
1246 YAML;
1247         $this->parser->parse($yaml);
1248
1249         $yaml = <<<YAML
1250 bar:
1251     <<: *foo
1252 YAML;
1253         $this->parser->parse($yaml);
1254     }
1255 }
1256
1257 class B
1258 {
1259     public $b = 'foo';
1260 }