X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;f=vendor%2Fsymfony%2Fyaml%2FTests%2FParserTest.php;h=6372fe45eef89f507aad1707efc206d14ff0a043;hb=5b8bb166bfa98770daef9de5c127fc2e6ef02340;hp=2c3a6e0b8f53f4b91bce129a47699952da409e09;hpb=eba34333e3c89f208d2f72fa91351ad019a71583;p=yaffs-website diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php index 2c3a6e0b8..6372fe45e 100644 --- a/vendor/symfony/yaml/Tests/ParserTest.php +++ b/vendor/symfony/yaml/Tests/ParserTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\Yaml\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; class ParserTest extends TestCase { @@ -28,44 +30,75 @@ class ParserTest extends TestCase protected function tearDown() { $this->parser = null; + + chmod(__DIR__.'/Fixtures/not_readable.yml', 0644); } /** * @dataProvider getDataFormSpecifications */ - public function testSpecifications($file, $expected, $yaml, $comment) + public function testSpecifications($expected, $yaml, $comment, $deprecated) { + $deprecations = array(); + + if ($deprecated) { + set_error_handler(function ($type, $msg) use (&$deprecations) { + if (E_USER_DEPRECATED !== $type) { + restore_error_handler(); + + if (class_exists('PHPUnit_Util_ErrorHandler')) { + return \call_user_func_array('PHPUnit_Util_ErrorHandler::handleError', \func_get_args()); + } + + return \call_user_func_array('PHPUnit\Util\ErrorHandler::handleError', \func_get_args()); + } + + $deprecations[] = $msg; + }); + } + $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment); + + if ($deprecated) { + restore_error_handler(); + + $this->assertCount(1, $deprecations); + $this->assertContains(true !== $deprecated ? $deprecated : 'Using the comma as a group separator for floats is deprecated since Symfony 3.2 and will be removed in 4.0 on line 1.', $deprecations[0]); + } } public function getDataFormSpecifications() { - $parser = new Parser(); - $path = __DIR__.'/Fixtures'; - - $tests = array(); - $files = $parser->parse(file_get_contents($path.'/index.yml')); - foreach ($files as $file) { - $yamls = file_get_contents($path.'/'.$file.'.yml'); + return $this->loadTestsFromFixtureFiles('index.yml'); + } - // split YAMLs documents - foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { - if (!$yaml) { - continue; - } + /** + * @group legacy + * @expectedDeprecationMessage Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable + * @dataProvider getNonStringMappingKeysData + */ + public function testNonStringMappingKeys($expected, $yaml, $comment) + { + $this->assertSame($expected, var_export($this->parser->parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS), true), $comment); + } - $test = $parser->parse($yaml); - if (isset($test['todo']) && $test['todo']) { - // TODO - } else { - eval('$expected = '.trim($test['php']).';'); + public function getNonStringMappingKeysData() + { + return $this->loadTestsFromFixtureFiles('nonStringKeys.yml'); + } - $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']); - } - } - } + /** + * @group legacy + * @dataProvider getLegacyNonStringMappingKeysData + */ + public function testLegacyNonStringMappingKeys($expected, $yaml, $comment) + { + $this->assertSame($expected, var_export($this->parser->parse($yaml), true), $comment); + } - return $tests; + public function getLegacyNonStringMappingKeysData() + { + return $this->loadTestsFromFixtureFiles('legacyNonStringKeys.yml'); } public function testTabsInYaml() @@ -440,11 +473,17 @@ EOF; public function testObjectSupportEnabled() { $input = <<<'EOF' -foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +foo: !php/object O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} bar: 1 EOF; - $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); + } + /** + * @group legacy + */ + public function testObjectSupportEnabledPassingTrue() + { $input = <<<'EOF' foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} bar: 1 @@ -452,6 +491,33 @@ EOF; $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); } + /** + * @group legacy + * @dataProvider deprecatedObjectValueProvider + */ + public function testObjectSupportEnabledWithDeprecatedTag($yaml) + { + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($yaml, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); + } + + public function deprecatedObjectValueProvider() + { + return array( + array( + <<assertEquals($expected, $this->parser->parse($yaml, $flags)); + } + + /** + * @group legacy + * @dataProvider getObjectForMapTests + */ + public function testObjectForMapEnabledWithMappingUsingBooleanToggles($yaml, $expected) { $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true)); } @@ -519,8 +596,8 @@ YAML; $yaml = <<<'YAML' map: - 0: one - 1: two + '0': one + '1': two YAML; $expected = new \stdClass(); $expected->map = new \stdClass(); @@ -537,7 +614,28 @@ YAML; */ public function testObjectsSupportDisabledWithExceptions($yaml) { - $this->parser->parse($yaml, true, false); + $this->parser->parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); + } + + public function testCanParseContentWithTrailingSpaces() + { + $yaml = "items: \n foo: bar"; + + $expected = array( + 'items' => array('foo' => 'bar'), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @dataProvider invalidDumpedObjectProvider + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testObjectsSupportDisabledWithExceptionsUsingBooleanToggles($yaml) + { + $this->parser->parse($yaml, true); } public function invalidDumpedObjectProvider() @@ -693,6 +791,88 @@ EOT; $this->assertSame($expected, $this->parser->parse($yaml)); } + public function testNonStringFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + {} +# comment + d: + 1.1 +# another comment +EOT; + $expected = array( + 'a' => array( + 'b' => array(), + 'd' => 1.1, + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function getParseExceptionNotAffectedMultiLineStringLastResortParsing() + { + $tests = array(); + + $yaml = <<<'EOT' +a + b: +EOT; + $tests['parse error on first line'] = array($yaml); + + $yaml = <<<'EOT' +a + +b + c: +EOT; + $tests['parse error due to inconsistent indentation'] = array($yaml); + + $yaml = <<<'EOT' + & * ! | > ' " % @ ` #, { asd a;sdasd }-@^qw3 +EOT; + $tests['symfony/symfony/issues/22967#issuecomment-322067742'] = array($yaml); + + return $tests; + } + + /** + * @dataProvider getParseExceptionNotAffectedMultiLineStringLastResortParsing + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseExceptionNotAffectedByMultiLineStringLastResortParsing($yaml) + { + $this->parser->parse($yaml); + } + + public function testMultiLineStringLastResortParsing() + { + $yaml = <<<'EOT' +test: + You can have things that don't look like strings here + true + yes you can +EOT; + $expected = array( + 'test' => 'You can have things that don\'t look like strings here true yes you can', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + + $yaml = <<<'EOT' +a: + b + c +EOT; + $expected = array( + 'a' => 'b c', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ @@ -730,6 +910,7 @@ EOF * * @see http://yaml.org/spec/1.2/spec.html#id2759572 * @see http://yaml.org/spec/1.1/#id932806 + * @group legacy */ public function testMappingDuplicateKeyBlock() { @@ -749,6 +930,9 @@ EOD; $this->assertSame($expected, Yaml::parse($input)); } + /** + * @group legacy + */ public function testMappingDuplicateKeyFlow() { $input = <<<'EOD' @@ -763,6 +947,74 @@ EOD; $this->assertSame($expected, Yaml::parse($input)); } + /** + * @group legacy + * @dataProvider getParseExceptionOnDuplicateData + * @expectedDeprecation Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated %s and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d. + * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 + */ + public function testParseExceptionOnDuplicate($input, $duplicateKey, $lineNumber) + { + Yaml::parse($input); + } + + public function getParseExceptionOnDuplicateData() + { + $tests = array(); + + $yaml = <<assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml)); } + /** + * @group legacy + * @expectedDeprecation Implicit casting of numeric key to string is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 2. + */ public function testFloatKeys() { $yaml = <<<'EOF' @@ -944,8 +1200,51 @@ EOF; /** * @group legacy - * @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. - * throw ParseException in Symfony 3.0 + * @expectedDeprecation Implicit casting of non-string key to string is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 1. + */ + public function testBooleanKeys() + { + $yaml = <<<'EOF' +true: foo +false: bar +EOF; + + $expected = array( + 1 => 'foo', + 0 => 'bar', + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function testExplicitStringCasting() + { + $yaml = <<<'EOF' +'1.2': "bar" +!!str 1.3: "baz" + +'true': foo +!!str false: bar + +!!str null: 'null' +'~': 'null' +EOF; + + $expected = array( + '1.2' => 'bar', + '1.3' => 'baz', + 'true' => 'foo', + 'false' => 'bar', + 'null' => 'null', + '~' => 'null', + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage A colon cannot be used in an unquoted mapping value */ public function testColonInMappingValueException() { @@ -1152,43 +1451,142 @@ EOT } /** - * @param $lineNumber - * @param $yaml - * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider + * @dataProvider getBinaryData */ - public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) + public function testParseBinaryData($data) + { + $this->assertSame(array('data' => 'Hello world'), $this->parser->parse($data)); + } + + public function getBinaryData() + { + return array( + 'enclosed with double quotes' => array('data: !!binary "SGVsbG8gd29ybGQ="'), + 'enclosed with single quotes' => array("data: !!binary 'SGVsbG8gd29ybGQ='"), + 'containing spaces' => array('data: !!binary "SGVs bG8gd 29ybGQ="'), + 'in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVsbG8gd29ybGQ= +EOT + ), + 'containing spaces in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVs bG8gd 29ybGQ= +EOT + ), + ); + } + + /** + * @dataProvider getInvalidBinaryData + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidBinaryData($data, $expectedMessage) { if (method_exists($this, 'expectException')) { - $this->expectException('\Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + $this->expectExceptionMessageRegExp($expectedMessage); } else { - $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + $this->setExpectedExceptionRegExp(ParseException::class, $expectedMessage); } - $this->parser->parse($yaml); + $this->parser->parse($data); } - public function parserThrowsExceptionWithCorrectLineNumberProvider() + public function getInvalidBinaryData() { return array( - array( - 4, - <<<'YAML' -foo: - - - # bar - bar: "123", -YAML - ), - array( - 5, - <<<'YAML' -foo: - - - # bar - # bar - bar: "123", -YAML + 'length not a multiple of four' => array('data: !!binary "SGVsbG8d29ybGQ="', '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/'), + 'invalid characters' => array('!!binary "SGVsbG8#d29ybGQ="', '/The base64 encoded data \(.*\) contains invalid characters/'), + 'too many equals characters' => array('data: !!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'), + 'misplaced equals character' => array('data: !!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'), + 'length not a multiple of four in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVsbG8d29ybGQ= +EOT + , + '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/', + ), + 'invalid characters in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVsbG8#d29ybGQ= +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ), + 'too many equals characters in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVsbG8gd29yb=== +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ), + 'misplaced equals character in block scalar' => array( + <<<'EOT' +data: !!binary | + SGVsbG8gd29ybG=Q +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ), + ); + } + + public function testParseDateAsMappingValue() + { + $yaml = <<<'EOT' +date: 2002-12-14 +EOT; + $expectedDate = new \DateTime(); + $expectedDate->setTimeZone(new \DateTimeZone('UTC')); + $expectedDate->setDate(2002, 12, 14); + $expectedDate->setTime(0, 0, 0); + + $this->assertEquals(array('date' => $expectedDate), $this->parser->parse($yaml, Yaml::PARSE_DATETIME)); + } + + /** + * @param $lineNumber + * @param $yaml + * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider + */ + public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) + { + if (method_exists($this, 'expectException')) { + $this->expectException('\Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } else { + $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } + + $this->parser->parse($yaml); + } + + public function parserThrowsExceptionWithCorrectLineNumberProvider() + { + return array( + array( + 4, + <<<'YAML' +foo: + - + # bar + bar: "123", +YAML + ), + array( + 5, + <<<'YAML' +foo: + - + # bar + # bar + bar: "123", +YAML ), array( 8, @@ -1221,6 +1619,307 @@ YAML ); } + public function testParseMultiLineQuotedString() + { + $yaml = <<assertSame(array('foo' => 'bar baz foobar foo', 'bar' => 'baz'), $this->parser->parse($yaml)); + } + + public function testMultiLineQuotedStringWithTrailingBackslash() + { + $yaml = <<assertSame(array('foobar' => 'foobar'), $this->parser->parse($yaml)); + } + + public function testCommentCharactersInMultiLineQuotedStrings() + { + $yaml = << array( + 'foobar' => 'foo #bar', + 'bar' => 'baz', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testBlankLinesInQuotedMultiLineString() + { + $yaml = << "foo\nbar", + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testParseMultiLineUnquotedString() + { + $yaml = <<assertSame(array('foo' => 'bar baz foobar foo', 'bar' => 'baz'), $this->parser->parse($yaml)); + } + + public function testParseMultiLineString() + { + $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz")); + } + + /** + * @dataProvider multiLineDataProvider + */ + public function testParseMultiLineMappingValue($yaml, $expected, $parseError) + { + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function multiLineDataProvider() + { + $tests = array(); + + $yaml = <<<'EOF' +foo: +- bar: + one + + two + three +EOF; + $expected = array( + 'foo' => array( + array( + 'bar' => "one\ntwo three", + ), + ), + ); + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar +"foo" +EOF; + $expected = 'bar "foo"'; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar +"foo +EOF; + $expected = 'bar "foo'; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar + +'foo' +EOF; + $expected = "bar\n'foo'"; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar + +foo' +EOF; + $expected = "bar\nfoo'"; + + $tests[] = array($yaml, $expected, false); + + return $tests; + } + + public function testTaggedInlineMapping() + { + $this->assertEquals(new TaggedValue('foo', array('foo' => 'bar')), $this->parser->parse('!foo {foo: bar}', Yaml::PARSE_CUSTOM_TAGS)); + } + + /** + * @dataProvider taggedValuesProvider + */ + public function testCustomTagSupport($expected, $yaml) + { + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS)); + } + + public function taggedValuesProvider() + { + return array( + 'sequences' => array( + array(new TaggedValue('foo', array('yaml')), new TaggedValue('quz', array('bar'))), + << array( + new TaggedValue('foo', array('foo' => new TaggedValue('quz', array('bar')), 'quz' => new TaggedValue('foo', array('quz' => 'bar')))), + << array( + array(new TaggedValue('foo', array('foo', 'bar')), new TaggedValue('quz', array('foo' => 'bar', 'quz' => new TaggedValue('bar', array('one' => 'bar'))))), + <<parser->parse('!iterator [foo]'); + } + + /** + * @group legacy + * @expectedDeprecation Using the unquoted scalar value "!iterator foo" is deprecated since Symfony 3.3 and will be considered as a tagged value in 4.0. You must quote it on line 1. + */ + public function testUnsupportedTagWithScalar() + { + $this->assertEquals('!iterator foo', $this->parser->parse('!iterator foo')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage The built-in tag "!!foo" is not implemented at line 1 (near "!!foo"). + */ + public function testExceptionWhenUsingUnsuportedBuiltInTags() + { + $this->parser->parse('!!foo'); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 1. + */ + public function testComplexMappingThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 2. + */ + public function testComplexMappingNestedInMappingThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 1. + */ + public function testComplexMappingNestedInSequenceThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Unable to parse at line 1 (near "[parameters]"). + */ + public function testParsingIniThrowsException() + { + $ini = <<parser->parse($ini); + } + + private function loadTestsFromFixtureFiles($testsFile) + { + $parser = new Parser(); + + $tests = array(); + $files = $parser->parseFile(__DIR__.'/Fixtures/'.$testsFile); + foreach ($files as $file) { + $yamls = file_get_contents(__DIR__.'/Fixtures/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $parser->parse($yaml); + if (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + + $tests[] = array(var_export($expected, true), $test['yaml'], $test['test'], isset($test['deprecated']) ? $test['deprecated'] : false); + } + } + } + + return $tests; + } + public function testCanParseVeryLongValue() { $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000); @@ -1252,9 +1951,312 @@ bar: YAML; $this->parser->parse($yaml); } + + public function testPhpConstantTagMappingKey() + { + $yaml = << array( + 'foo' => array( + 'from' => array( + 'bar', + ), + 'to' => 'baz', + ), + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + /** + * @group legacy + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 2. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 4. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 5. + */ + public function testDeprecatedPhpConstantTagMappingKey() + { + $yaml = << array( + 'foo' => array( + 'from' => array( + 'bar', + ), + 'to' => 'baz', + ), + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + /** + * @group legacy + * @expectedDeprecation Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead. + */ + public function testPhpConstantTagMappingKeyWithKeysCastToStrings() + { + $yaml = << array( + 'foo' => array( + 'from' => array( + 'bar', + ), + 'to' => 'baz', + ), + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS)); + } + + public function testMergeKeysWhenMappingsAreParsedAsObjects() + { + $yaml = << (object) array( + 'bar' => 1, + ), + 'bar' => (object) array( + 'baz' => 2, + 'bar' => 1, + ), + 'baz' => (object) array( + 'baz_foo' => 3, + 'baz_bar' => 4, + ), + 'foobar' => (object) array( + 'bar' => null, + 'baz' => 2, + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + } + + public function testFilenamesAreParsedAsStringsWithoutFlag() + { + $file = __DIR__.'/Fixtures/index.yml'; + + $this->assertSame($file, $this->parser->parse($file)); + } + + public function testParseFile() + { + $this->assertInternalType('array', $this->parser->parseFile(__DIR__.'/Fixtures/index.yml')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessageRegExp #^File ".+/Fixtures/nonexistent.yml" does not exist\.$# + */ + public function testParsingNonExistentFilesThrowsException() + { + $this->parser->parseFile(__DIR__.'/Fixtures/nonexistent.yml'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessageRegExp #^File ".+/Fixtures/not_readable.yml" cannot be read\.$# + */ + public function testParsingNotReadableFilesThrowsException() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + + $file = __DIR__.'/Fixtures/not_readable.yml'; + chmod($file, 0200); + + $this->parser->parseFile($file); + } + + public function testParseReferencesOnMergeKeys() + { + $yaml = << array( + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'baz', + ), + 'mergekeyderef' => array( + 'd' => 'quux', + 'b' => 'bar', + 'c' => 'baz', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testParseReferencesOnMergeKeysWithMappingsParsedAsObjects() + { + $yaml = << (object) array( + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'baz', + ), + 'mergekeyderef' => (object) array( + 'd' => 'quux', + 'b' => 'bar', + 'c' => 'baz', + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Reference "foo" does not exist + */ + public function testEvalRefException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @dataProvider indentedMappingData + */ + public function testParseIndentedMappings($yaml, $expected) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function indentedMappingData() + { + $tests = array(); + + $yaml = << array( + array( + 'bar' => 'foobar', + 'baz' => 'foobaz', + ), + ), + ); + $tests['comment line is first line in indented block'] = array($yaml, $expected); + + $yaml = << array( + array( + 'bar' => array( + 'baz' => array(1, 2, 3), + ), + ), + ), + ); + $tests['mapping value on new line starting with a comment line'] = array($yaml, $expected); + + $yaml = << array( + array( + 'bar' => 'foobar', + ), + ), + ); + $tests['mapping in sequence starting on a new line'] = array($yaml, $expected); + + $yaml = << array( + 'bar' => 'baz', + ), + ); + $tests['blank line at the beginning of an indented mapping value'] = array($yaml, $expected); + + return $tests; + } } class B { public $b = 'foo'; + + const FOO = 'foo'; + const BAR = 'bar'; + const BAZ = 'baz'; }