From 6329e9fce69b538bfe10321aa7fc70deb2649160 Mon Sep 17 00:00:00 2001 From: Itamar Date: Wed, 12 May 2021 20:36:00 +0300 Subject: LanguageServer/Cpp: Add tests The Cpp LanguageServer tests can be run with: CppLanguageServer -t The tests now only cover some very simple autocomplete and "find declaration" use cases, but it's a start :) --- .../HackStudio/LanguageServers/Cpp/CMakeLists.txt | 1 + .../HackStudio/LanguageServers/Cpp/Tests.cpp | 135 +++++++++++++++++++++ .../HackStudio/LanguageServers/Cpp/Tests.h | 9 ++ .../HackStudio/LanguageServers/Cpp/main.cpp | 21 +++- 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.cpp create mode 100644 Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.h diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt index 55f6995844..a6c405548d 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt @@ -1,6 +1,7 @@ set(SOURCES LexerAutoComplete.cpp ParserAutoComplete.cpp + Tests.cpp main.cpp ) diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.cpp new file mode 100644 index 0000000000..a76855a96e --- /dev/null +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021, Itamar S. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "Tests.h" +#include "../FileDB.h" +#include "ParserAutoComplete.h" + +using namespace LanguageServers; +using namespace LanguageServers::Cpp; + +static bool s_some_test_failed = false; + +#define I_TEST(name) \ + { \ + printf("Testing " #name "... "); \ + fflush(stdout); \ + } + +#define PASS \ + do { \ + printf("PASS\n"); \ + fflush(stdout); \ + return; \ + } while (0) + +#define FAIL(reason) \ + do { \ + printf("FAIL: " #reason "\n"); \ + s_some_test_failed = true; \ + return; \ + } while (0) + +static void test_complete_local_args(); +static void test_complete_local_vars(); +static void test_complete_type(); +static void test_find_variable_definition(); + +int run_tests() +{ + test_complete_local_args(); + test_complete_local_vars(); + test_complete_type(); + test_find_variable_definition(); + return s_some_test_failed ? 1 : 0; +} + +void test_complete_local_args() +{ + I_TEST(Complete Local Args) + FileDB filedb; + String content = R"( +int main(int argc, char** argv){ +ar +} +)"; + filedb.add("a.cpp", content); + ParserAutoComplete autocomplete(filedb); + auto suggestions = autocomplete.get_suggestions("a.cpp", { 2, 2 }); + if (suggestions.size() != 2) + FAIL(bad size); + + if (suggestions[0].completion == "argc" && suggestions[1].completion == "argv") + PASS; + + FAIL("wrong results"); +} + +void test_complete_local_vars() +{ + I_TEST(Complete Local Vars) + FileDB filedb; + String content = R"( +int main(int argc, char** argv){ +int myvar1 = 3; +myv +} +)"; + filedb.add("a.cpp", content); + ParserAutoComplete autocomplete(filedb); + auto suggestions = autocomplete.get_suggestions("a.cpp", { 3, 3 }); + if (suggestions.size() != 1) + FAIL(bad size); + + if (suggestions[0].completion == "myvar1") + PASS; + + FAIL("wrong results"); +} + +void test_complete_type() +{ + I_TEST(Complete Type) + FileDB filedb; + String content = R"( +struct MyStruct { +int x; +} +void foo(){ +MyS +} +)"; + filedb.add("a.cpp", content); + ParserAutoComplete autocomplete(filedb); + auto suggestions = autocomplete.get_suggestions("a.cpp", { 5, 3 }); + if (suggestions.size() != 1) + FAIL(bad size); + + if (suggestions[0].completion == "MyStruct") + PASS; + + FAIL("wrong results"); +} + +void test_find_variable_definition() +{ + I_TEST(Find Variable Declaration) + FileDB filedb; + String content = R"( +int main(int argc, char** argv){ +argv = nullptr; +} +)"; + filedb.add("a.cpp", content); + ParserAutoComplete autocomplete(filedb); + auto position = autocomplete.find_declaration_of("a.cpp", { 2, 1 }); + if (!position.has_value()) + FAIL("declaration not found"); + + if (position.value().file == "a.cpp" && position.value().line == 1 && position.value().column >= 19) + PASS; + FAIL("wrong declaration location"); +} diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.h new file mode 100644 index 0000000000..0c98313e9a --- /dev/null +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/Tests.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2021, Itamar S. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +int run_tests(); diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/main.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/main.cpp index a13c424f26..6e404c6af7 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/main.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/main.cpp @@ -5,7 +5,9 @@ */ #include "ClientConnection.h" +#include "Tests.h" #include +#include #include #include #include @@ -13,7 +15,24 @@ #include #include -int main(int, char**) +static int mode_server(); + +int main(int argc, char** argv) +{ + bool tests = false; + + Core::ArgsParser parser; + parser.add_option(tests, "Run tests", "tests", 't'); + parser.parse(argc, argv); + + if (tests) { + return run_tests(); + } + + return mode_server(); +} + +int mode_server() { Core::EventLoop event_loop; if (pledge("stdio unix recvfd rpath ", nullptr) < 0) { -- cgit v1.2.3