Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Side by Side Diff: chrome/tools/profile_reset/jtl_parser_unittest.cc

Issue 24998003: Compiler for the JSON Traversal Language. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments, added some unittests. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/tools/profile_reset/jtl_parser.h"
6
7 #include <string>
8
9 #include "base/json/json_writer.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/values.h"
12 #include "testing/gmock/include/gmock/gmock-matchers.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace {
16
17 // Helpers -------------------------------------------------------------------
18
19 void ExpectNextOperation(JtlParser* parser,
20 const char* expected_name,
21 const char* expected_args,
22 bool expected_ends_sentence) {
23 std::string actual_name;
24 base::ListValue actual_args;
25 std::string actual_args_json;
26 bool actual_ends_sentence;
27
28 EXPECT_FALSE(parser->HasFinished());
29 EXPECT_TRUE(parser->ParseNextOperation(
30 &actual_name, &actual_args, &actual_ends_sentence));
31 EXPECT_EQ(expected_name, actual_name);
32 base::JSONWriter::Write(&actual_args, &actual_args_json);
33 EXPECT_EQ(expected_args, actual_args_json);
34 EXPECT_EQ(expected_ends_sentence, actual_ends_sentence);
35 }
36
37 void ExpectNextOperationToFail(JtlParser* parser,
38 size_t expected_line_number,
39 const char* expected_context_prefix) {
40 std::string actual_name;
41 base::ListValue actual_args;
42 bool actual_ends_sentence;
43
44 EXPECT_FALSE(parser->HasFinished());
45 EXPECT_FALSE(parser->ParseNextOperation(
46 &actual_name, &actual_args, &actual_ends_sentence));
47 EXPECT_THAT(parser->last_context(),
48 testing::StartsWith(expected_context_prefix));
49 EXPECT_EQ(expected_line_number, parser->last_line_number());
50 }
51
52 JtlParser* CreateParserFromVerboseText(const std::string& verbose_text) {
53 std::string compacted_source_code;
54 std::vector<size_t> newline_indices;
55 EXPECT_TRUE(JtlParser::RemoveCommentsAndAllWhitespace(
56 verbose_text, &compacted_source_code, &newline_indices, NULL));
57 return new JtlParser(compacted_source_code, newline_indices);
58 }
59
60 // Tests ---------------------------------------------------------------------
61
62 TEST(JtlParser, CompactingEmpty) {
63 const char kSourceCode[] = "";
64 const char kCompactedSourceCode[] = "";
65
66 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
67 EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
68 }
69
70 TEST(JtlParser, CompactingTrivial) {
71 const char kSourceCode[] = "foo";
72 const char kCompactedSourceCode[] = "foo";
73
74 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
75 EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
76 }
77
78 TEST(JtlParser, CompactingOneLine) {
79 const char kSourceCode[] = " \r f\to o ( true ) ";
80 const char kCompactedSourceCode[] = "foo(true)";
81
82 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
83 EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
84 for (size_t i = 0; i < arraysize(kCompactedSourceCode) - 1; ++i) {
85 SCOPED_TRACE(testing::Message("Position ") << i);
86 EXPECT_EQ(0u, parser->GetOriginalLineNumber(i));
87 }
88 }
89
90 TEST(JtlParser, CompactingMultipleLines) {
91 const char kSourceCode[] = "a\nbb\n \nccc \n\n d( \n e \n )";
92 const char kCompactedSourceCode[] = "abbcccd(e)";
93 const size_t kLineNumbers[] = {0u, 1u, 1u, 3u, 3u, 3u, 5u, 5u, 6u, 7u};
94 COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
95 mismatched_test_data);
96
97 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
98 EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
99 for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
100 SCOPED_TRACE(testing::Message("Position ") << i);
101 EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
102 }
103 }
104
105 TEST(JtlParser, HandlingCommentsAndStringLiterals) {
106 struct TestCase {
107 const char* source_code;
108 const char* compacted_source_code;
109 } cases[] = {
110 {"//", ""},
111 {"//comment", ""},
112 {"foo //comment", "foo"},
113 {"\"literal\"", "\"literal\""},
114 {"\"literal with space\"", "\"literal with space\""},
115 {"\"\"", "\"\""},
116 {"\"\"\"\"", "\"\"\"\""},
117 {"\"\" // comment", "\"\""},
118 {"\"literal\" // comment", "\"literal\""},
119 {"\"literal\" \"literal\" // comment", "\"literal\"\"literal\""},
120 {"foo // \"not a literal\"", "foo"},
121 {"foo // \"not even matched", "foo"},
122 {"foo // \"not a literal\" \"not even matched", "foo"},
123 {"\"literal\" // \"not a literal\"", "\"literal\""},
124 {"\"literal\" // \"not even matched", "\"literal\""},
125 {"\"//not a comment//\"", "\"//not a comment//\""},
126 {"\"//not a comment//\" // comment", "\"//not a comment//\""},
127 {"// \"//not a literal//\" // comment", ""},
128 {"\"literal // \"not a literal or a comment//\"",
129 "\"literal // \"notaliteraloracomment"}
130 };
131
132 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
133 SCOPED_TRACE(cases[i].source_code);
134 scoped_ptr<JtlParser> parser(
135 CreateParserFromVerboseText(cases[i].source_code));
136 EXPECT_EQ(cases[i].compacted_source_code, parser->compacted_source());
137 }
138 }
139
140 TEST(JtlParser, MismatchedDoubleQuotesInLine) {
141 struct TestCase {
142 const char* source_code;
143 size_t error_line_number;
144 } cases[] = {
145 {"\"", 0},
146 {"\"mismatched literal", 0},
147 {"\n\"", 1},
148 {"\"\n\"", 0},
149 {"\"\"\"", 0},
150 {"\"\"\n\"", 1},
151 {"\"\"\n\"\n\"", 1},
152 {"\" // comment", 0},
153 {"\"\" // comment\n\"", 1},
154 {"\"\" // comment\n\"// comment", 1},
155 {"\" // not a comment\"\n\"// comment", 1},
156 {"foo(\"bar\");\nfoo(\"mismatched);", 1},
157 {"foo(\n\"bar\", \"mismatched);", 1},
158 {"foo(\n\"bar\", \"mismatched); //comment", 1},
159 {"foo(\n\"bar\", \"mismatched);\ngood(\"bar\")", 1}
160 };
161
162 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
163 SCOPED_TRACE(cases[i].source_code);
164 std::string compacted_source_code;
165 std::vector<size_t> newline_indices;
166 size_t error_line_number;
167 EXPECT_FALSE(JtlParser::RemoveCommentsAndAllWhitespace(
168 cases[i].source_code,
169 &compacted_source_code,
170 &newline_indices,
171 &error_line_number));
172 EXPECT_EQ(cases[i].error_line_number, error_line_number);
173 }
174 }
175
176 TEST(JtlParser, CompactingMultipleLinesWithComments) {
177 const char kSourceCode[] =
178 "a/ /b//Comment \n//\n// Full line comment\n cd //";
battre 2013/10/01 12:18:26 Nit: change format? "a/ /b//Comment \n" "/
engedy 2013/10/01 15:09:33 Done.
179 const char kCompactedSourceCode[] = "a//bcd";
180 const size_t kLineNumbers[] = {0u, 0u, 0u, 0u, 3u, 3u};
181 COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
182 mismatched_test_data);
183
184 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
185 EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
186 for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
187 SCOPED_TRACE(testing::Message("Position ") << i);
188 EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
189 }
190 }
191
192 TEST(JtlParser, ParsingEmpty) {
193 const char kSourceCode[] = "";
194
195 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
196 EXPECT_TRUE(parser->HasFinished());
197 }
198
199 TEST(JtlParser, ParsingOneWellFormedOperation) {
200 struct TestCase {
201 const char* source_code;
202 const char* expected_name;
203 const char* expected_args;
204 const bool expected_ends_sentence;
205 } cases[] = {
206 {"foo1;", "foo1", "[]", true},
207 {"foo2()/", "foo2", "[]", false},
208 {"foo3(true);", "foo3", "[true]", true},
209 {"foo4(false)/", "foo4", "[false]", false},
210 {"foo5(\"bar\")/", "foo5", "[\"bar\"]", false},
battre 2013/10/01 12:18:26 \"foo bar\" to add whitespaces?
engedy 2013/10/01 15:09:33 Done.
211 {"foo6(true, \"bar\")/", "foo6", "[true,\"bar\"]", false},
212 {"foo7(\"bar\", false, true);", "foo7", "[\"bar\",false,true]", true}
213 };
214
215 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
216 SCOPED_TRACE(cases[i].expected_name);
217 scoped_ptr<JtlParser> parser(
218 CreateParserFromVerboseText(cases[i].source_code));
219 ExpectNextOperation(parser.get(),
220 cases[i].expected_name,
221 cases[i].expected_args,
222 cases[i].expected_ends_sentence);
223 EXPECT_TRUE(parser->HasFinished());
224 }
225 }
226
227 TEST(JtlParser, ParsingMultipleWellFormedOperations) {
228 const char kSourceCode[] =
229 "foo1(true)/foo2/foo3(\"bar\");"
230 "foo4(\"bar\", false);";
231
232 scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
233 ExpectNextOperation(parser.get(), "foo1", "[true]", false);
234 ExpectNextOperation(parser.get(), "foo2", "[]", false);
235 ExpectNextOperation(parser.get(), "foo3", "[\"bar\"]", true);
236 ExpectNextOperation(parser.get(), "foo4", "[\"bar\",false]", true);
237 EXPECT_TRUE(parser->HasFinished());
238 }
239
240 TEST(JtlParser, ParsingTrickyStringLiterals) {
241 struct TestCase {
242 const char* source_code;
243 const char* expected_name;
244 const char* expected_args;
245 const bool expected_ends_sentence;
246 } cases[] = {
247 {"prev()/foo1(\"\");next(true);", "foo1", "[\"\"]", true},
248 {"prev()/foo2(\",\",true);next(true);", "foo2", "[\",\",true]", true},
249 {"prev()/foo3(\")\",true);next(true);", "foo3", "[\")\",true]", true},
250 {"prev()/foo4(\";\",true);next(true);", "foo4", "[\";\",true]", true},
251 {"prev()/foo5(\"/\",true)/next(true);", "foo5", "[\"/\",true]", false},
252 {"prev()/foo6(\"//\",true)/next(true);", "foo6", "[\"//\",true]", false},
253 };
254
255 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
256 SCOPED_TRACE(cases[i].expected_name);
257 scoped_ptr<JtlParser> parser(
258 CreateParserFromVerboseText(cases[i].source_code));
259 ExpectNextOperation(parser.get(), "prev", "[]", false);
260 ExpectNextOperation(parser.get(),
261 cases[i].expected_name,
262 cases[i].expected_args,
263 cases[i].expected_ends_sentence);
264 ExpectNextOperation(parser.get(), "next", "[true]", true);
265 EXPECT_TRUE(parser->HasFinished());
266 }
267 }
268
269 TEST(JtlParser, FirstOperationIsIllFormed) {
270 struct TestCase {
271 const char* source_code;
272 const char* operation_name;
273 } cases[] = {
274 {";;", ";"},
275 {"bad_args1(not a boolean value);", "bad_args1"},
276 {"bad_args2(,);", "bad_args2"},
277 {"bad_args3(...);", "bad_args3"},
278 {"bad_args4(1);", "bad_args4"},
279 {"bad_args5(1.2);", "bad_args5"},
280 {"bad_args6([\"bar\"]);", "bad_args6"},
281 {"bad_args7(False);", "bad_args7"},
282 {"bad_args8(True);", "bad_args8"},
283 {"bad_quotes1(missing two, true)/good();", "bad_quotes1"},
284 {"bad_quotes2(true, \"missing one)/good(); //\"", "bad_quotes2"},
285 {"bad_quotes3(\"too\" \"much\", true)/good();", "bad_quotes3"},
286 {"bad_missing_separator1", "bad_missing_separator1"},
287 {"bad_missing_separator2()good();", "bad_missing_separator2"},
288 {"bad_parenthesis1(true/good();", "bad_parenthesis1"},
289 {"bad_parenthesis2(true/good());", "bad_parenthesis2"},
290 {"bad_parenthesis3)/good();", "bad_parenthesis3"}
291 };
292
293 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
294 SCOPED_TRACE(cases[i].operation_name);
295 scoped_ptr<JtlParser> parser(
296 CreateParserFromVerboseText(cases[i].source_code));
297 ExpectNextOperationToFail(parser.get(), 0, cases[i].operation_name);
298 }
299 }
300
301 TEST(JtlParser, SecondOperationIsIllFormed) {
302 struct TestCase {
303 const char* source_code;
304 const char* bad_operation_name;
305 } cases[] = {
306 {"\ngood(true,false)\n/bad_args(,);", "bad_args"},
307 {"\ngood(true,false)\n/bad_quotes1(missing two, true)/good();",
308 "bad_quotes1"},
309 {"\ngood(true,false)\n/bad_quotes2(\"missing one, true)/good(); //\"",
310 "bad_quotes2"},
311 {"\ngood(true,false)\n/bad_quotes3(\"too\" \"many\", true)/good();",
312 "bad_quotes3"},
313 {"\ngood(true,false)\n/missing_separator1", "missing_separator1"},
314 {"\ngood(true,false)\n/missing_separator2()good()", "missing_separator2"},
315 {"\ngood(true,false)\n/bad_parens1(true/good();", "bad_parens1"},
316 {"\ngood(true,false)\n/bad_parens2(true/good());", "bad_parens2"},
317 {"\ngood(true,false)\n/bad_parens3)/good();", "bad_parens3"}
318 };
319
320 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
321 SCOPED_TRACE(cases[i].bad_operation_name);
322 scoped_ptr<JtlParser> parser(
323 CreateParserFromVerboseText(cases[i].source_code));
324 ExpectNextOperation(parser.get(), "good", "[true,false]", false);
325 ExpectNextOperationToFail(parser.get(), 2, cases[i].bad_operation_name);
326 }
327 }
328
329 } // namespace
OLDNEW
« chrome/tools/profile_reset/jtl_parser.cc ('K') | « chrome/tools/profile_reset/jtl_parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698