brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.4 KiB · 7bd11e7 Raw
547 lines · cpp
1//===- unittest/Support/YAMLParserTest ------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/YAMLParser.h"10#include "llvm/ADT/Twine.h"11#include "llvm/Support/Casting.h"12#include "llvm/Support/MemoryBuffer.h"13#include "llvm/Support/SourceMgr.h"14#include "gtest/gtest.h"15 16namespace llvm {17 18static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) {19  // Prevent SourceMgr from writing errors to stderr20  // to reduce noise in unit test runs.21}22 23// Assumes Ctx is an SMDiagnostic where Diag can be stored.24static void CollectDiagnosticsOutput(const SMDiagnostic &Diag, void *Ctx) {25  SMDiagnostic* DiagOut = static_cast<SMDiagnostic*>(Ctx);26  *DiagOut = Diag;27}28 29// Checks that the given input gives a parse error. Makes sure that an error30// text is available and the parse fails.31static void ExpectParseError(StringRef Message, StringRef Input) {32  SourceMgr SM;33  yaml::Stream Stream(Input, SM);34  SM.setDiagHandler(SuppressDiagnosticsOutput);35  EXPECT_FALSE(Stream.validate()) << Message << ": " << Input;36  EXPECT_TRUE(Stream.failed()) << Message << ": " << Input;37}38 39// Checks that the given input can be parsed without error.40static void ExpectParseSuccess(StringRef Message, StringRef Input) {41  SourceMgr SM;42  yaml::Stream Stream(Input, SM);43  EXPECT_TRUE(Stream.validate()) << Message << ": " << Input;44}45 46TEST(YAMLParser, ParsesEmptyArray) {47  ExpectParseSuccess("Empty array", "[]");48}49 50TEST(YAMLParser, ParsesComplexMap) {51  ExpectParseSuccess("Complex block map", "? a\n: b");52}53 54TEST(YAMLParser, FailsIfNotClosingArray) {55  ExpectParseError("Not closing array", "[");56  ExpectParseError("Not closing array", "  [  ");57  ExpectParseError("Not closing array", "  [x");58}59 60TEST(YAMLParser, ParsesEmptyArrayWithWhitespace) {61  ExpectParseSuccess("Array with spaces", "  [  ]  ");62  ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");63}64 65TEST(YAMLParser, ParsesEmptyObject) {66  ExpectParseSuccess("Empty object", "[{}]");67}68 69TEST(YAMLParser, ParsesObject) {70  ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");71}72 73TEST(YAMLParser, ParsesMultipleKeyValuePairsInObject) {74  ExpectParseSuccess("Multiple key, value pairs",75                     "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");76}77 78TEST(YAMLParser, FailsIfNotClosingObject) {79  ExpectParseError("Missing close on empty", "[{]");80  ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");81}82 83TEST(YAMLParser, FailsIfMissingColon) {84  ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");85  ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");86}87 88TEST(YAMLParser, FailsOnMissingQuote) {89  // Missing open quote counts as a plain scalar per YAML spec90  // (Following is equivalent to JSON [{"a\":\"b\"": null}])91  ExpectParseSuccess("Missing open quote", "[{a\":\"b\"}]");92  // Closing quote is more strict -- plain scalars cannot start with a quote93  ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");94}95 96TEST(YAMLParser, ParsesEscapedQuotes) {97  ExpectParseSuccess("Parses escaped string in key and value",98                     "[{\"a\":\"\\\"b\\\"  \\\" \\\"\"}]");99}100 101TEST(YAMLParser, ParsesEmptyString) {102  ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");103}104 105TEST(YAMLParser, ParsesMultipleObjects) {106  ExpectParseSuccess(107      "Multiple objects in array",108      "["109      " { \"a\" : \"b\" },"110      " { \"a\" : \"b\" },"111      " { \"a\" : \"b\" }"112      "]");113}114 115TEST(YAMLParser, FailsOnMissingComma) {116  ExpectParseError(117      "Missing comma",118      "["119      " { \"a\" : \"b\" }"120      " { \"a\" : \"b\" }"121      "]");122}123 124TEST(YAMLParser, ParsesSpacesInBetweenTokens) {125  ExpectParseSuccess(126      "Various whitespace between tokens",127      " \t \n\n \r [ \t \n\n \r"128      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"129      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"130      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"131      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r");132}133 134TEST(YAMLParser, ParsesArrayOfArrays) {135  ExpectParseSuccess("Array of arrays", "[[]]");136}137 138TEST(YAMLParser, ParsesPlainScalars) {139  ExpectParseSuccess("Plain scalar", "hello");140  ExpectParseSuccess("Plain scalar beginning with a question mark", "?hello");141  ExpectParseSuccess("Plain scalar beginning with a colon", ":hello");142  ExpectParseSuccess("Plain scalar beginning with two colons", "::hello");143  ExpectParseSuccess("Plain scalar beginning with a hyphen", "-hello");144  ExpectParseSuccess("Multi-line plain scalar", "Hello\nworld");145  ExpectParseSuccess("Plain scalar with indicator characters",146                     "He-!l*lo, []world{}");147  ExpectParseSuccess("Plain scalar with indicator characters used as block key",148                     "He-!l*lo, []world{}: value");149  ExpectParseSuccess("Plain scalar in flow sequence", "hello");150  ExpectParseSuccess(151      "Plain scalar beginning with a question mark in flow sequence",152      "[ ?hello ]");153  ExpectParseSuccess("Plain scalar beginning with a colon in flow sequence",154                     "[ :hello ]");155  ExpectParseSuccess("Plain scalar beginning with two colons in flow sequence",156                     "[ ::hello ]");157  ExpectParseSuccess("Plain scalar beginning with a hyphen in flow sequence",158                     "[ -hello ]");159  ExpectParseSuccess("Multi-line plain scalar in flow sequence",160                     "[ Hello\nworld ]");161  ExpectParseSuccess(162      "Plain scalar with non-flow indicator characters in flow sequence",163      "[ He-!l*lo, world ]");164  ExpectParseSuccess(165      "Plain scalar with non-flow indicator characters used as flow key",166      "{ He-!l*lo, world: value } ");167  ExpectParseError(168      "Plain scalar with flow indicator characters inside flow sequence",169      "[ Hello[world ]");170  ExpectParseError(171      "Plain scalar with flow indicator characters inside flow key",172      "{ Hello[world: value }");173  // Multi-line plain scalar in keys is strictly invalid per the spec, but many174  // implementations accept it in flow keys nonetheless.  Block keys are not175  // accepted by any other implementation I can find.176  ExpectParseSuccess("Multi-line plain scalar in block key", "a\nb: c");177  ExpectParseSuccess("Multi-line plain scalar in flow key", "{\na\nb: c\n}");178}179 180TEST(YAMLParser, ParsesBlockLiteralScalars) {181  ExpectParseSuccess("Block literal scalar", "test: |\n  Hello\n  World\n");182  ExpectParseSuccess("Block literal scalar EOF", "test: |\n  Hello\n  World");183  ExpectParseSuccess("Empty block literal scalar header EOF", "test: | ");184  ExpectParseSuccess("Empty block literal scalar", "test: |\ntest2: 20");185  ExpectParseSuccess("Empty block literal scalar 2", "- | \n  \n\n \n- 42");186  ExpectParseSuccess("Block literal scalar in sequence",187                     "- |\n  Testing\n  Out\n\n- 22");188  ExpectParseSuccess("Block literal scalar in document",189                     "--- |\n  Document\n...");190  ExpectParseSuccess("Empty non indented lines still count",191                     "- |\n  First line\n \n\n  Another line\n\n- 2");192  ExpectParseSuccess("Comment in block literal scalar header",193                     "test: | # Comment \n  No Comment\ntest 2: | # Void");194  ExpectParseSuccess("Chomping indicators in block literal scalar header",195                     "test: |- \n  Hello\n\ntest 2: |+ \n\n  World\n\n\n");196  ExpectParseSuccess("Indent indicators in block literal scalar header",197                     "test: |1 \n  \n Hello \n  World\n");198  ExpectParseSuccess("Chomping and indent indicators in block literals",199                     "test: |-1\n Hello\ntest 2: |9+\n         World");200  ExpectParseSuccess("Trailing comments in block literals",201                     "test: |\n  Content\n # Trailing\n  #Comment\ntest 2: 3");202  ExpectParseError("Invalid block scalar header", "test: | failure");203  ExpectParseError("Invalid line indentation", "test: |\n  First line\n Error");204  ExpectParseError("Long leading space line", "test: |\n   \n  Test\n");205}206 207TEST(YAMLParser, NullTerminatedBlockScalars) {208  SourceMgr SM;209  yaml::Stream Stream("test: |\n  Hello\n  World\n", SM);210  yaml::Document &Doc = *Stream.begin();211  yaml::MappingNode *Map = cast<yaml::MappingNode>(Doc.getRoot());212  StringRef Value =213      cast<yaml::BlockScalarNode>(Map->begin()->getValue())->getValue();214 215  EXPECT_EQ(Value, "Hello\nWorld\n");216  EXPECT_EQ(Value.data()[Value.size()], '\0');217}218 219TEST(YAMLParser, HandlesEndOfFileGracefully) {220  ExpectParseError("In string starting with EOF", "[\"");221  ExpectParseError("In string hitting EOF", "[\"   ");222  ExpectParseError("In string escaping EOF", "[\"  \\");223  ExpectParseError("In array starting with EOF", "[");224  ExpectParseError("In array element starting with EOF", "[[], ");225  ExpectParseError("In array hitting EOF", "[[] ");226  ExpectParseError("In array hitting EOF", "[[]");227  ExpectParseError("In object hitting EOF", "{\"\"");228  // This one is valid, equivalent to the JSON {"": null}229  ExpectParseSuccess("In complex block map hitting EOF", "?");230  // Equivalent to JSON [null]231  ExpectParseSuccess("In block sequence hitting EOF", "-");232}233 234TEST(YAMLParser, HandlesNullValuesInKeyValueNodesGracefully) {235  ExpectParseError("KeyValueNode with null key", "? \"\n:");236  ExpectParseError("KeyValueNode with null value", "test: '");237}238 239TEST(YAMLParser, BlockSequenceEOF) {240  SourceMgr SM;241  yaml::Stream Stream("-", SM);242  EXPECT_TRUE(isa_and_present<yaml::SequenceNode>(Stream.begin()->getRoot()));243}244 245// Checks that the given string can be parsed into an identical string inside246// of an array.247static void ExpectCanParseString(StringRef String) {248  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();249  SourceMgr SM;250  yaml::Stream Stream(StringInArray, SM);251  yaml::SequenceNode *ParsedSequence252    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());253  StringRef ParsedString254    = dyn_cast<yaml::ScalarNode>(255      static_cast<yaml::Node*>(ParsedSequence->begin()))->getRawValue();256  ParsedString = ParsedString.substr(1, ParsedString.size() - 2);257  EXPECT_EQ(String, ParsedString.str());258}259 260// Checks that parsing the given string inside an array fails.261static void ExpectCannotParseString(StringRef String) {262  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();263  ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),264                   StringInArray);265}266 267TEST(YAMLParser, ParsesStrings) {268  ExpectCanParseString("");269  ExpectCannotParseString("\\");270  ExpectCannotParseString("\"");271  ExpectCanParseString(" ");272  ExpectCanParseString("\\ ");273  ExpectCanParseString("\\\"");274  ExpectCannotParseString("\"\\");275  ExpectCannotParseString(" \\");276  ExpectCanParseString("\\\\");277  ExpectCannotParseString("\\\\\\");278  ExpectCanParseString("\\\\\\\\");279  ExpectCanParseString("\\\" ");280  ExpectCannotParseString("\\\\\" ");281  ExpectCanParseString("\\\\\\\" ");282  ExpectCanParseString("    \\\\  \\\"  \\\\\\\"   ");283}284 285TEST(YAMLParser, WorksWithIteratorAlgorithms) {286  SourceMgr SM;287  yaml::Stream Stream("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", SM);288  yaml::SequenceNode *Array289    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());290  EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));291}292 293TEST(YAMLParser, DefaultDiagnosticFilename) {294  SourceMgr SM;295 296  SMDiagnostic GeneratedDiag;297  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);298 299  // When we construct a YAML stream over an unnamed string,300  // the filename is hard-coded as "YAML".301  yaml::Stream UnnamedStream("[]", SM);302  UnnamedStream.printError(UnnamedStream.begin()->getRoot(), "Hello, World!");303  EXPECT_EQ("YAML", GeneratedDiag.getFilename());304}305 306TEST(YAMLParser, DiagnosticFilenameFromBufferID) {307  SourceMgr SM;308 309  SMDiagnostic GeneratedDiag;310  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);311 312  // When we construct a YAML stream over a named buffer,313  // we get its ID as filename in diagnostics.314  std::unique_ptr<MemoryBuffer> Buffer =315      MemoryBuffer::getMemBuffer("[]", "buffername.yaml");316  yaml::Stream Stream(Buffer->getMemBufferRef(), SM);317  Stream.printError(Stream.begin()->getRoot(), "Hello, World!");318  EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());319}320 321TEST(YAMLParser, SameNodeIteratorOperatorNotEquals) {322  SourceMgr SM;323  yaml::Stream Stream("[\"1\", \"2\"]", SM);324 325  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(326                                              Stream.begin()->getRoot());327 328  auto Begin = Node->begin();329  auto End = Node->end();330 331  EXPECT_NE(Begin, End);332  EXPECT_EQ(Begin, Begin);333  EXPECT_EQ(End, End);334}335 336TEST(YAMLParser, SameNodeIteratorOperatorEquals) {337  SourceMgr SM;338  yaml::Stream Stream("[\"1\", \"2\"]", SM);339 340  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(341                                              Stream.begin()->getRoot());342 343  auto Begin = Node->begin();344  auto End = Node->end();345 346  EXPECT_NE(Begin, End);347  EXPECT_EQ(Begin, Begin);348  EXPECT_EQ(End, End);349}350 351TEST(YAMLParser, DifferentNodesIteratorOperatorNotEquals) {352  SourceMgr SM;353  yaml::Stream Stream("[\"1\", \"2\"]", SM);354  yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);355 356  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(357                                                  Stream.begin()->getRoot());358  yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(359                                              AnotherStream.begin()->getRoot());360 361  auto Begin = Node->begin();362  auto End = Node->end();363 364  auto AnotherBegin = AnotherNode->begin();365  auto AnotherEnd = AnotherNode->end();366 367  EXPECT_NE(Begin, AnotherBegin);368  EXPECT_NE(Begin, AnotherEnd);369  EXPECT_EQ(End, AnotherEnd);370}371 372TEST(YAMLParser, DifferentNodesIteratorOperatorEquals) {373  SourceMgr SM;374  yaml::Stream Stream("[\"1\", \"2\"]", SM);375  yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);376 377  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(378                                                    Stream.begin()->getRoot());379  yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(380                                             AnotherStream.begin()->getRoot());381 382  auto Begin = Node->begin();383  auto End = Node->end();384 385  auto AnotherBegin = AnotherNode->begin();386  auto AnotherEnd = AnotherNode->end();387 388  EXPECT_NE(Begin, AnotherBegin);389  EXPECT_NE(Begin, AnotherEnd);390  EXPECT_EQ(End, AnotherEnd);391}392 393TEST(YAMLParser, FlowSequenceTokensOutsideFlowSequence) {394  auto FlowSequenceStrs = {",", "]", "}"};395  SourceMgr SM;396 397  for (auto &Str : FlowSequenceStrs) {398    yaml::Stream Stream(Str, SM);399    yaml::Document &Doc = *Stream.begin();400    EXPECT_FALSE(Doc.skip());401  }402}403 404static void expectCanParseBool(StringRef S, bool Expected) {405  std::optional<bool> Parsed = yaml::parseBool(S);406  EXPECT_TRUE(Parsed.has_value());407  EXPECT_EQ(*Parsed, Expected);408}409 410static void expectCannotParseBool(StringRef S) {411  EXPECT_FALSE(yaml::parseBool(S).has_value());412}413 414TEST(YAMLParser, ParsesBools) {415  // Test true values.416  expectCanParseBool("ON", true);417  expectCanParseBool("On", true);418  expectCanParseBool("on", true);419  expectCanParseBool("TRUE", true);420  expectCanParseBool("True", true);421  expectCanParseBool("true", true);422  expectCanParseBool("Y", true);423  expectCanParseBool("y", true);424  expectCanParseBool("YES", true);425  expectCanParseBool("Yes", true);426  expectCanParseBool("yes", true);427  expectCannotParseBool("1");428 429  // Test false values.430  expectCanParseBool("FALSE", false);431  expectCanParseBool("False", false);432  expectCanParseBool("false", false);433  expectCanParseBool("N", false);434  expectCanParseBool("n", false);435  expectCanParseBool("NO", false);436  expectCanParseBool("No", false);437  expectCanParseBool("no", false);438  expectCanParseBool("OFF", false);439  expectCanParseBool("Off", false);440  expectCanParseBool("off", false);441  expectCannotParseBool("0");442}443 444// Checks that the given string can be parsed into an expected scalar value.445static void expectCanParseScalar(StringRef Input, StringRef Expected) {446  SourceMgr SM;447  yaml::Stream Stream(Input, SM);448  yaml::Node *Root = Stream.begin()->getRoot();449  ASSERT_NE(Root, nullptr);450  auto *ScalarNode = dyn_cast<yaml::ScalarNode>(Root);451  ASSERT_NE(ScalarNode, nullptr);452  SmallVector<char> Storage;453  StringRef Result = ScalarNode->getValue(Storage);454  EXPECT_EQ(Result, Expected);455}456 457TEST(YAMLParser, UnfoldsScalarValue) {458  // Double-quoted values459  expectCanParseScalar("\"\"", "");460  expectCanParseScalar("\"  \t\t  \t\t  \"", "  \t\t  \t\t  ");461  expectCanParseScalar("\"\n\"", " ");462  expectCanParseScalar("\"\r\"", " ");463  expectCanParseScalar("\"\r\n\"", " ");464  expectCanParseScalar("\"\n\n\"", "\n");465  expectCanParseScalar("\"\r\r\"", "\n");466  expectCanParseScalar("\"\n\r\"", "\n");467  expectCanParseScalar("\"\r\n\r\n\"", "\n");468  expectCanParseScalar("\"\n\n\n\"", "\n\n");469  expectCanParseScalar("\"\r\r\r\"", "\n\n");470  expectCanParseScalar("\"\r\n\r\n\r\n\"", "\n\n");471  expectCanParseScalar("\" \t \t \n\t \t \t\r \t \t \"", "\n");472  expectCanParseScalar("\" \t A \t \n \t B \t \"", " \t A B \t ");473  expectCanParseScalar("\" \t \\ \r\r\t \\  \t \"", " \t  \n  \t ");474  expectCanParseScalar("\"A\nB\"", "A B");475  expectCanParseScalar("\"A\rB\"", "A B");476  expectCanParseScalar("\"A\r\nB\"", "A B");477  expectCanParseScalar("\"A\n\nB\"", "A\nB");478  expectCanParseScalar("\"A\r\rB\"", "A\nB");479  expectCanParseScalar("\"A\n\rB\"", "A\nB");480  expectCanParseScalar("\"A\r\n\r\nB\"", "A\nB");481  expectCanParseScalar("\"A\n\n\nB\"", "A\n\nB");482  expectCanParseScalar("\"A\r\r\rB\"", "A\n\nB");483  expectCanParseScalar("\"A\r\n\r\n\r\nB\"", "A\n\nB");484  expectCanParseScalar("\"A \t \t \n\t \t \t B\"", "A B");485  expectCanParseScalar("\"A \t \t \n\t \t \t\r \t \t B\"", "A\nB");486  expectCanParseScalar("\"A \t \t \n\t \t \t\r\n \t \r  \t B\"", "A\n\nB");487  expectCanParseScalar("\"A\\\rB\"", "AB");488  expectCanParseScalar("\"A\\\nB\"", "AB");489  expectCanParseScalar("\"A\\\r\nB\"", "AB");490  expectCanParseScalar("\"A \t \\\rB\"", "A \t B");491  expectCanParseScalar("\"A  \t\\\nB\"", "A  \tB");492  expectCanParseScalar("\"A\t  \\\r\nB\"", "A\t  B");493  expectCanParseScalar("\"A\\\r\rB\"", "A B");494  expectCanParseScalar("\"A\\\n\nB\"", "A B");495  expectCanParseScalar("\"A\\\r\n\r\nB\"", "A B");496  expectCanParseScalar("\"A\\\r\r\rB\"", "A\nB");497  expectCanParseScalar("\"A\\\n\n\nB\"", "A\nB");498  expectCanParseScalar("\"A\\\r\n\r\n\r\nB\"", "A\nB");499  expectCanParseScalar("\"A\r\\ \rB\"", "A   B");500  // Single-quoted values501  expectCanParseScalar("''", "");502  expectCanParseScalar("'  \t\t  \t\t  '", "  \t\t  \t\t  ");503  expectCanParseScalar("'\n'", " ");504  expectCanParseScalar("'\r'", " ");505  expectCanParseScalar("'\r\n'", " ");506  expectCanParseScalar("'\n\n'", "\n");507  expectCanParseScalar("'\r\r'", "\n");508  expectCanParseScalar("'\n\r'", "\n");509  expectCanParseScalar("'\r\n\r\n'", "\n");510  expectCanParseScalar("'\n\n\n'", "\n\n");511  expectCanParseScalar("'\r\r\r'", "\n\n");512  expectCanParseScalar("'\r\n\r\n\r\n'", "\n\n");513  expectCanParseScalar("' \t \t \n\t \t \t\r \t \t '", "\n");514  expectCanParseScalar("' \t A \t \n \t B \t '", " \t A B \t ");515  expectCanParseScalar("'A\nB'", "A B");516  expectCanParseScalar("'A\rB'", "A B");517  expectCanParseScalar("'A\r\nB'", "A B");518  expectCanParseScalar("'A\n\nB'", "A\nB");519  expectCanParseScalar("'A\r\rB'", "A\nB");520  expectCanParseScalar("'A\n\rB'", "A\nB");521  expectCanParseScalar("'A\r\n\r\nB'", "A\nB");522  expectCanParseScalar("'A\n\n\nB'", "A\n\nB");523  expectCanParseScalar("'A\r\r\rB'", "A\n\nB");524  expectCanParseScalar("'A\r\n\r\n\r\nB'", "A\n\nB");525  expectCanParseScalar("'A \t \t \n\t \t \t B'", "A B");526  expectCanParseScalar("'A \t \t \n\t \t \t\r \t \t B'", "A\nB");527  expectCanParseScalar("'A \t \t \n\t \t \t\r\n \t \r  \t B'", "A\n\nB");528  // Plain values529  expectCanParseScalar("A  \t \r \n \t \r\n \t\r\r\t  ", "A");530  expectCanParseScalar("A \t \n \t B", "A B");531  expectCanParseScalar("A\nB", "A B");532  expectCanParseScalar("A\rB", "A B");533  expectCanParseScalar("A\r\nB", "A B");534  expectCanParseScalar("A\n\nB", "A\nB");535  expectCanParseScalar("A\r\rB", "A\nB");536  expectCanParseScalar("A\n\rB", "A\nB");537  expectCanParseScalar("A\r\n\r\nB", "A\nB");538  expectCanParseScalar("A\n\n\nB", "A\n\nB");539  expectCanParseScalar("A\r\r\rB", "A\n\nB");540  expectCanParseScalar("A\r\n\r\n\r\nB", "A\n\nB");541  expectCanParseScalar("A \t \t \n\t \t \t B", "A B");542  expectCanParseScalar("A \t \t \n\t \t \t\r \t \t B", "A\nB");543  expectCanParseScalar("A \t \t \n\t \t \t\r\n \t \r  \t B", "A\n\nB");544}545 546} // end namespace llvm547