refactor: simplify CompilationDatabase, extract ArgumentParser, remove pimpl (#371)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#include "test/test.h"
|
||||
#include "command/toolchain_provider.h"
|
||||
#include "command/command.h"
|
||||
|
||||
namespace clice::testing {
|
||||
|
||||
@@ -8,25 +8,25 @@ namespace {
|
||||
TEST_SUITE(ToolchainProvider) {
|
||||
|
||||
TEST_CASE(InitiallyEmpty) {
|
||||
ToolchainProvider provider;
|
||||
EXPECT_FALSE(provider.has_cached_entries());
|
||||
CompilationDatabase cdb;
|
||||
EXPECT_FALSE(cdb.has_cached_toolchain());
|
||||
}
|
||||
|
||||
TEST_CASE(InjectResultsPopulatesCache) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
std::vector<ToolchainResult> results;
|
||||
results.push_back({
|
||||
"key1",
|
||||
{"-cc1", "-triple", "x86_64-linux-gnu"}
|
||||
});
|
||||
provider.inject_results(results);
|
||||
cdb.inject_results(results);
|
||||
|
||||
EXPECT_TRUE(provider.has_cached_entries());
|
||||
EXPECT_TRUE(cdb.has_cached_toolchain());
|
||||
}
|
||||
|
||||
TEST_CASE(InjectResultsSkipsDuplicateKeys) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
std::vector<ToolchainResult> results;
|
||||
results.push_back({
|
||||
@@ -37,141 +37,140 @@ TEST_CASE(InjectResultsSkipsDuplicateKeys) {
|
||||
"key1",
|
||||
{"-cc1", "-triple", "aarch64"}
|
||||
});
|
||||
provider.inject_results(results);
|
||||
cdb.inject_results(results);
|
||||
|
||||
// After injection, query_cached with same key should return the first result.
|
||||
// We verify indirectly: inject twice, cache should still work.
|
||||
EXPECT_TRUE(provider.has_cached_entries());
|
||||
// After injection, cache should still work.
|
||||
EXPECT_TRUE(cdb.has_cached_toolchain());
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesReturnsUncachedOnly) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
// Two entries with same flags but different user-content options.
|
||||
// They share the same cache key, so only one query is needed.
|
||||
ToolchainProvider::PendingEntry entry1;
|
||||
CompilationDatabase::PendingEntry entry1;
|
||||
entry1.file = "a.cpp";
|
||||
entry1.directory = "/tmp";
|
||||
entry1.arguments = {"clang++", "-std=c++17", "-DFOO", "a.cpp"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry2;
|
||||
CompilationDatabase::PendingEntry entry2;
|
||||
entry2.file = "b.cpp";
|
||||
entry2.directory = "/tmp";
|
||||
entry2.arguments = {"clang++", "-std=c++17", "-DBAR", "b.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry1, entry2});
|
||||
auto queries = cdb.get_pending_queries({entry1, entry2});
|
||||
// Same driver, same extension, same non-content flags → one query.
|
||||
EXPECT_EQ(queries.size(), 1u);
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesDeduplicatesSameKey) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
// Three entries with same driver and same flags (only -I/-D differ,
|
||||
// which are user-content options excluded from the cache key).
|
||||
ToolchainProvider::PendingEntry entry1;
|
||||
CompilationDatabase::PendingEntry entry1;
|
||||
entry1.file = "x.cpp";
|
||||
entry1.directory = "/project";
|
||||
entry1.arguments = {"clang++", "-Wall", "-O2", "-DFOO=1", "-I/inc/a", "x.cpp"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry2;
|
||||
CompilationDatabase::PendingEntry entry2;
|
||||
entry2.file = "y.cpp";
|
||||
entry2.directory = "/project";
|
||||
entry2.arguments = {"clang++", "-Wall", "-O2", "-DBAR=2", "-I/inc/b", "y.cpp"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry3;
|
||||
CompilationDatabase::PendingEntry entry3;
|
||||
entry3.file = "z.cpp";
|
||||
entry3.directory = "/project";
|
||||
entry3.arguments = {"clang++", "-Wall", "-O2", "-Uhello", "z.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry1, entry2, entry3});
|
||||
auto queries = cdb.get_pending_queries({entry1, entry2, entry3});
|
||||
// Same driver, same extension, same non-content flags → same key.
|
||||
EXPECT_EQ(queries.size(), 1u);
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesDifferentDrivers) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
ToolchainProvider::PendingEntry entry1;
|
||||
CompilationDatabase::PendingEntry entry1;
|
||||
entry1.file = "a.cpp";
|
||||
entry1.directory = "/tmp";
|
||||
entry1.arguments = {"clang++", "a.cpp"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry2;
|
||||
CompilationDatabase::PendingEntry entry2;
|
||||
entry2.file = "b.cpp";
|
||||
entry2.directory = "/tmp";
|
||||
entry2.arguments = {"g++", "b.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry1, entry2});
|
||||
auto queries = cdb.get_pending_queries({entry1, entry2});
|
||||
// Different drivers → different keys → two queries.
|
||||
EXPECT_EQ(queries.size(), 2u);
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesDifferentTargets) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
ToolchainProvider::PendingEntry entry1;
|
||||
CompilationDatabase::PendingEntry entry1;
|
||||
entry1.file = "a.cpp";
|
||||
entry1.directory = "/tmp";
|
||||
entry1.arguments = {"clang++", "--target=x86_64-linux-gnu", "a.cpp"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry2;
|
||||
CompilationDatabase::PendingEntry entry2;
|
||||
entry2.file = "b.cpp";
|
||||
entry2.directory = "/tmp";
|
||||
entry2.arguments = {"clang++", "--target=aarch64-linux-gnu", "b.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry1, entry2});
|
||||
auto queries = cdb.get_pending_queries({entry1, entry2});
|
||||
// Different targets → different keys → two queries.
|
||||
EXPECT_EQ(queries.size(), 2u);
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesDifferentLanguageMode) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
// clang foo.h (default: c-header) vs clang -x c++ foo.h (c++)
|
||||
// produce different system include paths, so they must have different keys.
|
||||
ToolchainProvider::PendingEntry entry1;
|
||||
CompilationDatabase::PendingEntry entry1;
|
||||
entry1.file = "foo.h";
|
||||
entry1.directory = "/tmp";
|
||||
entry1.arguments = {"clang", "foo.h"};
|
||||
|
||||
ToolchainProvider::PendingEntry entry2;
|
||||
CompilationDatabase::PendingEntry entry2;
|
||||
entry2.file = "foo.h";
|
||||
entry2.directory = "/tmp";
|
||||
entry2.arguments = {"clang", "-x", "c++", "foo.h"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry1, entry2});
|
||||
auto queries = cdb.get_pending_queries({entry1, entry2});
|
||||
// -x c++ changes language mode → different keys → two queries.
|
||||
EXPECT_EQ(queries.size(), 2u);
|
||||
}
|
||||
|
||||
TEST_CASE(GetPendingQueriesSkipsEmptyArgs) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
ToolchainProvider::PendingEntry empty;
|
||||
CompilationDatabase::PendingEntry empty;
|
||||
empty.file = "empty.cpp";
|
||||
empty.directory = "/tmp";
|
||||
// arguments is empty
|
||||
|
||||
ToolchainProvider::PendingEntry valid;
|
||||
CompilationDatabase::PendingEntry valid;
|
||||
valid.file = "valid.cpp";
|
||||
valid.directory = "/tmp";
|
||||
valid.arguments = {"clang++", "valid.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({empty, valid});
|
||||
auto queries = cdb.get_pending_queries({empty, valid});
|
||||
EXPECT_EQ(queries.size(), 1u);
|
||||
}
|
||||
|
||||
TEST_CASE(InjectThenGetPendingSkipsCached) {
|
||||
ToolchainProvider provider;
|
||||
CompilationDatabase cdb;
|
||||
|
||||
// First, get pending queries to learn what key is generated.
|
||||
ToolchainProvider::PendingEntry entry;
|
||||
CompilationDatabase::PendingEntry entry;
|
||||
entry.file = "test.cpp";
|
||||
entry.directory = "/tmp";
|
||||
entry.arguments = {"clang++", "test.cpp"};
|
||||
|
||||
auto queries = provider.get_pending_queries({entry});
|
||||
auto queries = cdb.get_pending_queries({entry});
|
||||
ASSERT_EQ(queries.size(), 1u);
|
||||
|
||||
// Inject a result for that key.
|
||||
@@ -180,23 +179,13 @@ TEST_CASE(InjectThenGetPendingSkipsCached) {
|
||||
queries[0].key,
|
||||
{"-cc1", "-triple", "x86_64-linux-gnu"}
|
||||
});
|
||||
provider.inject_results(results);
|
||||
cdb.inject_results(results);
|
||||
|
||||
// Now the same entry should produce no pending queries.
|
||||
auto queries2 = provider.get_pending_queries({entry});
|
||||
auto queries2 = cdb.get_pending_queries({entry});
|
||||
EXPECT_EQ(queries2.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(MoveConstruction) {
|
||||
ToolchainProvider provider;
|
||||
std::vector<ToolchainResult> results;
|
||||
results.push_back({"key1", {"-cc1"}});
|
||||
provider.inject_results(results);
|
||||
|
||||
ToolchainProvider moved(std::move(provider));
|
||||
EXPECT_TRUE(moved.has_cached_entries());
|
||||
}
|
||||
|
||||
}; // TEST_SUITE(ToolchainProvider)
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user