You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

217 lines
8.2 KiB

#include "config.h"
#include "filesystem.h"
#include "source_clang.h"
#include <glib.h>
std::string main_error = R"(int main() {
int number=2;
number=3
}
)";
//Requires display server to work
//However, it is possible to use the Broadway backend if the test is run in a pure terminal environment:
//broadwayd&
//make test
void flush_events() {
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
}
int main() {
auto app = Gtk::Application::create();
Gsv::init();
#ifdef JUCI_USE_UCTAGS
Config::get().project.ctags_command = "uctags";
#else
Config::get().project.ctags_command = "ctags";
#endif
#ifdef _WIN32
g_assert_cmpstr(std::getenv("MSYSTEM_PREFIX"), !=, nullptr);
#endif
Config::get().project.default_build_path = "./build";
Source::ClangView *clang_view = new Source::ClangView(boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/source_clang_test_files/main.cpp"),
Source::LanguageManager::get_default()->get_language("cpp"));
while(!clang_view->parsed)
flush_events();
g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0);
//test get_declaration and get_implementation
clang_view->place_cursor_at_line_index(15, 7);
auto location = clang_view->get_declaration_location();
g_assert_cmpuint(location.line, ==, 6);
clang_view->place_cursor_at_line_index(location.line, location.index);
auto impl_locations = clang_view->get_implementation_locations();
g_assert_cmpuint(impl_locations.size(), ==, 1);
g_assert_cmpuint(impl_locations[0].line, ==, 11);
clang_view->place_cursor_at_line_index(location.line, location.index);
location = clang_view->get_declaration_location();
g_assert_cmpuint(location.line, ==, 6);
//test get_usages and get_methods
auto locations = clang_view->get_usages();
g_assert_cmpuint(locations.size(), >, 0);
locations = clang_view->get_methods();
g_assert_cmpuint(locations.size(), >, 0);
//Test rename class (error if not constructor and destructor is renamed as well)
auto saved_main = clang_view->get_buffer()->get_text();
clang_view->place_cursor_at_line_index(0, 6);
auto token = clang_view->get_token(clang_view->get_buffer()->get_insert()->get_iter());
g_assert_cmpstr(token.c_str(), ==, "TestClass");
location = clang_view->get_declaration_location();
g_assert_cmpuint(location.line, ==, 0);
clang_view->rename_similar_tokens("RenamedTestClass");
while(!clang_view->parsed)
flush_events();
auto iter = clang_view->get_buffer()->get_insert()->get_iter();
iter.backward_char();
token = clang_view->get_token(iter);
g_assert_cmpstr(token.c_str(), ==, "RenamedTestClass");
g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0);
clang_view->get_buffer()->set_text(saved_main);
clang_view->save();
//test error
clang_view->get_buffer()->set_text(main_error);
while(!clang_view->parsed)
flush_events();
g_assert_cmpuint(clang_view->clang_diagnostics.size(), >, 0);
g_assert_cmpuint(clang_view->get_fix_its().size(), >, 0);
// test remove_include_guard
{
clang_view->language = Source::LanguageManager::get_default()->get_language("chdr");
std::string source = "#ifndef F\n#define F\n#endif // F";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n \n ");
source = "#ifndef F\n#define F\n#endif // F\n";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n \n \n");
source = "/*test*/\n#ifndef F\n#define F\n#endif // F\n";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, "/*test*/\n \n \n \n");
source = "//test\n#ifndef F\n#define F\n#endif // F\n";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, "//test\n \n \n \n");
source = "#ifndef F /*test*/\n#define F\n#endif // F";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n \n ");
source = "#ifndef F //test\n#define F\n#endif // F";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n \n ");
source = "#ifndef F\n//test\n#define F\n#endif // F\n";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n//test\n \n \n");
source = "#if !defined(F)\n#define F\n#endif\n";
clangmm::remove_include_guard(source);
g_assert_cmpstr(source.c_str(), ==, " \n \n \n");
source = "#ifndef F\ntest\n#define F\n#endif // F\n";
auto old_source = source;
clangmm::remove_include_guard(source);
g_assert_cmpstr(old_source.c_str(), ==, source.c_str());
source = "test\n#ifndef F\n#define F\n#endif // F\n";
old_source = source;
clangmm::remove_include_guard(source);
g_assert_cmpstr(old_source.c_str(), ==, source.c_str());
source = "#ifndef F\n#define F\n#endif // F\ntest\n";
old_source = source;
clangmm::remove_include_guard(source);
g_assert_cmpstr(old_source.c_str(), ==, source.c_str());
}
// Test Implement method
{
clang_view->get_buffer()->set_text(R"(#include <string>
#include <map>
#include <vector>
namespace N {
class T {
void f1();
void f1(T &t);
void f1(const T &t);
void f1(std::vector<T> ts);
void f1(const std::vector<T> &ts);
std::string f2();
const std::string &f3();
std::vector<T> f4();
std::vector<T*> f5();
std::vector<T&> f6();
std::map<T, std::string> f7();
static
std::map<T,
std::string
> f8();
void f9() const;
};
}
)");
while(!clang_view->parsed)
flush_events();
g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0);
auto buffer = clang_view->get_buffer();
buffer->place_cursor(buffer->get_iter_at_line_offset(6, 9));
auto method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f1() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(7, 9));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f1(T &t) {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(8, 9));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f1(const T &t) {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(9, 9));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f1(std::vector<T> ts) {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(10, 9));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f1(const std::vector<T> &ts) {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(11, 16));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::string N::T::f2() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(12, 23));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "const std::string &N::T::f3() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(13, 19));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::vector<N::T> N::T::f4() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(14, 20));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::vector<N::T *> N::T::f5() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(15, 20));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::vector<N::T &> N::T::f6() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(16, 29));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::map<N::T, std::string> N::T::f7() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(20, 6));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "std::map<N::T, std::string> N::T::f8() {}");
buffer->place_cursor(buffer->get_iter_at_line_offset(21, 9));
method = clang_view->get_method();
g_assert_cmpstr(method.c_str(), ==, "void N::T::f9() const {}");
}
clang_view->async_delete();
clang_view->delete_thread.join();
flush_events();
}