mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Use indented TEST_SUITE
This commit is contained in:
parent
424c7b69db
commit
297ed1d13e
@ -3257,193 +3257,187 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("LexFunctionDeclaration");
|
TEST_SUITE("LexFunctionDeclaration") {
|
||||||
|
TEST_CASE("simple") {
|
||||||
|
std::string buffer_content = " void Foo(); ";
|
||||||
|
lsPosition declaration = CharPos(buffer_content, 'F');
|
||||||
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
TEST_CASE("simple") {
|
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
||||||
std::string buffer_content = " void Foo(); ";
|
&newlines_after_name);
|
||||||
lsPosition declaration = CharPos(buffer_content, 'F');
|
REQUIRE(insert_text == "void Foo() {\n}");
|
||||||
std::string insert_text;
|
REQUIRE(newlines_after_name == 0);
|
||||||
int newlines_after_name = 0;
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
||||||
&newlines_after_name);
|
&insert_text, &newlines_after_name);
|
||||||
REQUIRE(insert_text == "void Foo() {\n}");
|
REQUIRE(insert_text == "void Type::Foo() {\n}");
|
||||||
REQUIRE(newlines_after_name == 0);
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
}
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
TEST_CASE("ctor") {
|
||||||
&insert_text, &newlines_after_name);
|
std::string buffer_content = " Foo(); ";
|
||||||
REQUIRE(insert_text == "void Type::Foo() {\n}");
|
lsPosition declaration = CharPos(buffer_content, 'F');
|
||||||
REQUIRE(newlines_after_name == 0);
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"),
|
||||||
|
&insert_text, &newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "Foo::Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("dtor") {
|
||||||
|
std::string buffer_content = " ~Foo(); ";
|
||||||
|
lsPosition declaration = CharPos(buffer_content, '~');
|
||||||
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"),
|
||||||
|
&insert_text, &newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "Foo::~Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("complex return type") {
|
||||||
|
std::string buffer_content = " std::vector<int> Foo(); ";
|
||||||
|
lsPosition declaration = CharPos(buffer_content, 'F');
|
||||||
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
||||||
|
&newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "std::vector<int> Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
||||||
|
&insert_text, &newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "std::vector<int> Type::Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("extra complex return type") {
|
||||||
|
std::string buffer_content = " std::function < int() > \n Foo(); ";
|
||||||
|
lsPosition declaration = CharPos(buffer_content, 'F');
|
||||||
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
||||||
|
&newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "std::function < int() > \n Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
||||||
|
&insert_text, &newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "std::function < int() > \n Type::Foo() {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("parameters") {
|
||||||
|
std::string buffer_content = "void Foo(int a,\n\n int b); ";
|
||||||
|
lsPosition declaration = CharPos(buffer_content, 'F');
|
||||||
|
std::string insert_text;
|
||||||
|
int newlines_after_name = 0;
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
||||||
|
&newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "void Foo(int a,\n\n int b) {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 2);
|
||||||
|
|
||||||
|
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
||||||
|
&insert_text, &newlines_after_name);
|
||||||
|
REQUIRE(insert_text == "void Type::Foo(int a,\n\n int b) {\n}");
|
||||||
|
REQUIRE(newlines_after_name == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ctor") {
|
TEST_SUITE("LexWordAroundPos") {
|
||||||
std::string buffer_content = " Foo(); ";
|
TEST_CASE("edges") {
|
||||||
lsPosition declaration = CharPos(buffer_content, 'F');
|
std::string content = "Foobar";
|
||||||
std::string insert_text;
|
REQUIRE(LexWordAroundPos(CharPos(content, 'F'), content) == "Foobar");
|
||||||
int newlines_after_name = 0;
|
REQUIRE(LexWordAroundPos(CharPos(content, 'o'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'b'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'a'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'r'), content) == "Foobar");
|
||||||
|
}
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"),
|
TEST_CASE("simple") {
|
||||||
&insert_text, &newlines_after_name);
|
std::string content = " Foobar ";
|
||||||
REQUIRE(insert_text == "Foo::Foo() {\n}");
|
REQUIRE(LexWordAroundPos(CharPos(content, 'F'), content) == "Foobar");
|
||||||
REQUIRE(newlines_after_name == 0);
|
REQUIRE(LexWordAroundPos(CharPos(content, 'o'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'b'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'a'), content) == "Foobar");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'r'), content) == "Foobar");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("underscores and numbers") {
|
||||||
|
std::string content = " _my_t5ype7 ";
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '_'), content) == "_my_t5ype7");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '5'), content) == "_my_t5ype7");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, 'e'), content) == "_my_t5ype7");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '7'), content) == "_my_t5ype7");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("dot, dash, colon are skipped") {
|
||||||
|
std::string content = "1. 2- 3:";
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '1'), content) == "1");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '2'), content) == "2");
|
||||||
|
REQUIRE(LexWordAroundPos(CharPos(content, '3'), content) == "3");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dtor") {
|
TEST_SUITE("FindIncludeLine") {
|
||||||
std::string buffer_content = " ~Foo(); ";
|
TEST_CASE("in document") {
|
||||||
lsPosition declaration = CharPos(buffer_content, '~');
|
std::vector<std::string> lines = {
|
||||||
std::string insert_text;
|
"#include <bbb>", // 0
|
||||||
int newlines_after_name = 0;
|
"#include <ddd>" // 1
|
||||||
|
};
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Foo"),
|
REQUIRE(FindIncludeLine(lines, "#include <bbb>") == nullopt);
|
||||||
&insert_text, &newlines_after_name);
|
}
|
||||||
REQUIRE(insert_text == "Foo::~Foo() {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 0);
|
TEST_CASE("insert before") {
|
||||||
|
std::vector<std::string> lines = {
|
||||||
|
"#include <bbb>", // 0
|
||||||
|
"#include <ddd>" // 1
|
||||||
|
};
|
||||||
|
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <aaa>") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("insert middle") {
|
||||||
|
std::vector<std::string> lines = {
|
||||||
|
"#include <bbb>", // 0
|
||||||
|
"#include <ddd>" // 1
|
||||||
|
};
|
||||||
|
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <ccc>") == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("insert after") {
|
||||||
|
std::vector<std::string> lines = {
|
||||||
|
"#include <bbb>", // 0
|
||||||
|
"#include <ddd>", // 1
|
||||||
|
"", // 2
|
||||||
|
};
|
||||||
|
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <eee>") == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ignore header") {
|
||||||
|
std::vector<std::string> lines = {
|
||||||
|
"// FOOBAR", // 0
|
||||||
|
"// FOOBAR", // 1
|
||||||
|
"// FOOBAR", // 2
|
||||||
|
"// FOOBAR", // 3
|
||||||
|
"", // 4
|
||||||
|
"#include <bbb>", // 5
|
||||||
|
"#include <ddd>", // 6
|
||||||
|
"", // 7
|
||||||
|
};
|
||||||
|
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <a>") == 5);
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <c>") == 6);
|
||||||
|
REQUIRE(FindIncludeLine(lines, "#include <e>") == 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("complex return type") {
|
|
||||||
std::string buffer_content = " std::vector<int> Foo(); ";
|
|
||||||
lsPosition declaration = CharPos(buffer_content, 'F');
|
|
||||||
std::string insert_text;
|
|
||||||
int newlines_after_name = 0;
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
|
||||||
&newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "std::vector<int> Foo() {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 0);
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
|
||||||
&insert_text, &newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "std::vector<int> Type::Foo() {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("extra complex return type") {
|
|
||||||
std::string buffer_content = " std::function < int() > \n Foo(); ";
|
|
||||||
lsPosition declaration = CharPos(buffer_content, 'F');
|
|
||||||
std::string insert_text;
|
|
||||||
int newlines_after_name = 0;
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
|
||||||
&newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "std::function < int() > \n Foo() {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 0);
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
|
||||||
&insert_text, &newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "std::function < int() > \n Type::Foo() {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("parameters") {
|
|
||||||
std::string buffer_content = "void Foo(int a,\n\n int b); ";
|
|
||||||
lsPosition declaration = CharPos(buffer_content, 'F');
|
|
||||||
std::string insert_text;
|
|
||||||
int newlines_after_name = 0;
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, nullopt, &insert_text,
|
|
||||||
&newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "void Foo(int a,\n\n int b) {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 2);
|
|
||||||
|
|
||||||
LexFunctionDeclaration(buffer_content, declaration, std::string("Type"),
|
|
||||||
&insert_text, &newlines_after_name);
|
|
||||||
REQUIRE(insert_text == "void Type::Foo(int a,\n\n int b) {\n}");
|
|
||||||
REQUIRE(newlines_after_name == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
|
||||||
TEST_SUITE("LexWordAroundPos");
|
|
||||||
|
|
||||||
TEST_CASE("edges") {
|
|
||||||
std::string content = "Foobar";
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'F'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'o'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'b'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'a'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'r'), content) == "Foobar");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("simple") {
|
|
||||||
std::string content = " Foobar ";
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'F'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'o'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'b'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'a'), content) == "Foobar");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'r'), content) == "Foobar");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("underscores and numbers") {
|
|
||||||
std::string content = " _my_t5ype7 ";
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '_'), content) == "_my_t5ype7");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '5'), content) == "_my_t5ype7");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, 'e'), content) == "_my_t5ype7");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '7'), content) == "_my_t5ype7");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("dot, dash, colon are skipped") {
|
|
||||||
std::string content = "1. 2- 3:";
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '1'), content) == "1");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '2'), content) == "2");
|
|
||||||
REQUIRE(LexWordAroundPos(CharPos(content, '3'), content) == "3");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
|
||||||
TEST_SUITE("FindIncludeLine");
|
|
||||||
|
|
||||||
TEST_CASE("in document") {
|
|
||||||
std::vector<std::string> lines = {
|
|
||||||
"#include <bbb>", // 0
|
|
||||||
"#include <ddd>" // 1
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <bbb>") == nullopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("insert before") {
|
|
||||||
std::vector<std::string> lines = {
|
|
||||||
"#include <bbb>", // 0
|
|
||||||
"#include <ddd>" // 1
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <aaa>") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("insert middle") {
|
|
||||||
std::vector<std::string> lines = {
|
|
||||||
"#include <bbb>", // 0
|
|
||||||
"#include <ddd>" // 1
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <ccc>") == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("insert after") {
|
|
||||||
std::vector<std::string> lines = {
|
|
||||||
"#include <bbb>", // 0
|
|
||||||
"#include <ddd>", // 1
|
|
||||||
"", // 2
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <eee>") == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("ignore header") {
|
|
||||||
std::vector<std::string> lines = {
|
|
||||||
"// FOOBAR", // 0
|
|
||||||
"// FOOBAR", // 1
|
|
||||||
"// FOOBAR", // 2
|
|
||||||
"// FOOBAR", // 3
|
|
||||||
"", // 4
|
|
||||||
"#include <bbb>", // 5
|
|
||||||
"#include <ddd>", // 6
|
|
||||||
"", // 7
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <a>") == 5);
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <c>") == 6);
|
|
||||||
REQUIRE(FindIncludeLine(lines, "#include <e>") == 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
@ -82,8 +82,6 @@ optional<std::string> ReadJsonRpcContentFrom(
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("FindIncludeLine");
|
|
||||||
|
|
||||||
std::function<optional<char>()> MakeContentReader(std::string* content,
|
std::function<optional<char>()> MakeContentReader(std::string* content,
|
||||||
bool can_be_empty) {
|
bool can_be_empty) {
|
||||||
return [content, can_be_empty]() -> optional<char> {
|
return [content, can_be_empty]() -> optional<char> {
|
||||||
@ -97,31 +95,31 @@ std::function<optional<char>()> MakeContentReader(std::string* content,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ReadContentFromSource") {
|
TEST_SUITE("FindIncludeLine") {
|
||||||
auto parse_correct = [](std::string content) -> std::string {
|
TEST_CASE("ReadContentFromSource") {
|
||||||
auto reader = MakeContentReader(&content, false /*can_be_empty*/);
|
auto parse_correct = [](std::string content) -> std::string {
|
||||||
auto got = ReadJsonRpcContentFrom(reader);
|
auto reader = MakeContentReader(&content, false /*can_be_empty*/);
|
||||||
REQUIRE(got);
|
auto got = ReadJsonRpcContentFrom(reader);
|
||||||
return got.value();
|
REQUIRE(got);
|
||||||
};
|
return got.value();
|
||||||
|
};
|
||||||
|
|
||||||
auto parse_incorrect = [](std::string content) -> optional<std::string> {
|
auto parse_incorrect = [](std::string content) -> optional<std::string> {
|
||||||
auto reader = MakeContentReader(&content, true /*can_be_empty*/);
|
auto reader = MakeContentReader(&content, true /*can_be_empty*/);
|
||||||
return ReadJsonRpcContentFrom(reader);
|
return ReadJsonRpcContentFrom(reader);
|
||||||
};
|
};
|
||||||
|
|
||||||
REQUIRE(parse_correct("Content-Length: 0\r\n\r\n") == "");
|
REQUIRE(parse_correct("Content-Length: 0\r\n\r\n") == "");
|
||||||
REQUIRE(parse_correct("Content-Length: 1\r\n\r\na") == "a");
|
REQUIRE(parse_correct("Content-Length: 1\r\n\r\na") == "a");
|
||||||
REQUIRE(parse_correct("Content-Length: 4\r\n\r\nabcd") == "abcd");
|
REQUIRE(parse_correct("Content-Length: 4\r\n\r\nabcd") == "abcd");
|
||||||
|
|
||||||
REQUIRE(parse_incorrect("ggg") == optional<std::string>());
|
REQUIRE(parse_incorrect("ggg") == optional<std::string>());
|
||||||
REQUIRE(parse_incorrect("Content-Length: 0\r\n") == optional<std::string>());
|
REQUIRE(parse_incorrect("Content-Length: 0\r\n") == optional<std::string>());
|
||||||
REQUIRE(parse_incorrect("Content-Length: 5\r\n\r\nab") ==
|
REQUIRE(parse_incorrect("Content-Length: 5\r\n\r\nab") ==
|
||||||
optional<std::string>());
|
optional<std::string>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
|
||||||
optional<char> ReadCharFromStdinBlocking() {
|
optional<char> ReadCharFromStdinBlocking() {
|
||||||
// Bad stdin means parent process has probably exited. Either way, cquery
|
// Bad stdin means parent process has probably exited. Either way, cquery
|
||||||
// can no longer be communicated with so just exit.
|
// can no longer be communicated with so just exit.
|
||||||
|
@ -213,59 +213,55 @@ bool SubstringMatch(const std::string& search, const std::string& content) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("Offset");
|
TEST_SUITE("Offset") {
|
||||||
|
TEST_CASE("past end") {
|
||||||
|
std::string content = "foo";
|
||||||
|
int offset = GetOffsetForPosition(lsPosition(10, 10), content);
|
||||||
|
REQUIRE(offset <= content.size());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("past end") {
|
TEST_CASE("in middle of content") {
|
||||||
std::string content = "foo";
|
std::string content = "abcdefghijk";
|
||||||
int offset = GetOffsetForPosition(lsPosition(10, 10), content);
|
for (int i = 0; i < content.size(); ++i) {
|
||||||
REQUIRE(offset <= content.size());
|
int offset = GetOffsetForPosition(lsPosition(0, i), content);
|
||||||
}
|
REQUIRE(i == offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("in middle of content") {
|
TEST_CASE("at end of content") {
|
||||||
std::string content = "abcdefghijk";
|
REQUIRE(GetOffsetForPosition(lsPosition(0, 0), "") == 0);
|
||||||
for (int i = 0; i < content.size(); ++i) {
|
REQUIRE(GetOffsetForPosition(lsPosition(0, 1), "a") == 1);
|
||||||
int offset = GetOffsetForPosition(lsPosition(0, i), content);
|
|
||||||
REQUIRE(i == offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("at end of content") {
|
TEST_SUITE("Substring") {
|
||||||
REQUIRE(GetOffsetForPosition(lsPosition(0, 0), "") == 0);
|
TEST_CASE("match") {
|
||||||
REQUIRE(GetOffsetForPosition(lsPosition(0, 1), "a") == 1);
|
// Sanity.
|
||||||
|
REQUIRE(SubstringMatch("a", "aa"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "aa"));
|
||||||
|
|
||||||
|
// Empty string matches anything.
|
||||||
|
REQUIRE(SubstringMatch("", ""));
|
||||||
|
REQUIRE(SubstringMatch("", "aa"));
|
||||||
|
|
||||||
|
// Match in start/middle/end.
|
||||||
|
REQUIRE(SubstringMatch("a", "abbbb"));
|
||||||
|
REQUIRE(SubstringMatch("a", "bbabb"));
|
||||||
|
REQUIRE(SubstringMatch("a", "bbbba"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "aabbb"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "bbaab"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "bbbaa"));
|
||||||
|
|
||||||
|
// Capitalization.
|
||||||
|
REQUIRE(SubstringMatch("aa", "aA"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "Aa"));
|
||||||
|
REQUIRE(SubstringMatch("aa", "AA"));
|
||||||
|
|
||||||
|
// Token skipping.
|
||||||
|
REQUIRE(SubstringMatch("ad", "abcd"));
|
||||||
|
REQUIRE(SubstringMatch("ad", "ABCD"));
|
||||||
|
|
||||||
|
// Ordering.
|
||||||
|
REQUIRE(!SubstringMatch("ad", "dcba"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
|
||||||
TEST_SUITE("Substring");
|
|
||||||
|
|
||||||
TEST_CASE("match") {
|
|
||||||
// Sanity.
|
|
||||||
REQUIRE(SubstringMatch("a", "aa"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "aa"));
|
|
||||||
|
|
||||||
// Empty string matches anything.
|
|
||||||
REQUIRE(SubstringMatch("", ""));
|
|
||||||
REQUIRE(SubstringMatch("", "aa"));
|
|
||||||
|
|
||||||
// Match in start/middle/end.
|
|
||||||
REQUIRE(SubstringMatch("a", "abbbb"));
|
|
||||||
REQUIRE(SubstringMatch("a", "bbabb"));
|
|
||||||
REQUIRE(SubstringMatch("a", "bbbba"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "aabbb"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "bbaab"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "bbbaa"));
|
|
||||||
|
|
||||||
// Capitalization.
|
|
||||||
REQUIRE(SubstringMatch("aa", "aA"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "Aa"));
|
|
||||||
REQUIRE(SubstringMatch("aa", "AA"));
|
|
||||||
|
|
||||||
// Token skipping.
|
|
||||||
REQUIRE(SubstringMatch("ad", "abcd"));
|
|
||||||
REQUIRE(SubstringMatch("ad", "ABCD"));
|
|
||||||
|
|
||||||
// Ordering.
|
|
||||||
REQUIRE(!SubstringMatch("ad", "dcba"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
22
src/match.cc
22
src/match.cc
@ -76,16 +76,14 @@ bool GroupMatch::IsMatch(const std::string& value,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("Matcher");
|
TEST_SUITE("Matcher") {
|
||||||
|
TEST_CASE("sanity") {
|
||||||
TEST_CASE("sanity") {
|
// Matcher m("abc");
|
||||||
// Matcher m("abc");
|
// TODO: check case
|
||||||
// TODO: check case
|
// CHECK(m.IsMatch("abc"));
|
||||||
// CHECK(m.IsMatch("abc"));
|
// CHECK(m.IsMatch("fooabc"));
|
||||||
// CHECK(m.IsMatch("fooabc"));
|
// CHECK(m.IsMatch("abc"));
|
||||||
// CHECK(m.IsMatch("abc"));
|
// CHECK(m.IsMatch("abcfoo"));
|
||||||
// CHECK(m.IsMatch("abcfoo"));
|
// CHECK(m.IsMatch("11a11b11c11"));
|
||||||
// CHECK(m.IsMatch("11a11b11c11"));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
@ -87,40 +87,38 @@ void MakeDirectoryRecursive(std::string path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("Platform");
|
TEST_SUITE("Platform") {
|
||||||
|
TEST_CASE("Split strings") {
|
||||||
|
std::vector<std::string> actual = Split("/a/b/c/", '/');
|
||||||
|
std::vector<std::string> expected{"a", "b", "c"};
|
||||||
|
REQUIRE(actual == expected);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Split strings") {
|
TEST_CASE("Mutex lock/unlock (single process)") {
|
||||||
std::vector<std::string> actual = Split("/a/b/c/", '/');
|
auto m1 = CreatePlatformMutex("indexer-platformmutexttest");
|
||||||
std::vector<std::string> expected{"a", "b", "c"};
|
auto l1 = CreatePlatformScopedMutexLock(m1.get());
|
||||||
REQUIRE(actual == expected);
|
auto m2 = CreatePlatformMutex("indexer-platformmutexttest");
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Mutex lock/unlock (single process)") {
|
int value = 0;
|
||||||
auto m1 = CreatePlatformMutex("indexer-platformmutexttest");
|
|
||||||
auto l1 = CreatePlatformScopedMutexLock(m1.get());
|
|
||||||
auto m2 = CreatePlatformMutex("indexer-platformmutexttest");
|
|
||||||
|
|
||||||
int value = 0;
|
volatile bool did_run = false;
|
||||||
|
std::thread t([&]() {
|
||||||
volatile bool did_run = false;
|
did_run = true;
|
||||||
std::thread t([&]() {
|
auto l2 = CreatePlatformScopedMutexLock(m2.get());
|
||||||
did_run = true;
|
value = 1;
|
||||||
auto l2 = CreatePlatformScopedMutexLock(m2.get());
|
});
|
||||||
value = 1;
|
while (!did_run)
|
||||||
});
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
while (!did_run)
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
|
|
||||||
// Other thread has had a chance to run, but it should not have
|
// Other thread has had a chance to run, but it should not have
|
||||||
// written to value yet (ie, it should be waiting).
|
// written to value yet (ie, it should be waiting).
|
||||||
REQUIRE(value == 0);
|
REQUIRE(value == 0);
|
||||||
|
|
||||||
// Release the lock, wait for other thread to finish. Verify it
|
// Release the lock, wait for other thread to finish. Verify it
|
||||||
// wrote the expected value.
|
// wrote the expected value.
|
||||||
l1.reset();
|
l1.reset();
|
||||||
t.join();
|
t.join();
|
||||||
REQUIRE(value == 1);
|
REQUIRE(value == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
1682
src/project.cc
1682
src/project.cc
File diff suppressed because it is too large
Load Diff
252
src/query.cc
252
src/query.cc
@ -823,132 +823,130 @@ void QueryDatabase::UpdateDetailedNames(size_t* qualified_name_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("query");
|
TEST_SUITE("query") {
|
||||||
|
IndexUpdate GetDelta(IndexFile previous, IndexFile current) {
|
||||||
|
QueryDatabase db;
|
||||||
|
IdMap previous_map(&db, previous.id_cache);
|
||||||
|
IdMap current_map(&db, current.id_cache);
|
||||||
|
return IndexUpdate::CreateDelta(&previous_map, ¤t_map, &previous,
|
||||||
|
¤t);
|
||||||
|
}
|
||||||
|
|
||||||
IndexUpdate GetDelta(IndexFile previous, IndexFile current) {
|
TEST_CASE("remove defs") {
|
||||||
QueryDatabase db;
|
IndexFile previous("foo.cc");
|
||||||
IdMap previous_map(&db, previous.id_cache);
|
IndexFile current("foo.cc");
|
||||||
IdMap current_map(&db, current.id_cache);
|
|
||||||
return IndexUpdate::CreateDelta(&previous_map, ¤t_map, &previous,
|
previous.Resolve(previous.ToTypeId("usr1"))->def.definition_spelling =
|
||||||
¤t);
|
Range(Position(1, 0));
|
||||||
|
previous.Resolve(previous.ToFuncId("usr2"))->def.definition_spelling =
|
||||||
|
Range(Position(2, 0));
|
||||||
|
previous.Resolve(previous.ToVarId("usr3"))->def.definition_spelling =
|
||||||
|
Range(Position(3, 0));
|
||||||
|
|
||||||
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
|
REQUIRE(update.types_removed == std::vector<Usr>{"usr1"});
|
||||||
|
REQUIRE(update.funcs_removed == std::vector<Usr>{"usr2"});
|
||||||
|
REQUIRE(update.vars_removed == std::vector<Usr>{"usr3"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("do not remove ref-only defs") {
|
||||||
|
IndexFile previous("foo.cc");
|
||||||
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
|
previous.Resolve(previous.ToTypeId("usr1"))
|
||||||
|
->uses.push_back(Range(Position(1, 0)));
|
||||||
|
previous.Resolve(previous.ToFuncId("usr2"))
|
||||||
|
->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
previous.Resolve(previous.ToVarId("usr3"))
|
||||||
|
->uses.push_back(Range(Position(3, 0)));
|
||||||
|
|
||||||
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
|
REQUIRE(update.types_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.funcs_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.vars_removed == std::vector<Usr>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("func callers") {
|
||||||
|
IndexFile previous("foo.cc");
|
||||||
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
|
IndexFunc* pf = previous.Resolve(previous.ToFuncId("usr"));
|
||||||
|
IndexFunc* cf = current.Resolve(current.ToFuncId("usr"));
|
||||||
|
|
||||||
|
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
|
||||||
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
|
REQUIRE(update.funcs_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.funcs_callers.size() == 1);
|
||||||
|
REQUIRE(update.funcs_callers[0].id == QueryFuncId(0));
|
||||||
|
REQUIRE(update.funcs_callers[0].to_remove.size() == 1);
|
||||||
|
REQUIRE(update.funcs_callers[0].to_remove[0].loc.range ==
|
||||||
|
Range(Position(1, 0)));
|
||||||
|
REQUIRE(update.funcs_callers[0].to_add.size() == 1);
|
||||||
|
REQUIRE(update.funcs_callers[0].to_add[0].loc.range == Range(Position(2, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("type usages") {
|
||||||
|
IndexFile previous("foo.cc");
|
||||||
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
|
IndexType* pt = previous.Resolve(previous.ToTypeId("usr"));
|
||||||
|
IndexType* ct = current.Resolve(current.ToTypeId("usr"));
|
||||||
|
|
||||||
|
pt->uses.push_back(Range(Position(1, 0)));
|
||||||
|
ct->uses.push_back(Range(Position(2, 0)));
|
||||||
|
|
||||||
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
|
REQUIRE(update.types_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.types_def_update == std::vector<QueryType::DefUpdate>{});
|
||||||
|
REQUIRE(update.types_uses.size() == 1);
|
||||||
|
REQUIRE(update.types_uses[0].to_remove.size() == 1);
|
||||||
|
REQUIRE(update.types_uses[0].to_remove[0].range == Range(Position(1, 0)));
|
||||||
|
REQUIRE(update.types_uses[0].to_add.size() == 1);
|
||||||
|
REQUIRE(update.types_uses[0].to_add[0].range == Range(Position(2, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("apply delta") {
|
||||||
|
IndexFile previous("foo.cc");
|
||||||
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
|
IndexFunc* pf = previous.Resolve(previous.ToFuncId("usr"));
|
||||||
|
IndexFunc* cf = current.Resolve(current.ToFuncId("usr"));
|
||||||
|
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(4, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(5, 0)),
|
||||||
|
false /*is_implicit*/));
|
||||||
|
|
||||||
|
QueryDatabase db;
|
||||||
|
IdMap previous_map(&db, previous.id_cache);
|
||||||
|
IdMap current_map(&db, current.id_cache);
|
||||||
|
REQUIRE(db.funcs.size() == 1);
|
||||||
|
|
||||||
|
IndexUpdate import_update =
|
||||||
|
IndexUpdate::CreateDelta(nullptr, &previous_map, nullptr, &previous);
|
||||||
|
IndexUpdate delta_update = IndexUpdate::CreateDelta(
|
||||||
|
&previous_map, ¤t_map, &previous, ¤t);
|
||||||
|
|
||||||
|
db.ApplyIndexUpdate(&import_update);
|
||||||
|
REQUIRE(db.funcs[0].callers.size() == 2);
|
||||||
|
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(1, 0)));
|
||||||
|
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(2, 0)));
|
||||||
|
|
||||||
|
db.ApplyIndexUpdate(&delta_update);
|
||||||
|
REQUIRE(db.funcs[0].callers.size() == 2);
|
||||||
|
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(4, 0)));
|
||||||
|
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(5, 0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("remove defs") {
|
|
||||||
IndexFile previous("foo.cc");
|
|
||||||
IndexFile current("foo.cc");
|
|
||||||
|
|
||||||
previous.Resolve(previous.ToTypeId("usr1"))->def.definition_spelling =
|
|
||||||
Range(Position(1, 0));
|
|
||||||
previous.Resolve(previous.ToFuncId("usr2"))->def.definition_spelling =
|
|
||||||
Range(Position(2, 0));
|
|
||||||
previous.Resolve(previous.ToVarId("usr3"))->def.definition_spelling =
|
|
||||||
Range(Position(3, 0));
|
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
|
||||||
|
|
||||||
REQUIRE(update.types_removed == std::vector<Usr>{"usr1"});
|
|
||||||
REQUIRE(update.funcs_removed == std::vector<Usr>{"usr2"});
|
|
||||||
REQUIRE(update.vars_removed == std::vector<Usr>{"usr3"});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("do not remove ref-only defs") {
|
|
||||||
IndexFile previous("foo.cc");
|
|
||||||
IndexFile current("foo.cc");
|
|
||||||
|
|
||||||
previous.Resolve(previous.ToTypeId("usr1"))
|
|
||||||
->uses.push_back(Range(Position(1, 0)));
|
|
||||||
previous.Resolve(previous.ToFuncId("usr2"))
|
|
||||||
->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
previous.Resolve(previous.ToVarId("usr3"))
|
|
||||||
->uses.push_back(Range(Position(3, 0)));
|
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
|
||||||
|
|
||||||
REQUIRE(update.types_removed == std::vector<Usr>{});
|
|
||||||
REQUIRE(update.funcs_removed == std::vector<Usr>{});
|
|
||||||
REQUIRE(update.vars_removed == std::vector<Usr>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("func callers") {
|
|
||||||
IndexFile previous("foo.cc");
|
|
||||||
IndexFile current("foo.cc");
|
|
||||||
|
|
||||||
IndexFunc* pf = previous.Resolve(previous.ToFuncId("usr"));
|
|
||||||
IndexFunc* cf = current.Resolve(current.ToFuncId("usr"));
|
|
||||||
|
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
|
||||||
|
|
||||||
REQUIRE(update.funcs_removed == std::vector<Usr>{});
|
|
||||||
REQUIRE(update.funcs_callers.size() == 1);
|
|
||||||
REQUIRE(update.funcs_callers[0].id == QueryFuncId(0));
|
|
||||||
REQUIRE(update.funcs_callers[0].to_remove.size() == 1);
|
|
||||||
REQUIRE(update.funcs_callers[0].to_remove[0].loc.range ==
|
|
||||||
Range(Position(1, 0)));
|
|
||||||
REQUIRE(update.funcs_callers[0].to_add.size() == 1);
|
|
||||||
REQUIRE(update.funcs_callers[0].to_add[0].loc.range == Range(Position(2, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("type usages") {
|
|
||||||
IndexFile previous("foo.cc");
|
|
||||||
IndexFile current("foo.cc");
|
|
||||||
|
|
||||||
IndexType* pt = previous.Resolve(previous.ToTypeId("usr"));
|
|
||||||
IndexType* ct = current.Resolve(current.ToTypeId("usr"));
|
|
||||||
|
|
||||||
pt->uses.push_back(Range(Position(1, 0)));
|
|
||||||
ct->uses.push_back(Range(Position(2, 0)));
|
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
|
||||||
|
|
||||||
REQUIRE(update.types_removed == std::vector<Usr>{});
|
|
||||||
REQUIRE(update.types_def_update == std::vector<QueryType::DefUpdate>{});
|
|
||||||
REQUIRE(update.types_uses.size() == 1);
|
|
||||||
REQUIRE(update.types_uses[0].to_remove.size() == 1);
|
|
||||||
REQUIRE(update.types_uses[0].to_remove[0].range == Range(Position(1, 0)));
|
|
||||||
REQUIRE(update.types_uses[0].to_add.size() == 1);
|
|
||||||
REQUIRE(update.types_uses[0].to_add[0].range == Range(Position(2, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("apply delta") {
|
|
||||||
IndexFile previous("foo.cc");
|
|
||||||
IndexFile current("foo.cc");
|
|
||||||
|
|
||||||
IndexFunc* pf = previous.Resolve(previous.ToFuncId("usr"));
|
|
||||||
IndexFunc* cf = current.Resolve(current.ToFuncId("usr"));
|
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(1, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
pf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(4, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
cf->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(5, 0)),
|
|
||||||
false /*is_implicit*/));
|
|
||||||
|
|
||||||
QueryDatabase db;
|
|
||||||
IdMap previous_map(&db, previous.id_cache);
|
|
||||||
IdMap current_map(&db, current.id_cache);
|
|
||||||
REQUIRE(db.funcs.size() == 1);
|
|
||||||
|
|
||||||
IndexUpdate import_update =
|
|
||||||
IndexUpdate::CreateDelta(nullptr, &previous_map, nullptr, &previous);
|
|
||||||
IndexUpdate delta_update = IndexUpdate::CreateDelta(
|
|
||||||
&previous_map, ¤t_map, &previous, ¤t);
|
|
||||||
|
|
||||||
db.ApplyIndexUpdate(&import_update);
|
|
||||||
REQUIRE(db.funcs[0].callers.size() == 2);
|
|
||||||
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(1, 0)));
|
|
||||||
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(2, 0)));
|
|
||||||
|
|
||||||
db.ApplyIndexUpdate(&delta_update);
|
|
||||||
REQUIRE(db.funcs[0].callers.size() == 2);
|
|
||||||
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(4, 0)));
|
|
||||||
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(5, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
@ -379,107 +379,105 @@ std::vector<CXUnsavedFile> WorkingFiles::AsUnsavedFiles() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE("WorkingFile");
|
|
||||||
|
|
||||||
lsPosition CharPos(const WorkingFile& file,
|
lsPosition CharPos(const WorkingFile& file,
|
||||||
char character,
|
char character,
|
||||||
int character_offset = 0) {
|
int character_offset = 0) {
|
||||||
return CharPos(file.buffer_content, character, character_offset);
|
return CharPos(file.buffer_content, character, character_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("simple call") {
|
TEST_SUITE("WorkingFile") {
|
||||||
WorkingFile f("foo.cc", "abcd(1, 2");
|
TEST_CASE("simple call") {
|
||||||
int active_param = 0;
|
WorkingFile f("foo.cc", "abcd(1, 2");
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) ==
|
int active_param = 0;
|
||||||
"abcd");
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) ==
|
||||||
REQUIRE(active_param == 0);
|
"abcd");
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '1'), &active_param) ==
|
REQUIRE(active_param == 0);
|
||||||
"abcd");
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '1'), &active_param) ==
|
||||||
REQUIRE(active_param == 0);
|
"abcd");
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) ==
|
REQUIRE(active_param == 0);
|
||||||
"abcd");
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) ==
|
||||||
REQUIRE(active_param == 1);
|
"abcd");
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) ==
|
REQUIRE(active_param == 1);
|
||||||
"abcd");
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) ==
|
||||||
REQUIRE(active_param == 1);
|
"abcd");
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '2'), &active_param) ==
|
REQUIRE(active_param == 1);
|
||||||
"abcd");
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '2'), &active_param) ==
|
||||||
REQUIRE(active_param == 1);
|
"abcd");
|
||||||
|
REQUIRE(active_param == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("nested call") {
|
||||||
|
WorkingFile f("foo.cc", "abcd(efg(), 2");
|
||||||
|
int active_param = 0;
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'e'), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'f'), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g'), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 1), &active_param) ==
|
||||||
|
"efg");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 2), &active_param) ==
|
||||||
|
"efg");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 1);
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) ==
|
||||||
|
"abcd");
|
||||||
|
REQUIRE(active_param == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("auto-insert )") {
|
||||||
|
WorkingFile f("foo.cc", "abc()");
|
||||||
|
int active_param = 0;
|
||||||
|
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ')'), &active_param) ==
|
||||||
|
"abc");
|
||||||
|
REQUIRE(active_param == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("existing completion") {
|
||||||
|
WorkingFile f("foo.cc", "zzz.asdf");
|
||||||
|
bool is_global_completion;
|
||||||
|
std::string existing_completion;
|
||||||
|
|
||||||
|
f.FindStableCompletionSource(CharPos(f, '.'), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "zzz");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 'a', 1), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "a");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 's', 1), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "as");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 'd', 1), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "asd");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 'f', 1), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "asdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("existing completion underscore") {
|
||||||
|
WorkingFile f("foo.cc", "ABC_DEF");
|
||||||
|
bool is_global_completion;
|
||||||
|
std::string existing_completion;
|
||||||
|
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 'C'), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "AB");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, '_'), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "ABC");
|
||||||
|
f.FindStableCompletionSource(CharPos(f, 'D'), &is_global_completion,
|
||||||
|
&existing_completion);
|
||||||
|
REQUIRE(existing_completion == "ABC_");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("nested call") {
|
|
||||||
WorkingFile f("foo.cc", "abcd(efg(), 2");
|
|
||||||
int active_param = 0;
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, '('), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'e'), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'f'), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g'), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 1), &active_param) ==
|
|
||||||
"efg");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, 'g', 2), &active_param) ==
|
|
||||||
"efg");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ','), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 1);
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ' '), &active_param) ==
|
|
||||||
"abcd");
|
|
||||||
REQUIRE(active_param == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("auto-insert )") {
|
|
||||||
WorkingFile f("foo.cc", "abc()");
|
|
||||||
int active_param = 0;
|
|
||||||
REQUIRE(f.FindClosestCallNameInBuffer(CharPos(f, ')'), &active_param) ==
|
|
||||||
"abc");
|
|
||||||
REQUIRE(active_param == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("existing completion") {
|
|
||||||
WorkingFile f("foo.cc", "zzz.asdf");
|
|
||||||
bool is_global_completion;
|
|
||||||
std::string existing_completion;
|
|
||||||
|
|
||||||
f.FindStableCompletionSource(CharPos(f, '.'), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "zzz");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 'a', 1), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "a");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 's', 1), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "as");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 'd', 1), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "asd");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 'f', 1), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "asdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("existing completion underscore") {
|
|
||||||
WorkingFile f("foo.cc", "ABC_DEF");
|
|
||||||
bool is_global_completion;
|
|
||||||
std::string existing_completion;
|
|
||||||
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 'C'), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "AB");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, '_'), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "ABC");
|
|
||||||
f.FindStableCompletionSource(CharPos(f, 'D'), &is_global_completion,
|
|
||||||
&existing_completion);
|
|
||||||
REQUIRE(existing_completion == "ABC_");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_SUITE_END();
|
|
||||||
|
2
third_party/doctest
vendored
2
third_party/doctest
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 11147357234d0166c9ec96c4d9e328464b884da3
|
Subproject commit 79a379827251cd819c5286070834ccd0ac628af9
|
2
third_party/loguru
vendored
2
third_party/loguru
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ac23215b4b9e878dfe5c2fd3d4afbf7a63cdad12
|
Subproject commit 83b6f3c3d16e40453ec0d12d3baef42cd2f37c3b
|
2
third_party/rapidjson
vendored
2
third_party/rapidjson
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 0163a53f4a1c72e6a05848a63d80eee0d8e3f387
|
Subproject commit 17ae6ffa857173c25708e61610121bc908c0a6cd
|
2
third_party/sparsepp
vendored
2
third_party/sparsepp
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b1d54fbe547cab3a13d181f16f1de758d6827f81
|
Subproject commit bfb0de71ee7fa12a5f12c3ef61ce9f1d6d86d907
|
Loading…
Reference in New Issue
Block a user