X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;f=vendor%2Fsymfony%2Fyaml%2FTests%2FParserTest.php;h=6372fe45eef89f507aad1707efc206d14ff0a043;hb=5b8bb166bfa98770daef9de5c127fc2e6ef02340;hp=4f0cf8866b935b68187389cbd79ae72259492b18;hpb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;p=yaffs-website diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php index 4f0cf8866..6372fe45e 100644 --- a/vendor/symfony/yaml/Tests/ParserTest.php +++ b/vendor/symfony/yaml/Tests/ParserTest.php @@ -13,8 +13,9 @@ namespace Symfony\Component\Yaml\Tests; use PHPUnit\Framework\TestCase; use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; class ParserTest extends TestCase { @@ -29,12 +30,14 @@ 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, $deprecated) + public function testSpecifications($expected, $yaml, $comment, $deprecated) { $deprecations = array(); @@ -44,10 +47,10 @@ class ParserTest extends TestCase 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()); } - 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; @@ -60,38 +63,42 @@ class ParserTest extends TestCase restore_error_handler(); $this->assertCount(1, $deprecations); - $this->assertContains('Using the comma as a group separator for floats is deprecated since version 3.2 and will be removed in 4.0.', $deprecations[0]); + $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'], isset($test['deprecated']) ? $test['deprecated'] : false); - } - } - } + /** + * @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() @@ -466,7 +473,7 @@ 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, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); @@ -486,14 +493,29 @@ EOF; /** * @group legacy + * @dataProvider deprecatedObjectValueProvider */ - public function testObjectSupportEnabledWithDeprecatedTag() + public function testObjectSupportEnabledWithDeprecatedTag($yaml) { - $input = <<<'EOF' + $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(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); +YAML + ), + array( + <<assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + $flags = Yaml::PARSE_OBJECT_FOR_MAP; + + $this->assertEquals($expected, $this->parser->parse($yaml, $flags)); } /** @@ -572,8 +596,8 @@ YAML; $yaml = <<<'YAML' map: - 0: one - 1: two + '0': one + '1': two YAML; $expected = new \stdClass(); $expected->map = new \stdClass(); @@ -593,6 +617,17 @@ YAML; $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 @@ -756,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 */ @@ -833,7 +950,7 @@ EOD; /** * @group legacy * @dataProvider getParseExceptionOnDuplicateData - * @expectedDeprecation Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated %s. + * @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) @@ -1059,6 +1176,10 @@ EOF; $this->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' @@ -1077,6 +1198,50 @@ EOF; $this->assertEquals($expected, $this->parser->parse($yaml)); } + /** + * @group legacy + * @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 @@ -1467,6 +1632,49 @@ EOT; $this->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); @@ -1511,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'; }