Tests.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Tests.h"
  7. #include "../FileDB.h"
  8. #include "CppComprehensionEngine.h"
  9. #include <AK/LexicalPath.h>
  10. #include <LibCore/File.h>
  11. #include <LibMain/Main.h>
  12. static bool s_some_test_failed = false;
  13. #define I_TEST(name) \
  14. { \
  15. printf("Testing " #name "... "); \
  16. fflush(stdout); \
  17. }
  18. #define PASS \
  19. do { \
  20. printf("PASS\n"); \
  21. fflush(stdout); \
  22. return; \
  23. } while (0)
  24. #define FAIL(reason) \
  25. do { \
  26. printf("FAIL: " #reason "\n"); \
  27. s_some_test_failed = true; \
  28. return; \
  29. } while (0)
  30. constexpr char TESTS_ROOT_DIR[] = "/home/anon/Tests/cpp-tests/comprehension";
  31. class FileDB : public CodeComprehension::FileDB {
  32. public:
  33. FileDB() = default;
  34. void add(String filename, String content)
  35. {
  36. m_map.set(filename, content);
  37. }
  38. virtual Optional<String> get_or_read_from_filesystem(StringView filename) const override
  39. {
  40. String target_filename = filename;
  41. if (!project_root().is_null() && filename.starts_with(project_root())) {
  42. target_filename = LexicalPath::relative_path(filename, project_root());
  43. }
  44. return m_map.get(target_filename);
  45. }
  46. private:
  47. HashMap<String, String> m_map;
  48. };
  49. static void test_complete_local_args();
  50. static void test_complete_local_vars();
  51. static void test_complete_type();
  52. static void test_find_variable_definition();
  53. static void test_complete_includes();
  54. static void test_parameters_hint();
  55. int run_tests()
  56. {
  57. test_complete_local_args();
  58. test_complete_local_vars();
  59. test_complete_type();
  60. test_find_variable_definition();
  61. test_complete_includes();
  62. test_parameters_hint();
  63. return s_some_test_failed ? 1 : 0;
  64. }
  65. static void add_file(FileDB& filedb, String const& name)
  66. {
  67. auto file = Core::File::open(LexicalPath::join(TESTS_ROOT_DIR, name).string(), Core::OpenMode::ReadOnly);
  68. VERIFY(!file.is_error());
  69. filedb.add(name, String::copy(file.value()->read_all()));
  70. }
  71. void test_complete_local_args()
  72. {
  73. I_TEST(Complete Local Args)
  74. FileDB filedb;
  75. add_file(filedb, "complete_local_args.cpp");
  76. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  77. auto suggestions = engine.get_suggestions("complete_local_args.cpp", { 2, 6 });
  78. if (suggestions.size() != 2)
  79. FAIL(bad size);
  80. if (suggestions[0].completion == "argc" && suggestions[1].completion == "argv")
  81. PASS;
  82. FAIL("wrong results");
  83. }
  84. void test_complete_local_vars()
  85. {
  86. I_TEST(Complete Local Vars)
  87. FileDB filedb;
  88. add_file(filedb, "complete_local_vars.cpp");
  89. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  90. auto suggestions = autocomplete.get_suggestions("complete_local_vars.cpp", { 3, 7 });
  91. if (suggestions.size() != 1)
  92. FAIL(bad size);
  93. if (suggestions[0].completion == "myvar1")
  94. PASS;
  95. FAIL("wrong results");
  96. }
  97. void test_complete_type()
  98. {
  99. I_TEST(Complete Type)
  100. FileDB filedb;
  101. add_file(filedb, "complete_type.cpp");
  102. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  103. auto suggestions = autocomplete.get_suggestions("complete_type.cpp", { 5, 7 });
  104. if (suggestions.size() != 1)
  105. FAIL(bad size);
  106. if (suggestions[0].completion == "MyStruct")
  107. PASS;
  108. FAIL("wrong results");
  109. }
  110. void test_find_variable_definition()
  111. {
  112. I_TEST(Find Variable Declaration)
  113. FileDB filedb;
  114. add_file(filedb, "find_variable_declaration.cpp");
  115. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  116. auto position = engine.find_declaration_of("find_variable_declaration.cpp", { 2, 5 });
  117. if (!position.has_value())
  118. FAIL("declaration not found");
  119. if (position.value().file == "find_variable_declaration.cpp" && position.value().line == 0 && position.value().column >= 19)
  120. PASS;
  121. FAIL("wrong declaration location");
  122. }
  123. void test_complete_includes()
  124. {
  125. I_TEST(Complete include statements)
  126. FileDB filedb;
  127. filedb.set_project_root(TESTS_ROOT_DIR);
  128. add_file(filedb, "complete_includes.cpp");
  129. add_file(filedb, "sample_header.h");
  130. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  131. auto suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 0, 22 });
  132. if (suggestions.size() != 1)
  133. FAIL(project include - bad size);
  134. if (suggestions[0].completion != "\"sample_header.h\"")
  135. FAIL("project include - wrong results");
  136. suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 1, 18 });
  137. if (suggestions.size() != 1)
  138. FAIL(global include - bad size);
  139. if (suggestions[0].completion != "<sys/cdefs.h>")
  140. FAIL("global include - wrong results");
  141. PASS;
  142. }
  143. void test_parameters_hint()
  144. {
  145. I_TEST(Function Parameters hint)
  146. FileDB filedb;
  147. filedb.set_project_root(TESTS_ROOT_DIR);
  148. add_file(filedb, "parameters_hint1.cpp");
  149. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  150. auto result = engine.get_function_params_hint("parameters_hint1.cpp", { 4, 9 });
  151. if (!result.has_value())
  152. FAIL("failed to get parameters hint (1)");
  153. if (result->params != Vector<String> { "int x", "char y" } || result->current_index != 0)
  154. FAIL("bad result (1)");
  155. result = engine.get_function_params_hint("parameters_hint1.cpp", { 5, 15 });
  156. if (!result.has_value())
  157. FAIL("failed to get parameters hint (2)");
  158. if (result->params != Vector<String> { "int x", "char y" } || result->current_index != 1)
  159. FAIL("bad result (2)");
  160. result = engine.get_function_params_hint("parameters_hint1.cpp", { 6, 8 });
  161. if (!result.has_value())
  162. FAIL("failed to get parameters hint (3)");
  163. if (result->params != Vector<String> { "int x", "char y" } || result->current_index != 0)
  164. FAIL("bad result (3)");
  165. PASS;
  166. }
  167. ErrorOr<int> serenity_main(Main::Arguments)
  168. {
  169. return run_tests();
  170. }