mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Enhance index test selection filtering
This commit is contained in:
parent
4781e9a53d
commit
719c6c9ae9
@ -454,7 +454,8 @@ Command line options:
|
|||||||
--test-unit Run unit tests.
|
--test-unit Run unit tests.
|
||||||
--test-index <opt_filter_path>
|
--test-index <opt_filter_path>
|
||||||
Run index tests. opt_filter_path can be used to specify which
|
Run index tests. opt_filter_path can be used to specify which
|
||||||
test to run. If not provided all tests are run.
|
test to run (ie, "foo" will run all tests which contain "foo"
|
||||||
|
in the path). If not provided all tests are run.
|
||||||
--log-stdin-stdout-to-stderr
|
--log-stdin-stdout-to-stderr
|
||||||
Print stdin and stdout messages to stderr. This is a aid for
|
Print stdin and stdout messages to stderr. This is a aid for
|
||||||
developing new language clients, as it makes it easier to figure
|
developing new language clients, as it makes it easier to figure
|
||||||
|
203
src/test.cc
203
src/test.cc
@ -132,116 +132,117 @@ void RunIndexTests(const std::string& filter_path) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (path.find(filter_path) == std::string::npos)
|
||||||
if (!EndsWith(path, filter_path))
|
continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// Parse expected output from the test, parse it into JSON document.
|
if (!filter_path.empty())
|
||||||
std::vector<std::string> lines_with_endings = ReadLinesWithEnding(path);
|
std::cout << "Running " << path << std::endl;
|
||||||
TextReplacer text_replacer;
|
|
||||||
std::vector<std::string> flags;
|
|
||||||
std::unordered_map<std::string, std::string> all_expected_output;
|
|
||||||
ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags,
|
|
||||||
&all_expected_output);
|
|
||||||
|
|
||||||
// Build flags.
|
// Parse expected output from the test, parse it into JSON document.
|
||||||
bool had_extra_flags = !flags.empty();
|
std::vector<std::string> lines_with_endings = ReadLinesWithEnding(path);
|
||||||
if (!AnyStartsWith(flags, "-x"))
|
TextReplacer text_replacer;
|
||||||
flags.push_back("-xc++");
|
std::vector<std::string> flags;
|
||||||
if (!AnyStartsWith(flags, "-std"))
|
std::unordered_map<std::string, std::string> all_expected_output;
|
||||||
flags.push_back("-std=c++11");
|
ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags,
|
||||||
flags.push_back("-resource_dir=" + GetDefaultResourceDirectory());
|
&all_expected_output);
|
||||||
if (had_extra_flags) {
|
|
||||||
|
// Build flags.
|
||||||
|
bool had_extra_flags = !flags.empty();
|
||||||
|
if (!AnyStartsWith(flags, "-x"))
|
||||||
|
flags.push_back("-xc++");
|
||||||
|
if (!AnyStartsWith(flags, "-std"))
|
||||||
|
flags.push_back("-std=c++11");
|
||||||
|
flags.push_back("-resource_dir=" + GetDefaultResourceDirectory());
|
||||||
|
if (had_extra_flags) {
|
||||||
|
std::cout << "For " << path << std::endl;
|
||||||
|
std::cout << " flags: " << StringJoin(flags) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run test.
|
||||||
|
Config config;
|
||||||
|
FileConsumer::SharedState file_consumer_shared;
|
||||||
|
PerformanceImportFile perf;
|
||||||
|
std::vector<std::unique_ptr<IndexFile>> dbs =
|
||||||
|
Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index,
|
||||||
|
false /*dump_ast*/);
|
||||||
|
|
||||||
|
for (const auto& entry : all_expected_output) {
|
||||||
|
const std::string& expected_path = entry.first;
|
||||||
|
std::string expected_output = text_replacer.Apply(entry.second);
|
||||||
|
|
||||||
|
// FIXME: promote to utils, find and remove duplicates (ie,
|
||||||
|
// cquery_call_tree.cc, maybe something in project.cc).
|
||||||
|
auto basename = [](const std::string& path) -> std::string {
|
||||||
|
size_t last_index = path.find_last_of('/');
|
||||||
|
if (last_index == std::string::npos)
|
||||||
|
return path;
|
||||||
|
return path.substr(last_index + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto severity_to_string = [](const lsDiagnosticSeverity& severity) {
|
||||||
|
switch (severity) {
|
||||||
|
case lsDiagnosticSeverity::Error:
|
||||||
|
return "error ";
|
||||||
|
case lsDiagnosticSeverity::Warning:
|
||||||
|
return "warning ";
|
||||||
|
case lsDiagnosticSeverity::Information:
|
||||||
|
return "information ";
|
||||||
|
case lsDiagnosticSeverity::Hint:
|
||||||
|
return "hint ";
|
||||||
|
}
|
||||||
|
assert(false && "not reached");
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get output from index operation.
|
||||||
|
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
||||||
|
if (!db->diagnostics_.empty()) {
|
||||||
std::cout << "For " << path << std::endl;
|
std::cout << "For " << path << std::endl;
|
||||||
std::cout << " flags: " << StringJoin(flags) << std::endl;
|
for (const lsDiagnostic& diagnostic : db->diagnostics_) {
|
||||||
|
std::cout << " ";
|
||||||
|
if (diagnostic.severity)
|
||||||
|
std::cout << severity_to_string(*diagnostic.severity);
|
||||||
|
std::cout << basename(db->path) << ":"
|
||||||
|
<< diagnostic.range.start.ToString() << "-"
|
||||||
|
<< diagnostic.range.end.ToString() << ": "
|
||||||
|
<< diagnostic.message << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
std::string actual_output = "{}";
|
||||||
|
if (db) {
|
||||||
|
VerifySerializeToFrom(db);
|
||||||
|
actual_output = db->ToString();
|
||||||
|
}
|
||||||
|
actual_output = text_replacer.Apply(actual_output);
|
||||||
|
|
||||||
// Run test.
|
// Compare output via rapidjson::Document to ignore any formatting
|
||||||
Config config;
|
// differences.
|
||||||
FileConsumer::SharedState file_consumer_shared;
|
rapidjson::Document actual;
|
||||||
PerformanceImportFile perf;
|
actual.Parse(actual_output.c_str());
|
||||||
std::vector<std::unique_ptr<IndexFile>> dbs =
|
rapidjson::Document expected;
|
||||||
Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index,
|
expected.Parse(expected_output.c_str());
|
||||||
false /*dump_ast*/);
|
|
||||||
|
|
||||||
for (const auto& entry : all_expected_output) {
|
if (actual == expected) {
|
||||||
const std::string& expected_path = entry.first;
|
// std::cout << "[PASSED] " << path << std::endl;
|
||||||
std::string expected_output = text_replacer.Apply(entry.second);
|
} else {
|
||||||
|
DiffDocuments(path, expected_path, expected, actual);
|
||||||
// FIXME: promote to utils, find and remove duplicates (ie,
|
std::cout << std::endl;
|
||||||
// cquery_call_tree.cc, maybe something in project.cc).
|
std::cout << std::endl;
|
||||||
auto basename = [](const std::string& path) -> std::string {
|
std::cout
|
||||||
size_t last_index = path.find_last_of('/');
|
<< "[Enter to continue - type u to update test, a to update all]";
|
||||||
if (last_index == std::string::npos)
|
char c = 'u';
|
||||||
return path;
|
if (!update_all) {
|
||||||
return path.substr(last_index + 1);
|
c = (char)std::cin.get();
|
||||||
};
|
std::cin.get();
|
||||||
|
|
||||||
auto severity_to_string = [](const lsDiagnosticSeverity& severity) {
|
|
||||||
switch (severity) {
|
|
||||||
case lsDiagnosticSeverity::Error:
|
|
||||||
return "error ";
|
|
||||||
case lsDiagnosticSeverity::Warning:
|
|
||||||
return "warning ";
|
|
||||||
case lsDiagnosticSeverity::Information:
|
|
||||||
return "information ";
|
|
||||||
case lsDiagnosticSeverity::Hint:
|
|
||||||
return "hint ";
|
|
||||||
}
|
|
||||||
assert(false && "not reached");
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get output from index operation.
|
|
||||||
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
|
||||||
if (!db->diagnostics_.empty()) {
|
|
||||||
std::cout << "For " << path << std::endl;
|
|
||||||
for (const lsDiagnostic& diagnostic : db->diagnostics_) {
|
|
||||||
std::cout << " ";
|
|
||||||
if (diagnostic.severity)
|
|
||||||
std::cout << severity_to_string(*diagnostic.severity);
|
|
||||||
std::cout << basename(db->path) << ":"
|
|
||||||
<< diagnostic.range.start.ToString() << "-"
|
|
||||||
<< diagnostic.range.end.ToString() << ": "
|
|
||||||
<< diagnostic.message << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::string actual_output = "{}";
|
|
||||||
if (db) {
|
|
||||||
VerifySerializeToFrom(db);
|
|
||||||
actual_output = db->ToString();
|
|
||||||
}
|
|
||||||
actual_output = text_replacer.Apply(actual_output);
|
|
||||||
|
|
||||||
// Compare output via rapidjson::Document to ignore any formatting
|
if (c == 'a')
|
||||||
// differences.
|
update_all = true;
|
||||||
rapidjson::Document actual;
|
|
||||||
actual.Parse(actual_output.c_str());
|
|
||||||
rapidjson::Document expected;
|
|
||||||
expected.Parse(expected_output.c_str());
|
|
||||||
|
|
||||||
if (actual == expected) {
|
if (update_all || c == 'u') {
|
||||||
// std::cout << "[PASSED] " << path << std::endl;
|
// Note: we use |entry.second| instead of |expected_output| because
|
||||||
} else {
|
// |expected_output| has had text replacements applied.
|
||||||
DiffDocuments(path, expected_path, expected, actual);
|
UpdateTestExpectation(path, entry.second, ToString(actual) + "\n");
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout
|
|
||||||
<< "[Enter to continue - type u to update test, a to update all]";
|
|
||||||
char c = 'u';
|
|
||||||
if (!update_all) {
|
|
||||||
c = (char)std::cin.get();
|
|
||||||
std::cin.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == 'a')
|
|
||||||
update_all = true;
|
|
||||||
|
|
||||||
if (update_all || c == 'u') {
|
|
||||||
// Note: we use |entry.second| instead of |expected_output| because
|
|
||||||
// |expected_output| has had text replacements applied.
|
|
||||||
UpdateTestExpectation(path, entry.second, ToString(actual) + "\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user