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