1cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===- unittest/Tooling/CompilationDatabaseTest.cpp -----------------------===//
2cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//
3cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//                     The LLVM Compiler Infrastructure
4cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//
5cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// This file is distributed under the University of Illinois Open Source
6cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// License. See LICENSE.TXT for details.
7cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//
8cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===----------------------------------------------------------------------===//
9cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
10cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/ASTConsumer.h"
11cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/DeclCXX.h"
12cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/DeclGroup.h"
13cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Frontend/FrontendAction.h"
14d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper#include "clang/Tooling/FileMatchTrie.h"
157fd90b03a28df0626fdb44d05be9ddcdb2562686Daniel Jasper#include "clang/Tooling/JSONCompilationDatabase.h"
16cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Tooling/Tooling.h"
178229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include "llvm/Support/Path.h"
18cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "gtest/gtest.h"
19cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
20cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace clang {
21cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace tooling {
22cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
231a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimekstatic void expectFailure(StringRef JSONDatabase, StringRef Explanation) {
241a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  std::string ErrorMessage;
25ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  EXPECT_EQ(nullptr, JSONCompilationDatabase::loadFromBuffer(JSONDatabase,
26ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                                             ErrorMessage))
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    << "Expected an error because of: " << Explanation.str();
281a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek}
291a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek
301a8d6861278051b2109c98baf6a7478a6f3f98aaManuel KlimekTEST(JSONCompilationDatabase, ErrsOnInvalidFormat) {
311a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("", "Empty database");
321a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("{", "Invalid JSON");
331a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[[]]", "Array instead of object");
341a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{\"a\":[]}]", "Array instead of value");
351a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{\"a\":\"b\"}]", "Unknown key");
361a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{[]:\"\"}]", "Incorrectly typed entry");
371a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{}]", "Empty entry");
381a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{\"directory\":\"\",\"command\":\"\"}]", "Missing file");
391a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{\"directory\":\"\",\"file\":\"\"}]", "Missing command");
401a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek  expectFailure("[{\"command\":\"\",\"file\":\"\"}]", "Missing directory");
411a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek}
421a8d6861278051b2109c98baf6a7478a6f3f98aaManuel Klimek
43a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimekstatic std::vector<std::string> getAllFiles(StringRef JSONDatabase,
44a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek                                            std::string &ErrorMessage) {
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<CompilationDatabase> Database(
46a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek      JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
47a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  if (!Database) {
48a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek    ADD_FAILURE() << ErrorMessage;
49a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek    return std::vector<std::string>();
50a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  }
51a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  return Database->getAllFiles();
52a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek}
53a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek
547e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidisstatic std::vector<CompileCommand> getAllCompileCommands(StringRef JSONDatabase,
557e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis                                                    std::string &ErrorMessage) {
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<CompilationDatabase> Database(
577e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis      JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
587e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  if (!Database) {
597e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis    ADD_FAILURE() << ErrorMessage;
607e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis    return std::vector<CompileCommand>();
617e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  }
627e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  return Database->getAllCompileCommands();
637e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis}
647e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
65a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel KlimekTEST(JSONCompilationDatabase, GetAllFiles) {
66a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  std::string ErrorMessage;
67a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  EXPECT_EQ(std::vector<std::string>(),
68a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek            getAllFiles("[]", ErrorMessage)) << ErrorMessage;
69a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek
70a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  std::vector<std::string> expected_files;
713201da38bdd7cea1d05700858d2af94287044887Daniel Jasper  SmallString<16> PathStorage;
723201da38bdd7cea1d05700858d2af94287044887Daniel Jasper  llvm::sys::path::native("//net/dir/file1", PathStorage);
733201da38bdd7cea1d05700858d2af94287044887Daniel Jasper  expected_files.push_back(PathStorage.str());
743201da38bdd7cea1d05700858d2af94287044887Daniel Jasper  llvm::sys::path::native("//net/dir/file2", PathStorage);
753201da38bdd7cea1d05700858d2af94287044887Daniel Jasper  expected_files.push_back(PathStorage.str());
76a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  EXPECT_EQ(expected_files, getAllFiles(
778a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper    "[{\"directory\":\"//net/dir\","
78a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek      "\"command\":\"command\","
79a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek      "\"file\":\"file1\"},"
808a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper    " {\"directory\":\"//net/dir\","
81a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek      "\"command\":\"command\","
82a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek      "\"file\":\"file2\"}]",
83a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek    ErrorMessage)) << ErrorMessage;
84a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek}
85a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek
867e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios KyrtzidisTEST(JSONCompilationDatabase, GetAllCompileCommands) {
877e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  std::string ErrorMessage;
887e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(0u,
897e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis            getAllCompileCommands("[]", ErrorMessage).size()) << ErrorMessage;
907e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
917e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef Directory1("//net/dir1");
927e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef FileName1("file1");
937e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef Command1("command1");
947e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef Directory2("//net/dir2");
957e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef FileName2("file1");
967e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  StringRef Command2("command1");
977e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
987e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  std::vector<CompileCommand> Commands = getAllCompileCommands(
997e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis      ("[{\"directory\":\"" + Directory1 + "\"," +
1007e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis             "\"command\":\"" + Command1 + "\","
1017e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis             "\"file\":\"" + FileName1 + "\"},"
1027e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis       " {\"directory\":\"" + Directory2 + "\"," +
1037e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis             "\"command\":\"" + Command2 + "\","
1047e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis             "\"file\":\"" + FileName2 + "\"}]").str(),
1057e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis      ErrorMessage);
1067e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(2U, Commands.size()) << ErrorMessage;
1077e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(Directory1, Commands[0].Directory) << ErrorMessage;
1087e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  ASSERT_EQ(1u, Commands[0].CommandLine.size());
1097e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(Command1, Commands[0].CommandLine[0]) << ErrorMessage;
1107e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(Directory2, Commands[1].Directory) << ErrorMessage;
1117e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  ASSERT_EQ(1u, Commands[1].CommandLine.size());
1127e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(Command2, Commands[1].CommandLine[0]) << ErrorMessage;
1137e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis}
1147e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
115cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstatic CompileCommand findCompileArgsInJsonDatabase(StringRef FileName,
116cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                                    StringRef JSONDatabase,
117cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                                    std::string &ErrorMessage) {
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<CompilationDatabase> Database(
119cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
120cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (!Database)
121cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return CompileCommand();
122cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<CompileCommand> Commands = Database->getCompileCommands(FileName);
123cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_LE(Commands.size(), 1u);
124cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (Commands.empty())
125cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return CompileCommand();
126cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return Commands[0];
127cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
128cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
129d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasperstruct FakeComparator : public PathComparator {
130d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  virtual ~FakeComparator() {}
1312dbe2fa7eb3ccf8eabae884a177b4570d3fb260dDaniel Jasper  virtual bool equivalent(StringRef FileA, StringRef FileB) const {
1322dbe2fa7eb3ccf8eabae884a177b4570d3fb260dDaniel Jasper    return FileA.equals_lower(FileB);
133d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  }
134d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper};
135d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
136d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasperclass FileMatchTrieTest : public ::testing::Test {
137d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasperprotected:
138d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  FileMatchTrieTest() : Trie(new FakeComparator()) {}
139d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
140d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  StringRef find(StringRef Path) {
141d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper    llvm::raw_string_ostream ES(Error);
142d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper    return Trie.findEquivalent(Path, ES);
143d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  }
144d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
145d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  FileMatchTrie Trie;
146d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  std::string Error;
147d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper};
148d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
149d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, InsertingRelativePath) {
1508a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/path/file.cc");
151d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  Trie.insert("file.cc");
1528a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/path/file.cc", find("//net/path/file.cc"));
153d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
154d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
155d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, MatchingRelativePath) {
156d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  EXPECT_EQ("", find("file.cc"));
157d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
158d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
159d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, ReturnsBestResults) {
1608a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/d/c/b.cc");
1618a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/d/b/b.cc");
1628a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/d/b/b.cc", find("//net/d/b/b.cc"));
163d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
164d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
165d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, HandlesSymlinks) {
1668a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/AA/file.cc");
1678a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/AA/file.cc", find("//net/aa/file.cc"));
168d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
169d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
170d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, ReportsSymlinkAmbiguity) {
1718a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/Aa/file.cc");
1728a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/aA/file.cc");
1738a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_TRUE(find("//net/aa/file.cc").empty());
174d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  EXPECT_EQ("Path is ambiguous", Error);
175d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
176d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
177d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, LongerMatchingSuffixPreferred) {
1788a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/src/Aa/file.cc");
1798a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/src/aA/file.cc");
1808a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/SRC/aa/file.cc");
1818a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/SRC/aa/file.cc", find("//net/src/aa/file.cc"));
182d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
183d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
184d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, EmptyTrie) {
1858a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_TRUE(find("//net/some/path").empty());
186d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
187d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
188d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, NoResult) {
1898a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/somepath/otherfile.cc");
1908a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/otherpath/somefile.cc");
1918a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("", find("//net/somepath/somefile.cc"));
192d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
193d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
194d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, RootElementDifferent) {
1958a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/path/file.cc");
1968a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  Trie.insert("//net/otherpath/file.cc");
1978a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/path/file.cc", find("//net/path/file.cc"));
198d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
199d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
200d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel JasperTEST_F(FileMatchTrieTest, CannotResolveRelativePath) {
201d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  EXPECT_EQ("", find("relative-path.cc"));
202d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper  EXPECT_EQ("Cannot resolve relative paths", Error);
203d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper}
204d3420c906e3605d94c084e8b8b1f3fa490093c86Daniel Jasper
205cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(findCompileArgsInJsonDatabase, FindsNothingIfEmpty) {
206cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
207cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand NotFound = findCompileArgsInJsonDatabase(
208cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    "a-file.cpp", "", ErrorMessage);
209cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
210cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
211cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
212cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
213cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(findCompileArgsInJsonDatabase, ReadsSingleEntry) {
2148a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Directory("//net/some/directory");
2158a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef FileName("//net/path/to/a-file.cpp");
2168a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Command("//net/path/to/compiler and some arguments");
217cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
218cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
219cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    FileName,
220cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ("[{\"directory\":\"" + Directory + "\"," +
221cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"command\":\"" + Command + "\","
222cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"file\":\"" + FileName + "\"}]").str(),
223cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage);
224cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
225cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(4u, FoundCommand.CommandLine.size()) << ErrorMessage;
2268a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/path/to/compiler",
2278a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper            FoundCommand.CommandLine[0]) << ErrorMessage;
228cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("and", FoundCommand.CommandLine[1]) << ErrorMessage;
229cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("some", FoundCommand.CommandLine[2]) << ErrorMessage;
230cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("arguments", FoundCommand.CommandLine[3]) << ErrorMessage;
231cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
232cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand NotFound = findCompileArgsInJsonDatabase(
233cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    "a-file.cpp",
234cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ("[{\"directory\":\"" + Directory + "\"," +
235cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"command\":\"" + Command + "\","
236cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"file\":\"" + FileName + "\"}]").str(),
237cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage);
238cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
239cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
240cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
241cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
242cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(findCompileArgsInJsonDatabase, ReadsCompileCommandLinesWithSpaces) {
2438a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Directory("//net/some/directory");
2448a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef FileName("//net/path/to/a-file.cpp");
2458a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Command("\\\"//net/path to compiler\\\" \\\"and an argument\\\"");
246cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
247cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
248cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    FileName,
249cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ("[{\"directory\":\"" + Directory + "\"," +
250cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"command\":\"" + Command + "\","
251cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"file\":\"" + FileName + "\"}]").str(),
252cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage);
253cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(2u, FoundCommand.CommandLine.size());
2548a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/path to compiler",
2558a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper            FoundCommand.CommandLine[0]) << ErrorMessage;
256cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("and an argument", FoundCommand.CommandLine[1]) << ErrorMessage;
257cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
258cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
259cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(findCompileArgsInJsonDatabase, ReadsDirectoryWithSpaces) {
2608a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Directory("//net/some directory / with spaces");
2618a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef FileName("//net/path/to/a-file.cpp");
262cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  StringRef Command("a command");
263cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
264cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
265cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    FileName,
266cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ("[{\"directory\":\"" + Directory + "\"," +
267cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"command\":\"" + Command + "\","
268cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       "\"file\":\"" + FileName + "\"}]").str(),
269cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage);
270cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
271cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
272cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
273cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(findCompileArgsInJsonDatabase, FindsEntry) {
2748a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  StringRef Directory("//net/directory");
275cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  StringRef FileName("file");
276cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  StringRef Command("command");
277cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string JsonDatabase = "[";
278cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  for (int I = 0; I < 10; ++I) {
279cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    if (I > 0) JsonDatabase += ",";
280cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    JsonDatabase +=
281cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      ("{\"directory\":\"" + Directory + Twine(I) + "\"," +
282cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        "\"command\":\"" + Command + Twine(I) + "\","
283cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        "\"file\":\"" + FileName + Twine(I) + "\"}").str();
284cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
285cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  JsonDatabase += "]";
286cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
287cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
2888a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper    "//net/directory4/file4", JsonDatabase, ErrorMessage);
2898a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper  EXPECT_EQ("//net/directory4", FoundCommand.Directory) << ErrorMessage;
290cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1u, FoundCommand.CommandLine.size()) << ErrorMessage;
291cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("command4", FoundCommand.CommandLine[0]) << ErrorMessage;
292cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
293cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
294cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstatic std::vector<std::string> unescapeJsonCommandLine(StringRef Command) {
295cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string JsonDatabase =
2968a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper    ("[{\"directory\":\"//net/root\", \"file\":\"test\", \"command\": \"" +
297cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek     Command + "\"}]").str();
298cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::string ErrorMessage;
299cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
3008a5e8c35e1beced2f098a775648e8648294967d2Daniel Jasper    "//net/root/test", JsonDatabase, ErrorMessage);
301cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(ErrorMessage.empty()) << ErrorMessage;
302cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return FoundCommand.CommandLine;
303cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
304cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
305cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, ReturnsEmptyArrayOnEmptyString) {
306cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine("");
307cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(Result.empty());
308cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
309cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
310cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, SplitsOnSpaces) {
311cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine("a b c");
312cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(3ul, Result.size());
313cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("a", Result[0]);
314cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("b", Result[1]);
315cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("c", Result[2]);
316cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
317cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
318cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, MungesMultipleSpaces) {
319cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine("   a   b   ");
320cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(2ul, Result.size());
321cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("a", Result[0]);
322cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("b", Result[1]);
323cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
324cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
325cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, UnescapesBackslashCharacters) {
326cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Backslash = unescapeJsonCommandLine("a\\\\\\\\");
327cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Backslash.size());
328cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("a\\", Backslash[0]);
329cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Quote = unescapeJsonCommandLine("a\\\\\\\"");
330cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Quote.size());
331cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("a\"", Quote[0]);
332cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
333cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
334cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, DoesNotMungeSpacesBetweenQuotes) {
335cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine("\\\"  a  b  \\\"");
336cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Result.size());
337cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("  a  b  ", Result[0]);
338cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
339cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
340cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, AllowsMultipleQuotedArguments) {
341cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine(
342cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "  \\\" a \\\"  \\\" b \\\"  ");
343cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(2ul, Result.size());
344cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ(" a ", Result[0]);
345cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ(" b ", Result[1]);
346cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
347cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
348cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, AllowsEmptyArgumentsInQuotes) {
349cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine(
350cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "\\\"\\\"\\\"\\\"");
351cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Result.size());
352cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_TRUE(Result[0].empty()) << Result[0];
353cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
354cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
355cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, ParsesEscapedQuotesInQuotedStrings) {
356cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine(
357cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "\\\"\\\\\\\"\\\"");
358cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Result.size());
359cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("\"", Result[0]);
360cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
361cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
362cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, ParsesMultipleArgumentsWithEscapedCharacters) {
363cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Result = unescapeJsonCommandLine(
364cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "  \\\\\\\"  \\\"a \\\\\\\" b \\\"     \\\"and\\\\\\\\c\\\"   \\\\\\\"");
365cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(4ul, Result.size());
366cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("\"", Result[0]);
367cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("a \" b ", Result[1]);
368cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("and\\c", Result[2]);
369cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("\"", Result[3]);
370cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
371cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
372cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, ParsesStringsWithoutSpacesIntoSingleArgument) {
373cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> QuotedNoSpaces = unescapeJsonCommandLine(
374cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "\\\"a\\\"\\\"b\\\"");
375cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, QuotedNoSpaces.size());
376cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("ab", QuotedNoSpaces[0]);
377cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
378cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> MixedNoSpaces = unescapeJsonCommandLine(
379cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      "\\\"a\\\"bcd\\\"ef\\\"\\\"\\\"\\\"g\\\"");
380cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, MixedNoSpaces.size());
381cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("abcdefg", MixedNoSpaces[0]);
382cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
383cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
384cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(unescapeJsonCommandLine, ParsesQuotedStringWithoutClosingQuote) {
385cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Unclosed = unescapeJsonCommandLine("\\\"abc");
386cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Unclosed.size());
387cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("abc", Unclosed[0]);
388cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
389cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> Empty = unescapeJsonCommandLine("\\\"");
390cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  ASSERT_EQ(1ul, Empty.size());
391cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  EXPECT_EQ("", Empty[0]);
392cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
393cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
394b88d9480e04039188c39e49367cb13d64e644cf8Peter CollingbourneTEST(unescapeJsonCommandLine, ParsesSingleQuotedString) {
395b88d9480e04039188c39e49367cb13d64e644cf8Peter Collingbourne  std::vector<std::string> Args = unescapeJsonCommandLine("a'\\\\b \\\"c\\\"'");
396b88d9480e04039188c39e49367cb13d64e644cf8Peter Collingbourne  ASSERT_EQ(1ul, Args.size());
397b88d9480e04039188c39e49367cb13d64e644cf8Peter Collingbourne  EXPECT_EQ("a\\b \"c\"", Args[0]);
398b88d9480e04039188c39e49367cb13d64e644cf8Peter Collingbourne}
399b88d9480e04039188c39e49367cb13d64e644cf8Peter Collingbourne
40030318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekTEST(FixedCompilationDatabase, ReturnsFixedCommandLine) {
40130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<std::string> CommandLine;
40230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("one");
40330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("two");
40430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  FixedCompilationDatabase Database(".", CommandLine);
40530318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<CompileCommand> Result =
40630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek    Database.getCompileCommands("source");
40730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(1ul, Result.size());
40830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<std::string> ExpectedCommandLine(1, "clang-tool");
40930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ExpectedCommandLine.insert(ExpectedCommandLine.end(),
41030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek                             CommandLine.begin(), CommandLine.end());
41130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ExpectedCommandLine.push_back("source");
41230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(".", Result[0].Directory);
41330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(ExpectedCommandLine, Result[0].CommandLine);
41430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek}
41530318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek
416a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel KlimekTEST(FixedCompilationDatabase, GetAllFiles) {
417a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  std::vector<std::string> CommandLine;
418a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  CommandLine.push_back("one");
419a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  CommandLine.push_back("two");
420a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  FixedCompilationDatabase Database(".", CommandLine);
421a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek
422a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek  EXPECT_EQ(0ul, Database.getAllFiles().size());
423a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek}
424a3c70966babdd6c63623470fbba9bb4ec37de4a5Manuel Klimek
4257e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios KyrtzidisTEST(FixedCompilationDatabase, GetAllCompileCommands) {
4267e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  std::vector<std::string> CommandLine;
4277e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  CommandLine.push_back("one");
4287e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  CommandLine.push_back("two");
4297e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  FixedCompilationDatabase Database(".", CommandLine);
4307e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
4317e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis  EXPECT_EQ(0ul, Database.getAllCompileCommands().size());
4327e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis}
4337e96bfb4d507700a122f270a11ce3fc0e8e36c85Argyrios Kyrtzidis
43430318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekTEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
43530318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  int Argc = 0;
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
437ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr));
43830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_FALSE(Database);
43930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(0, Argc);
44030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek}
44130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek
44230318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekTEST(ParseFixedCompilationDatabase, ReturnsNullWithoutDoubleDash) {
44330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  int Argc = 2;
44430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  const char *Argv[] = { "1", "2" };
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
44630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek      FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
44730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_FALSE(Database);
44830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(2, Argc);
44930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek}
45030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek
45130318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekTEST(ParseFixedCompilationDatabase, ReturnsArgumentsAfterDoubleDash) {
45230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  int Argc = 5;
453c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  const char *Argv[] = {
454c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane    "1", "2", "--\0no-constant-folding", "-DDEF3", "-DDEF4"
455c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  };
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
45730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek      FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE((bool)Database);
45930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<CompileCommand> Result =
46030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek    Database->getCompileCommands("source");
46130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(1ul, Result.size());
46230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(".", Result[0].Directory);
46330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<std::string> CommandLine;
46430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("clang-tool");
465c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  CommandLine.push_back("-DDEF3");
466c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  CommandLine.push_back("-DDEF4");
46730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("source");
46830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(CommandLine, Result[0].CommandLine);
46930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(2, Argc);
47030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek}
47130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek
47230318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekTEST(ParseFixedCompilationDatabase, ReturnsEmptyCommandLine) {
47330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  int Argc = 3;
47430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  const char *Argv[] = { "1", "2", "--\0no-constant-folding" };
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
47630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek      FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE((bool)Database);
47830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<CompileCommand> Result =
47930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek    Database->getCompileCommands("source");
48030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(1ul, Result.size());
48130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(".", Result[0].Directory);
48230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  std::vector<std::string> CommandLine;
48330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("clang-tool");
48430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  CommandLine.push_back("source");
48530318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  ASSERT_EQ(CommandLine, Result[0].CommandLine);
48630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek  EXPECT_EQ(2, Argc);
48730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek}
48830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek
489c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin VaneTEST(ParseFixedCompilationDatabase, HandlesPositionalArgs) {
490c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  const char *Argv[] = {"1", "2", "--", "-c", "somefile.cpp", "-DDEF3"};
491c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  int Argc = sizeof(Argv) / sizeof(char*);
492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
493c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane      FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE((bool)Database);
495c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  std::vector<CompileCommand> Result =
496c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane    Database->getCompileCommands("source");
497c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(1ul, Result.size());
498c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(".", Result[0].Directory);
499c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  std::vector<std::string> Expected;
500c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("clang-tool");
501c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("-c");
502c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("-DDEF3");
503c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("source");
504c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(Expected, Result[0].CommandLine);
505c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  EXPECT_EQ(2, Argc);
506c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane}
507c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane
508c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin VaneTEST(ParseFixedCompilationDatabase, HandlesArgv0) {
509c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  const char *Argv[] = {"1", "2", "--", "mytool", "somefile.cpp"};
510c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  int Argc = sizeof(Argv) / sizeof(char*);
511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FixedCompilationDatabase> Database(
512c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane      FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE((bool)Database);
514c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  std::vector<CompileCommand> Result =
515c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane    Database->getCompileCommands("source");
516c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(1ul, Result.size());
517c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(".", Result[0].Directory);
518c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  std::vector<std::string> Expected;
519c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("clang-tool");
520c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  Expected.push_back("source");
521c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  ASSERT_EQ(Expected, Result[0].CommandLine);
522c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane  EXPECT_EQ(2, Argc);
523c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane}
524c8f03423e23d4e093d8149fd924e6fef26a15e94Edwin Vane
525cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace tooling
526cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace clang
527