Add triple support for the IBM BG/P and BG/Q supercomputers.
[oota-llvm.git] / unittests / Support / JSONParserTest.cpp
1 //===- unittest/Tooling/JSONParserTest ------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Support/Casting.h"
11 #include "llvm/Support/JSONParser.h"
12 #include "llvm/ADT/Twine.h"
13 #include "gtest/gtest.h"
14
15 namespace llvm {
16
17 // Checks that the given input gives a parse error. Makes sure that an error
18 // text is available and the parse fails.
19 static void ExpectParseError(StringRef Message, StringRef Input) {
20   SourceMgr SM;
21   JSONParser Parser(Input, &SM);
22   EXPECT_FALSE(Parser.validate()) << Message << ": " << Input;
23   EXPECT_TRUE(Parser.failed()) << Message << ": " << Input;
24 }
25
26 // Checks that the given input can be parsed without error.
27 static void ExpectParseSuccess(StringRef Message, StringRef Input) {
28   SourceMgr SM;
29   JSONParser Parser(Input, &SM);
30   EXPECT_TRUE(Parser.validate()) << Message << ": " << Input;
31 }
32
33 TEST(JSONParser, FailsOnEmptyString) {
34   ExpectParseError("Empty JSON text", "");
35 }
36  
37 TEST(JSONParser, FailsIfStartsWithString) {
38   ExpectParseError("Top-level string", "\"x\"");
39 }
40
41 TEST(JSONParser, ParsesEmptyArray) {
42   ExpectParseSuccess("Empty array", "[]");
43 }
44
45 TEST(JSONParser, FailsIfNotClosingArray) {
46   ExpectParseError("Not closing array", "[");
47   ExpectParseError("Not closing array", "  [  ");
48   ExpectParseError("Not closing array", "  [x");
49 }
50
51 TEST(JSONParser, ParsesEmptyArrayWithWhitespace) {
52   ExpectParseSuccess("Array with spaces", "  [  ]  ");
53   ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");
54 }
55
56 TEST(JSONParser, ParsesEmptyObject) {
57   ExpectParseSuccess("Empty object", "[{}]");
58 }
59
60 TEST(JSONParser, ParsesObject) {
61   ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");
62 }
63
64 TEST(JSONParser, ParsesMultipleKeyValuePairsInObject) {
65   ExpectParseSuccess("Multiple key, value pairs",
66                      "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");
67 }
68
69 TEST(JSONParser, FailsIfNotClosingObject) {
70   ExpectParseError("Missing close on empty", "[{]");
71   ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");
72 }
73
74 TEST(JSONParser, FailsIfMissingColon) {
75   ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");
76   ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");
77 }
78
79 TEST(JSONParser, FailsOnMissingQuote) {
80   ExpectParseError("Missing open quote", "[{a\":\"b\"}]");
81   ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");
82 }
83
84 TEST(JSONParser, ParsesEscapedQuotes) {
85   ExpectParseSuccess("Parses escaped string in key and value",
86                      "[{\"a\":\"\\\"b\\\"  \\\" \\\"\"}]");
87 }
88
89 TEST(JSONParser, ParsesEmptyString) {
90   ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");
91 }
92
93 TEST(JSONParser, FailsOnMissingString) {
94   ExpectParseError("Missing value", "[{\"a\":}]");
95   ExpectParseError("Missing key", "[{:\"b\"}]");
96 }
97
98 TEST(JSONParser, ParsesMultipleObjects) {
99   ExpectParseSuccess(
100       "Multiple objects in array",
101       "["
102       " { \"a\" : \"b\" },"
103       " { \"a\" : \"b\" },"
104       " { \"a\" : \"b\" }"
105       "]");
106 }
107
108 TEST(JSONParser, FailsOnMissingComma) {
109   ExpectParseError(
110       "Missing comma",
111       "["
112       " { \"a\" : \"b\" }"
113       " { \"a\" : \"b\" }"
114       "]");
115 }
116
117 TEST(JSONParser, FailsOnSuperfluousComma) {
118   ExpectParseError("Superfluous comma in array", "[ { \"a\" : \"b\" }, ]");
119   ExpectParseError("Superfluous comma in object", "{ \"a\" : \"b\", }");
120 }
121
122 TEST(JSONParser, ParsesSpacesInBetweenTokens) {
123   ExpectParseSuccess(
124       "Various whitespace between tokens",
125       " \t \n\n \r [ \t \n\n \r"
126       " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
127       " \t \n\n \r \"b\"\t \n\n \r } \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 }
131
132 TEST(JSONParser, ParsesArrayOfArrays) {
133   ExpectParseSuccess("Array of arrays", "[[]]");
134 }
135
136 TEST(JSONParser, HandlesEndOfFileGracefully) {
137   ExpectParseError("In string starting with EOF", "[\"");
138   ExpectParseError("In string hitting EOF", "[\"   ");
139   ExpectParseError("In string escaping EOF", "[\"  \\");
140   ExpectParseError("In array starting with EOF", "[");
141   ExpectParseError("In array element starting with EOF", "[[], ");
142   ExpectParseError("In array hitting EOF", "[[] ");
143   ExpectParseError("In array hitting EOF", "[[]");
144   ExpectParseError("In object hitting EOF", "{\"\"");
145 }
146
147 // Checks that the given string can be parsed into an identical string inside
148 // of an array.
149 static void ExpectCanParseString(StringRef String) {
150   std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
151   SourceMgr SM;
152   JSONParser Parser(StringInArray, &SM);
153   const JSONArray *ParsedArray = dyn_cast<JSONArray>(Parser.parseRoot());
154   StringRef ParsedString =
155       dyn_cast<JSONString>(*ParsedArray->begin())->getRawText();
156   EXPECT_EQ(String, ParsedString.str());
157 }
158
159 // Checks that parsing the given string inside an array fails.
160 static void ExpectCannotParseString(StringRef String) {
161   std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
162   ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),
163                    StringInArray);
164 }
165
166 TEST(JSONParser, ParsesStrings) {
167   ExpectCanParseString("");
168   ExpectCannotParseString("\\");
169   ExpectCannotParseString("\"");
170   ExpectCanParseString(" ");
171   ExpectCanParseString("\\ ");
172   ExpectCanParseString("\\\"");
173   ExpectCannotParseString("\"\\");
174   ExpectCannotParseString(" \\");
175   ExpectCanParseString("\\\\");
176   ExpectCannotParseString("\\\\\\");
177   ExpectCanParseString("\\\\\\\\");
178   ExpectCanParseString("\\\" ");
179   ExpectCannotParseString("\\\\\" ");
180   ExpectCanParseString("\\\\\\\" ");
181   ExpectCanParseString("    \\\\  \\\"  \\\\\\\"   ");
182 }
183
184 TEST(JSONParser, WorksWithIteratorAlgorithms) {
185   SourceMgr SM;
186   JSONParser Parser("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", &SM);
187   const JSONArray *Array = dyn_cast<JSONArray>(Parser.parseRoot());
188   EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
189 }
190
191 } // end namespace llvm