193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//===- unittest/Support/YAMLParserTest ------------------------------------===//
293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//
393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//                     The LLVM Compiler Infrastructure
493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//
593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// This file is distributed under the University of Illinois Open Source
693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// License. See LICENSE.TXT for details.
793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//
893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//===----------------------------------------------------------------------===//
993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
1093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/ADT/SmallString.h"
1193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/ADT/Twine.h"
1293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/Casting.h"
1393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/SourceMgr.h"
1493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/YAMLParser.h"
1593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "gtest/gtest.h"
1693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
1793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencernamespace llvm {
1893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
19d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzikstatic void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) {
20d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzik  // Prevent SourceMgr from writing errors to stderr
21d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzik  // to reduce noise in unit test runs.
22d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzik}
23d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzik
2493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// Checks that the given input gives a parse error. Makes sure that an error
2593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// text is available and the parse fails.
2693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void ExpectParseError(StringRef Message, StringRef Input) {
2793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  SourceMgr SM;
2893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::Stream Stream(Input, SM);
29d7122b8d3c48eab05d425c99fee53cde07feafe4Nick Kledzik  SM.setDiagHandler(SuppressDiagnosticsOutput);
3093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  EXPECT_FALSE(Stream.validate()) << Message << ": " << Input;
3193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  EXPECT_TRUE(Stream.failed()) << Message << ": " << Input;
3293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
3393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
3493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// Checks that the given input can be parsed without error.
3593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void ExpectParseSuccess(StringRef Message, StringRef Input) {
3693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  SourceMgr SM;
3793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::Stream Stream(Input, SM);
3893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  EXPECT_TRUE(Stream.validate()) << Message << ": " << Input;
3993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
4093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
4193210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesEmptyArray) {
4293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Empty array", "[]");
4393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
4493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
4593210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, FailsIfNotClosingArray) {
4693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Not closing array", "[");
4793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Not closing array", "  [  ");
4893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Not closing array", "  [x");
4993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
5093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
5193210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesEmptyArrayWithWhitespace) {
5293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Array with spaces", "  [  ]  ");
5393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");
5493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
5593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
5693210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesEmptyObject) {
5793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Empty object", "[{}]");
5893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
5993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
6093210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesObject) {
6193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");
6293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
6393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
6493210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesMultipleKeyValuePairsInObject) {
6593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Multiple key, value pairs",
6693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer                     "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");
6793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
6893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
6993210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, FailsIfNotClosingObject) {
7093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing close on empty", "[{]");
7193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");
7293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
7393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
7493210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, FailsIfMissingColon) {
7593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");
7693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");
7793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
7893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
7993210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, FailsOnMissingQuote) {
8093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing open quote", "[{a\":\"b\"}]");
8193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");
8293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
8393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
8493210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesEscapedQuotes) {
8593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Parses escaped string in key and value",
8693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer                     "[{\"a\":\"\\\"b\\\"  \\\" \\\"\"}]");
8793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
8893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
8993210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesEmptyString) {
9093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");
9193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
9293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
9393210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesMultipleObjects) {
9493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess(
9593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "Multiple objects in array",
9693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "["
9793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " { \"a\" : \"b\" },"
9893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " { \"a\" : \"b\" },"
9993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " { \"a\" : \"b\" }"
10093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "]");
10193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
10293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
10393210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, FailsOnMissingComma) {
10493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError(
10593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "Missing comma",
10693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "["
10793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " { \"a\" : \"b\" }"
10893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " { \"a\" : \"b\" }"
10993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "]");
11093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
11193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
11293210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesSpacesInBetweenTokens) {
11393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess(
11493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      "Various whitespace between tokens",
11593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " \t \n\n \r [ \t \n\n \r"
11693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
11793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"
11893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
11993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r");
12093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
12193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
12293210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesArrayOfArrays) {
12393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseSuccess("Array of arrays", "[[]]");
12493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
12593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
12693210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, HandlesEndOfFileGracefully) {
12793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In string starting with EOF", "[\"");
12893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In string hitting EOF", "[\"   ");
12993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In string escaping EOF", "[\"  \\");
13093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In array starting with EOF", "[");
13193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In array element starting with EOF", "[[], ");
13293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In array hitting EOF", "[[] ");
13393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In array hitting EOF", "[[]");
13493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError("In object hitting EOF", "{\"\"");
13593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
13693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
13793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// Checks that the given string can be parsed into an identical string inside
13893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// of an array.
13993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void ExpectCanParseString(StringRef String) {
14093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
14193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  SourceMgr SM;
14293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::Stream Stream(StringInArray, SM);
14393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::SequenceNode *ParsedSequence
14493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
14593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  StringRef ParsedString
14693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer    = dyn_cast<yaml::ScalarNode>(
14793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer      static_cast<yaml::Node*>(ParsedSequence->begin()))->getRawValue();
14893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ParsedString = ParsedString.substr(1, ParsedString.size() - 2);
14993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  EXPECT_EQ(String, ParsedString.str());
15093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
15193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
15293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// Checks that parsing the given string inside an array fails.
15393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void ExpectCannotParseString(StringRef String) {
15493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
15593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),
15693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer                   StringInArray);
15793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
15893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
15993210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, ParsesStrings) {
16093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("");
16193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString("\\");
16293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString("\"");
16393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString(" ");
16493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\ ");
16593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\\"");
16693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString("\"\\");
16793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString(" \\");
16893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\\\");
16993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString("\\\\\\");
17093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\\\\\\\");
17193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\\" ");
17293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCannotParseString("\\\\\" ");
17393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("\\\\\\\" ");
17493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  ExpectCanParseString("    \\\\  \\\"  \\\\\\\"   ");
17593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
17693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
17793210e847a1496b24cef881723e57c489082dcfeMichael J. SpencerTEST(YAMLParser, WorksWithIteratorAlgorithms) {
17893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  SourceMgr SM;
17993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::Stream Stream("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", SM);
18093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  yaml::SequenceNode *Array
18193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
18293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer  EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
18393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}
18493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer
18593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} // end namespace llvm
186