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

Unified 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: Fixed linker errors on Win. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/tools/profile_reset/jtl_parser.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/tools/profile_reset/jtl_parser_unittest.cc
diff --git a/chrome/tools/profile_reset/jtl_parser_unittest.cc b/chrome/tools/profile_reset/jtl_parser_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..58ee3d67a207cdc08c59e58d4606f4ebb411bcd7
--- /dev/null
+++ b/chrome/tools/profile_reset/jtl_parser_unittest.cc
@@ -0,0 +1,343 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/tools/profile_reset/jtl_parser.h"
+
+#include "base/json/json_writer.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// Helpers -------------------------------------------------------------------
+
+void ExpectNextOperation(JtlParser* parser,
+ const char* expected_name,
+ const char* expected_args_json,
+ bool expected_ends_sentence) {
+ std::string actual_name;
+ base::ListValue actual_args;
+ std::string actual_args_json;
+ bool actual_ends_sentence;
+
+ EXPECT_FALSE(parser->HasFinished());
+ EXPECT_TRUE(parser->ParseNextOperation(
+ &actual_name, &actual_args, &actual_ends_sentence));
+ EXPECT_EQ(expected_name, actual_name);
+ base::JSONWriter::Write(&actual_args, &actual_args_json);
+ EXPECT_EQ(expected_args_json, actual_args_json);
+ EXPECT_EQ(expected_ends_sentence, actual_ends_sentence);
+}
+
+void ExpectNextOperationToFail(JtlParser* parser,
+ size_t expected_line_number,
+ const char* expected_context_prefix) {
+ std::string actual_name;
+ base::ListValue actual_args;
+ bool actual_ends_sentence;
+
+ EXPECT_FALSE(parser->HasFinished());
+ EXPECT_FALSE(parser->ParseNextOperation(
+ &actual_name, &actual_args, &actual_ends_sentence));
+ EXPECT_THAT(parser->GetLastContext(),
+ testing::StartsWith(expected_context_prefix));
+ EXPECT_EQ(expected_line_number, parser->GetLastLineNumber());
+}
+
+JtlParser* CreateParserFromVerboseText(const std::string& verbose_text) {
+ std::string compacted_source_code;
+ std::vector<size_t> newline_indices;
+ EXPECT_TRUE(JtlParser::RemoveCommentsAndAllWhitespace(
+ verbose_text, &compacted_source_code, &newline_indices, NULL));
+ return new JtlParser(compacted_source_code, newline_indices);
+}
+
+// Tests ---------------------------------------------------------------------
+
+TEST(JtlParser, CompactingEmpty) {
+ const char kSourceCode[] = "";
+ const char kCompactedSourceCode[] = "";
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
+}
+
+TEST(JtlParser, CompactingTrivial) {
+ const char kSourceCode[] = "foo";
+ const char kCompactedSourceCode[] = "foo";
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
+}
+
+TEST(JtlParser, CompactingOneLine) {
+ const char kSourceCode[] = " \r f\to o ( true ) ";
+ const char kCompactedSourceCode[] = "foo(true)";
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
+ for (size_t i = 0; i < arraysize(kCompactedSourceCode) - 1; ++i) {
+ SCOPED_TRACE(testing::Message("Position ") << i);
+ EXPECT_EQ(0u, parser->GetOriginalLineNumber(i));
+ }
+}
+
+TEST(JtlParser, CompactingMultipleLines) {
+ const char kSourceCode[] = "a\nbb\n \nccc \n\n d( \n e \n )";
+ const char kCompactedSourceCode[] = "abbcccd(e)";
+ const size_t kLineNumbers[] = {0u, 1u, 1u, 3u, 3u, 3u, 5u, 5u, 6u, 7u};
+ COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
+ mismatched_test_data);
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
+ for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
+ SCOPED_TRACE(testing::Message("Position ") << i);
+ EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
+ }
+}
+
+TEST(JtlParser, CompactingMultipleLinesWithComments) {
+ const char kSourceCode[] =
+ "a/ /b//Comment \n"
+ "//\n"
+ "// Full line comment\n"
+ " cd //";
+ const char kCompactedSourceCode[] = "a//bcd";
+ const size_t kLineNumbers[] = {0u, 0u, 0u, 0u, 3u, 3u};
+ COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
+ mismatched_test_data);
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
+ for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
+ SCOPED_TRACE(testing::Message("Position ") << i);
+ EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
+ }
+}
+
+TEST(JtlParser, HandlingCommentsAndStringLiterals) {
+ struct TestCase {
+ const char* source_code;
+ const char* compacted_source_code;
+ } cases[] = {
+ {"//", ""},
+ {"//comment", ""},
+ {"foo // comment", "foo"},
+ {"foo // // comment", "foo"},
+ {"foo //", "foo"},
+ {"\"literal\"", "\"literal\""},
+ {"\"literal with space\"", "\"literal with space\""},
+ {"\"\"", "\"\""},
+ {"\"\"\"\"", "\"\"\"\""},
+ {"\"\" // comment", "\"\""},
+ {"\"literal\" // comment", "\"literal\""},
+ {"\"literal\" \"literal\" // comment", "\"literal\"\"literal\""},
+ {"foo // \"not a literal\"", "foo"},
+ {"foo // \"not even matched", "foo"},
+ {"foo // \"not a literal\" \"not even matched", "foo"},
+ {"\"literal\" // \"not a literal\"", "\"literal\""},
+ {"\"literal\" // \"not even matched", "\"literal\""},
+ {"\"//not a comment//\"", "\"//not a comment//\""},
+ {"\"//not a comment//\" // comment", "\"//not a comment//\""},
+ {"// \"//not a literal//\" // comment", ""},
+ {"\"literal\" // \"//not a literal//\" // comment", "\"literal\""},
+ {"\"//not a comment//\" // \"//not a literal//\" // comment",
+ "\"//not a comment//\""},
+ {"\"literal // \"not a literal nor a comment",
+ "\"literal // \"notaliteralnoracomment"},
+ {"\"literal // \"not a literal nor a comment//\"",
+ "\"literal // \"notaliteralnoracomment"}
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].source_code);
+ scoped_ptr<JtlParser> parser(
+ CreateParserFromVerboseText(cases[i].source_code));
+ EXPECT_EQ(cases[i].compacted_source_code, parser->compacted_source());
+ }
+}
+
+TEST(JtlParser, MismatchedDoubleQuotesBeforeEndOfLine) {
+ struct TestCase {
+ const char* source_code;
+ size_t error_line_number;
+ } cases[] = {
+ {"\"", 0},
+ {"\"mismatched literal", 0},
+ {"\n\"", 1},
+ {"\"\n\"", 0},
+ {"\"\"\"", 0},
+ {"\"\"\n\"", 1},
+ {"\"\"\n\"\n\"", 1},
+ {"\" // not a comment", 0},
+ {"\" // not a comment\n\"", 0},
+ {"\"\" // comment\n\"", 1},
+ {"\"\"\" // not a comment\n\"", 0},
+ {"\"\"\" // \" neither a literal nor a comment\"\n\"", 0},
+ {"\"\" // comment\n\"// not a comment", 1},
+ {"\" // not a comment\"\n\"// not a comment", 1},
+ {"foo(\"bar\");\nfoo(\"mismatched);", 1},
+ {"foo(\n\"bar\", \"mismatched);", 1},
+ {"foo(\n\"bar\", \"mismatched); //comment", 1},
+ {"foo(\n\"bar\", \"mismatched);\ngood(\"bar\")", 1}
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].source_code);
+ std::string compacted_source_code;
+ std::vector<size_t> newline_indices;
+ size_t error_line_number;
+ EXPECT_FALSE(JtlParser::RemoveCommentsAndAllWhitespace(
+ cases[i].source_code,
+ &compacted_source_code,
+ &newline_indices,
+ &error_line_number));
+ EXPECT_EQ(cases[i].error_line_number, error_line_number);
+ }
+}
+
+TEST(JtlParser, ParsingEmpty) {
+ const char kSourceCode[] = "";
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ EXPECT_TRUE(parser->HasFinished());
+}
+
+TEST(JtlParser, ParsingOneWellFormedOperation) {
+ struct TestCase {
+ const char* source_code;
+ const char* expected_name;
+ const char* expected_args;
+ const bool expected_ends_sentence;
+ } cases[] = {
+ {"foo1;", "foo1", "[]", true},
+ {"foo2()/", "foo2", "[]", false},
+ {"foo3(true);", "foo3", "[true]", true},
+ {"foo4(false)/", "foo4", "[false]", false},
+ {"foo5(\"bar\")/", "foo5", "[\"bar\"]", false},
+ {"foo6(\" b a r \")/", "foo6", "[\" b a r \"]", false},
+ {"foo7(true, \"bar\")/", "foo7", "[true,\"bar\"]", false},
+ {"foo8(\"bar\", false, true);", "foo8", "[\"bar\",false,true]", true},
+ {"foo9(\"bar\", \" b a r \");", "foo9", "[\"bar\",\" b a r \"]", true}
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].expected_name);
+ scoped_ptr<JtlParser> parser(
+ CreateParserFromVerboseText(cases[i].source_code));
+ ExpectNextOperation(parser.get(),
+ cases[i].expected_name,
+ cases[i].expected_args,
+ cases[i].expected_ends_sentence);
+ EXPECT_TRUE(parser->HasFinished());
+ }
+}
+
+TEST(JtlParser, ParsingMultipleWellFormedOperations) {
+ const char kSourceCode[] =
+ "foo1(true)/foo2/foo3(\"bar\");"
+ "foo4(\"bar\", false);";
+
+ scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
+ ExpectNextOperation(parser.get(), "foo1", "[true]", false);
+ ExpectNextOperation(parser.get(), "foo2", "[]", false);
+ ExpectNextOperation(parser.get(), "foo3", "[\"bar\"]", true);
+ ExpectNextOperation(parser.get(), "foo4", "[\"bar\",false]", true);
+ EXPECT_TRUE(parser->HasFinished());
+}
+
+TEST(JtlParser, ParsingTrickyStringLiterals) {
+ struct TestCase {
+ const char* source_code;
+ const char* expected_name;
+ const char* expected_args;
+ const bool expected_ends_sentence;
+ } cases[] = {
+ {"prev()/foo1(\"\");next(true);", "foo1", "[\"\"]", true},
+ {"prev()/foo2(\" \");next(true);", "foo2", "[\" \"]", true},
+ {"prev()/foo3(\",\",true);next(true);", "foo3", "[\",\",true]", true},
+ {"prev()/foo4(\")\",true);next(true);", "foo4", "[\")\",true]", true},
+ {"prev()/foo5(\";\",true);next(true);", "foo5", "[\";\",true]", true},
+ {"prev()/foo6(\"/\",true)/next(true);", "foo6", "[\"/\",true]", false},
+ {"prev()/foo7(\"//\",true)/next(true);", "foo7", "[\"//\",true]", false},
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].expected_name);
+ scoped_ptr<JtlParser> parser(
+ CreateParserFromVerboseText(cases[i].source_code));
+ ExpectNextOperation(parser.get(), "prev", "[]", false);
+ ExpectNextOperation(parser.get(),
+ cases[i].expected_name,
+ cases[i].expected_args,
+ cases[i].expected_ends_sentence);
+ ExpectNextOperation(parser.get(), "next", "[true]", true);
+ EXPECT_TRUE(parser->HasFinished());
+ }
+}
+
+TEST(JtlParser, FirstOperationIsIllFormed) {
+ struct TestCase {
+ const char* source_code;
+ const char* operation_name;
+ } cases[] = {
+ {";;", ";"},
+ {"bad_args1(not a boolean value);", "bad_args1"},
+ {"bad_args2(,);", "bad_args2"},
+ {"bad_args3(...);", "bad_args3"},
+ {"bad_args4(1);", "bad_args4"},
+ {"bad_args5(1.2);", "bad_args5"},
+ {"bad_args6([\"bar\"]);", "bad_args6"},
+ {"bad_args7(False);", "bad_args7"},
+ {"bad_args8(True);", "bad_args8"},
+ {"bad_quotes1(missing both, true)/good();", "bad_quotes1"},
+ {"bad_quotes2(true, \"missing one)/good(); //\"", "bad_quotes2"},
+ {"bad_quotes3(\"too\" \"much\", true)/good();", "bad_quotes3"},
+ {"bad_missing_separator1", "bad_missing_separator1"},
+ {"bad_missing_separator2()good();", "bad_missing_separator2"},
+ {"bad_parenthesis1(true/good();", "bad_parenthesis1"},
+ {"bad_parenthesis2(true/good());", "bad_parenthesis2"},
+ {"bad_parenthesis3)/good();", "bad_parenthesis3"}
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].operation_name);
+ scoped_ptr<JtlParser> parser(
+ CreateParserFromVerboseText(cases[i].source_code));
+ ExpectNextOperationToFail(parser.get(), 0, cases[i].operation_name);
+ }
+}
+
+TEST(JtlParser, SecondOperationIsIllFormed) {
+ struct TestCase {
+ const char* source_code;
+ const char* bad_operation_name;
+ } cases[] = {
+ {"\ngood(true,false)\n/bad_args(,);", "bad_args"},
+ {"\ngood(true,false)\n/bad_quotes1(missing both, true)/good();",
+ "bad_quotes1"},
+ {"\ngood(true,false)\n/bad_quotes2(\"missing one, true)/good(); //\"",
+ "bad_quotes2"},
+ {"\ngood(true,false)\n/bad_quotes3(\"too\" \"many\", true)/good();",
+ "bad_quotes3"},
+ {"\ngood(true,false)\n/missing_separator1", "missing_separator1"},
+ {"\ngood(true,false)\n/missing_separator2()good()", "missing_separator2"},
+ {"\ngood(true,false)\n/bad_parens1(true/good();", "bad_parens1"},
+ {"\ngood(true,false)\n/bad_parens2(true/good());", "bad_parens2"},
+ {"\ngood(true,false)\n/bad_parens3)/good();", "bad_parens3"}
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ SCOPED_TRACE(cases[i].bad_operation_name);
+ scoped_ptr<JtlParser> parser(
+ CreateParserFromVerboseText(cases[i].source_code));
+ ExpectNextOperation(parser.get(), "good", "[true,false]", false);
+ ExpectNextOperationToFail(parser.get(), 2, cases[i].bad_operation_name);
+ }
+}
+
+} // namespace
« no previous file with comments | « 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