11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2013 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/tools/profile_reset/jtl_parser.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/json/json_writer.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/values.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gmock/include/gmock/gmock.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Helpers -------------------------------------------------------------------
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExpectNextOperation(JtlParser* parser,
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         const char* expected_name,
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         const char* expected_args_json,
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         bool expected_ends_sentence) {
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string actual_name;
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ListValue actual_args;
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string actual_args_json;
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool actual_ends_sentence;
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(parser->HasFinished());
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(parser->ParseNextOperation(
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &actual_name, &actual_args, &actual_ends_sentence));
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(expected_name, actual_name);
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::JSONWriter::Write(&actual_args, &actual_args_json);
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(expected_args_json, actual_args_json);
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(expected_ends_sentence, actual_ends_sentence);
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExpectNextOperationToFail(JtlParser* parser,
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               size_t expected_line_number,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               const char* expected_context_prefix) {
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string actual_name;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ListValue actual_args;
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool actual_ends_sentence;
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(parser->HasFinished());
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(parser->ParseNextOperation(
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &actual_name, &actual_args, &actual_ends_sentence));
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_THAT(parser->GetLastContext(),
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              testing::StartsWith(expected_context_prefix));
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(expected_line_number, parser->GetLastLineNumber());
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciJtlParser* CreateParserFromVerboseText(const std::string& verbose_text) {
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string compacted_source_code;
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<size_t> newline_indices;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(JtlParser::RemoveCommentsAndAllWhitespace(
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      verbose_text, &compacted_source_code, &newline_indices, NULL));
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return new JtlParser(compacted_source_code, newline_indices);
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests ---------------------------------------------------------------------
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, CompactingEmpty) {
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] = "";
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kCompactedSourceCode[] = "";
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, CompactingTrivial) {
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] = "foo";
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kCompactedSourceCode[] = "foo";
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, CompactingOneLine) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] = "  \r f\to o  ( true )   ";
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kCompactedSourceCode[] = "foo(true)";
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(kCompactedSourceCode) - 1; ++i) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message("Position ") << i);
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(0u, parser->GetOriginalLineNumber(i));
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, CompactingMultipleLines) {
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] = "a\nbb\n \nccc  \n\n  d( \n e \n )";
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kCompactedSourceCode[] = "abbcccd(e)";
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLineNumbers[] = {0u, 1u, 1u, 3u, 3u, 3u, 5u, 5u, 6u, 7u};
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 mismatched_test_data);
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message("Position ") << i);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, CompactingMultipleLinesWithComments) {
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] =
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "a/ /b//Comment \n"
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "//\n"
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "// Full line comment\n"
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      " cd //";
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kCompactedSourceCode[] = "a//bcd";
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kLineNumbers[] = {0u, 0u, 0u, 0u, 3u, 3u};
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  COMPILE_ASSERT(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 mismatched_test_data);
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message("Position ") << i);
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, HandlingCommentsAndStringLiterals) {
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* compacted_source_code;
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"//", ""},
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"//comment", ""},
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo // comment", "foo"},
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo // // comment", "foo"},
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo //", "foo"},
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\"", "\"literal\""},
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal with space\"", "\"literal with space\""},
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"", "\"\""},
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\"\"", "\"\"\"\""},
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\" // comment", "\"\""},
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\" // comment", "\"literal\""},
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\" \"literal\" // comment", "\"literal\"\"literal\""},
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo // \"not a literal\"", "foo"},
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo // \"not even matched", "foo"},
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo // \"not a literal\" \"not even matched", "foo"},
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\" // \"not a literal\"", "\"literal\""},
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\" // \"not even matched", "\"literal\""},
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"//not a comment//\"", "\"//not a comment//\""},
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"//not a comment//\" // comment", "\"//not a comment//\""},
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"// \"//not a literal//\" // comment", ""},
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal\" // \"//not a literal//\" // comment", "\"literal\""},
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"//not a comment//\" // \"//not a literal//\" // comment",
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "\"//not a comment//\""},
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal // \"not a literal nor a comment",
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "\"literal // \"notaliteralnoracomment"},
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"literal // \"not a literal nor a comment//\"",
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "\"literal // \"notaliteralnoracomment"}
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].source_code);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<JtlParser> parser(
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateParserFromVerboseText(cases[i].source_code));
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(cases[i].compacted_source_code, parser->compacted_source());
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, MismatchedDoubleQuotesBeforeEndOfLine) {
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t error_line_number;
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"", 0},
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"mismatched literal", 0},
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\n\"", 1},
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\n\"", 0},
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\"", 0},
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\n\"", 1},
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\n\"\n\"", 1},
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\" // not a comment", 0},
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\" // not a comment\n\"", 0},
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\" // comment\n\"", 1},
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\" // not a comment\n\"", 0},
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\"\" // \" neither a literal nor a comment\"\n\"", 0},
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\"\" // comment\n\"// not a comment", 1},
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\" // not a comment\"\n\"// not a comment", 1},
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo(\"bar\");\nfoo(\"mismatched);", 1},
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo(\n\"bar\", \"mismatched);", 1},
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo(\n\"bar\", \"mismatched); //comment", 1},
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo(\n\"bar\", \"mismatched);\ngood(\"bar\")", 1}
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].source_code);
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string compacted_source_code;
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<size_t> newline_indices;
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t error_line_number;
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_FALSE(JtlParser::RemoveCommentsAndAllWhitespace(
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].source_code,
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &compacted_source_code,
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &newline_indices,
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &error_line_number));
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(cases[i].error_line_number, error_line_number);
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, ParsingEmpty) {
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] = "";
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(parser->HasFinished());
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, ParsingOneWellFormedOperation) {
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* expected_name;
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* expected_args;
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const bool expected_ends_sentence;
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo1;", "foo1", "[]", true},
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo2().", "foo2", "[]", false},
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo3(true);", "foo3", "[true]", true},
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo4(false).", "foo4", "[false]", false},
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo5(\"bar\").", "foo5", "[\"bar\"]", false},
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo6(\" b a r \").", "foo6", "[\" b a r \"]", false},
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo7(true, \"bar\").", "foo7", "[true,\"bar\"]", false},
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo8(\"bar\", false, true);", "foo8", "[\"bar\",false,true]", true},
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"foo9(\"bar\", \" b a r \");", "foo9", "[\"bar\",\" b a r \"]", true}
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].expected_name);
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<JtlParser> parser(
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateParserFromVerboseText(cases[i].source_code));
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperation(parser.get(),
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_name,
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_args,
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_ends_sentence);
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(parser->HasFinished());
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, ParsingMultipleWellFormedOperations) {
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kSourceCode[] =
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "foo1(true).foo2.foo3(\"bar\");"
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "foo4(\"bar\", false);";
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectNextOperation(parser.get(), "foo1", "[true]", false);
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectNextOperation(parser.get(), "foo2", "[]", false);
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectNextOperation(parser.get(), "foo3", "[\"bar\"]", true);
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectNextOperation(parser.get(), "foo4", "[\"bar\",false]", true);
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(parser->HasFinished());
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, ParsingTrickyStringLiterals) {
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* expected_name;
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* expected_args;
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const bool expected_ends_sentence;
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo1(\"\");next(true);", "foo1", "[\"\"]", true},
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo2(\" \");next(true);", "foo2", "[\" \"]", true},
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo3(\",\",true);next(true);", "foo3", "[\",\",true]", true},
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo4(\")\",true);next(true);", "foo4", "[\")\",true]", true},
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo5(\";\",true);next(true);", "foo5", "[\";\",true]", true},
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo6(\"/\",true).next(true);", "foo6", "[\"/\",true]", false},
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo7(\"//\",true).next(true);", "foo7", "[\"//\",true]", false},
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"prev().foo8(\".\",true).next(true);", "foo8", "[\".\",true]", false},
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].expected_name);
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<JtlParser> parser(
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateParserFromVerboseText(cases[i].source_code));
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperation(parser.get(), "prev", "[]", false);
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperation(parser.get(),
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_name,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_args,
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        cases[i].expected_ends_sentence);
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperation(parser.get(), "next", "[true]", true);
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(parser->HasFinished());
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, FirstOperationIsIllFormed) {
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* operation_name;
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {";;", ";"},
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args1(not a boolean value);", "bad_args1"},
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args2(,);", "bad_args2"},
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args3(...);", "bad_args3"},
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args4(1);", "bad_args4"},
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args5(1.2);", "bad_args5"},
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args6([\"bar\"]);", "bad_args6"},
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args7(False);", "bad_args7"},
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_args8(True);", "bad_args8"},
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_quotes1(missing both, true).good();", "bad_quotes1"},
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_quotes2(true, \"missing one).good(); //\"", "bad_quotes2"},
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_quotes3(\"too\" \"much\", true).good();", "bad_quotes3"},
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_missing_separator1", "bad_missing_separator1"},
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_missing_separator2()good();", "bad_missing_separator2"},
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_parenthesis1(true.good();", "bad_parenthesis1"},
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_parenthesis2(true.good());", "bad_parenthesis2"},
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"bad_parenthesis3).good();", "bad_parenthesis3"}
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].operation_name);
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<JtlParser> parser(
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateParserFromVerboseText(cases[i].source_code));
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperationToFail(parser.get(), 0, cases[i].operation_name);
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlParser, SecondOperationIsIllFormed) {
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* source_code;
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* bad_operation_name;
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_args(,);", "bad_args"},
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_quotes1(missing both, true).good();",
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "bad_quotes1"},
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_quotes2(\"missing one, true).good(); //\"",
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "bad_quotes2"},
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_quotes3(\"too\" \"many\", true).good();",
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "bad_quotes3"},
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_separator1()/good();", "bad_separator1"},
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.missing_separator1", "missing_separator1"},
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.missing_separator2()good();",
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       "missing_separator2"},
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_parens1(true.good();", "bad_parens1"},
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_parens2(true.good());", "bad_parens2"},
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      {"\ngood(true,false)\n.bad_parens3).good();", "bad_parens3"}
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(cases[i].bad_operation_name);
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<JtlParser> parser(
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateParserFromVerboseText(cases[i].source_code));
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperation(parser.get(), "good", "[true,false]", false);
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectNextOperationToFail(parser.get(), 2, cases[i].bad_operation_name);
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
347