Tests.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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/DeprecatedFile.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. #define RUN(function) \
  31. function; \
  32. if (s_some_test_failed) { \
  33. return 1; \
  34. }
  35. constexpr auto TESTS_ROOT_DIR = "/home/anon/Tests/cpp-tests/comprehension"sv;
  36. class FileDB : public CodeComprehension::FileDB {
  37. public:
  38. FileDB() = default;
  39. void add(DeprecatedString filename, DeprecatedString content)
  40. {
  41. m_map.set(filename, content);
  42. }
  43. virtual Optional<DeprecatedString> get_or_read_from_filesystem(StringView filename) const override
  44. {
  45. DeprecatedString target_filename = filename;
  46. if (!project_root().is_null() && filename.starts_with(project_root())) {
  47. target_filename = LexicalPath::relative_path(filename, project_root());
  48. }
  49. return m_map.get(target_filename);
  50. }
  51. private:
  52. HashMap<DeprecatedString, DeprecatedString> m_map;
  53. };
  54. static void test_complete_local_args();
  55. static void test_complete_local_vars();
  56. static void test_complete_type();
  57. static void test_find_variable_definition();
  58. static void test_find_array_variable_declaration_single();
  59. static void test_find_array_variable_declaration_single_empty();
  60. static void test_find_array_variable_declaration_double();
  61. static void test_complete_includes();
  62. static void test_parameters_hint();
  63. int run_tests()
  64. {
  65. RUN(test_complete_local_args());
  66. RUN(test_complete_local_vars());
  67. RUN(test_complete_type());
  68. RUN(test_find_variable_definition());
  69. RUN(test_find_array_variable_declaration_single());
  70. RUN(test_find_array_variable_declaration_single_empty());
  71. RUN(test_find_array_variable_declaration_double());
  72. RUN(test_complete_includes());
  73. RUN(test_parameters_hint());
  74. return 0;
  75. }
  76. static void add_file(FileDB& filedb, DeprecatedString const& name)
  77. {
  78. auto file = Core::DeprecatedFile::open(LexicalPath::join(TESTS_ROOT_DIR, name).string(), Core::OpenMode::ReadOnly);
  79. VERIFY(!file.is_error());
  80. filedb.add(name, DeprecatedString::copy(file.value()->read_all()));
  81. }
  82. void test_complete_local_args()
  83. {
  84. I_TEST(Complete Local Args)
  85. FileDB filedb;
  86. add_file(filedb, "complete_local_args.cpp");
  87. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  88. auto suggestions = engine.get_suggestions("complete_local_args.cpp", { 2, 6 });
  89. if (suggestions.size() != 2)
  90. FAIL(bad size);
  91. if (suggestions[0].completion == "argc" && suggestions[1].completion == "argv")
  92. PASS;
  93. FAIL("wrong results");
  94. }
  95. void test_complete_local_vars()
  96. {
  97. I_TEST(Complete Local Vars)
  98. FileDB filedb;
  99. add_file(filedb, "complete_local_vars.cpp");
  100. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  101. auto suggestions = autocomplete.get_suggestions("complete_local_vars.cpp", { 3, 7 });
  102. if (suggestions.size() != 1)
  103. FAIL(bad size);
  104. if (suggestions[0].completion == "myvar1")
  105. PASS;
  106. FAIL("wrong results");
  107. }
  108. void test_complete_type()
  109. {
  110. I_TEST(Complete Type)
  111. FileDB filedb;
  112. add_file(filedb, "complete_type.cpp");
  113. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  114. auto suggestions = autocomplete.get_suggestions("complete_type.cpp", { 5, 7 });
  115. if (suggestions.size() != 1)
  116. FAIL(bad size);
  117. if (suggestions[0].completion == "MyStruct")
  118. PASS;
  119. FAIL("wrong results");
  120. }
  121. void test_find_variable_definition()
  122. {
  123. I_TEST(Find Variable Declaration)
  124. FileDB filedb;
  125. add_file(filedb, "find_variable_declaration.cpp");
  126. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  127. auto position = engine.find_declaration_of("find_variable_declaration.cpp", { 2, 5 });
  128. if (!position.has_value())
  129. FAIL("declaration not found");
  130. if (position.value().file == "find_variable_declaration.cpp" && position.value().line == 0 && position.value().column >= 19)
  131. PASS;
  132. FAIL("wrong declaration location");
  133. }
  134. void test_find_array_variable_declaration_single()
  135. {
  136. I_TEST(Find 1D Array as a Variable Declaration)
  137. FileDB filedb;
  138. auto filename = "find_array_variable_declaration.cpp";
  139. add_file(filedb, filename);
  140. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  141. auto position = engine.find_declaration_of(filename, { 3, 6 });
  142. if (!position.has_value())
  143. FAIL("declaration not found");
  144. if (position.value().file == filename && position.value().line == 2 && position.value().column >= 4)
  145. PASS;
  146. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  147. FAIL("wrong declaration location");
  148. }
  149. void test_find_array_variable_declaration_single_empty()
  150. {
  151. I_TEST(Find 1D Empty size Array as a Variable Declaration)
  152. FileDB filedb;
  153. auto filename = "find_array_variable_declaration.cpp";
  154. add_file(filedb, filename);
  155. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  156. auto position = engine.find_declaration_of(filename, { 6, 6 });
  157. if (!position.has_value())
  158. FAIL("declaration not found");
  159. if (position.value().file == filename && position.value().line == 5 && position.value().column >= 4)
  160. PASS;
  161. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  162. FAIL("wrong declaration location");
  163. }
  164. void test_find_array_variable_declaration_double()
  165. {
  166. I_TEST(Find 2D Array as a Variable Declaration)
  167. FileDB filedb;
  168. auto filename = "find_array_variable_declaration.cpp";
  169. add_file(filedb, filename);
  170. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  171. auto position = engine.find_declaration_of(filename, { 9, 6 });
  172. if (!position.has_value())
  173. FAIL("declaration not found");
  174. if (position.value().file == filename && position.value().line == 8 && position.value().column >= 4)
  175. PASS;
  176. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  177. FAIL("wrong declaration location");
  178. }
  179. void test_complete_includes()
  180. {
  181. I_TEST(Complete include statements)
  182. FileDB filedb;
  183. filedb.set_project_root(TESTS_ROOT_DIR);
  184. add_file(filedb, "complete_includes.cpp");
  185. add_file(filedb, "sample_header.h");
  186. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  187. auto suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 0, 22 });
  188. if (suggestions.size() != 1)
  189. FAIL(project include - bad size);
  190. if (suggestions[0].completion != "\"sample_header.h\"")
  191. FAIL("project include - wrong results");
  192. suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 1, 18 });
  193. if (suggestions.size() != 1)
  194. FAIL(global include - bad size);
  195. if (suggestions[0].completion != "<sys/cdefs.h>")
  196. FAIL("global include - wrong results");
  197. PASS;
  198. }
  199. void test_parameters_hint()
  200. {
  201. I_TEST(Function Parameters hint)
  202. FileDB filedb;
  203. filedb.set_project_root(TESTS_ROOT_DIR);
  204. add_file(filedb, "parameters_hint1.cpp");
  205. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  206. auto result = engine.get_function_params_hint("parameters_hint1.cpp", { 4, 9 });
  207. if (!result.has_value())
  208. FAIL("failed to get parameters hint (1)");
  209. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 0)
  210. FAIL("bad result (1)");
  211. result = engine.get_function_params_hint("parameters_hint1.cpp", { 5, 15 });
  212. if (!result.has_value())
  213. FAIL("failed to get parameters hint (2)");
  214. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 1)
  215. FAIL("bad result (2)");
  216. result = engine.get_function_params_hint("parameters_hint1.cpp", { 6, 8 });
  217. if (!result.has_value())
  218. FAIL("failed to get parameters hint (3)");
  219. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 0)
  220. FAIL("bad result (3)");
  221. PASS;
  222. }
  223. ErrorOr<int> serenity_main(Main::Arguments)
  224. {
  225. return run_tests();
  226. }