ParserTest::getBlockChompingTests()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 305
Code Lines 261

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 261
dl 0
loc 305
rs 8
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
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;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Symfony\Component\Yaml\Parser;
16
use Symfony\Component\Yaml\Yaml;
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']).';');
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
62
63
                    $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $expected seems to be never defined.
Loading history...
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);
0 ignored issues
show
Unused Code introduced by
The assignment to $content is dead and can be removed.
Loading history...
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');
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->parser->parse($input, false, true) targeting Symfony\Component\Yaml\Parser::parse() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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
    public function testParseReferencesOnMergeKeys()
1257
    {
1258
        $yaml = <<<YAML
1259
mergekeyrefdef:
1260
    a: foo
1261
    <<: &quux
1262
        b: bar
1263
        c: baz
1264
mergekeyderef:
1265
    d: quux
1266
    <<: *quux
1267
YAML;
1268
        $expected = array(
1269
            'mergekeyrefdef' => array(
1270
                'a' => 'foo',
1271
                'b' => 'bar',
1272
                'c' => 'baz',
1273
            ),
1274
            'mergekeyderef' => array(
1275
                'd' => 'quux',
1276
                'b' => 'bar',
1277
                'c' => 'baz',
1278
            ),
1279
        );
1280
1281
        $this->assertSame($expected, $this->parser->parse($yaml));
1282
    }
1283
1284
    /**
1285
     * @expectedException \Symfony\Component\Yaml\Exception\ParseException
1286
     * @expectedExceptionMessage Reference "foo" does not exist
1287
     */
1288
    public function testEvalRefException()
1289
    {
1290
        $yaml = <<<EOE
1291
foo: { &foo { a: Steve, <<: *foo} }
1292
EOE;
1293
        $this->parser->parse($yaml);
1294
    }
1295
}
1296
1297
class B
1298
{
1299
    public $b = 'foo';
1300
}
1301