.*)#u', $values['value'], $matches)) {
+ $isRef = $matches['ref'];
+ $values['value'] = $matches['value'];
+ }
+
+ $subTag = null;
+ if ($mergeNode) {
+ // Merge keys
+ } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) {
+ // hash
+ // if next line is less indented or equal, then it means that the current value is null
+ if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ if (null !== $subTag) {
+ $data[$key] = new TaggedValue($subTag, '');
+ } else {
+ $data[$key] = null;
+ }
+ } else {
+ @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED);
+ }
+ } else {
+ $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
+ if ('<<' === $key) {
+ $this->refs[$refMatches['ref']] = $value;
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) {
+ $value = (array) $value;
+ }
+
+ $data += $value;
+ } elseif ($allowOverwrite || !isset($data[$key])) {
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if (null !== $subTag) {
+ $data[$key] = new TaggedValue($subTag, $value);
+ } else {
+ $data[$key] = $value;
+ }
+ } else {
+ @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED);
+ }
+ }
+ } else {
+ $value = $this->parseValue(rtrim($values['value']), $flags, $context);
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ $data[$key] = $value;
+ } else {
+ @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), E_USER_DEPRECATED);
+ }
+ }
+ if ($isRef) {
+ $this->refs[$isRef] = $data[$key];
+ }
+ } else {
+ // multiple documents are not supported
+ if ('---' === $this->currentLine) {
+ throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
+ }
+
+ if (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1]) {
+ @trigger_error($this->getDeprecationMessage('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.'), E_USER_DEPRECATED);
+ }
+
+ // 1-liner optionally followed by newline(s)
+ if (is_string($value) && $this->lines[0] === trim($value)) {
+ try {
+ $value = Inline::parse($this->lines[0], $flags, $this->refs);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+
+ return $value;
+ }
+
+ // try to parse the value as a multi-line string as a last resort
+ if (0 === $this->currentLineNb) {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = false;
+ $value = '';
+
+ foreach ($this->lines as $line) {
+ if ('' === trim($line)) {
+ $value .= "\n";
+ } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
+ $value .= ' ';
+ }
+
+ if ('' !== trim($line) && '\\' === substr($line, -1)) {
+ $value .= ltrim(substr($line, 0, -1));
+ } elseif ('' !== trim($line)) {
+ $value .= trim($line);
+ }
+
+ if ('' === trim($line)) {
+ $previousLineWasNewline = true;
+ $previousLineWasTerminatedWithBackslash = false;
+ } elseif ('\\' === substr($line, -1)) {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = true;
+ } else {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = false;
+ }
+ }
+
+ try {
+ return Inline::parse(trim($value));
+ } catch (ParseException $e) {
+ // fall-through to the ParseException thrown below
+ }
+ }
+
+ throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ } while ($this->moveToNextLine());
+
+ if (null !== $tag) {
+ $data = new TaggedValue($tag, $data);
+ }
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !is_object($data) && 'mapping' === $context) {
+ $object = new \stdClass();
+
+ foreach ($data as $key => $value) {
+ $object->$key = $value;
+ }
+
+ $data = $object;
+ }
+
+ return empty($data) ? null : $data;
+ }
+
+ private function parseBlock($offset, $yaml, $flags)
+ {
+ $skippedLineNumbers = $this->skippedLineNumbers;
+
+ foreach ($this->locallySkippedLineNumbers as $lineNumber) {
+ if ($lineNumber < $offset) {
+ continue;
+ }
+
+ $skippedLineNumbers[] = $lineNumber;
+ }
+
+ $parser = new self();
+ $parser->offset = $offset;
+ $parser->totalNumberOfLines = $this->totalNumberOfLines;
+ $parser->skippedLineNumbers = $skippedLineNumbers;
+ $parser->refs = &$this->refs;
+
+ return $parser->doParse($yaml, $flags);
+ }
+
+ /**
+ * Returns the current line number (takes the offset into account).
+ *
+ * @internal
+ *
+ * @return int The current line number
+ */
+ public function getRealCurrentLineNb()
+ {
+ $realCurrentLineNumber = $this->currentLineNb + $this->offset;
+
+ foreach ($this->skippedLineNumbers as $skippedLineNumber) {
+ if ($skippedLineNumber > $realCurrentLineNumber) {
+ break;
+ }
+
+ ++$realCurrentLineNumber;
+ }
+
+ return $realCurrentLineNumber;
+ }
+
+ /**
+ * Returns the current line indentation.
+ *
+ * @return int The current line indentation
+ */
+ private function getCurrentLineIndentation()
+ {
+ return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
+ }
+
+ /**
+ * Returns the next embed block of YAML.
+ *
+ * @param int $indentation The indent level at which the block is to be read, or null for default
+ * @param bool $inSequence True if the enclosing data structure is a sequence
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When indentation problem are detected
+ */
+ private function getNextEmbedBlock($indentation = null, $inSequence = false)
+ {
+ $oldLineIndentation = $this->getCurrentLineIndentation();
+ $blockScalarIndentations = array();
+
+ if ($this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $oldLineIndentation;
+ }
+
+ if (!$this->moveToNextLine()) {
+ return;
+ }
+
+ if (null === $indentation) {
+ $newIndent = null;
+ $movements = 0;
+
+ do {
+ $EOF = false;
+
+ // empty and comment-like lines do not influence the indentation depth
+ if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } else {
+ $newIndent = $this->getCurrentLineIndentation();
+ }
+ } while (!$EOF && null === $newIndent);
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();
+
+ if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ } else {
+ $newIndent = $indentation;
+ }
+
+ $data = array();
+ if ($this->getCurrentLineIndentation() >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
+ $data[] = $this->currentLine;
+ } else {
+ $this->moveToPreviousLine();
+
+ return;
+ }
+
+ if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {
+ // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
+ // and therefore no nested list or mapping
+ $this->moveToPreviousLine();
+
+ return;
+ }
+
+ $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
+
+ if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $this->getCurrentLineIndentation();
+ }
+
+ $previousLineIndentation = $this->getCurrentLineIndentation();
+
+ while ($this->moveToNextLine()) {
+ $indent = $this->getCurrentLineIndentation();
+
+ // terminate all block scalars that are more indented than the current line
+ if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) {
+ foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
+ if ($blockScalarIndentation >= $indent) {
+ unset($blockScalarIndentations[$key]);
+ }
+ }
+ }
+
+ if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $indent;
+ }
+
+ $previousLineIndentation = $indent;
+
+ if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
+ $this->moveToPreviousLine();
+ break;
+ }
+
+ if ($this->isCurrentLineBlank()) {
+ $data[] = substr($this->currentLine, $newIndent);
+ continue;
+ }
+
+ if ($indent >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } elseif ($this->isCurrentLineComment()) {
+ $data[] = $this->currentLine;
+ } elseif (0 == $indent) {
+ $this->moveToPreviousLine();
+
+ break;
+ } else {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ }
+
+ return implode("\n", $data);
+ }
+
+ /**
+ * Moves the parser to the next line.
+ *
+ * @return bool
+ */
+ private function moveToNextLine()
+ {
+ if ($this->currentLineNb >= count($this->lines) - 1) {
+ return false;
+ }
+
+ $this->currentLine = $this->lines[++$this->currentLineNb];
+
+ return true;
+ }
+
+ /**
+ * Moves the parser to the previous line.
+ *
+ * @return bool
+ */
+ private function moveToPreviousLine()
+ {
+ if ($this->currentLineNb < 1) {
+ return false;
+ }
+
+ $this->currentLine = $this->lines[--$this->currentLineNb];
+
+ return true;
+ }
+
+ /**
+ * Parses a YAML value.
+ *
+ * @param string $value A YAML value
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ * @param string $context The parser context (either sequence or mapping)
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException When reference does not exist
+ */
+ private function parseValue($value, $flags, $context)
+ {
+ if (0 === strpos($value, '*')) {
+ if (false !== $pos = strpos($value, '#')) {
+ $value = substr($value, 1, $pos - 2);
+ } else {
+ $value = substr($value, 1);
+ }
+
+ if (!array_key_exists($value, $this->refs)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
+ }
+
+ return $this->refs[$value];
+ }
+
+ if (self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
+ $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
+
+ $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
+
+ if ('' !== $matches['tag']) {
+ if ('!!binary' === $matches['tag']) {
+ return Inline::evaluateBinaryScalar($data);
+ } elseif ('tagged' === $matches['tag']) {
+ return new TaggedValue(substr($matches['tag'], 1), $data);
+ } elseif ('!' !== $matches['tag']) {
+ @trigger_error($this->getDeprecationMessage(sprintf('Using the custom tag "%s" for the value "%s" is deprecated since Symfony 3.3. It will be replaced by an instance of %s in 4.0.', $matches['tag'], $data, TaggedValue::class)), E_USER_DEPRECATED);
+ }
+ }
+
+ return $data;
+ }
+
+ try {
+ $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null;
+
+ // do not take following lines into account when the current line is a quoted single line value
+ if (null !== $quotation && self::preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) {
+ return Inline::parse($value, $flags, $this->refs);
+ }
+
+ $lines = array();
+
+ while ($this->moveToNextLine()) {
+ // unquoted strings end before the first unindented line
+ if (null === $quotation && 0 === $this->getCurrentLineIndentation()) {
+ $this->moveToPreviousLine();
+
+ break;
+ }
+
+ $lines[] = trim($this->currentLine);
+
+ // quoted string values end with a line that is terminated with the quotation character
+ if ('' !== $this->currentLine && substr($this->currentLine, -1) === $quotation) {
+ break;
+ }
+ }
+
+ for ($i = 0, $linesCount = count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) {
+ if ('' === $lines[$i]) {
+ $value .= "\n";
+ $previousLineBlank = true;
+ } elseif ($previousLineBlank) {
+ $value .= $lines[$i];
+ $previousLineBlank = false;
+ } else {
+ $value .= ' '.$lines[$i];
+ $previousLineBlank = false;
+ }
+ }
+
+ Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
+
+ $parsedValue = Inline::parse($value, $flags, $this->refs);
+
+ if ('mapping' === $context && is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
+ throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+
+ return $parsedValue;
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Parses a block scalar.
+ *
+ * @param string $style The style indicator that was used to begin this block scalar (| or >)
+ * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -)
+ * @param int $indentation The indentation indicator that was used to begin this block scalar
+ *
+ * @return string The text value
+ */
+ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
+ {
+ $notEOF = $this->moveToNextLine();
+ if (!$notEOF) {
+ return '';
+ }
+
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ $blockLines = array();
+
+ // leading blank lines are consumed before determining indentation
+ while ($notEOF && $isCurrentLineBlank) {
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $blockLines[] = '';
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+
+ // determine indentation if not specified
+ if (0 === $indentation) {
+ if (self::preg_match('/^ +/', $this->currentLine, $matches)) {
+ $indentation = strlen($matches[0]);
+ }
+ }
+
+ if ($indentation > 0) {
+ $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
+
+ while (
+ $notEOF && (
+ $isCurrentLineBlank ||
+ self::preg_match($pattern, $this->currentLine, $matches)
+ )
+ ) {
+ if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
+ $blockLines[] = substr($this->currentLine, $indentation);
+ } elseif ($isCurrentLineBlank) {
+ $blockLines[] = '';
+ } else {
+ $blockLines[] = $matches[1];
+ }
+
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+ } elseif ($notEOF) {
+ $blockLines[] = '';
+ }
+
+ if ($notEOF) {
+ $blockLines[] = '';
+ $this->moveToPreviousLine();
+ } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
+ $blockLines[] = '';
+ }
+
+ // folded style
+ if ('>' === $style) {
+ $text = '';
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+
+ for ($i = 0, $blockLinesCount = count($blockLines); $i < $blockLinesCount; ++$i) {
+ if ('' === $blockLines[$i]) {
+ $text .= "\n";
+ $previousLineIndented = false;
+ $previousLineBlank = true;
+ } elseif (' ' === $blockLines[$i][0]) {
+ $text .= "\n".$blockLines[$i];
+ $previousLineIndented = true;
+ $previousLineBlank = false;
+ } elseif ($previousLineIndented) {
+ $text .= "\n".$blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ } elseif ($previousLineBlank || 0 === $i) {
+ $text .= $blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ } else {
+ $text .= ' '.$blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ }
+ }
+ } else {
+ $text = implode("\n", $blockLines);
+ }
+
+ // deal with trailing newlines
+ if ('' === $chomping) {
+ $text = preg_replace('/\n+$/', "\n", $text);
+ } elseif ('-' === $chomping) {
+ $text = preg_replace('/\n+$/', '', $text);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Returns true if the next line is indented.
+ *
+ * @return bool Returns true if the next line is indented, false otherwise
+ */
+ private function isNextLineIndented()
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $movements = 0;
+
+ do {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));
+
+ if ($EOF) {
+ return false;
+ }
+
+ $ret = $this->getCurrentLineIndentation() > $currentIndentation;
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the current line is blank or if it is a comment line.
+ *
+ * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
+ */
+ private function isCurrentLineEmpty()
+ {
+ return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
+ }
+
+ /**
+ * Returns true if the current line is blank.
+ *
+ * @return bool Returns true if the current line is blank, false otherwise
+ */
+ private function isCurrentLineBlank()
+ {
+ return '' == trim($this->currentLine, ' ');
+ }
+
+ /**
+ * Returns true if the current line is a comment line.
+ *
+ * @return bool Returns true if the current line is a comment line, false otherwise
+ */
+ private function isCurrentLineComment()
+ {
+ //checking explicitly the first char of the trim is faster than loops or strpos
+ $ltrimmedLine = ltrim($this->currentLine, ' ');
+
+ return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
+ }
+
+ private function isCurrentLineLastLineInDocument()
+ {
+ return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
+ }
+
+ /**
+ * Cleanups a YAML string to be parsed.
+ *
+ * @param string $value The input YAML string
+ *
+ * @return string A cleaned up YAML string
+ */
+ private function cleanup($value)
+ {
+ $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+ // strip YAML header
+ $count = 0;
+ $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
+ $this->offset += $count;
+
+ // remove leading comments
+ $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
+ if (1 === $count) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+ }
+
+ // remove start of the document marker (---)
+ $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
+ if (1 === $count) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+
+ // remove end of the document marker (...)
+ $value = preg_replace('#\.\.\.\s*$#', '', $value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Returns true if the next line starts unindented collection.
+ *
+ * @return bool Returns true if the next line starts unindented collection, false otherwise
+ */
+ private function isNextLineUnIndentedCollection()
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $movements = 0;
+
+ do {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));
+
+ if ($EOF) {
+ return false;
+ }
+
+ $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem();
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the string is un-indented collection item.
+ *
+ * @return bool Returns true if the string is un-indented collection item, false otherwise
+ */
+ private function isStringUnIndentedCollectionItem()
+ {
+ return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
+ }
+
+ /**
+ * Tests whether or not the current line is the header of a block scalar.
+ *
+ * @return bool
+ */
+ private function isBlockScalarHeader()
+ {
+ return (bool) self::preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
+ }
+
+ /**
+ * A local wrapper for `preg_match` which will throw a ParseException if there
+ * is an internal error in the PCRE engine.
+ *
+ * This avoids us needing to check for "false" every time PCRE is used
+ * in the YAML engine
+ *
+ * @throws ParseException on a PCRE internal error
+ *
+ * @see preg_last_error()
+ *
+ * @internal
+ */
+ public static function preg_match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
+ {
+ if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) {
+ switch (preg_last_error()) {
+ case PREG_INTERNAL_ERROR:
+ $error = 'Internal PCRE error.';
+ break;
+ case PREG_BACKTRACK_LIMIT_ERROR:
+ $error = 'pcre.backtrack_limit reached.';
+ break;
+ case PREG_RECURSION_LIMIT_ERROR:
+ $error = 'pcre.recursion_limit reached.';
+ break;
+ case PREG_BAD_UTF8_ERROR:
+ $error = 'Malformed UTF-8 data.';
+ break;
+ case PREG_BAD_UTF8_OFFSET_ERROR:
+ $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
+ break;
+ default:
+ $error = 'Error.';
+ }
+
+ throw new ParseException($error);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Trim the tag on top of the value.
+ *
+ * Prevent values such as `!foo {quz: bar}` to be considered as
+ * a mapping block.
+ */
+ private function trimTag($value)
+ {
+ if ('!' === $value[0]) {
+ return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' ');
+ }
+
+ return $value;
+ }
+
+ private function getLineTag($value, $flags, $nextLineCheck = true)
+ {
+ if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) {
+ return;
+ }
+
+ if ($nextLineCheck && !$this->isNextLineIndented()) {
+ return;
+ }
+
+ $tag = substr($matches['tag'], 1);
+
+ // Built-in tags
+ if ($tag && '!' === $tag[0]) {
+ throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+
+ if (Yaml::PARSE_CUSTOM_TAGS & $flags) {
+ return $tag;
+ }
+
+ throw new ParseException(sprintf('Tags support is not enabled. You must use the flag `Yaml::PARSE_CUSTOM_TAGS` to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+
+ private function getDeprecationMessage($message)
+ {
+ $message = rtrim($message, '.');
+
+ if (null !== $this->filename) {
+ $message .= ' in '.$this->filename;
+ }
+
+ $message .= ' on line '.($this->getRealCurrentLineNb() + 1);
+
+ return $message.'.';
+ }
+}
diff --git a/vendor/symfony/yaml/README.md b/vendor/symfony/yaml/README.md
new file mode 100644
index 0000000..0d32488
--- /dev/null
+++ b/vendor/symfony/yaml/README.md
@@ -0,0 +1,13 @@
+Yaml Component
+==============
+
+The Yaml component loads and dumps YAML files.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/yaml/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/vendor/symfony/yaml/Tag/TaggedValue.php b/vendor/symfony/yaml/Tag/TaggedValue.php
new file mode 100644
index 0000000..000c1d9
--- /dev/null
+++ b/vendor/symfony/yaml/Tag/TaggedValue.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tag;
+
+/**
+ * @author Nicolas Grekas
+ * @author Guilhem N.
+ */
+final class TaggedValue
+{
+ private $tag;
+ private $value;
+
+ /**
+ * @param string $tag
+ * @param mixed $value
+ */
+ public function __construct($tag, $value)
+ {
+ $this->tag = $tag;
+ $this->value = $value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTag()
+ {
+ return $this->tag;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/Command/LintCommandTest.php b/vendor/symfony/yaml/Tests/Command/LintCommandTest.php
new file mode 100644
index 0000000..5d0f44d
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Command/LintCommandTest.php
@@ -0,0 +1,139 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests\Command;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Command\LintCommand;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Tester\CommandTester;
+
+/**
+ * Tests the YamlLintCommand.
+ *
+ * @author Robin Chalas
+ */
+class LintCommandTest extends TestCase
+{
+ private $files;
+
+ public function testLintCorrectFile()
+ {
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile('foo: bar');
+
+ $ret = $tester->execute(array('filename' => $filename), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+
+ $this->assertEquals(0, $ret, 'Returns 0 in case of success');
+ $this->assertRegExp('/^\/\/ OK in /', trim($tester->getDisplay()));
+ }
+
+ public function testLintIncorrectFile()
+ {
+ $incorrectContent = '
+foo:
+bar';
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile($incorrectContent);
+
+ $ret = $tester->execute(array('filename' => $filename), array('decorated' => false));
+
+ $this->assertEquals(1, $ret, 'Returns 1 in case of error');
+ $this->assertContains('Unable to parse at line 3 (near "bar").', trim($tester->getDisplay()));
+ }
+
+ public function testConstantAsKey()
+ {
+ $yaml = <<createCommandTester()->execute(array('filename' => $this->createFile($yaml)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success');
+ }
+
+ public function testCustomTags()
+ {
+ $yaml = <<createCommandTester()->execute(array('filename' => $this->createFile($yaml), '--parse-tags' => true), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success');
+ }
+
+ public function testCustomTagsError()
+ {
+ $yaml = <<createCommandTester()->execute(array('filename' => $this->createFile($yaml)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(1, $ret, 'lint:yaml exits with code 1 in case of error');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testLintFileNotReadable()
+ {
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile('');
+ unlink($filename);
+
+ $ret = $tester->execute(array('filename' => $filename), array('decorated' => false));
+ }
+
+ /**
+ * @return string Path to the new file
+ */
+ private function createFile($content)
+ {
+ $filename = tempnam(sys_get_temp_dir().'/framework-yml-lint-test', 'sf-');
+ file_put_contents($filename, $content);
+
+ $this->files[] = $filename;
+
+ return $filename;
+ }
+
+ /**
+ * @return CommandTester
+ */
+ protected function createCommandTester()
+ {
+ $application = new Application();
+ $application->add(new LintCommand());
+ $command = $application->find('lint:yaml');
+
+ return new CommandTester($command);
+ }
+
+ protected function setUp()
+ {
+ $this->files = array();
+ @mkdir(sys_get_temp_dir().'/framework-yml-lint-test');
+ }
+
+ protected function tearDown()
+ {
+ foreach ($this->files as $file) {
+ if (file_exists($file)) {
+ unlink($file);
+ }
+ }
+
+ rmdir(sys_get_temp_dir().'/framework-yml-lint-test');
+ }
+}
+
+class Foo
+{
+ const TEST = 'foo';
+}
diff --git a/vendor/symfony/yaml/Tests/DumperTest.php b/vendor/symfony/yaml/Tests/DumperTest.php
new file mode 100644
index 0000000..b474391
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/DumperTest.php
@@ -0,0 +1,495 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Dumper;
+use Symfony\Component\Yaml\Yaml;
+
+class DumperTest extends TestCase
+{
+ protected $parser;
+ protected $dumper;
+ protected $path;
+
+ protected $array = array(
+ '' => 'bar',
+ 'foo' => '#bar',
+ 'foo\'bar' => array(),
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ ),
+ ),
+ );
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ $this->dumper = new Dumper();
+ $this->path = __DIR__.'/Fixtures';
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+ $this->dumper = null;
+ $this->path = null;
+ $this->array = null;
+ }
+
+ public function testIndentationInConstructor()
+ {
+ $dumper = new Dumper(7);
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $dumper->dump($this->array, 4, 0));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testSetIndentation()
+ {
+ $this->dumper->setIndentation(7);
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0));
+ }
+
+ public function testSpecifications()
+ {
+ $files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
+ foreach ($files as $file) {
+ $yamls = file_get_contents($this->path.'/'.$file.'.yml');
+
+ // split YAMLs documents
+ foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
+ if (!$yaml) {
+ continue;
+ }
+
+ $test = $this->parser->parse($yaml);
+ if (isset($test['dump_skip']) && $test['dump_skip']) {
+ continue;
+ } elseif (isset($test['todo']) && $test['todo']) {
+ // TODO
+ } else {
+ eval('$expected = '.trim($test['php']).';');
+ $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
+ }
+ }
+ }
+ }
+
+ public function testInlineLevel()
+ {
+ $expected = <<<'EOF'
+{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar: [1, foo]
+foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar: [1, foo]
+ foobar: { foo: bar, bar: [1, foo] }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar: [1, foo]
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT);
+
+ $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testObjectSupportEnabledPassingTrue()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true);
+
+ $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects');
+ }
+
+ public function testObjectSupportDisabledButNoExceptions()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));
+
+ $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\DumpException
+ */
+ public function testObjectSupportDisabledWithExceptions()
+ {
+ $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE);
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \Symfony\Component\Yaml\Exception\DumpException
+ */
+ public function testObjectSupportDisabledWithExceptionsPassingTrue()
+ {
+ $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true);
+ }
+
+ public function testEmptyArray()
+ {
+ $dump = $this->dumper->dump(array());
+ $this->assertEquals('{ }', $dump);
+
+ $dump = $this->dumper->dump(array(), 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE);
+ $this->assertEquals('[]', $dump);
+
+ $dump = $this->dumper->dump(array(), 9, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE);
+ $this->assertEquals('[]', $dump);
+
+ $dump = $this->dumper->dump(new \ArrayObject(), 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP);
+ $this->assertEquals('{ }', $dump);
+
+ $dump = $this->dumper->dump(new \stdClass(), 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP);
+ $this->assertEquals('{ }', $dump);
+ }
+
+ /**
+ * @dataProvider getEscapeSequences
+ */
+ public function testEscapedEscapeSequencesInQuotedScalar($input, $expected)
+ {
+ $this->assertEquals($expected, $this->dumper->dump($input));
+ }
+
+ public function getEscapeSequences()
+ {
+ return array(
+ 'empty string' => array('', "''"),
+ 'null' => array("\x0", '"\\0"'),
+ 'bell' => array("\x7", '"\\a"'),
+ 'backspace' => array("\x8", '"\\b"'),
+ 'horizontal-tab' => array("\t", '"\\t"'),
+ 'line-feed' => array("\n", '"\\n"'),
+ 'vertical-tab' => array("\v", '"\\v"'),
+ 'form-feed' => array("\xC", '"\\f"'),
+ 'carriage-return' => array("\r", '"\\r"'),
+ 'escape' => array("\x1B", '"\\e"'),
+ 'space' => array(' ', "' '"),
+ 'double-quote' => array('"', "'\"'"),
+ 'slash' => array('/', '/'),
+ 'backslash' => array('\\', '\\'),
+ 'next-line' => array("\xC2\x85", '"\\N"'),
+ 'non-breaking-space' => array("\xc2\xa0", '"\\_"'),
+ 'line-separator' => array("\xE2\x80\xA8", '"\\L"'),
+ 'paragraph-separator' => array("\xE2\x80\xA9", '"\\P"'),
+ 'colon' => array(':', "':'"),
+ );
+ }
+
+ public function testBinaryDataIsDumpedBase64Encoded()
+ {
+ $binaryData = file_get_contents(__DIR__.'/Fixtures/arrow.gif');
+ $expected = '{ data: !!binary '.base64_encode($binaryData).' }';
+
+ $this->assertSame($expected, $this->dumper->dump(array('data' => $binaryData)));
+ }
+
+ public function testNonUtf8DataIsDumpedBase64Encoded()
+ {
+ // "für" (ISO-8859-1 encoded)
+ $this->assertSame('!!binary ZsM/cg==', $this->dumper->dump("f\xc3\x3fr"));
+ }
+
+ /**
+ * @dataProvider objectAsMapProvider
+ */
+ public function testDumpObjectAsMap($object, $expected)
+ {
+ $yaml = $this->dumper->dump($object, 0, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $this->assertEquals($expected, Yaml::parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
+ }
+
+ public function objectAsMapProvider()
+ {
+ $tests = array();
+
+ $bar = new \stdClass();
+ $bar->class = 'classBar';
+ $bar->args = array('bar');
+ $zar = new \stdClass();
+ $foo = new \stdClass();
+ $foo->bar = $bar;
+ $foo->zar = $zar;
+ $object = new \stdClass();
+ $object->foo = $foo;
+ $tests['stdClass'] = array($object, $object);
+
+ $arrayObject = new \ArrayObject();
+ $arrayObject['foo'] = 'bar';
+ $arrayObject['baz'] = 'foobar';
+ $parsedArrayObject = new \stdClass();
+ $parsedArrayObject->foo = 'bar';
+ $parsedArrayObject->baz = 'foobar';
+ $tests['ArrayObject'] = array($arrayObject, $parsedArrayObject);
+
+ $a = new A();
+ $tests['arbitrary-object'] = array($a, null);
+
+ return $tests;
+ }
+
+ public function testDumpingArrayObjectInstancesRespectsInlineLevel()
+ {
+ $deep = new \ArrayObject(array('deep1' => 'd', 'deep2' => 'e'));
+ $inner = new \ArrayObject(array('inner1' => 'b', 'inner2' => 'c', 'inner3' => $deep));
+ $outer = new \ArrayObject(array('outer1' => 'a', 'outer2' => $inner));
+
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $expected = <<assertSame($expected, $yaml);
+ }
+
+ public function testDumpingArrayObjectInstancesWithNumericKeysInlined()
+ {
+ $deep = new \ArrayObject(array('d', 'e'));
+ $inner = new \ArrayObject(array('b', 'c', $deep));
+ $outer = new \ArrayObject(array('a', $inner));
+
+ $yaml = $this->dumper->dump($outer, 0, 0, Yaml::DUMP_OBJECT_AS_MAP);
+ $expected = <<assertSame($expected, $yaml);
+ }
+
+ public function testDumpingArrayObjectInstancesWithNumericKeysRespectsInlineLevel()
+ {
+ $deep = new \ArrayObject(array('d', 'e'));
+ $inner = new \ArrayObject(array('b', 'c', $deep));
+ $outer = new \ArrayObject(array('a', $inner));
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+ $expected = <<assertEquals($expected, $yaml);
+ }
+
+ public function testDumpEmptyArrayObjectInstanceAsMap()
+ {
+ $this->assertSame('{ }', $this->dumper->dump(new \ArrayObject(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
+ }
+
+ public function testDumpEmptyStdClassInstanceAsMap()
+ {
+ $this->assertSame('{ }', $this->dumper->dump(new \stdClass(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
+ }
+
+ public function testDumpingStdClassInstancesRespectsInlineLevel()
+ {
+ $deep = new \stdClass();
+ $deep->deep1 = 'd';
+ $deep->deep2 = 'e';
+
+ $inner = new \stdClass();
+ $inner->inner1 = 'b';
+ $inner->inner2 = 'c';
+ $inner->inner3 = $deep;
+
+ $outer = new \stdClass();
+ $outer->outer1 = 'a';
+ $outer->outer2 = $inner;
+
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $expected = <<assertSame($expected, $yaml);
+ }
+
+ public function testDumpMultiLineStringAsScalarBlock()
+ {
+ $data = array(
+ 'data' => array(
+ 'single_line' => 'foo bar baz',
+ 'multi_line' => "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz",
+ 'multi_line_with_carriage_return' => "foo\nbar\r\nbaz",
+ 'nested_inlined_multi_line_string' => array(
+ 'inlined_multi_line' => "foo\nbar\r\nempty line:\n\nbaz",
+ ),
+ ),
+ );
+
+ $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace()
+ {
+ $data = array(
+ 'data' => array(
+ 'multi_line' => " the first line has leading spaces\nThe second line does not.",
+ ),
+ );
+
+ $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ public function testCarriageReturnIsMaintainedWhenDumpingAsMultiLineLiteralBlock()
+ {
+ $this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(array("a\r\nb\nc"), 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testZeroIndentationThrowsException()
+ {
+ new Dumper(0);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testNegativeIndentationThrowsException()
+ {
+ new Dumper(-4);
+ }
+}
+
+class A
+{
+ public $a = 'foo';
+}
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml
new file mode 100644
index 0000000..5f9c942
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml
@@ -0,0 +1,31 @@
+--- %YAML:1.0
+test: Simple Alias Example
+brief: >
+ If you need to refer to the same item of data twice,
+ you can give that item an alias. The alias is a plain
+ string, starting with an ampersand. The item may then
+ be referred to by the alias throughout your document
+ by using an asterisk before the name of the alias.
+ This is called an anchor.
+yaml: |
+ - &showell Steve
+ - Clark
+ - Brian
+ - Oren
+ - *showell
+php: |
+ array('Steve', 'Clark', 'Brian', 'Oren', 'Steve')
+
+---
+test: Alias of a Mapping
+brief: >
+ An alias can be used on any item of data, including
+ sequences, mappings, and other complex data types.
+yaml: |
+ - &hello
+ Meat: pork
+ Starch: potato
+ - banana
+ - *hello
+php: |
+ array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato'))
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml
new file mode 100644
index 0000000..dfd9302
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml
@@ -0,0 +1,202 @@
+--- %YAML:1.0
+test: Simple Sequence
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ - carrot
+php: |
+ array('apple', 'banana', 'carrot')
+---
+test: Sequence With Item Being Null In The Middle
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ -
+ - carrot
+php: |
+ array('apple', null, 'carrot')
+---
+test: Sequence With Last Item Being Null
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ -
+php: |
+ array('apple', 'banana', null)
+---
+test: Nested Sequences
+brief: |
+ You can include a sequence within another
+ sequence by giving the sequence an empty
+ dash, followed by an indented list.
+yaml: |
+ -
+ - foo
+ - bar
+ - baz
+php: |
+ array(array('foo', 'bar', 'baz'))
+---
+test: Mixed Sequences
+brief: |
+ Sequences can contain any YAML data,
+ including strings and other sequences.
+yaml: |
+ - apple
+ -
+ - foo
+ - bar
+ - x123
+ - banana
+ - carrot
+php: |
+ array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot')
+---
+test: Deeply Nested Sequences
+brief: |
+ Sequences can be nested even deeper, with each
+ level of indentation representing a level of
+ depth.
+yaml: |
+ -
+ -
+ - uno
+ - dos
+php: |
+ array(array(array('uno', 'dos')))
+---
+test: Simple Mapping
+brief: |
+ You can add a keyed list (also known as a dictionary or
+ hash) to your document by placing each member of the
+ list on a new line, with a colon separating the key
+ from its value. In YAML, this type of list is called
+ a mapping.
+yaml: |
+ foo: whatever
+ bar: stuff
+php: |
+ array('foo' => 'whatever', 'bar' => 'stuff')
+---
+test: Sequence in a Mapping
+brief: |
+ A value in a mapping can be a sequence.
+yaml: |
+ foo: whatever
+ bar:
+ - uno
+ - dos
+php: |
+ array('foo' => 'whatever', 'bar' => array('uno', 'dos'))
+---
+test: Nested Mappings
+brief: |
+ A value in a mapping can be another mapping.
+yaml: |
+ foo: whatever
+ bar:
+ fruit: apple
+ name: steve
+ sport: baseball
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ )
+ )
+---
+test: Mixed Mapping
+brief: |
+ A mapping can contain any assortment
+ of mappings and sequences as values.
+yaml: |
+ foo: whatever
+ bar:
+ -
+ fruit: apple
+ name: steve
+ sport: baseball
+ - more
+ -
+ python: rocks
+ perl: papers
+ ruby: scissorses
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ ),
+ 'more',
+ array(
+ 'python' => 'rocks',
+ 'perl' => 'papers',
+ 'ruby' => 'scissorses'
+ )
+ )
+ )
+---
+test: Mapping-in-Sequence Shortcut
+todo: true
+brief: |
+ If you are adding a mapping to a sequence, you
+ can place the mapping on the same line as the
+ dash as a shortcut.
+yaml: |
+ - work on YAML.py:
+ - work on Store
+php: |
+ array(array('work on YAML.py' => array('work on Store')))
+---
+test: Sequence-in-Mapping Shortcut
+todo: true
+brief: |
+ The dash in a sequence counts as indentation, so
+ you can add a sequence inside of a mapping without
+ needing spaces as indentation.
+yaml: |
+ allow:
+ - 'localhost'
+ - '%.sourceforge.net'
+ - '%.freepan.org'
+php: |
+ array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org'))
+---
+todo: true
+test: Merge key
+brief: |
+ A merge key ('<<') can be used in a mapping to insert other mappings. If
+ the value associated with the merge key is a mapping, each of its key/value
+ pairs is inserted into the current mapping.
+yaml: |
+ mapping:
+ name: Joe
+ job: Accountant
+ <<:
+ age: 38
+php: |
+ array(
+ 'mapping' =>
+ array(
+ 'name' => 'Joe',
+ 'job' => 'Accountant',
+ 'age' => 38
+ )
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml
new file mode 100644
index 0000000..f7ca469
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml
@@ -0,0 +1,51 @@
+---
+test: One Element Mapping
+brief: |
+ A mapping with one key/value pair
+yaml: |
+ foo: bar
+php: |
+ array('foo' => 'bar')
+---
+test: Multi Element Mapping
+brief: |
+ More than one key/value pair
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Values aligned
+brief: |
+ Often times human editors of documents will align the values even
+ though YAML emitters generally don't.
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Colons aligned
+brief: |
+ Spaces can come before the ': ' key/value separator.
+yaml: |
+ red : baron
+ white : walls
+ blue : berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml
new file mode 100644
index 0000000..d988102
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml
@@ -0,0 +1,85 @@
+--- %YAML:1.0
+test: Trailing Document Separator
+todo: true
+brief: >
+ You can separate YAML documents
+ with a string of three dashes.
+yaml: |
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ { 'foo': 1, 'bar': 2 } ],
+ { 'more': 'stuff' }
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: Leading Document Separator
+todo: true
+brief: >
+ You can explicitly give an opening
+ document separator to your YAML stream.
+yaml: |
+ ---
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ {'foo': 1, 'bar': 2}],
+ {'more': 'stuff'}
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: YAML Header
+todo: true
+brief: >
+ The opening separator can contain directives
+ to the YAML parser, such as the version
+ number.
+yaml: |
+ --- %YAML:1.0
+ foo: 1
+ bar: 2
+php: |
+ array('foo' => 1, 'bar' => 2)
+documents: 1
+
+---
+test: Red Herring Document Separator
+brief: >
+ Separators included in blocks or strings
+ are treated as blocks or strings, as the
+ document separator should have no indentation
+ preceding it.
+yaml: |
+ foo: |
+ ---
+php: |
+ array('foo' => "---\n")
+
+---
+test: Multiple Document Separators in Block
+brief: >
+ This technique allows you to embed other YAML
+ documents within literal blocks.
+yaml: |
+ foo: |
+ ---
+ foo: bar
+ ---
+ yo: baz
+ bar: |
+ fooness
+php: |
+ array(
+ 'foo' => "---\nfoo: bar\n---\nyo: baz\n",
+ 'bar' => "fooness\n"
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml
new file mode 100644
index 0000000..e8506fc
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml
@@ -0,0 +1,25 @@
+---
+test: Missing value for hash item
+todo: true
+brief: |
+ Third item in this hash doesn't have a value
+yaml: |
+ okay: value
+ also okay: ~
+ causes error because no value specified
+ last key: value okay here too
+python-error: causes error because no value specified
+
+---
+test: Not indenting enough
+brief: |
+ There was a bug in PyYaml where it was off by one
+ in the indentation check. It was allowing the YAML
+ below.
+# This is actually valid YAML now. Someone should tell showell.
+yaml: |
+ foo:
+ firstline: 1
+ secondline: 2
+php: |
+ array('foo' => null, 'firstline' => 1, 'secondline' => 2)
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml
new file mode 100644
index 0000000..03090e4
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml
@@ -0,0 +1,60 @@
+---
+test: Simple Inline Array
+brief: >
+ Sequences can be contained on a
+ single line, using the inline syntax.
+ Separate each entry with commas and
+ enclose in square brackets.
+yaml: |
+ seq: [ a, b, c ]
+php: |
+ array('seq' => array('a', 'b', 'c'))
+---
+test: Simple Inline Hash
+brief: >
+ Mapping can also be contained on
+ a single line, using the inline
+ syntax. Each key-value pair is
+ separated by a colon, with a comma
+ between each entry in the mapping.
+ Enclose with curly braces.
+yaml: |
+ hash: { name: Steve, foo: bar }
+php: |
+ array('hash' => array('name' => 'Steve', 'foo' => 'bar'))
+---
+test: Multi-line Inline Collections
+todo: true
+brief: >
+ Both inline sequences and inline mappings
+ can span multiple lines, provided that you
+ indent the additional lines.
+yaml: |
+ languages: [ Ruby,
+ Perl,
+ Python ]
+ websites: { YAML: yaml.org,
+ Ruby: ruby-lang.org,
+ Python: python.org,
+ Perl: use.perl.org }
+php: |
+ array(
+ 'languages' => array('Ruby', 'Perl', 'Python'),
+ 'websites' => array(
+ 'YAML' => 'yaml.org',
+ 'Ruby' => 'ruby-lang.org',
+ 'Python' => 'python.org',
+ 'Perl' => 'use.perl.org'
+ )
+ )
+---
+test: Commas in Values (not in the spec!)
+todo: true
+brief: >
+ List items in collections are delimited by commas, but
+ there must be a space after each comma. This allows you
+ to add numbers without quoting.
+yaml: |
+ attendances: [ 45,123, 70,000, 17,222 ]
+php: |
+ array('attendances' => array(45123, 70000, 17222))
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml
new file mode 100644
index 0000000..a14735a
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml
@@ -0,0 +1,176 @@
+--- %YAML:1.0
+test: Single ending newline
+brief: >
+ A pipe character, followed by an indented
+ block of text is treated as a literal
+ block, in which newlines are preserved
+ throughout the block, including the final
+ newline.
+yaml: |
+ ---
+ this: |
+ Foo
+ Bar
+php: |
+ array('this' => "Foo\nBar\n")
+---
+test: The '+' indicator
+brief: >
+ The '+' indicator says to keep newlines at the end of text
+ blocks.
+yaml: |
+ normal: |
+ extra new lines not kept
+
+ preserving: |+
+ extra new lines are kept
+
+
+ dummy: value
+php: |
+ array(
+ 'normal' => "extra new lines not kept\n",
+ 'preserving' => "extra new lines are kept\n\n\n",
+ 'dummy' => 'value'
+ )
+---
+test: Three trailing newlines in literals
+brief: >
+ To give you more control over how space
+ is preserved in text blocks, YAML has
+ the keep '+' and chomp '-' indicators.
+ The keep indicator will preserve all
+ ending newlines, while the chomp indicator
+ will strip all ending newlines.
+yaml: |
+ clipped: |
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
+---
+test: Extra trailing newlines with spaces
+todo: true
+brief: >
+ Normally, only a single newline is kept
+ from the end of a literal block, unless the
+ keep '+' character is used in combination
+ with the pipe. The following example
+ will preserve all ending whitespace
+ since the last line of both literal blocks
+ contains spaces which extend past the indentation
+ level.
+yaml: |
+ ---
+ this: |
+ Foo
+
+
+ kept: |+
+ Foo
+
+
+php: |
+ array('this' => "Foo\n\n \n",
+ 'kept' => "Foo\n\n \n" )
+
+---
+test: Folded Block in a Sequence
+brief: >
+ A greater-then character, followed by an indented
+ block of text is treated as a folded block, in
+ which lines of text separated by a single newline
+ are concatenated as a single line.
+yaml: |
+ ---
+ - apple
+ - banana
+ - >
+ can't you see
+ the beauty of yaml?
+ hmm
+ - dog
+php: |
+ array(
+ 'apple',
+ 'banana',
+ "can't you see the beauty of yaml? hmm\n",
+ 'dog'
+ )
+---
+test: Folded Block as a Mapping Value
+brief: >
+ Both literal and folded blocks can be
+ used in collections, as values in a
+ sequence or a mapping.
+yaml: |
+ ---
+ quote: >
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+ source: espn
+php: |
+ array(
+ 'quote' => "Mark McGwire's year was crippled by a knee injury.\n",
+ 'source' => 'espn'
+ )
+---
+test: Three trailing newlines in folded blocks
+brief: >
+ The keep and chomp indicators can also
+ be applied to folded blocks.
+yaml: |
+ clipped: >
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: >-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: >+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
new file mode 100644
index 0000000..9a5300f
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
@@ -0,0 +1,45 @@
+--- %YAML:1.0
+test: Empty Sequence
+brief: >
+ You can represent the empty sequence
+ with an empty inline sequence.
+yaml: |
+ empty: []
+php: |
+ array('empty' => array())
+---
+test: Empty Mapping
+brief: >
+ You can represent the empty mapping
+ with an empty inline mapping.
+yaml: |
+ empty: {}
+php: |
+ array('empty' => array())
+---
+test: Empty Sequence as Entire Document
+yaml: |
+ []
+php: |
+ array()
+---
+test: Empty Mapping as Entire Document
+yaml: |
+ {}
+php: |
+ array()
+---
+test: Null as Document
+yaml: |
+ ~
+php: |
+ null
+---
+test: Empty String
+brief: >
+ You can represent an empty string
+ with a pair of quotes.
+yaml: |
+ ''
+php: |
+ ''
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml
new file mode 100644
index 0000000..3f93c98
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml
@@ -0,0 +1,1701 @@
+--- %YAML:1.0
+test: Sequence of scalars
+spec: 2.1
+yaml: |
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey')
+---
+test: Mapping of scalars to scalars
+spec: 2.2
+yaml: |
+ hr: 65
+ avg: 0.278
+ rbi: 147
+php: |
+ array('hr' => 65, 'avg' => 0.278, 'rbi' => 147)
+---
+test: Mapping of scalars to sequences
+spec: 2.3
+yaml: |
+ american:
+ - Boston Red Sox
+ - Detroit Tigers
+ - New York Yankees
+ national:
+ - New York Mets
+ - Chicago Cubs
+ - Atlanta Braves
+php: |
+ array('american' =>
+ array( 'Boston Red Sox', 'Detroit Tigers',
+ 'New York Yankees' ),
+ 'national' =>
+ array( 'New York Mets', 'Chicago Cubs',
+ 'Atlanta Braves' )
+ )
+---
+test: Sequence of mappings
+spec: 2.4
+yaml: |
+ -
+ name: Mark McGwire
+ hr: 65
+ avg: 0.278
+ -
+ name: Sammy Sosa
+ hr: 63
+ avg: 0.288
+php: |
+ array(
+ array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278),
+ array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288)
+ )
+---
+test: Legacy A5
+todo: true
+spec: legacy_A5
+yaml: |
+ ?
+ - New York Yankees
+ - Atlanta Braves
+ :
+ - 2001-07-02
+ - 2001-08-12
+ - 2001-08-14
+ ?
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+perl-busted: >
+ YAML.pm will be able to emulate this behavior soon. In this regard
+ it may be somewhat more correct than Python's native behaviour which
+ can only use tuples as mapping keys. PyYAML will also need to figure
+ out some clever way to roundtrip structured keys.
+python: |
+ [
+ {
+ ('New York Yankees', 'Atlanta Braves'):
+ [yaml.timestamp('2001-07-02'),
+ yaml.timestamp('2001-08-12'),
+ yaml.timestamp('2001-08-14')],
+ ('Detroit Tigers', 'Chicago Cubs'):
+ [yaml.timestamp('2001-07-23')]
+ }
+ ]
+ruby: |
+ {
+ [ 'New York Yankees', 'Atlanta Braves' ] =>
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ],
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
+ [ Date.new( 2001, 7, 23 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence of sequences
+spec: 2.5
+yaml: |
+ - [ name , hr , avg ]
+ - [ Mark McGwire , 65 , 0.278 ]
+ - [ Sammy Sosa , 63 , 0.288 ]
+php: |
+ array(
+ array( 'name', 'hr', 'avg' ),
+ array( 'Mark McGwire', 65, 0.278 ),
+ array( 'Sammy Sosa', 63, 0.288 )
+ )
+---
+test: Mapping of mappings
+todo: true
+spec: 2.6
+yaml: |
+ Mark McGwire: {hr: 65, avg: 0.278}
+ Sammy Sosa: {
+ hr: 63,
+ avg: 0.288
+ }
+php: |
+ array(
+ 'Mark McGwire' =>
+ array( 'hr' => 65, 'avg' => 0.278 ),
+ 'Sammy Sosa' =>
+ array( 'hr' => 63, 'avg' => 0.288 )
+ )
+---
+test: Two documents in a stream each with a leading comment
+todo: true
+spec: 2.7
+yaml: |
+ # Ranking of 1998 home runs
+ ---
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+
+ # Team ranking
+ ---
+ - Chicago Cubs
+ - St Louis Cardinals
+ruby: |
+ y = YAML::Stream.new
+ y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] )
+ y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] )
+documents: 2
+
+---
+test: Play by play feed from a game
+todo: true
+spec: 2.8
+yaml: |
+ ---
+ time: 20:03:20
+ player: Sammy Sosa
+ action: strike (miss)
+ ...
+ ---
+ time: 20:03:47
+ player: Sammy Sosa
+ action: grand slam
+ ...
+perl: |
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]
+documents: 2
+
+---
+test: Single document with two comments
+spec: 2.9
+yaml: |
+ hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+ rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array(
+ 'hr' => array( 'Mark McGwire', 'Sammy Sosa' ),
+ 'rbi' => array( 'Sammy Sosa', 'Ken Griffey' )
+ )
+---
+test: Node for Sammy Sosa appears twice in this document
+spec: 2.10
+yaml: |
+ ---
+ hr:
+ - Mark McGwire
+ # Following node labeled SS
+ - &SS Sammy Sosa
+ rbi:
+ - *SS # Subsequent occurrence
+ - Ken Griffey
+php: |
+ array(
+ 'hr' =>
+ array('Mark McGwire', 'Sammy Sosa'),
+ 'rbi' =>
+ array('Sammy Sosa', 'Ken Griffey')
+ )
+---
+test: Mapping between sequences
+todo: true
+spec: 2.11
+yaml: |
+ ? # PLAY SCHEDULE
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+
+ ? [ New York Yankees,
+ Atlanta Braves ]
+ : [ 2001-07-02, 2001-08-12,
+ 2001-08-14 ]
+ruby: |
+ {
+ [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence key shortcut
+spec: 2.12
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ quantity: 1
+ - item : Basketball
+ quantity: 4
+ - item : Big Shoes
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 4,
+ ),
+ array (
+ 'item' => 'Big Shoes',
+ 'quantity' => 1,
+ )
+ )
+perl: |
+ [
+ { item => 'Super Hoop', quantity => 1 },
+ { item => 'Basketball', quantity => 4 },
+ { item => 'Big Shoes', quantity => 1 }
+ ]
+
+ruby: |
+ [
+ { 'item' => 'Super Hoop', 'quantity' => 1 },
+ { 'item' => 'Basketball', 'quantity' => 4 },
+ { 'item' => 'Big Shoes', 'quantity' => 1 }
+ ]
+python: |
+ [
+ { 'item': 'Super Hoop', 'quantity': 1 },
+ { 'item': 'Basketball', 'quantity': 4 },
+ { 'item': 'Big Shoes', 'quantity': 1 }
+ ]
+syck: |
+ struct test_node map1[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Super Hoop" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node map2[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Basketball" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "4" },
+ end_node
+ };
+ struct test_node map3[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Big Shoes" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node seq[] = {
+ { T_MAP, 0, 0, map1 },
+ { T_MAP, 0, 0, map2 },
+ { T_MAP, 0, 0, map3 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_SEQ, 0, 0, seq },
+ end_node
+ };
+
+
+---
+test: Literal perserves newlines
+todo: true
+spec: 2.13
+yaml: |
+ # ASCII Art
+ --- |
+ \//||\/||
+ // || ||_
+perl: |
+ "\\//||\\/||\n// || ||_\n"
+ruby: |
+ "\\//||\\/||\n// || ||_\n"
+python: |
+ [
+ flushLeft(
+ """
+ \//||\/||
+ // || ||_
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "\\//||\\/||\n// || ||_\n" },
+ end_node
+ };
+
+---
+test: Folded treats newlines as a space
+todo: true
+spec: 2.14
+yaml: |
+ ---
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+perl: |
+ "Mark McGwire's year was crippled by a knee injury."
+ruby: |
+ "Mark McGwire's year was crippled by a knee injury."
+python: |
+ [ "Mark McGwire's year was crippled by a knee injury." ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." },
+ end_node
+ };
+
+---
+test: Newlines preserved for indented and blank lines
+todo: true
+spec: 2.15
+yaml: |
+ --- >
+ Sammy Sosa completed another
+ fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+perl: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+ruby: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+python: |
+ [
+ flushLeft(
+ """
+ Sammy Sosa completed another fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" },
+ end_node
+ };
+
+
+---
+test: Indentation determines scope
+spec: 2.16
+yaml: |
+ name: Mark McGwire
+ accomplishment: >
+ Mark set a major league
+ home run record in 1998.
+ stats: |
+ 65 Home Runs
+ 0.278 Batting Average
+php: |
+ array(
+ 'name' => 'Mark McGwire',
+ 'accomplishment' => "Mark set a major league home run record in 1998.\n",
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n"
+ )
+---
+test: Quoted scalars
+todo: true
+spec: 2.17
+yaml: |
+ unicode: "Sosa did fine.\u263A"
+ control: "\b1998\t1999\t2000\n"
+ hexesc: "\x0D\x0A is \r\n"
+
+ single: '"Howdy!" he cried.'
+ quoted: ' # not a ''comment''.'
+ tie-fighter: '|\-*-/|'
+ruby: |
+ {
+ "tie-fighter" => "|\\-*-/|",
+ "control"=>"\0101998\t1999\t2000\n",
+ "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'),
+ "quoted"=>" # not a 'comment'.",
+ "single"=>"\"Howdy!\" he cried.",
+ "hexesc"=>"\r\n is \r\n"
+ }
+---
+test: Multiline flow scalars
+todo: true
+spec: 2.18
+yaml: |
+ plain:
+ This unquoted scalar
+ spans many lines.
+
+ quoted: "So does this
+ quoted scalar.\n"
+ruby: |
+ {
+ 'plain' => 'This unquoted scalar spans many lines.',
+ 'quoted' => "So does this quoted scalar.\n"
+ }
+---
+test: Integers
+spec: 2.19
+yaml: |
+ canonical: 12345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'octal' => 014,
+ 'hexadecimal' => 0xC
+ )
+---
+test: Decimal Integer
+deprecated: true
+spec: 2.19
+yaml: |
+ decimal: +12,345
+php: |
+ array(
+ 'decimal' => 12345.0,
+ )
+---
+# FIX: spec shows parens around -inf and NaN
+test: Floating point
+spec: 2.20
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ negative infinity: -.inf
+ not a number: .NaN
+ float as whole number: !!float 1
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0),
+ 'float as whole number' => (float) 1
+ )
+---
+test: Fixed Floating point
+deprecated: true
+spec: 2.20
+yaml: |
+ fixed: 1,230.15
+php: |
+ array(
+ 'fixed' => 1230.15,
+ )
+---
+test: Timestamps
+todo: true
+spec: 2.22
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ spaced: 2001-12-14 21:59:43.10 -05:00
+ date: 2002-12-14 # Time is noon UTC
+php: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: legacy Timestamps test
+todo: true
+spec: legacy D4
+yaml: |
+ canonical: 2001-12-15T02:59:43.00Z
+ iso8601: 2001-02-28t21:59:43.00-05:00
+ spaced: 2001-12-14 21:59:43.00 -05:00
+ date: 2002-12-14
+php: |
+ array(
+ 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ),
+ 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Various explicit families
+todo: true
+spec: 2.23
+yaml: |
+ not-date: !!str 2002-04-28
+ picture: !binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+ application specific tag: !!something |
+ The semantics of the tag
+ above may be different for
+ different documents.
+
+ruby-setup: |
+ YAML.add_private_type( "something" ) do |type, val|
+ "SOMETHING: #{val}"
+ end
+ruby: |
+ {
+ 'not-date' => '2002-04-28',
+ 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;",
+ 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n"
+ }
+---
+test: Application specific family
+todo: true
+spec: 2.24
+yaml: |
+ # Establish a tag prefix
+ --- !clarkevans.com,2002/graph/^shape
+ # Use the prefix: shorthand for
+ # !clarkevans.com,2002/graph/circle
+ - !^circle
+ center: &ORIGIN {x: 73, 'y': 129}
+ radius: 7
+ - !^line # !clarkevans.com,2002/graph/line
+ start: *ORIGIN
+ finish: { x: 89, 'y': 102 }
+ - !^label
+ start: *ORIGIN
+ color: 0xFFEEBB
+ value: Pretty vector drawing.
+ruby-setup: |
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
+ if Array === val
+ val << "Shape Container"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ one_shape_proc = Proc.new { |type, val|
+ scheme, domain, type = type.split( /:/, 3 )
+ if val.is_a? ::Hash
+ val['TYPE'] = "Shape: #{type}"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc )
+ruby: |
+ [
+ {
+ "radius" => 7,
+ "center"=>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "TYPE" => "Shape: graph/circle"
+ }, {
+ "finish" =>
+ {
+ "x" => 89,
+ "y" => 102
+ },
+ "TYPE" => "Shape: graph/line",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ }
+ }, {
+ "TYPE" => "Shape: graph/label",
+ "value" => "Pretty vector drawing.",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "color" => 16772795
+ },
+ "Shape Container"
+ ]
+# ---
+# test: Unordered set
+# spec: 2.25
+# yaml: |
+# # sets are represented as a
+# # mapping where each key is
+# # associated with the empty string
+# --- !set
+# ? Mark McGwire
+# ? Sammy Sosa
+# ? Ken Griff
+---
+test: Ordered mappings
+todo: true
+spec: 2.26
+yaml: |
+ # ordered maps are represented as
+ # a sequence of mappings, with
+ # each mapping having one key
+ --- !omap
+ - Mark McGwire: 65
+ - Sammy Sosa: 63
+ - Ken Griffy: 58
+ruby: |
+ YAML::Omap[
+ 'Mark McGwire', 65,
+ 'Sammy Sosa', 63,
+ 'Ken Griffy', 58
+ ]
+---
+test: Invoice
+dump_skip: true
+spec: 2.27
+yaml: |
+ --- !clarkevans.com,2002/^invoice
+ invoice: 34843
+ date : 2001-01-23
+ bill-to: &id001
+ given : Chris
+ family : Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ ship-to: *id001
+ product:
+ -
+ sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ -
+ sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+ tax : 251.42
+ total: 4443.52
+ comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
+php: |
+ array(
+ 'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001),
+ 'bill-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'ship-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'product' =>
+ array(
+ array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ),
+ array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 )
+ ),
+ 'tax' => 251.42, 'total' => 4443.52,
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n"
+ )
+---
+test: Log file
+todo: true
+spec: 2.28
+yaml: |
+ ---
+ Time: 2001-11-23 15:01:42 -05:00
+ User: ed
+ Warning: >
+ This is an error message
+ for the log file
+ ---
+ Time: 2001-11-23 15:02:31 -05:00
+ User: ed
+ Warning: >
+ A slightly different error
+ message.
+ ---
+ Date: 2001-11-23 15:03:17 -05:00
+ User: ed
+ Fatal: >
+ Unknown variable "bar"
+ Stack:
+ - file: TopClass.py
+ line: 23
+ code: |
+ x = MoreObject("345\n")
+ - file: MoreClass.py
+ line: 58
+ code: |-
+ foo = bar
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
+ y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
+ 'Stack' => [
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
+documents: 3
+
+---
+test: Throwaway comments
+yaml: |
+ ### These are four throwaway comment ###
+
+ ### lines (the second line is empty). ###
+ this: | # Comments may trail lines.
+ contains three lines of text.
+ The third one starts with a
+ # character. This isn't a comment.
+
+ # These are three throwaway comment
+ # lines (the first line is empty).
+php: |
+ array(
+ 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"
+ )
+---
+test: Document with a single value
+todo: true
+yaml: |
+ --- >
+ This YAML stream contains a single text value.
+ The next stream is a log file - a sequence of
+ log entries. Adding an entry to the log is a
+ simple matter of appending it at the end.
+ruby: |
+ "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n"
+---
+test: Document stream
+todo: true
+yaml: |
+ ---
+ at: 2001-08-12 09:25:00.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/index.html'
+ ---
+ at: 2001-08-12 09:25:10.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/toc.html'
+ruby: |
+ y = YAML::Stream.new
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/index.html'
+ } )
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/toc.html'
+ } )
+documents: 2
+
+---
+test: Top level mapping
+yaml: |
+ # This stream is an example of a top-level mapping.
+ invoice : 34843
+ date : 2001-01-23
+ total : 4443.52
+php: |
+ array(
+ 'invoice' => 34843,
+ 'date' => gmmktime(0, 0, 0, 1, 23, 2001),
+ 'total' => 4443.52
+ )
+---
+test: Single-line documents
+todo: true
+yaml: |
+ # The following is a sequence of three documents.
+ # The first contains an empty mapping, the second
+ # an empty sequence, and the last an empty string.
+ --- {}
+ --- [ ]
+ --- ''
+ruby: |
+ y = YAML::Stream.new
+ y.add( {} )
+ y.add( [] )
+ y.add( '' )
+documents: 3
+
+---
+test: Document with pause
+todo: true
+yaml: |
+ # A communication channel based on a YAML stream.
+ ---
+ sent at: 2002-06-06 11:46:25.10 Z
+ payload: Whatever
+ # Receiver can process this as soon as the following is sent:
+ ...
+ # Even if the next message is sent long after:
+ ---
+ sent at: 2002-06-06 12:05:53.47 Z
+ payload: Whatever
+ ...
+ruby: |
+ y = YAML::Stream.new
+ y.add(
+ { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ),
+ 'payload' => 'Whatever' }
+ )
+ y.add(
+ { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) }
+ )
+documents: 2
+
+---
+test: Explicit typing
+deprecated: Using the non-specific tag "!" is deprecated since Symfony 3.4 as its behavior will change in 4.0.
+yaml: |
+ integer: 12
+ also int: ! "12"
+ string: !!str 12
+php: |
+ array( 'integer' => 12, 'also int' => 12, 'string' => '12' )
+---
+test: Private types
+todo: true
+yaml: |
+ # Both examples below make use of the 'x-private:ball'
+ # type family URI, but with different semantics.
+ ---
+ pool: !!ball
+ number: 8
+ color: black
+ ---
+ bearing: !!ball
+ material: steel
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'pool' =>
+ YAML::PrivateType.new( 'ball',
+ { 'number' => 8, 'color' => 'black' } ) }
+ )
+ y.add( { 'bearing' =>
+ YAML::PrivateType.new( 'ball',
+ { 'material' => 'steel' } ) }
+ )
+documents: 2
+
+---
+test: Type family under yaml.org
+yaml: |
+ # The URI is 'tag:yaml.org,2002:str'
+ - !!str a Unicode string
+php: |
+ array( 'a Unicode string' )
+---
+test: Type family under perl.yaml.org
+todo: true
+yaml: |
+ # The URI is 'tag:perl.yaml.org,2002:Text::Tabs'
+ - !perl/Text::Tabs {}
+ruby: |
+ [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ]
+---
+test: Type family under clarkevans.com
+todo: true
+yaml: |
+ # The URI is 'tag:clarkevans.com,2003-02:timesheet'
+ - !clarkevans.com,2003-02/timesheet {}
+ruby: |
+ [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ]
+---
+test: URI Escaping
+todo: true
+yaml: |
+ same:
+ - !domain.tld,2002/type\x30 value
+ - !domain.tld,2002/type0 value
+ different: # As far as the YAML parser is concerned
+ - !domain.tld,2002/type%30 value
+ - !domain.tld,2002/type0 value
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
+ "ONE: #{val}"
+ }
+ YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
+ "TWO: #{val}"
+ }
+ruby: |
+ { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] }
+---
+test: URI Prefixing
+todo: true
+yaml: |
+ # 'tag:domain.tld,2002:invoice' is some type family.
+ invoice: !domain.tld,2002/^invoice
+ # 'seq' is shorthand for 'tag:yaml.org,2002:seq'.
+ # This does not effect '^customer' below
+ # because it is does not specify a prefix.
+ customers: !seq
+ # '^customer' is shorthand for the full
+ # notation 'tag:domain.tld,2002:customer'.
+ - !^customer
+ given : Chris
+ family : Dumars
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val|
+ if val.is_a? ::Hash
+ scheme, domain, type = type.split( /:/, 3 )
+ val['type'] = "domain #{type}"
+ val
+ else
+ raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect
+ end
+ }
+ruby: |
+ { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }
+
+---
+test: Overriding anchors
+yaml: |
+ anchor : &A001 This scalar has an anchor.
+ override : &A001 >
+ The alias node below is a
+ repeated use of this value.
+ alias : *A001
+php: |
+ array( 'anchor' => 'This scalar has an anchor.',
+ 'override' => "The alias node below is a repeated use of this value.\n",
+ 'alias' => "The alias node below is a repeated use of this value.\n" )
+---
+test: Flow and block formatting
+todo: true
+yaml: |
+ empty: []
+ flow: [ one, two, three # May span lines,
+ , four, # indentation is
+ five ] # mostly ignored.
+ block:
+ - First item in top sequence
+ -
+ - Subordinate sequence entry
+ - >
+ A folded sequence entry
+ - Sixth item in top sequence
+ruby: |
+ { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ],
+ 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
+ "A folded sequence entry\n", 'Sixth item in top sequence' ] }
+---
+test: Complete mapping test
+todo: true
+yaml: |
+ empty: {}
+ flow: { one: 1, two: 2 }
+ spanning: { one: 1,
+ two: 2 }
+ block:
+ first : First entry
+ second:
+ key: Subordinate mapping
+ third:
+ - Subordinate sequence
+ - { }
+ - Previous mapping is empty.
+ - A key: value pair in a sequence.
+ A second: key:value pair.
+ - The previous entry is equal to the following one.
+ -
+ A key: value pair in a sequence.
+ A second: key:value pair.
+ !float 12 : This key is a float.
+ ? >
+ ?
+ : This key had to be protected.
+ "\a" : This key had to be escaped.
+ ? >
+ This is a
+ multi-line
+ folded key
+ : Whose value is
+ also multi-line.
+ ? this also works as a key
+ : with a value at the next line.
+ ?
+ - This key
+ - is a sequence
+ :
+ - With a sequence value.
+ ?
+ This: key
+ is a: mapping
+ :
+ with a: mapping value.
+ruby: |
+ { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 },
+ 'spanning' => { 'one' => 1, 'two' => 2 },
+ 'block' => { 'first' => 'First entry', 'second' =>
+ { 'key' => 'Subordinate mapping' }, 'third' =>
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
+ 'The previous entry is equal to the following one.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
+ "\a" => 'This key had to be escaped.',
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.",
+ 'this also works as a key' => 'with a value at the next line.',
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }
+ # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact
+ obj_y['block'].keys.each { |k|
+ if Hash === k
+ v = obj_y['block'][k]
+ if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.'
+ obj_r['block'][k] = v
+ end
+ end
+ }
+---
+test: Literal explicit indentation
+yaml: |
+ # Explicit indentation must
+ # be given in all the three
+ # following cases.
+ leading spaces: |2
+ This value starts with four spaces.
+
+ leading line break: |2
+
+ This value starts with a line break.
+
+ leading comment indicator: |2
+ # first line starts with a
+ # character.
+
+ # Explicit indentation may
+ # also be given when it is
+ # not required.
+ redundant: |2
+ This value is indented 2 spaces.
+php: |
+ array(
+ 'leading spaces' => " This value starts with four spaces.\n",
+ 'leading line break' => "\nThis value starts with a line break.\n",
+ 'leading comment indicator' => "# first line starts with a\n# character.\n",
+ 'redundant' => "This value is indented 2 spaces.\n"
+ )
+---
+test: Chomping and keep modifiers
+yaml: |
+ clipped: |
+ This has one newline.
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has two newlines.
+
+ same as "kept" above: "This has two newlines.\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has two newlines.\n\n",
+ 'same as "kept" above' => "This has two newlines.\n\n"
+ )
+---
+test: Literal combinations
+todo: true
+yaml: |
+ empty: |
+
+ literal: |
+ The \ ' " characters may be
+ freely used. Leading white
+ space is significant.
+
+ Line breaks are significant.
+ Thus this value contains one
+ empty line and ends with a
+ single line break, but does
+ not start with one.
+
+ is equal to: "The \\ ' \" characters may \
+ be\nfreely used. Leading white\n space \
+ is significant.\n\nLine breaks are \
+ significant.\nThus this value contains \
+ one\nempty line and ends with a\nsingle \
+ line break, but does\nnot start with one.\n"
+
+ # Comments may follow a block
+ # scalar value. They must be
+ # less indented.
+
+ # Modifiers may be combined in any order.
+ indented and chomped: |2-
+ This has no newline.
+
+ also written as: |-2
+ This has no newline.
+
+ both are equal to: " This has no newline."
+php: |
+ array(
+ 'empty' => '',
+ 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'indented and chomped' => ' This has no newline.',
+ 'also written as' => ' This has no newline.',
+ 'both are equal to' => ' This has no newline.'
+ )
+---
+test: Folded combinations
+todo: true
+yaml: |
+ empty: >
+
+ one paragraph: >
+ Line feeds are converted
+ to spaces, so this value
+ contains no line breaks
+ except for the final one.
+
+ multiple paragraphs: >2
+
+ An empty line, either
+ at the start or in
+ the value:
+
+ Is interpreted as a
+ line break. Thus this
+ value contains three
+ line breaks.
+
+ indented text: >
+ This is a folded
+ paragraph followed
+ by a list:
+ * first entry
+ * second entry
+ Followed by another
+ folded paragraph,
+ another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded
+ paragraph.
+
+ above is equal to: |
+ This is a folded paragraph followed by a list:
+ * first entry
+ * second entry
+ Followed by another folded paragraph, another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded paragraph.
+
+ # Explicit comments may follow
+ # but must be less indented.
+php: |
+ array(
+ 'empty' => '',
+ 'one paragraph' => 'Line feeds are converted to spaces, so this value'.
+ " contains no line breaks except for the final one.\n",
+ 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n".
+ "Is interpreted as a line break. Thus this value contains three line breaks.\n",
+ 'indented text' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n",
+ 'above is equal to' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n"
+ )
+---
+test: Single quotes
+todo: true
+yaml: |
+ empty: ''
+ second: '! : \ etc. can be used freely.'
+ third: 'a single quote '' must be escaped.'
+ span: 'this contains
+ six spaces
+
+ and one
+ line break'
+ is same as: "this contains six spaces\nand one line break"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : \\ etc. can be used freely.',
+ 'third' => "a single quote ' must be escaped.",
+ 'span' => "this contains six spaces\nand one line break",
+ 'is same as' => "this contains six spaces\nand one line break"
+ )
+---
+test: Double quotes
+todo: true
+yaml: |
+ empty: ""
+ second: "! : etc. can be used freely."
+ third: "a \" or a \\ must be escaped."
+ fourth: "this value ends with an LF.\n"
+ span: "this contains
+ four \
+ spaces"
+ is equal to: "this contains four spaces"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : etc. can be used freely.',
+ 'third' => 'a " or a \\ must be escaped.',
+ 'fourth' => "this value ends with an LF.\n",
+ 'span' => "this contains four spaces",
+ 'is equal to' => "this contains four spaces"
+ )
+---
+test: Unquoted strings
+todo: true
+yaml: |
+ first: There is no unquoted empty string.
+
+ second: 12 ## This is an integer.
+
+ third: !!str 12 ## This is a string.
+
+ span: this contains
+ six spaces
+
+ and one
+ line break
+
+ indicators: this has no comments.
+ #:foo and bar# are
+ both text.
+
+ flow: [ can span
+ lines, # comment
+ like
+ this ]
+
+ note: { one-line keys: but multi-line values }
+
+php: |
+ array(
+ 'first' => 'There is no unquoted empty string.',
+ 'second' => 12,
+ 'third' => '12',
+ 'span' => "this contains six spaces\nand one line break",
+ 'indicators' => "this has no comments. #:foo and bar# are both text.",
+ 'flow' => [ 'can span lines', 'like this' ],
+ 'note' => { 'one-line keys' => 'but multi-line values' }
+ )
+---
+test: Spanning sequences
+todo: true
+yaml: |
+ # The following are equal seqs
+ # with different identities.
+ flow: [ one, two ]
+ spanning: [ one,
+ two ]
+ block:
+ - one
+ - two
+php: |
+ array(
+ 'flow' => [ 'one', 'two' ],
+ 'spanning' => [ 'one', 'two' ],
+ 'block' => [ 'one', 'two' ]
+ )
+---
+test: Flow mappings
+yaml: |
+ # The following are equal maps
+ # with different identities.
+ flow: { one: 1, two: 2 }
+ block:
+ one: 1
+ two: 2
+php: |
+ array(
+ 'flow' => array( 'one' => 1, 'two' => 2 ),
+ 'block' => array( 'one' => 1, 'two' => 2 )
+ )
+---
+test: Representations of 12
+todo: true
+yaml: |
+ - 12 # An integer
+ # The following scalars
+ # are loaded to the
+ # string value '1' '2'.
+ - !!str 12
+ - '12'
+ - "12"
+ - "\
+ 1\
+ 2\
+ "
+ # Strings containing paths and regexps can be unquoted:
+ - /foo/bar
+ - d:/foo/bar
+ - foo/bar
+ - /a.*b/
+php: |
+ array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' )
+---
+test: "Null"
+todo: true
+yaml: |
+ canonical: ~
+
+ english: null
+
+ # This sequence has five
+ # entries, two with values.
+ sparse:
+ - ~
+ - 2nd entry
+ - Null
+ - 4th entry
+ -
+
+ four: This mapping has five keys,
+ only two with values.
+
+php: |
+ array (
+ 'canonical' => null,
+ 'english' => null,
+ 'sparse' => array( null, '2nd entry', null, '4th entry', null ]),
+ 'four' => 'This mapping has five keys, only two with values.'
+ )
+---
+test: Omap
+todo: true
+yaml: |
+ # Explicitly typed dictionary.
+ Bestiary: !omap
+ - aardvark: African pig-like ant eater. Ugly.
+ - anteater: South-American ant eater. Two species.
+ - anaconda: South-American constrictor snake. Scary.
+ # Etc.
+ruby: |
+ {
+ 'Bestiary' => YAML::Omap[
+ 'aardvark', 'African pig-like ant eater. Ugly.',
+ 'anteater', 'South-American ant eater. Two species.',
+ 'anaconda', 'South-American constrictor snake. Scary.'
+ ]
+ }
+
+---
+test: Pairs
+todo: true
+yaml: |
+ # Explicitly typed pairs.
+ tasks: !pairs
+ - meeting: with team.
+ - meeting: with boss.
+ - break: lunch.
+ - meeting: with client.
+ruby: |
+ {
+ 'tasks' => YAML::Pairs[
+ 'meeting', 'with team.',
+ 'meeting', 'with boss.',
+ 'break', 'lunch.',
+ 'meeting', 'with client.'
+ ]
+ }
+
+---
+test: Set
+todo: true
+yaml: |
+ # Explicitly typed set.
+ baseball players: !set
+ Mark McGwire:
+ Sammy Sosa:
+ Ken Griffey:
+ruby: |
+ {
+ 'baseball players' => YAML::Set[
+ 'Mark McGwire', nil,
+ 'Sammy Sosa', nil,
+ 'Ken Griffey', nil
+ ]
+ }
+
+---
+test: Integer
+yaml: |
+ canonical: 12345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'octal' => 12,
+ 'hexadecimal' => 12
+ )
+---
+test: Decimal
+deprecated: true
+yaml: |
+ decimal: +12,345
+php: |
+ array(
+ 'decimal' => 12345.0,
+ )
+---
+test: Fixed Float
+deprecated: true
+yaml: |
+ fixed: 1,230.15
+php: |
+ array(
+ 'fixed' => 1230.15,
+ )
+---
+test: Float
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ negative infinity: -.inf
+ not a number: .NaN
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0)
+ )
+---
+test: Timestamp
+todo: true
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ valid iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+ date (noon UTC): 2002-12-14
+ruby: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date (noon UTC)' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Binary
+todo: true
+yaml: |
+ canonical: !binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+ base64: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+ description: >
+ The binary value above is a tiny arrow
+ encoded as a gif image.
+ruby-setup: |
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
+ruby: |
+ {
+ 'canonical' => arrow_gif,
+ 'base64' => arrow_gif,
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n"
+ }
+
+---
+test: Merge key
+todo: true
+yaml: |
+ ---
+ - &CENTER { x: 1, y: 2 }
+ - &LEFT { x: 0, y: 2 }
+ - &BIG { r: 10 }
+ - &SMALL { r: 1 }
+
+ # All the following maps are equal:
+
+ - # Explicit keys
+ x: 1
+ y: 2
+ r: 10
+ label: center/big
+
+ - # Merge one map
+ << : *CENTER
+ r: 10
+ label: center/big
+
+ - # Merge multiple maps
+ << : [ *CENTER, *BIG ]
+ label: center/big
+
+ - # Override
+ << : [ *BIG, *LEFT, *SMALL ]
+ x: 1
+ label: center/big
+
+ruby-setup: |
+ center = { 'x' => 1, 'y' => 2 }
+ left = { 'x' => 0, 'y' => 2 }
+ big = { 'r' => 10 }
+ small = { 'r' => 1 }
+ node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' }
+ node2 = center.dup
+ node2.update( { 'r' => 10, 'label' => 'center/big' } )
+ node3 = big.dup
+ node3.update( center )
+ node3.update( { 'label' => 'center/big' } )
+ node4 = small.dup
+ node4.update( left )
+ node4.update( big )
+ node4.update( { 'x' => 1, 'label' => 'center/big' } )
+
+ruby: |
+ [
+ center, left, big, small, node1, node2, node3, node4
+ ]
+
+---
+test: Default key
+todo: true
+yaml: |
+ --- # Old schema
+ link with:
+ - library1.dll
+ - library2.dll
+ --- # New schema
+ link with:
+ - = : library1.dll
+ version: 1.2
+ - = : library2.dll
+ version: 2.3
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } )
+ obj_h = Hash[ 'version' => 1.2 ]
+ obj_h.default = 'library1.dll'
+ obj_h2 = Hash[ 'version' => 2.3 ]
+ obj_h2.default = 'library2.dll'
+ y.add( { 'link with' => [ obj_h, obj_h2 ] } )
+documents: 2
+
+---
+test: Special keys
+todo: true
+yaml: |
+ "!": These three keys
+ "&": had to be quoted
+ "=": and are normal strings.
+ # NOTE: the following node should NOT be serialized this way.
+ encoded node :
+ !special '!' : '!type'
+ !special|canonical '&' : 12
+ = : value
+ # The proper way to serialize the above node is as follows:
+ node : !!type &12 value
+ruby: |
+ { '!' => 'These three keys', '&' => 'had to be quoted',
+ '=' => 'and are normal strings.',
+ 'encoded node' => YAML::PrivateType.new( 'type', 'value' ),
+ 'node' => YAML::PrivateType.new( 'type', 'value' ) }
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml
new file mode 100644
index 0000000..dea0be0
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml
@@ -0,0 +1,266 @@
+--- %YAML:1.0
+test: Strings
+brief: >
+ Any group of characters beginning with an
+ alphabetic or numeric character is a string,
+ unless it belongs to one of the groups below
+ (such as an Integer or Time).
+yaml: |
+ String
+php: |
+ 'String'
+---
+test: String characters
+brief: >
+ A string can contain any alphabetic or
+ numeric character, along with many
+ punctuation characters, including the
+ period, dash, space, quotes, exclamation, and
+ question mark.
+yaml: |
+ - What's Yaml?
+ - It's for writing data structures in plain text.
+ - And?
+ - And what? That's not good enough for you?
+ - No, I mean, "And what about Yaml?"
+ - Oh, oh yeah. Uh.. Yaml for Ruby.
+php: |
+ array(
+ "What's Yaml?",
+ "It's for writing data structures in plain text.",
+ "And?",
+ "And what? That's not good enough for you?",
+ "No, I mean, \"And what about Yaml?\"",
+ "Oh, oh yeah. Uh.. Yaml for Ruby."
+ )
+---
+test: Indicators in Strings
+brief: >
+ Be careful using indicators in strings. In particular,
+ the comma, colon, and pound sign must be used carefully.
+yaml: |
+ the colon followed by space is an indicator: but is a string:right here
+ same for the pound sign: here we have it#in a string
+ the comma can, honestly, be used in most cases: [ but not in, inline collections ]
+php: |
+ array(
+ 'the colon followed by space is an indicator' => 'but is a string:right here',
+ 'same for the pound sign' => 'here we have it#in a string',
+ 'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections')
+ )
+---
+test: Forcing Strings
+brief: >
+ Any YAML type can be forced into a string using the
+ explicit !!str method.
+yaml: |
+ date string: !!str 2001-08-01
+ number string: !!str 192
+php: |
+ array(
+ 'date string' => '2001-08-01',
+ 'number string' => '192'
+ )
+---
+test: Single-quoted Strings
+brief: >
+ You can also enclose your strings within single quotes,
+ which allows use of slashes, colons, and other indicators
+ freely. Inside single quotes, you can represent a single
+ quote in your string by using two single quotes next to
+ each other.
+yaml: |
+ all my favorite symbols: '#:!/%.)'
+ a few i hate: '&(*'
+ why do i hate them?: 'it''s very hard to explain'
+ entities: '£ me'
+php: |
+ array(
+ 'all my favorite symbols' => '#:!/%.)',
+ 'a few i hate' => '&(*',
+ 'why do i hate them?' => 'it\'s very hard to explain',
+ 'entities' => '£ me'
+ )
+---
+test: Double-quoted Strings
+brief: >
+ Enclosing strings in double quotes allows you
+ to use escapings to represent ASCII and
+ Unicode characters.
+yaml: |
+ i know where i want my line breaks: "one here\nand another here\n"
+php: |
+ array(
+ 'i know where i want my line breaks' => "one here\nand another here\n"
+ )
+---
+test: Multi-line Quoted Strings
+todo: true
+brief: >
+ Both single- and double-quoted strings may be
+ carried on to new lines in your YAML document.
+ They must be indented a step and indentation
+ is interpreted as a single space.
+yaml: |
+ i want a long string: "so i'm going to
+ let it go on and on to other lines
+ until i end it with a quote."
+php: |
+ array('i want a long string' => "so i'm going to ".
+ "let it go on and on to other lines ".
+ "until i end it with a quote."
+ )
+
+---
+test: Plain scalars
+todo: true
+brief: >
+ Unquoted strings may also span multiple lines, if they
+ are free of YAML space indicators and indented.
+yaml: |
+ - My little toe is broken in two places;
+ - I'm crazy to have skied this way;
+ - I'm not the craziest he's seen, since there was always the German guy
+ who skied for 3 hours on a broken shin bone (just below the kneecap);
+ - Nevertheless, second place is respectable, and he doesn't
+ recommend going for the record;
+ - He's going to put my foot in plaster for a month;
+ - This would impair my skiing ability somewhat for the
+ duration, as can be imagined.
+php: |
+ array(
+ "My little toe is broken in two places;",
+ "I'm crazy to have skied this way;",
+ "I'm not the craziest he's seen, since there was always ".
+ "the German guy who skied for 3 hours on a broken shin ".
+ "bone (just below the kneecap);",
+ "Nevertheless, second place is respectable, and he doesn't ".
+ "recommend going for the record;",
+ "He's going to put my foot in plaster for a month;",
+ "This would impair my skiing ability somewhat for the duration, ".
+ "as can be imagined."
+ )
+---
+test: 'Null'
+brief: >
+ You can use the tilde '~' character for a null value.
+yaml: |
+ name: Mr. Show
+ hosted by: Bob and David
+ date of next season: ~
+php: |
+ array(
+ 'name' => 'Mr. Show',
+ 'hosted by' => 'Bob and David',
+ 'date of next season' => null
+ )
+---
+test: Boolean
+brief: >
+ You can use 'true' and 'false' for Boolean values.
+yaml: |
+ Is Gus a Liar?: true
+ Do I rely on Gus for Sustenance?: false
+php: |
+ array(
+ 'Is Gus a Liar?' => true,
+ 'Do I rely on Gus for Sustenance?' => false
+ )
+---
+test: Integers
+dump_skip: true
+brief: >
+ An integer is a series of numbers, optionally
+ starting with a positive or negative sign. Integers
+ may also contain commas for readability.
+yaml: |
+ zero: 0
+ simple: 12
+php: |
+ array(
+ 'zero' => 0,
+ 'simple' => 12,
+ )
+---
+test: Positive Big Integer
+deprecated: true
+dump_skip: true
+brief: >
+ An integer is a series of numbers, optionally
+ starting with a positive or negative sign. Integers
+ may also contain commas for readability.
+yaml: |
+ one-thousand: 1,000
+php: |
+ array(
+ 'one-thousand' => 1000.0,
+ )
+---
+test: Negative Big Integer
+deprecated: true
+dump_skip: true
+brief: >
+ An integer is a series of numbers, optionally
+ starting with a positive or negative sign. Integers
+ may also contain commas for readability.
+yaml: |
+ negative one-thousand: -1,000
+php: |
+ array(
+ 'negative one-thousand' => -1000.0
+ )
+---
+test: Floats
+dump_skip: true
+brief: >
+ Floats are represented by numbers with decimals,
+ allowing for scientific notation, as well as
+ positive and negative infinity and "not a number."
+yaml: |
+ a simple float: 2.00
+ scientific notation: 1.00009e+3
+php: |
+ array(
+ 'a simple float' => 2.0,
+ 'scientific notation' => 1000.09
+ )
+---
+test: Larger Float
+dump_skip: true
+deprecated: true
+brief: >
+ Floats are represented by numbers with decimals,
+ allowing for scientific notation, as well as
+ positive and negative infinity and "not a number."
+yaml: |
+ larger float: 1,000.09
+php: |
+ array(
+ 'larger float' => 1000.09,
+ )
+---
+test: Time
+todo: true
+brief: >
+ You can represent timestamps by using
+ ISO8601 format, or a variation which
+ allows spaces between the date, time and
+ time zone.
+yaml: |
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+php: |
+ array(
+ 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" )
+ )
+---
+test: Date
+todo: true
+brief: >
+ A date can be represented by its year,
+ month and day in ISO8601 order.
+yaml: |
+ 1976-07-31
+php: |
+ date( 1976, 7, 31 )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/arrow.gif b/vendor/symfony/yaml/Tests/Fixtures/arrow.gif
new file mode 100644
index 0000000..443aca4
Binary files /dev/null and b/vendor/symfony/yaml/Tests/Fixtures/arrow.gif differ
diff --git a/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml
new file mode 100644
index 0000000..26799e8
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml
@@ -0,0 +1,11 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ true: true
+ false: false
+php: |
+ array(
+ 'true' => true,
+ 'false' => false,
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml
new file mode 100644
index 0000000..ec456ed
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml
@@ -0,0 +1 @@
+value:
diff --git a/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml
new file mode 100644
index 0000000..6ca044c
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml
@@ -0,0 +1,155 @@
+test: outside double quotes
+yaml: |
+ \0 \ \a \b \n
+php: |
+ "\\0 \\ \\a \\b \\n"
+---
+test: null
+yaml: |
+ "\0"
+php: |
+ "\x00"
+---
+test: bell
+yaml: |
+ "\a"
+php: |
+ "\x07"
+---
+test: backspace
+yaml: |
+ "\b"
+php: |
+ "\x08"
+---
+test: horizontal tab (1)
+yaml: |
+ "\t"
+php: |
+ "\x09"
+---
+test: horizontal tab (2)
+yaml: |
+ "\ "
+php: |
+ "\x09"
+---
+test: line feed
+yaml: |
+ "\n"
+php: |
+ "\x0a"
+---
+test: vertical tab
+yaml: |
+ "\v"
+php: |
+ "\x0b"
+---
+test: form feed
+yaml: |
+ "\f"
+php: |
+ "\x0c"
+---
+test: carriage return
+yaml: |
+ "\r"
+php: |
+ "\x0d"
+---
+test: escape
+yaml: |
+ "\e"
+php: |
+ "\x1b"
+---
+test: space
+yaml: |
+ "\ "
+php: |
+ "\x20"
+---
+test: slash
+yaml: |
+ "\/"
+php: |
+ "\x2f"
+---
+test: backslash
+yaml: |
+ "\\"
+php: |
+ "\\"
+---
+test: Unicode next line
+yaml: |
+ "\N"
+php: |
+ "\xc2\x85"
+---
+test: Unicode non-breaking space
+yaml: |
+ "\_"
+php: |
+ "\xc2\xa0"
+---
+test: Unicode line separator
+yaml: |
+ "\L"
+php: |
+ "\xe2\x80\xa8"
+---
+test: Unicode paragraph separator
+yaml: |
+ "\P"
+php: |
+ "\xe2\x80\xa9"
+---
+test: Escaped 8-bit Unicode
+yaml: |
+ "\x42"
+php: |
+ "B"
+---
+test: Escaped 16-bit Unicode
+yaml: |
+ "\u20ac"
+php: |
+ "\xe2\x82\xac"
+---
+test: Escaped 32-bit Unicode
+yaml: |
+ "\U00000043"
+php: |
+ "C"
+---
+test: Example 5.13 Escaped Characters
+note: |
+ Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support
+ continuation of string across multiple lines? Keeping test here but disabled.
+todo: true
+yaml: |
+ "Fun with \\
+ \" \a \b \e \f \
+ \n \r \t \v \0 \
+ \ \_ \N \L \P \
+ \x41 \u0041 \U00000041"
+php: |
+ "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A"
+---
+test: Double quotes with a line feed
+yaml: |
+ { double: "some value\n \"some quoted string\" and 'some single quotes one'" }
+php: |
+ array(
+ 'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
+ )
+---
+test: Backslashes
+yaml: |
+ { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" }
+php: |
+ array(
+ 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var'
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/index.yml b/vendor/symfony/yaml/Tests/Fixtures/index.yml
new file mode 100644
index 0000000..3216a89
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/index.yml
@@ -0,0 +1,18 @@
+- escapedCharacters
+- sfComments
+- sfCompact
+- sfTests
+- sfObjects
+- sfMergeKey
+- sfQuotes
+- YtsAnchorAlias
+- YtsBasicTests
+- YtsBlockMapping
+- YtsDocumentSeparator
+- YtsErrorTests
+- YtsFlowCollections
+- YtsFoldedScalars
+- YtsNullsAndEmpties
+- YtsSpecificationExamples
+- YtsTypeTransfers
+- unindentedCollections
diff --git a/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml
new file mode 100644
index 0000000..5e8d091
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml
@@ -0,0 +1,23 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ true: true
+ false: false
+php: |
+ array(
+ 1 => true,
+ 0 => false,
+ )
+---
+test: Boolean
+yaml: |
+ false: used as key
+ logical: true
+ answer: false
+php: |
+ array(
+ false => 'used as key',
+ 'logical' => true,
+ 'answer' => false
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml
new file mode 100644
index 0000000..4e28201
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml
@@ -0,0 +1,2 @@
+- legacyBooleanMappingKeys
+- legacyNullMappingKey
diff --git a/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml b/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml
new file mode 100644
index 0000000..551a620
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml
@@ -0,0 +1,9 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ null: ~
+php: |
+ array(
+ '' => null,
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml
new file mode 100644
index 0000000..9d72f09
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml
@@ -0,0 +1,14 @@
+data:
+ single_line: 'foo bar baz'
+ multi_line: |
+ foo
+ line with trailing spaces:
+
+ bar
+ integer like line:
+ 123456789
+ empty line:
+
+ baz
+ multi_line_with_carriage_return: "foo\nbar\r\nbaz"
+ nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" }
diff --git a/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml
new file mode 100644
index 0000000..3f2dedd
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml
@@ -0,0 +1,4 @@
+data:
+ multi_line: |4
+ the first line has leading spaces
+ The second line does not.
diff --git a/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml
new file mode 100644
index 0000000..354b079
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml
@@ -0,0 +1,3 @@
+- booleanMappingKeys
+- numericMappingKeys
+- nullMappingKey
diff --git a/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml b/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml
new file mode 100644
index 0000000..3216a89
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml
@@ -0,0 +1,18 @@
+- escapedCharacters
+- sfComments
+- sfCompact
+- sfTests
+- sfObjects
+- sfMergeKey
+- sfQuotes
+- YtsAnchorAlias
+- YtsBasicTests
+- YtsBlockMapping
+- YtsDocumentSeparator
+- YtsErrorTests
+- YtsFlowCollections
+- YtsFoldedScalars
+- YtsNullsAndEmpties
+- YtsSpecificationExamples
+- YtsTypeTransfers
+- unindentedCollections
diff --git a/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml b/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml
new file mode 100644
index 0000000..7dcadc7
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml
@@ -0,0 +1,9 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ null: ~
+php: |
+ array(
+ 'null' => null,
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml
new file mode 100644
index 0000000..9cfb771
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml
@@ -0,0 +1,23 @@
+--- %YAML:1.0
+test: A sequence with an unordered array
+brief: >
+ A sequence with an unordered array
+yaml: |
+ 1: foo
+ 0: bar
+php: |
+ array(1 => 'foo', 0 => 'bar')
+---
+test: Integers as Map Keys
+brief: >
+ An integer can be used as dictionary key.
+yaml: |
+ 1: one
+ 2: two
+ 3: three
+php: |
+ array(
+ 1 => 'one',
+ 2 => 'two',
+ 3 => 'three'
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml
new file mode 100644
index 0000000..b72a9b6
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml
@@ -0,0 +1,76 @@
+--- %YAML:1.0
+test: Comments at the end of a line
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+ ex5: foo # comment with tab before
+ ex6: foo#foo # comment here
+ ex7: foo # ignore me # and me
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo')
+---
+test: Comments in the middle
+brief: >
+ Comments in the middle
+yaml: |
+ foo:
+ # some comment
+ # some comment
+ bar: foo
+ # some comment
+ # some comment
+php: |
+ array('foo' => array('bar' => 'foo'))
+---
+test: Comments on a hash line
+brief: >
+ Comments on a hash line
+yaml: |
+ foo: # a comment
+ foo: bar # a comment
+php: |
+ array('foo' => array('foo' => 'bar'))
+---
+test: 'Value starting with a #'
+brief: >
+ 'Value starting with a #'
+yaml: |
+ foo: '#bar'
+php: |
+ array('foo' => '#bar')
+---
+test: Document starting with a comment and a separator
+brief: >
+ Commenting before document start is allowed
+yaml: |
+ # document comment
+ ---
+ foo: bar # a comment
+php: |
+ array('foo' => 'bar')
+---
+test: Comment containing a colon on a hash line
+brief: >
+ Comment containing a colon on a scalar line
+yaml: 'foo # comment: this is also part of the comment'
+php: |
+ 'foo'
+---
+test: 'Hash key containing a #'
+brief: >
+ 'Hash key containing a #'
+yaml: 'foo#bar: baz'
+php: |
+ array('foo#bar' => 'baz')
+---
+test: 'Hash key ending with a space and a #'
+brief: >
+ 'Hash key ending with a space and a #'
+yaml: |
+ 'foo #': baz
+php: |
+ array('foo #' => 'baz')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml
new file mode 100644
index 0000000..1339d23
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml
@@ -0,0 +1,159 @@
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml
new file mode 100644
index 0000000..83264cf
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml
@@ -0,0 +1,61 @@
+--- %YAML:1.0
+test: Simple In Place Substitution
+brief: >
+ If you want to reuse an entire alias, only overwriting what is different
+ you can use a << in place substitution. This is not part of the official
+ YAML spec, but a widely implemented extension. See the following URL for
+ details: http://yaml.org/type/merge.html
+yaml: |
+ foo: &foo
+ a: Steve
+ b: Clark
+ c: Brian
+ e: notnull
+ bar:
+ a: before
+ d: other
+ e: ~
+ <<: *foo
+ b: new
+ x: Oren
+ c:
+ foo: bar
+ bar: foo
+ bar_inline: {a: before, d: other, <<: *foo, b: new, x: Oren, c: { foo: bar, bar: foo}}
+ foo2: &foo2
+ a: Ballmer
+ ding: &dong [ fi, fei, fo, fam]
+ check:
+ <<:
+ - *foo
+ - *dong
+ isit: tested
+ head:
+ <<: [ *foo , *dong , *foo2 ]
+ taz: &taz
+ a: Steve
+ w:
+ p: 1234
+ nested:
+ <<: *taz
+ d: Doug
+ w: &nestedref
+ p: 12345
+ z:
+ <<: *nestedref
+ head_inline: &head_inline { <<: [ *foo , *dong , *foo2 ] }
+ recursive_inline: { <<: *head_inline, c: { <<: *foo2 } }
+php: |
+ array(
+ 'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'),
+ 'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
+ 'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'e' => 'notnull', 'x' => 'Oren'),
+ 'foo2' => array('a' => 'Ballmer'),
+ 'ding' => array('fi', 'fei', 'fo', 'fam'),
+ 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
+ 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ 'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)),
+ 'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)),
+ 'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ 'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml
new file mode 100644
index 0000000..ee124b2
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml
@@ -0,0 +1,11 @@
+--- %YAML:1.0
+test: Objects
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml
new file mode 100644
index 0000000..7c60bae
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml
@@ -0,0 +1,33 @@
+--- %YAML:1.0
+test: Some characters at the beginning of a string must be escaped
+brief: >
+ Some characters at the beginning of a string must be escaped
+yaml: |
+ foo: '| bar'
+php: |
+ array('foo' => '| bar')
+---
+test: A key can be a quoted string
+brief: >
+ A key can be a quoted string
+yaml: |
+ "foo1": bar
+ 'foo2': bar
+ "foo \" bar": bar
+ 'foo '' bar': bar
+ 'foo3: ': bar
+ "foo4: ": bar
+ foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar }
+php: |
+ array(
+ 'foo1' => 'bar',
+ 'foo2' => 'bar',
+ 'foo " bar' => 'bar',
+ 'foo \' bar' => 'bar',
+ 'foo3: ' => 'bar',
+ 'foo4: ' => 'bar',
+ 'foo5' => array(
+ 'foo " bar: ' => 'bar',
+ 'foo \' bar: ' => 'bar',
+ ),
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml
new file mode 100644
index 0000000..2a0b9c8
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml
@@ -0,0 +1,140 @@
+--- %YAML:1.0
+test: Multiple quoted string on one line
+brief: >
+ Multiple quoted string on one line
+yaml: |
+ stripped_title: { name: "foo bar", help: "bar foo" }
+php: |
+ array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo'))
+---
+test: Empty sequence
+yaml: |
+ foo: [ ]
+php: |
+ array('foo' => array())
+---
+test: Empty value
+yaml: |
+ foo:
+php: |
+ array('foo' => null)
+---
+test: Inline string parsing
+brief: >
+ Inline string parsing
+yaml: |
+ test: ['complex: string', 'another [string]']
+php: |
+ array('test' => array('complex: string', 'another [string]'))
+---
+test: Boolean
+brief: >
+ Boolean
+yaml: |
+ - false
+ - true
+ - null
+ - ~
+ - 'false'
+ - 'true'
+ - 'null'
+ - '~'
+php: |
+ array(
+ false,
+ true,
+ null,
+ null,
+ 'false',
+ 'true',
+ 'null',
+ '~',
+ )
+---
+test: Empty lines in literal blocks
+brief: >
+ Empty lines in literal blocks
+yaml: |
+ foo:
+ bar: |
+ foo
+
+
+
+ bar
+php: |
+ array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
+---
+test: Empty lines in folded blocks
+brief: >
+ Empty lines in folded blocks
+yaml: |
+ foo:
+ bar: >
+
+ foo
+
+
+ bar
+php: |
+ array('foo' => array('bar' => "\nfoo\n\nbar\n"))
+---
+test: IP addresses
+brief: >
+ IP addresses
+yaml: |
+ foo: 10.0.0.2
+php: |
+ array('foo' => '10.0.0.2')
+---
+test: A sequence with an embedded mapping
+brief: >
+ A sequence with an embedded mapping
+yaml: |
+ - foo
+ - bar: { bar: foo }
+php: |
+ array('foo', array('bar' => array('bar' => 'foo')))
+---
+test: Octal
+brief: as in spec example 2.19, octal value is converted
+yaml: |
+ foo: 0123
+php: |
+ array('foo' => 83)
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: "0123"
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: '0123'
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: |
+ 0123
+php: |
+ array('foo' => "0123\n")
+---
+test: Document as a simple hash
+brief: Document as a simple hash
+yaml: |
+ { foo: bar }
+php: |
+ array('foo' => 'bar')
+---
+test: Document as a simple array
+brief: Document as a simple array
+yaml: |
+ [ foo, bar ]
+php: |
+ array('foo', 'bar')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml
new file mode 100644
index 0000000..0c96108
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml
@@ -0,0 +1,82 @@
+--- %YAML:1.0
+test: Unindented collection
+brief: >
+ Unindented collection
+yaml: |
+ collection:
+ - item1
+ - item2
+ - item3
+php: |
+ array('collection' => array('item1', 'item2', 'item3'))
+---
+test: Nested unindented collection (two levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')))
+---
+test: Nested unindented collection (three levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ subkey:
+ - one
+ - two
+ - three
+php: |
+ array('collection' => array('key' => array('subkey' => array('one', 'two', 'three'))))
+---
+test: Key/value after unindented collection (1)
+brief: >
+ Key/value after unindented collection (1)
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar')
+---
+test: Key/value after unindented collection (at the same level)
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar'))
+---
+test: Shortcut Key after unindented collection
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
+---
+test: Shortcut Key after unindented collection with custom spaces
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
diff --git a/vendor/symfony/yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Tests/InlineTest.php
new file mode 100644
index 0000000..3d86065
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/InlineTest.php
@@ -0,0 +1,807 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Inline;
+use Symfony\Component\Yaml\Yaml;
+
+class InlineTest extends TestCase
+{
+ protected function setUp()
+ {
+ Inline::initialize(0, 0);
+ }
+
+ /**
+ * @dataProvider getTestsForParse
+ */
+ public function testParse($yaml, $value, $flags = 0)
+ {
+ $this->assertSame($value, Inline::parse($yaml, $flags), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
+ }
+
+ /**
+ * @dataProvider getTestsForParseWithMapObjects
+ */
+ public function testParseWithMapObjects($yaml, $value, $flags = Yaml::PARSE_OBJECT_FOR_MAP)
+ {
+ $actual = Inline::parse($yaml, $flags);
+
+ $this->assertSame(serialize($value), serialize($actual));
+ }
+
+ /**
+ * @dataProvider getTestsForParsePhpConstants
+ */
+ public function testParsePhpConstants($yaml, $value)
+ {
+ $actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT);
+
+ $this->assertSame($value, $actual);
+ }
+
+ public function getTestsForParsePhpConstants()
+ {
+ return array(
+ array('!php/const Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
+ array('!php/const PHP_INT_MAX', PHP_INT_MAX),
+ array('[!php/const PHP_INT_MAX]', array(PHP_INT_MAX)),
+ array('{ foo: !php/const PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
+ array('!php/const NULL', null),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage The constant "WRONG_CONSTANT" is not defined
+ */
+ public function testParsePhpConstantThrowsExceptionWhenUndefined()
+ {
+ Inline::parse('!php/const WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp #The string "!php/const PHP_INT_MAX" could not be parsed as a constant.*#
+ */
+ public function testParsePhpConstantThrowsExceptionOnInvalidType()
+ {
+ Inline::parse('!php/const PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
+ }
+
+ /**
+ * @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 1.
+ * @dataProvider getTestsForParseLegacyPhpConstants
+ */
+ public function testDeprecatedConstantTag($yaml, $expectedValue)
+ {
+ $this->assertSame($expectedValue, Inline::parse($yaml, Yaml::PARSE_CONSTANT));
+ }
+
+ public function getTestsForParseLegacyPhpConstants()
+ {
+ return array(
+ array('!php/const:Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
+ array('!php/const:PHP_INT_MAX', PHP_INT_MAX),
+ array('[!php/const:PHP_INT_MAX]', array(PHP_INT_MAX)),
+ array('{ foo: !php/const:PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
+ array('!php/const:NULL', null),
+ );
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider getTestsForParseWithMapObjects
+ */
+ public function testParseWithMapObjectsPassingTrue($yaml, $value)
+ {
+ $actual = Inline::parse($yaml, false, false, true);
+
+ $this->assertSame(serialize($value), serialize($actual));
+ }
+
+ /**
+ * @dataProvider getTestsForDump
+ */
+ public function testDump($yaml, $value, $parseFlags = 0)
+ {
+ $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value), $parseFlags), 'check consistency');
+ }
+
+ public function testDumpNumericValueWithLocale()
+ {
+ $locale = setlocale(LC_NUMERIC, 0);
+ if (false === $locale) {
+ $this->markTestSkipped('Your platform does not support locales.');
+ }
+
+ try {
+ $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
+ if (false === setlocale(LC_NUMERIC, $requiredLocales)) {
+ $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales));
+ }
+
+ $this->assertEquals('1.2', Inline::dump(1.2));
+ $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
+ } finally {
+ setlocale(LC_NUMERIC, $locale);
+ }
+ }
+
+ public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
+ {
+ $value = '686e444';
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Found unknown escape character "\V".
+ */
+ public function testParseScalarWithNonEscapedBlackslashShouldThrowException()
+ {
+ Inline::parse('"Foo\Var"');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException()
+ {
+ Inline::parse('"Foo\\"');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
+ {
+ $value = "'don't do somthin' like that'";
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
+ {
+ $value = '"don"t do somthin" like that"';
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingKeyShouldThrowException()
+ {
+ $value = '{ "foo " bar": "bar" }';
+ Inline::parse($value);
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since Symfony 3.2 and will throw a ParseException in 4.0 on line 1.
+ * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
+ */
+ public function testParseMappingKeyWithColonNotFollowedBySpace()
+ {
+ Inline::parse('{1:""}');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingShouldThrowException()
+ {
+ Inline::parse('[foo] bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidSequenceShouldThrowException()
+ {
+ Inline::parse('{ foo: bar } bar');
+ }
+
+ public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
+ {
+ $value = "'don''t do somthin'' like that'";
+ $expect = "don't do somthin' like that";
+
+ $this->assertSame($expect, Inline::parseScalar($value));
+ }
+
+ /**
+ * @dataProvider getDataForParseReferences
+ */
+ public function testParseReferences($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml, 0, array('var' => 'var-value')));
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider getDataForParseReferences
+ */
+ public function testParseReferencesAsFifthArgument($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value')));
+ }
+
+ public function getDataForParseReferences()
+ {
+ return array(
+ 'scalar' => array('*var', 'var-value'),
+ 'list' => array('[ *var ]', array('var-value')),
+ 'list-in-list' => array('[[ *var ]]', array(array('var-value'))),
+ 'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))),
+ 'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))),
+ 'map' => array('{ key: *var }', array('key' => 'var-value')),
+ 'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))),
+ 'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))),
+ );
+ }
+
+ public function testParseMapReferenceInSequence()
+ {
+ $foo = array(
+ 'a' => 'Steve',
+ 'b' => 'Clark',
+ 'c' => 'Brian',
+ );
+ $this->assertSame(array($foo), Inline::parse('[*foo]', 0, array('foo' => $foo)));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testParseMapReferenceInSequenceAsFifthArgument()
+ {
+ $foo = array(
+ 'a' => 'Steve',
+ 'b' => 'Clark',
+ 'c' => 'Brian',
+ );
+ $this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character at line 1.
+ */
+ public function testParseUnquotedAsterisk()
+ {
+ Inline::parse('{ foo: * }');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character at line 1.
+ */
+ public function testParseUnquotedAsteriskFollowedByAComment()
+ {
+ Inline::parse('{ foo: * #foo }');
+ }
+
+ /**
+ * @dataProvider getReservedIndicators
+ */
+ public function testParseUnquotedScalarStartingWithReservedIndicator($indicator)
+ {
+ if (method_exists($this, 'expectExceptionMessage')) {
+ $this->expectException(ParseException::class);
+ $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
+ } else {
+ $this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
+ }
+
+ Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
+ }
+
+ public function getReservedIndicators()
+ {
+ return array(array('@'), array('`'));
+ }
+
+ /**
+ * @dataProvider getScalarIndicators
+ */
+ public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
+ {
+ if (method_exists($this, 'expectExceptionMessage')) {
+ $this->expectException(ParseException::class);
+ $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
+ } else {
+ $this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
+ }
+
+ Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
+ }
+
+ public function getScalarIndicators()
+ {
+ return array(array('|'), array('>'));
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Not quoting the scalar "%bar " starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0 on line 1.
+ * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
+ */
+ public function testParseUnquotedScalarStartingWithPercentCharacter()
+ {
+ Inline::parse('{ foo: %bar }');
+ }
+
+ /**
+ * @dataProvider getDataForIsHash
+ */
+ public function testIsHash($array, $expected)
+ {
+ $this->assertSame($expected, Inline::isHash($array));
+ }
+
+ public function getDataForIsHash()
+ {
+ return array(
+ array(array(), false),
+ array(array(1, 2, 3), false),
+ array(array(2 => 1, 1 => 2, 0 => 3), true),
+ array(array('foo' => 1, 'bar' => 2), true),
+ );
+ }
+
+ public function getTestsForParse()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('1_2', 12),
+ array('_12', '_12'),
+ array('12_', 12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('123.45_67', 123.4567),
+ array('0x4D2', 0x4D2),
+ array('0x_4_D_2_', 0x4D2),
+ array('02333', 02333),
+ array('0_2_3_3_3', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo: bar,bar: foo,"false": false, "null": null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),
+ array('{"foo:bar": "baz"}', array('foo:bar' => 'baz')),
+ array('{"foo":"bar"}', array('foo' => 'bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),
+ array('{ foo:{bar: foo} }', array('foo' => array('bar' => 'foo'))),
+ array('{ foo:[bar, foo] }', array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+ );
+ }
+
+ public function getTestsForParseWithMapObjects()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('0x4D2', 0x4D2),
+ array('02333', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo: bar,bar: foo,"false": false,"null": null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP),
+ array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),
+ array('{"foo:bar": "baz"}', (object) array('foo:bar' => 'baz')),
+ array('{"foo":"bar"}', (object) array('foo' => 'bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{}', new \stdClass()),
+ array('{ foo : bar, bar : {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{ foo : [], bar : {} }', (object) array('foo' => array(), 'bar' => new \stdClass())),
+ array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')),
+
+ array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))),
+ array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))),
+ array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))),
+ array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))),
+ );
+ }
+
+ public function getTestsForDump()
+ {
+ return array(
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array("'1_2'", '1_2'),
+ array('_12', '_12'),
+ array("'12_'", '12_'),
+ array("'quoted string'", 'quoted string'),
+ array('!!float 1230', 12.30e+02),
+ array('1234', 0x4D2),
+ array('1243', 02333),
+ array("'0x_4_D_2_'", '0x_4_D_2_'),
+ array("'0_2_3_3_3'", '0_2_3_3_3'),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ array("'-dash'", '-dash'),
+ array("'-'", '-'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ // sequences
+ array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))),
+ );
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, $day, $hour, $minute, $second)
+ {
+ $this->assertSame(gmmktime($hour, $minute, $second, $month, $day, $year), Inline::parse($yaml));
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone)
+ {
+ $expected = new \DateTime($yaml);
+ $expected->setTimeZone(new \DateTimeZone('UTC'));
+ $expected->setDate($year, $month, $day);
+
+ if (\PHP_VERSION_ID >= 70100) {
+ $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second));
+ } else {
+ $expected->setTime($hour, $minute, $second);
+ }
+
+ $date = Inline::parse($yaml, Yaml::PARSE_DATETIME);
+ $this->assertEquals($expected, $date);
+ $this->assertSame($timezone, $date->format('O'));
+ }
+
+ public function getTimestampTests()
+ {
+ return array(
+ 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'),
+ 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'),
+ 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'),
+ 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'),
+ );
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second)
+ {
+ $expected = new \DateTime($yaml);
+ $expected->setTimeZone(new \DateTimeZone('UTC'));
+ $expected->setDate($year, $month, $day);
+ if (\PHP_VERSION_ID >= 70100) {
+ $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second));
+ } else {
+ $expected->setTime($hour, $minute, $second);
+ }
+
+ $expectedNested = array('nested' => array($expected));
+ $yamlNested = "{nested: [$yaml]}";
+
+ $this->assertEquals($expectedNested, Inline::parse($yamlNested, Yaml::PARSE_DATETIME));
+ }
+
+ /**
+ * @dataProvider getDateTimeDumpTests
+ */
+ public function testDumpDateTime($dateTime, $expected)
+ {
+ $this->assertSame($expected, Inline::dump($dateTime));
+ }
+
+ public function getDateTimeDumpTests()
+ {
+ $tests = array();
+
+ $dateTime = new \DateTime('2001-12-15 21:59:43', new \DateTimeZone('UTC'));
+ $tests['date-time-utc'] = array($dateTime, '2001-12-15T21:59:43+00:00');
+
+ $dateTime = new \DateTimeImmutable('2001-07-15 21:59:43', new \DateTimeZone('Europe/Berlin'));
+ $tests['immutable-date-time-europe-berlin'] = array($dateTime, '2001-07-15T21:59:43+02:00');
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getBinaryData
+ */
+ public function testParseBinaryData($data)
+ {
+ $this->assertSame('Hello world', Inline::parse($data));
+ }
+
+ public function getBinaryData()
+ {
+ return array(
+ 'enclosed with double quotes' => array('!!binary "SGVsbG8gd29ybGQ="'),
+ 'enclosed with single quotes' => array("!!binary 'SGVsbG8gd29ybGQ='"),
+ 'containing spaces' => array('!!binary "SGVs bG8gd 29ybGQ="'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidBinaryData
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidBinaryData($data, $expectedMessage)
+ {
+ if (method_exists($this, 'expectException')) {
+ $this->expectExceptionMessageRegExp($expectedMessage);
+ } else {
+ $this->setExpectedExceptionRegExp(ParseException::class, $expectedMessage);
+ }
+
+ Inline::parse($data);
+ }
+
+ public function getInvalidBinaryData()
+ {
+ return array(
+ 'length not a multiple of four' => array('!!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('!!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'misplaced equals character' => array('!!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Malformed inline YAML string: {this, is not, supported} at line 1.
+ */
+ public function testNotSupportedMissingValue()
+ {
+ Inline::parse('{this, is not, supported}');
+ }
+
+ public function testVeryLongQuotedStrings()
+ {
+ $longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000);
+
+ $yamlString = Inline::dump(array('longStringWithQuotes' => $longStringWithQuotes));
+ $arrayFromYaml = Inline::parse($yamlString);
+
+ $this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']);
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0 on line 1.
+ */
+ public function testOmittedMappingKeyIsParsedAsColon()
+ {
+ $this->assertSame(array(':' => 'foo'), Inline::parse('{: foo}'));
+ }
+
+ /**
+ * @dataProvider getTestsForNullValues
+ */
+ public function testParseMissingMappingValueAsNull($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml));
+ }
+
+ public function getTestsForNullValues()
+ {
+ return array(
+ 'null before closing curly brace' => array('{foo:}', array('foo' => null)),
+ 'null before comma' => array('{foo:, bar: baz}', array('foo' => null, 'bar' => 'baz')),
+ );
+ }
+
+ public function testTheEmptyStringIsAValidMappingKey()
+ {
+ $this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }'));
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Implicit casting of incompatible mapping keys to strings 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.
+ * @dataProvider getNotPhpCompatibleMappingKeyData
+ */
+ public function testImplicitStringCastingOfMappingKeysIsDeprecated($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml));
+ }
+
+ /**
+ * @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.
+ * @expectedDeprecation Implicit casting of incompatible mapping keys to strings 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.
+ * @dataProvider getNotPhpCompatibleMappingKeyData
+ */
+ public function testExplicitStringCastingOfMappingKeys($yaml, $expected)
+ {
+ $this->assertSame($expected, Yaml::parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS));
+ }
+
+ public function getNotPhpCompatibleMappingKeyData()
+ {
+ return array(
+ 'boolean-true' => array('{true: "foo"}', array('true' => 'foo')),
+ 'boolean-false' => array('{false: "foo"}', array('false' => 'foo')),
+ 'null' => array('{null: "foo"}', array('null' => 'foo')),
+ 'float' => array('{0.25: "foo"}', array('0.25' => 'foo')),
+ );
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Support for the !str tag is deprecated since Symfony 3.4. Use the !!str tag instead on line 1.
+ */
+ public function testDeprecatedStrTag()
+ {
+ $this->assertSame(array('foo' => 'bar'), Inline::parse('{ foo: !str bar }'));
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/ParseExceptionTest.php b/vendor/symfony/yaml/Tests/ParseExceptionTest.php
new file mode 100644
index 0000000..39579ed
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/ParseExceptionTest.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Exception\ParseException;
+
+class ParseExceptionTest extends TestCase
+{
+ public function testGetMessage()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml');
+ $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")';
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+
+ public function testGetMessageWithUnicodeInFilename()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml');
+ $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")';
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php
new file mode 100644
index 0000000..617cd22
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/ParserTest.php
@@ -0,0 +1,2212 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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;
+
+class ParserTest extends TestCase
+{
+ /** @var Parser */
+ protected $parser;
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+
+ chmod(__DIR__.'/Fixtures/not_readable.yml', 0644);
+ }
+
+ /**
+ * @dataProvider getDataFormSpecifications
+ */
+ 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()
+ {
+ return $this->loadTestsFromFixtureFiles('index.yml');
+ }
+
+ /**
+ * @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);
+ }
+
+ public function getNonStringMappingKeysData()
+ {
+ return $this->loadTestsFromFixtureFiles('nonStringKeys.yml');
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider getLegacyNonStringMappingKeysData
+ */
+ public function testLegacyNonStringMappingKeys($expected, $yaml, $comment)
+ {
+ $this->assertSame($expected, var_export($this->parser->parse($yaml), true), $comment);
+ }
+
+ public function getLegacyNonStringMappingKeysData()
+ {
+ return $this->loadTestsFromFixtureFiles('legacyNonStringKeys.yml');
+ }
+
+ public function testTabsInYaml()
+ {
+ // test tabs in YAML
+ $yamls = array(
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $content = $this->parser->parse($yaml);
+
+ $this->fail('YAML files must not contain tabs');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
+ $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');
+ }
+ }
+ }
+
+ public function testEndOfTheDocumentMarker()
+ {
+ $yaml = <<<'EOF'
+--- %YAML:1.0
+foo
+...
+EOF;
+
+ $this->assertEquals('foo', $this->parser->parse($yaml));
+ }
+
+ public function getBlockChompingTests()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+
+bar: |-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+{}
+
+
+EOF;
+ $expected = array();
+ $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+
+bar: |
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo:
+- bar: |
+ one
+
+ two
+EOF;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => "one\n\ntwo",
+ ),
+ ),
+ );
+ $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+
+bar: |+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n\n",
+ 'bar' => "one\ntwo\n\n",
+ );
+ $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+
+bar: >-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+
+bar: >
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+
+bar: >+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n\n",
+ 'bar' => "one two\n\n",
+ );
+ $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getBlockChompingTests
+ */
+ public function testBlockChomping($expected, $yaml)
+ {
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * Regression test for issue #7989.
+ *
+ * @see https://github.com/symfony/symfony/issues/7989
+ */
+ public function testBlockLiteralWithLeadingNewlines()
+ {
+ $yaml = <<<'EOF'
+foo: |-
+
+
+ bar
+
+EOF;
+ $expected = array(
+ 'foo' => "\n\nbar",
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $input = <<<'EOF'
+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');
+ }
+
+ /**
+ * @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
+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(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
+ }
+
+ /**
+ * @dataProvider getObjectForMapTests
+ */
+ public function testObjectForMap($yaml, $expected)
+ {
+ $flags = Yaml::PARSE_OBJECT_FOR_MAP;
+
+ $this->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));
+ }
+
+ public function getObjectForMapTests()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo:
+ fiz: [cat]
+EOF;
+ $expected = new \stdClass();
+ $expected->foo = new \stdClass();
+ $expected->foo->fiz = array('cat');
+ $tests['mapping'] = array($yaml, $expected);
+
+ $yaml = '{ "foo": "bar", "fiz": "cat" }';
+ $expected = new \stdClass();
+ $expected->foo = 'bar';
+ $expected->fiz = 'cat';
+ $tests['inline-mapping'] = array($yaml, $expected);
+
+ $yaml = "foo: bar\nbaz: foobar";
+ $expected = new \stdClass();
+ $expected->foo = 'bar';
+ $expected->baz = 'foobar';
+ $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+array:
+ - key: one
+ - key: two
+EOT;
+ $expected = new \stdClass();
+ $expected->array = array();
+ $expected->array[0] = new \stdClass();
+ $expected->array[0]->key = 'one';
+ $expected->array[1] = new \stdClass();
+ $expected->array[1]->key = 'two';
+ $tests['nest-map-and-sequence'] = array($yaml, $expected);
+
+ $yaml = <<<'YAML'
+map:
+ 1: one
+ 2: two
+YAML;
+ $expected = new \stdClass();
+ $expected->map = new \stdClass();
+ $expected->map->{1} = 'one';
+ $expected->map->{2} = 'two';
+ $tests['numeric-keys'] = array($yaml, $expected);
+
+ $yaml = <<<'YAML'
+map:
+ '0': one
+ '1': two
+YAML;
+ $expected = new \stdClass();
+ $expected->map = new \stdClass();
+ $expected->map->{0} = 'one';
+ $expected->map->{1} = 'two';
+ $tests['zero-indexed-numeric-keys'] = array($yaml, $expected);
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider invalidDumpedObjectProvider
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testObjectsSupportDisabledWithExceptions($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
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testObjectsSupportDisabledWithExceptionsUsingBooleanToggles($yaml)
+ {
+ $this->parser->parse($yaml, true);
+ }
+
+ public function invalidDumpedObjectProvider()
+ {
+ $yamlTag = <<<'EOF'
+foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+ $localTag = <<<'EOF'
+foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+
+ return array(
+ 'yaml-tag' => array($yamlTag),
+ 'local-tag' => array($localTag),
+ );
+ }
+
+ /**
+ * @requires extension iconv
+ */
+ public function testNonUtf8Exception()
+ {
+ $yamls = array(
+ iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
+ iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
+ iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $this->parser->parse($yaml);
+
+ $this->fail('charsets other than UTF-8 are rejected.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
+ }
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testUnindentedCollectionException()
+ {
+ $yaml = <<<'EOF'
+
+collection:
+-item1
+-item2
+-item3
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testShortcutKeyUnindentedCollectionException()
+ {
+ $yaml = <<<'EOF'
+
+collection:
+- key: foo
+ foo: bar
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
+ */
+ public function testMultipleDocumentsNotSupportedException()
+ {
+ Yaml::parse(<<<'EOL'
+# Ranking of 1998 home runs
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Team ranking
+---
+- Chicago Cubs
+- St Louis Cardinals
+EOL
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testSequenceInAMapping()
+ {
+ Yaml::parse(<<<'EOF'
+yaml:
+ hash: me
+ - array stuff
+EOF
+ );
+ }
+
+ public function testSequenceInMappingStartedBySingleDashLine()
+ {
+ $yaml = <<<'EOT'
+a:
+-
+ b:
+ -
+ bar: baz
+- foo
+d: e
+EOT;
+ $expected = array(
+ 'a' => array(
+ array(
+ 'b' => array(
+ array(
+ 'bar' => 'baz',
+ ),
+ ),
+ ),
+ 'foo',
+ ),
+ 'd' => 'e',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testSequenceFollowedByCommentEmbeddedInMapping()
+ {
+ $yaml = <<<'EOT'
+a:
+ b:
+ - c
+# comment
+ d: e
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => array('c'),
+ 'd' => 'e',
+ ),
+ );
+
+ $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 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));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testMappingInASequence()
+ {
+ Yaml::parse(<<<'EOF'
+yaml:
+ - array stuff
+ hash: me
+EOF
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage missing colon
+ */
+ public function testScalarInSequence()
+ {
+ Yaml::parse(<<<'EOF'
+foo:
+ - bar
+"missing colon"
+ foo: bar
+EOF
+ );
+ }
+
+ /**
+ * > It is an error for two equal keys to appear in the same mapping node.
+ * > In such a case the YAML processor may continue, ignoring the second
+ * > `key: value` pair and issuing an appropriate warning. This strategy
+ * > preserves a consistent information model for one-pass and random access
+ * > applications.
+ *
+ * @see http://yaml.org/spec/1.2/spec.html#id2759572
+ * @see http://yaml.org/spec/1.1/#id932806
+ * @group legacy
+ */
+ public function testMappingDuplicateKeyBlock()
+ {
+ $input = <<<'EOD'
+parent:
+ child: first
+ child: duplicate
+parent:
+ child: duplicate
+ child: duplicate
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $this->assertSame($expected, Yaml::parse($input));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testMappingDuplicateKeyFlow()
+ {
+ $input = <<<'EOD'
+parent: { child: first, child: duplicate }
+parent: { child: duplicate, child: duplicate }
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $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('hash' => null), Yaml::parse($input));
+ }
+
+ public function testCommentAtTheRootIndent()
+ {
+ $this->assertEquals(array(
+ 'services' => array(
+ 'app.foo_service' => array(
+ 'class' => 'Foo',
+ ),
+ 'app/bar_service' => array(
+ 'class' => 'Bar',
+ ),
+ ),
+ ), Yaml::parse(<<<'EOF'
+# comment 1
+services:
+# comment 2
+ # comment 3
+ app.foo_service:
+ class: Foo
+# comment 4
+ # comment 5
+ app/bar_service:
+ class: Bar
+EOF
+ ));
+ }
+
+ public function testStringBlockWithComments()
+ {
+ $this->assertEquals(array('content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+
+ title
+
+
+footer # comment3
+EOT
+ ), Yaml::parse(<<<'EOF'
+content: |
+ # comment 1
+ header
+
+ # comment 2
+
+ title
+
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array('content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+
+ title
+
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<'EOF'
+-
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+
+ title
+
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testNestedFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array(
+ 'title' => 'some title',
+ 'content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+
+ title
+
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<'EOF'
+-
+ title: some title
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+
+ title
+
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testReferenceResolvingInInlineStrings()
+ {
+ $this->assertEquals(array(
+ 'var' => 'var-value',
+ 'scalar' => 'var-value',
+ 'list' => array('var-value'),
+ 'list_in_list' => array(array('var-value')),
+ 'map_in_list' => array(array('key' => 'var-value')),
+ 'embedded_mapping' => array(array('key' => 'var-value')),
+ 'map' => array('key' => 'var-value'),
+ 'list_in_map' => array('key' => array('var-value')),
+ 'map_in_map' => array('foo' => array('bar' => 'var-value')),
+ ), Yaml::parse(<<<'EOF'
+var: &var var-value
+scalar: *var
+list: [ *var ]
+list_in_list: [[ *var ]]
+map_in_list: [ { key: *var } ]
+embedded_mapping: [ key: *var ]
+map: { key: *var }
+list_in_map: { key: [*var] }
+map_in_map: { foo: { bar: *var } }
+EOF
+ ));
+ }
+
+ public function testYamlDirective()
+ {
+ $yaml = <<<'EOF'
+%YAML 1.2
+---
+foo: 1
+bar: 2
+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'
+foo:
+ 1.2: "bar"
+ 1.3: "baz"
+EOF;
+
+ $expected = array(
+ 'foo' => array(
+ '1.2' => 'bar',
+ '1.3' => 'baz',
+ ),
+ );
+
+ $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
+ */
+ public function testColonInMappingValueException()
+ {
+ $yaml = <<<'EOF'
+foo: bar: baz
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ public function testColonInMappingValueExceptionNotTriggeredByColonInComment()
+ {
+ $yaml = <<<'EOT'
+foo:
+ bar: foobar # Note: a comment after a colon
+EOT;
+
+ $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
+ }
+
+ /**
+ * @dataProvider getCommentLikeStringInScalarBlockData
+ */
+ public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
+ {
+ $this->assertSame($expectedParserResult, $this->parser->parse($yaml));
+ }
+
+ public function getCommentLikeStringInScalarBlockData()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOT'
+pages:
+ -
+ title: some title
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+
+ title
+
+
+ footer # comment3
+EOT;
+ $expected = array(
+ 'pages' => array(
+ array(
+ 'title' => 'some title',
+ 'content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+
+ title
+
+
+footer # comment3
+EOT
+ ,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+test: |
+ foo
+ # bar
+ baz
+collection:
+ - one: |
+ foo
+ # bar
+ baz
+ - two: |
+ foo
+ # bar
+ baz
+EOT;
+ $expected = array(
+ 'test' => <<<'EOT'
+foo
+# bar
+baz
+
+EOT
+ ,
+ 'collection' => array(
+ array(
+ 'one' => <<<'EOT'
+foo
+# bar
+baz
+
+EOT
+ ,
+ ),
+ array(
+ 'two' => <<<'EOT'
+foo
+# bar
+baz
+EOT
+ ,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+foo:
+ bar:
+ scalar-block: >
+ line1
+ line2>
+ baz:
+# comment
+ foobar: ~
+EOT;
+ $expected = array(
+ 'foo' => array(
+ 'bar' => array(
+ 'scalar-block' => "line1 line2>\n",
+ ),
+ 'baz' => array(
+ 'foobar' => null,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+a:
+ b: hello
+# c: |
+# first row
+# second row
+ d: hello
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => 'hello',
+ 'd' => 'hello',
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ return $tests;
+ }
+
+ public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
+ {
+ $yaml = <<<'EOT'
+test: >
+ A heading
+
+
+ - a list
+ - may be a good example
+
+EOT;
+
+ $this->assertSame(
+ array(
+ 'test' => <<<'EOT'
+A heading
+ - a list
- may be a good example
+EOT
+ ,
+ ),
+ $this->parser->parse($yaml)
+ );
+ }
+
+ public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
+ {
+ $yaml = <<<'EOT'
+test: >
+ A heading
+
+
+ - a list
+ - may be a good example
+
+EOT;
+
+ $this->assertSame(
+ array(
+ 'test' => <<<'EOT'
+A heading
+
+ - a list
+ - may be a good example
+
+EOT
+ ,
+ ),
+ $this->parser->parse($yaml)
+ );
+ }
+
+ /**
+ * @dataProvider getBinaryData
+ */
+ 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->expectExceptionMessageRegExp($expectedMessage);
+ } else {
+ $this->setExpectedExceptionRegExp(ParseException::class, $expectedMessage);
+ }
+
+ $this->parser->parse($data);
+ }
+
+ public function getInvalidBinaryData()
+ {
+ return array(
+ '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,
+ <<<'YAML'
+foo:
+ -
+ # foobar
+ baz: 123
+bar:
+ -
+ # bar
+ bar: "123",
+YAML
+ ),
+ array(
+ 10,
+ <<<'YAML'
+foo:
+ -
+ # foobar
+ # foobar
+ baz: 123
+bar:
+ -
+ # bar
+ # bar
+ bar: "123",
+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);
+ $trickyVal = array('x' => $longStringWithSpaces);
+
+ $yamlString = Yaml::dump($trickyVal);
+ $arrayFromYaml = $this->parser->parse($yamlString);
+
+ $this->assertEquals($trickyVal, $arrayFromYaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Reference "foo" does not exist at line 2
+ */
+ public function testParserCleansUpReferencesBetweenRuns()
+ {
+ $yaml = <<parser->parse($yaml);
+
+ $yaml = <<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');
+ }
+
+ $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';
+}
diff --git a/vendor/symfony/yaml/Tests/YamlTest.php b/vendor/symfony/yaml/Tests/YamlTest.php
new file mode 100644
index 0000000..3f6c252
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/YamlTest.php
@@ -0,0 +1,44 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Yaml;
+
+class YamlTest extends TestCase
+{
+ public function testParseAndDump()
+ {
+ $data = array('lorem' => 'ipsum', 'dolor' => 'sit');
+ $yml = Yaml::dump($data);
+ $parsed = Yaml::parse($yml);
+ $this->assertEquals($data, $parsed);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testZeroIndentationThrowsException()
+ {
+ Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testNegativeIndentationThrowsException()
+ {
+ Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4);
+ }
+}
diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php
new file mode 100644
index 0000000..6e863e1
--- /dev/null
+++ b/vendor/symfony/yaml/Unescaper.php
@@ -0,0 +1,142 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Unescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski
+ *
+ * @internal
+ */
+class Unescaper
+{
+ /**
+ * Regex fragment that matches an escaped character in a double quoted string.
+ */
+ const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';
+
+ /**
+ * Unescapes a single quoted string.
+ *
+ * @param string $value A single quoted string
+ *
+ * @return string The unescaped string
+ */
+ public function unescapeSingleQuotedString($value)
+ {
+ return str_replace('\'\'', '\'', $value);
+ }
+
+ /**
+ * Unescapes a double quoted string.
+ *
+ * @param string $value A double quoted string
+ *
+ * @return string The unescaped string
+ */
+ public function unescapeDoubleQuotedString($value)
+ {
+ $callback = function ($match) {
+ return $this->unescapeCharacter($match[0]);
+ };
+
+ // evaluate the string
+ return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
+ }
+
+ /**
+ * Unescapes a character that was found in a double-quoted string.
+ *
+ * @param string $value An escaped character
+ *
+ * @return string The unescaped character
+ */
+ private function unescapeCharacter($value)
+ {
+ switch ($value[1]) {
+ case '0':
+ return "\x0";
+ case 'a':
+ return "\x7";
+ case 'b':
+ return "\x8";
+ case 't':
+ return "\t";
+ case "\t":
+ return "\t";
+ case 'n':
+ return "\n";
+ case 'v':
+ return "\xB";
+ case 'f':
+ return "\xC";
+ case 'r':
+ return "\r";
+ case 'e':
+ return "\x1B";
+ case ' ':
+ return ' ';
+ case '"':
+ return '"';
+ case '/':
+ return '/';
+ case '\\':
+ return '\\';
+ case 'N':
+ // U+0085 NEXT LINE
+ return "\xC2\x85";
+ case '_':
+ // U+00A0 NO-BREAK SPACE
+ return "\xC2\xA0";
+ case 'L':
+ // U+2028 LINE SEPARATOR
+ return "\xE2\x80\xA8";
+ case 'P':
+ // U+2029 PARAGRAPH SEPARATOR
+ return "\xE2\x80\xA9";
+ case 'x':
+ return self::utf8chr(hexdec(substr($value, 2, 2)));
+ case 'u':
+ return self::utf8chr(hexdec(substr($value, 2, 4)));
+ case 'U':
+ return self::utf8chr(hexdec(substr($value, 2, 8)));
+ default:
+ throw new ParseException(sprintf('Found unknown escape character "%s".', $value));
+ }
+ }
+
+ /**
+ * Get the UTF-8 character for the given code point.
+ *
+ * @param int $c The unicode code point
+ *
+ * @return string The corresponding UTF-8 character
+ */
+ private static function utf8chr($c)
+ {
+ if (0x80 > $c %= 0x200000) {
+ return chr($c);
+ }
+ if (0x800 > $c) {
+ return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
+ }
+ if (0x10000 > $c) {
+ return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ }
+
+ return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ }
+}
diff --git a/vendor/symfony/yaml/Yaml.php b/vendor/symfony/yaml/Yaml.php
new file mode 100644
index 0000000..d429a33
--- /dev/null
+++ b/vendor/symfony/yaml/Yaml.php
@@ -0,0 +1,151 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Yaml offers convenience methods to load and dump YAML.
+ *
+ * @author Fabien Potencier
+ *
+ * @final since version 3.4
+ */
+class Yaml
+{
+ const DUMP_OBJECT = 1;
+ const PARSE_EXCEPTION_ON_INVALID_TYPE = 2;
+ const PARSE_OBJECT = 4;
+ const PARSE_OBJECT_FOR_MAP = 8;
+ const DUMP_EXCEPTION_ON_INVALID_TYPE = 16;
+ const PARSE_DATETIME = 32;
+ const DUMP_OBJECT_AS_MAP = 64;
+ const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
+ const PARSE_CONSTANT = 256;
+ const PARSE_CUSTOM_TAGS = 512;
+ const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
+
+ /**
+ * @deprecated since version 3.4, to be removed in 4.0. Quote your evaluable keys instead.
+ */
+ const PARSE_KEYS_AS_STRINGS = 2048;
+
+ /**
+ * Parses a YAML file into a PHP value.
+ *
+ * Usage:
+ *
+ * $array = Yaml::parseFile('config.yml');
+ * print_r($array);
+ *
+ *
+ * @param string $filename The path to the YAML file to be parsed
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed The YAML converted to a PHP value
+ *
+ * @throws ParseException If the file could not be read or the YAML is not valid
+ */
+ public static function parseFile($filename, $flags = 0)
+ {
+ $yaml = new Parser();
+
+ return $yaml->parseFile($filename, $flags);
+ }
+
+ /**
+ * Parses YAML into a PHP value.
+ *
+ * Usage:
+ *
+ * $array = Yaml::parse(file_get_contents('config.yml'));
+ * print_r($array);
+ *
+ *
+ * @param string $input A string containing YAML
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed The YAML converted to a PHP value
+ *
+ * @throws ParseException If the YAML is not valid
+ */
+ public static function parse($input, $flags = 0)
+ {
+ if (is_bool($flags)) {
+ @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED);
+
+ if ($flags) {
+ $flags = self::PARSE_EXCEPTION_ON_INVALID_TYPE;
+ } else {
+ $flags = 0;
+ }
+ }
+
+ if (func_num_args() >= 3) {
+ @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the PARSE_OBJECT flag instead.', E_USER_DEPRECATED);
+
+ if (func_get_arg(2)) {
+ $flags |= self::PARSE_OBJECT;
+ }
+ }
+
+ if (func_num_args() >= 4) {
+ @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED);
+
+ if (func_get_arg(3)) {
+ $flags |= self::PARSE_OBJECT_FOR_MAP;
+ }
+ }
+
+ $yaml = new Parser();
+
+ return $yaml->parse($input, $flags);
+ }
+
+ /**
+ * Dumps a PHP value to a YAML string.
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML.
+ *
+ * @param mixed $input The PHP value
+ * @param int $inline The level where you switch to inline YAML
+ * @param int $indent The amount of spaces to use for indentation of nested nodes
+ * @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string
+ *
+ * @return string A YAML string representing the original PHP value
+ */
+ public static function dump($input, $inline = 2, $indent = 4, $flags = 0)
+ {
+ if (is_bool($flags)) {
+ @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED);
+
+ if ($flags) {
+ $flags = self::DUMP_EXCEPTION_ON_INVALID_TYPE;
+ } else {
+ $flags = 0;
+ }
+ }
+
+ if (func_num_args() >= 5) {
+ @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the DUMP_OBJECT flag instead.', E_USER_DEPRECATED);
+
+ if (func_get_arg(4)) {
+ $flags |= self::DUMP_OBJECT;
+ }
+ }
+
+ $yaml = new Dumper($indent);
+
+ return $yaml->dump($input, $inline, 0, $flags);
+ }
+}
diff --git a/vendor/symfony/yaml/composer.json b/vendor/symfony/yaml/composer.json
new file mode 100644
index 0000000..a31a2ce
--- /dev/null
+++ b/vendor/symfony/yaml/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "symfony/yaml",
+ "type": "library",
+ "description": "Symfony Yaml Component",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Yaml\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/phpunit.xml.dist b/vendor/symfony/yaml/phpunit.xml.dist
new file mode 100644
index 0000000..7c732f8
--- /dev/null
+++ b/vendor/symfony/yaml/phpunit.xml.dist
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+ ./Tests
+ ./vendor
+
+
+
+