Tests.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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::File::open(LexicalPath::join(TESTS_ROOT_DIR, name).string(), Core::File::OpenMode::Read).release_value_but_fixme_should_propagate_errors();
  79. filedb.add(name, DeprecatedString::copy(MUST(file->read_until_eof())));
  80. }
  81. void test_complete_local_args()
  82. {
  83. I_TEST(Complete Local Args)
  84. FileDB filedb;
  85. add_file(filedb, "complete_local_args.cpp");
  86. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  87. auto suggestions = engine.get_suggestions("complete_local_args.cpp", { 2, 6 });
  88. if (suggestions.size() != 2)
  89. FAIL(bad size);
  90. if (suggestions[0].completion == "argc" && suggestions[1].completion == "argv")
  91. PASS;
  92. FAIL("wrong results");
  93. }
  94. void test_complete_local_vars()
  95. {
  96. I_TEST(Complete Local Vars)
  97. FileDB filedb;
  98. add_file(filedb, "complete_local_vars.cpp");
  99. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  100. auto suggestions = autocomplete.get_suggestions("complete_local_vars.cpp", { 3, 7 });
  101. if (suggestions.size() != 1)
  102. FAIL(bad size);
  103. if (suggestions[0].completion == "myvar1")
  104. PASS;
  105. FAIL("wrong results");
  106. }
  107. void test_complete_type()
  108. {
  109. I_TEST(Complete Type)
  110. FileDB filedb;
  111. add_file(filedb, "complete_type.cpp");
  112. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  113. auto suggestions = autocomplete.get_suggestions("complete_type.cpp", { 5, 7 });
  114. if (suggestions.size() != 1)
  115. FAIL(bad size);
  116. if (suggestions[0].completion == "MyStruct")
  117. PASS;
  118. FAIL("wrong results");
  119. }
  120. void test_find_variable_definition()
  121. {
  122. I_TEST(Find Variable Declaration)
  123. FileDB filedb;
  124. add_file(filedb, "find_variable_declaration.cpp");
  125. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  126. auto position = engine.find_declaration_of("find_variable_declaration.cpp", { 2, 5 });
  127. if (!position.has_value())
  128. FAIL("declaration not found");
  129. if (position.value().file == "find_variable_declaration.cpp" && position.value().line == 0 && position.value().column >= 19)
  130. PASS;
  131. FAIL("wrong declaration location");
  132. }
  133. void test_find_array_variable_declaration_single()
  134. {
  135. I_TEST(Find 1D Array as a Variable Declaration)
  136. FileDB filedb;
  137. auto filename = "find_array_variable_declaration.cpp";
  138. add_file(filedb, filename);
  139. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  140. auto position = engine.find_declaration_of(filename, { 3, 6 });
  141. if (!position.has_value())
  142. FAIL("declaration not found");
  143. if (position.value().file == filename && position.value().line == 2 && position.value().column >= 4)
  144. PASS;
  145. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  146. FAIL("wrong declaration location");
  147. }
  148. void test_find_array_variable_declaration_single_empty()
  149. {
  150. I_TEST(Find 1D Empty size Array as a Variable Declaration)
  151. FileDB filedb;
  152. auto filename = "find_array_variable_declaration.cpp";
  153. add_file(filedb, filename);
  154. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  155. auto position = engine.find_declaration_of(filename, { 6, 6 });
  156. if (!position.has_value())
  157. FAIL("declaration not found");
  158. if (position.value().file == filename && position.value().line == 5 && position.value().column >= 4)
  159. PASS;
  160. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  161. FAIL("wrong declaration location");
  162. }
  163. void test_find_array_variable_declaration_double()
  164. {
  165. I_TEST(Find 2D Array as a Variable Declaration)
  166. FileDB filedb;
  167. auto filename = "find_array_variable_declaration.cpp";
  168. add_file(filedb, filename);
  169. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  170. auto position = engine.find_declaration_of(filename, { 9, 6 });
  171. if (!position.has_value())
  172. FAIL("declaration not found");
  173. if (position.value().file == filename && position.value().line == 8 && position.value().column >= 4)
  174. PASS;
  175. printf("Found at position %zu %zu\n", position.value().line, position.value().column);
  176. FAIL("wrong declaration location");
  177. }
  178. void test_complete_includes()
  179. {
  180. I_TEST(Complete include statements)
  181. FileDB filedb;
  182. filedb.set_project_root(TESTS_ROOT_DIR);
  183. add_file(filedb, "complete_includes.cpp");
  184. add_file(filedb, "sample_header.h");
  185. CodeComprehension::Cpp::CppComprehensionEngine autocomplete(filedb);
  186. auto suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 0, 22 });
  187. if (suggestions.size() != 1)
  188. FAIL(project include - bad size);
  189. if (suggestions[0].completion != "\"sample_header.h\"")
  190. FAIL("project include - wrong results");
  191. suggestions = autocomplete.get_suggestions("complete_includes.cpp", { 1, 18 });
  192. if (suggestions.size() != 1)
  193. FAIL(global include - bad size);
  194. if (suggestions[0].completion != "<sys/cdefs.h>")
  195. FAIL("global include - wrong results");
  196. PASS;
  197. }
  198. void test_parameters_hint()
  199. {
  200. I_TEST(Function Parameters hint)
  201. FileDB filedb;
  202. filedb.set_project_root(TESTS_ROOT_DIR);
  203. add_file(filedb, "parameters_hint1.cpp");
  204. CodeComprehension::Cpp::CppComprehensionEngine engine(filedb);
  205. auto result = engine.get_function_params_hint("parameters_hint1.cpp", { 4, 9 });
  206. if (!result.has_value())
  207. FAIL("failed to get parameters hint (1)");
  208. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 0)
  209. FAIL("bad result (1)");
  210. result = engine.get_function_params_hint("parameters_hint1.cpp", { 5, 15 });
  211. if (!result.has_value())
  212. FAIL("failed to get parameters hint (2)");
  213. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 1)
  214. FAIL("bad result (2)");
  215. result = engine.get_function_params_hint("parameters_hint1.cpp", { 6, 8 });
  216. if (!result.has_value())
  217. FAIL("failed to get parameters hint (3)");
  218. if (result->params != Vector<DeprecatedString> { "int x", "char y" } || result->current_index != 0)
  219. FAIL("bad result (3)");
  220. PASS;
  221. }
  222. ErrorOr<int> serenity_main(Main::Arguments)
  223. {
  224. return run_tests();
  225. }