mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 15:45:08 +00:00
Some changes to index tests:
- Add EXTRA_FLAGS: which lets a test specify additional command line flags to pass to clang. - Show diagnostics in the terminal after indexing the file. - Allow the user to pass a test filter/file on the command line (ie, cquery --test-index foo.cc)
This commit is contained in:
parent
4bf8dbe3ea
commit
e26f1caaba
@ -1035,7 +1035,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (HasOption(options, "--test-index")) {
|
if (HasOption(options, "--test-index")) {
|
||||||
print_help = false;
|
print_help = false;
|
||||||
RunIndexTests();
|
RunIndexTests(options["--test-index"]);
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
std::cerr << std::endl << "[Enter] to exit" << std::endl;
|
std::cerr << std::endl << "[Enter] to exit" << std::endl;
|
||||||
std::cin.get();
|
std::cin.get();
|
||||||
@ -1058,7 +1058,9 @@ Command line options:
|
|||||||
Run as a language server. This implements the language server
|
Run as a language server. This implements the language server
|
||||||
spec over STDIN and STDOUT.
|
spec over STDIN and STDOUT.
|
||||||
--test-unit Run unit tests.
|
--test-unit Run unit tests.
|
||||||
--test-index Run index tests.
|
--test-index <opt_filter_path>
|
||||||
|
Run index tests. opt_filter_path can be used to specify which
|
||||||
|
test to run. 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
|
||||||
|
62
src/test.cc
62
src/test.cc
@ -107,7 +107,7 @@ IndexFile* FindDbForPathEnding(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunIndexTests() {
|
void RunIndexTests(const std::string& filter_path) {
|
||||||
SetTestOutputMode();
|
SetTestOutputMode();
|
||||||
|
|
||||||
// TODO: Assert that we need to be on clang >= 3.9.1
|
// TODO: Assert that we need to be on clang >= 3.9.1
|
||||||
@ -120,7 +120,24 @@ void RunIndexTests() {
|
|||||||
float memory_after = -1.;
|
float memory_after = -1.;
|
||||||
|
|
||||||
{
|
{
|
||||||
// if (path != "tests/inheritance/multiple_base_functions.cc") continue;
|
if (!EndsWith(path, filter_path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Parse expected output from the test, parse it into JSON document.
|
||||||
|
std::vector<std::string> flags;
|
||||||
|
std::unordered_map<std::string, std::string> all_expected_output =
|
||||||
|
ParseTestExpectation(path, &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;
|
||||||
|
}
|
||||||
|
|
||||||
Config config;
|
Config config;
|
||||||
FileConsumer::SharedState file_consumer_shared;
|
FileConsumer::SharedState file_consumer_shared;
|
||||||
@ -129,20 +146,49 @@ void RunIndexTests() {
|
|||||||
// std::cout << "[START] " << path << std::endl;
|
// std::cout << "[START] " << path << std::endl;
|
||||||
PerformanceImportFile perf;
|
PerformanceImportFile perf;
|
||||||
std::vector<std::unique_ptr<IndexFile>> dbs =
|
std::vector<std::unique_ptr<IndexFile>> dbs =
|
||||||
Parse(&config, &file_consumer_shared, path,
|
Parse(&config, &file_consumer_shared, path, flags,
|
||||||
{"-xc++", "-std=c++11",
|
|
||||||
"-resource-dir=" + GetDefaultResourceDirectory()},
|
|
||||||
{}, &perf, &index, false /*dump_ast*/);
|
{}, &perf, &index, false /*dump_ast*/);
|
||||||
|
|
||||||
// Parse expected output from the test, parse it into JSON document.
|
|
||||||
std::unordered_map<std::string, std::string> all_expected_output =
|
|
||||||
ParseTestExpectation(path);
|
|
||||||
for (auto& entry : all_expected_output) {
|
for (auto& entry : all_expected_output) {
|
||||||
const std::string& expected_path = entry.first;
|
const std::string& expected_path = entry.first;
|
||||||
const std::string& expected_output = entry.second;
|
const std::string& expected_output = 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) {
|
||||||
|
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");
|
||||||
|
};
|
||||||
|
|
||||||
// Get output from index operation.
|
// Get output from index operation.
|
||||||
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
||||||
|
if (!db->diagnostics_.empty()) {
|
||||||
|
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 = "{}";
|
std::string actual_output = "{}";
|
||||||
if (db) {
|
if (db) {
|
||||||
VerifySerializeToFrom(db);
|
VerifySerializeToFrom(db);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void RunIndexTests();
|
#include <string>
|
||||||
|
|
||||||
|
void RunIndexTests(const std::string& filter_path);
|
||||||
|
28
src/utils.cc
28
src/utils.cc
@ -281,9 +281,7 @@ std::vector<std::string> ToLines(const std::string& content,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> ParseTestExpectation(
|
std::unordered_map<std::string, std::string> ParseTestExpectation(
|
||||||
std::string filename) {
|
std::string filename, std::vector<std::string>* flags) {
|
||||||
bool in_output = false;
|
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
#include "bar.h"
|
#include "bar.h"
|
||||||
|
|
||||||
@ -292,6 +290,12 @@ std::unordered_map<std::string, std::string> ParseTestExpectation(
|
|||||||
/*
|
/*
|
||||||
// if no name is given assume to be this file name
|
// if no name is given assume to be this file name
|
||||||
// no output section means we don't check that index.
|
// no output section means we don't check that index.
|
||||||
|
|
||||||
|
// EXTRA_FLAGS parses until the first newline.
|
||||||
|
|
||||||
|
EXTRA_FLAGS:
|
||||||
|
-std=c++14
|
||||||
|
|
||||||
OUTPUT: bar.cc
|
OUTPUT: bar.cc
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -305,11 +309,29 @@ std::unordered_map<std::string, std::string> ParseTestExpectation(
|
|||||||
std::string active_output_filename;
|
std::string active_output_filename;
|
||||||
std::string active_output_contents;
|
std::string active_output_contents;
|
||||||
|
|
||||||
|
bool in_output = false;
|
||||||
|
for (std::string line_with_ending : ReadLinesWithEnding(filename)) {
|
||||||
|
if (StartsWith(line_with_ending, "EXTRA_FLAGS:")) {
|
||||||
|
assert(!in_output && "multiple EXTRA_FLAGS sections");
|
||||||
|
in_output = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trim(line_with_ending);
|
||||||
|
if (in_output && line_with_ending.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (in_output)
|
||||||
|
flags->push_back(line_with_ending);
|
||||||
|
}
|
||||||
|
|
||||||
|
in_output = false;
|
||||||
for (std::string line_with_ending : ReadLinesWithEnding(filename)) {
|
for (std::string line_with_ending : ReadLinesWithEnding(filename)) {
|
||||||
if (StartsWith(line_with_ending, "*/"))
|
if (StartsWith(line_with_ending, "*/"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (StartsWith(line_with_ending, "OUTPUT:")) {
|
if (StartsWith(line_with_ending, "OUTPUT:")) {
|
||||||
|
// Terminate the previous output section if we found a new one.
|
||||||
if (in_output) {
|
if (in_output) {
|
||||||
result[active_output_filename] = active_output_contents;
|
result[active_output_filename] = active_output_contents;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,8 @@ std::vector<std::string> ToLines(const std::string& content,
|
|||||||
bool trim_whitespace);
|
bool trim_whitespace);
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> ParseTestExpectation(
|
std::unordered_map<std::string, std::string> ParseTestExpectation(
|
||||||
std::string filename);
|
std::string filename,
|
||||||
|
std::vector<std::string>* flags);
|
||||||
void UpdateTestExpectation(const std::string& filename,
|
void UpdateTestExpectation(const std::string& filename,
|
||||||
const std::string& expectation,
|
const std::string& expectation,
|
||||||
const std::string& actual);
|
const std::string& actual);
|
||||||
|
Loading…
Reference in New Issue
Block a user