Use Input::push_input for tests plus extra mouse testing

This commit is contained in:
Paulb23 2022-04-22 17:39:12 +01:00
parent f4b0c7a1ea
commit 5e4e4967fe
5 changed files with 81 additions and 26 deletions

View file

@ -1446,4 +1446,8 @@ Input::Input() {
} }
} }
Input::~Input() {
singleton = nullptr;
}
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////

View file

@ -331,6 +331,7 @@ public:
void set_event_dispatch_function(EventDispatchFunc p_function); void set_event_dispatch_function(EventDispatchFunc p_function);
Input(); Input();
~Input();
}; };
VARIANT_ENUM_CAST(Input::MouseMode); VARIANT_ENUM_CAST(Input::MouseMode);

View file

@ -40,6 +40,7 @@ namespace TestCodeEdit {
TEST_CASE("[SceneTree][CodeEdit] line gutters") { TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
SUBCASE("[CodeEdit] breakpoints") { SUBCASE("[CodeEdit] breakpoints") {
SIGNAL_WATCH(code_edit, "breakpoint_toggled"); SIGNAL_WATCH(code_edit, "breakpoint_toggled");
@ -881,6 +882,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
TEST_CASE("[SceneTree][CodeEdit] delimiters") { TEST_CASE("[SceneTree][CodeEdit] delimiters") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
const Point2 OUTSIDE_DELIMETER = Point2(-1, -1); const Point2 OUTSIDE_DELIMETER = Point2(-1, -1);
@ -1759,6 +1761,7 @@ TEST_CASE("[SceneTree][CodeEdit] delimiters") {
TEST_CASE("[SceneTree][CodeEdit] indent") { TEST_CASE("[SceneTree][CodeEdit] indent") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
SUBCASE("[CodeEdit] indent settings") { SUBCASE("[CodeEdit] indent settings") {
code_edit->set_indent_size(10); code_edit->set_indent_size(10);
@ -2288,6 +2291,7 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
TEST_CASE("[SceneTree][CodeEdit] folding") { TEST_CASE("[SceneTree][CodeEdit] folding") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
SUBCASE("[CodeEdit] folding settings") { SUBCASE("[CodeEdit] folding settings") {
code_edit->set_line_folding_enabled(true); code_edit->set_line_folding_enabled(true);
@ -2672,6 +2676,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
TEST_CASE("[SceneTree][CodeEdit] completion") { TEST_CASE("[SceneTree][CodeEdit] completion") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
SUBCASE("[CodeEdit] auto brace completion") { SUBCASE("[CodeEdit] auto brace completion") {
code_edit->set_auto_brace_completion_enabled(true); code_edit->set_auto_brace_completion_enabled(true);
@ -2991,18 +2996,18 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
Point2 caret_pos = code_edit->get_caret_draw_pos(); Point2 caret_pos = code_edit->get_caret_draw_pos();
caret_pos.y -= code_edit->get_line_height(); caret_pos.y -= code_edit->get_line_height();
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 1); CHECK(code_edit->get_code_completion_selected_index() == 1);
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 0); CHECK(code_edit->get_code_completion_selected_index() == 0);
/* Single click selects. */ /* Single click selects. */
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 2); CHECK(code_edit->get_code_completion_selected_index() == 2);
/* Double click inserts. */ /* Double click inserts. */
SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos); SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == -1); CHECK(code_edit->get_code_completion_selected_index() == -1);
CHECK(code_edit->get_line(0) == "item_2"); CHECK(code_edit->get_line(0) == "item_2");
@ -3196,6 +3201,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
TEST_CASE("[SceneTree][CodeEdit] symbol lookup") { TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
code_edit->set_symbol_lookup_on_click_enabled(true); code_edit->set_symbol_lookup_on_click_enabled(true);
CHECK(code_edit->is_symbol_lookup_on_click_enabled()); CHECK(code_edit->is_symbol_lookup_on_click_enabled());
@ -3208,7 +3214,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
Point2 caret_pos = code_edit->get_caret_draw_pos(); Point2 caret_pos = code_edit->get_caret_draw_pos();
caret_pos.x += 58; caret_pos.x += 58;
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE, Key::NONE);
CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text"); CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
SIGNAL_WATCH(code_edit, "symbol_validate"); SIGNAL_WATCH(code_edit, "symbol_validate");
@ -3234,6 +3240,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
TEST_CASE("[SceneTree][CodeEdit] line length guidelines") { TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
TypedArray<int> guide_lines; TypedArray<int> guide_lines;
@ -3254,6 +3261,7 @@ TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
TEST_CASE("[SceneTree][CodeEdit] Backspace delete") { TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
/* Backspace with selection on first line. */ /* Backspace with selection on first line. */
code_edit->set_text(""); code_edit->set_text("");
@ -3301,6 +3309,7 @@ TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
TEST_CASE("[SceneTree][CodeEdit] New Line") { TEST_CASE("[SceneTree][CodeEdit] New Line") {
CodeEdit *code_edit = memnew(CodeEdit); CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit); SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
/* Add a new line. */ /* Add a new line. */
code_edit->set_text(""); code_edit->set_text("");

View file

@ -134,8 +134,10 @@ int register_test_command(String p_command, TestFunc p_function);
// Requires Message Queue and InputMap to be setup. // Requires Message Queue and InputMap to be setup.
// SEND_GUI_ACTION - takes an object and a input map key. e.g SEND_GUI_ACTION(code_edit, "ui_text_newline"). // SEND_GUI_ACTION - takes an object and a input map key. e.g SEND_GUI_ACTION(code_edit, "ui_text_newline").
// SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::CMD). // SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::CMD).
// SEND_GUI_MOUSE_EVENT - takes an object, position, mouse button and mouse mask e.g SEND_GUI_MOUSE_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE); // SEND_GUI_MOUSE_BUTTON_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
// SEND_GUI_DOUBLE_CLICK - takes an object and a position. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50)); // SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
// SEND_GUI_MOUSE_MOTION_EVENT - takes an object, position, mouse mask and modifiers e.g SEND_GUI_MOUSE_MOTION_EVENT(code_edit, Vector2(50, 50), MouseButton::MASK_LEFT, KeyModifierMask::CMD);
// SEND_GUI_DOUBLE_CLICK - takes an object, position and modifiers. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50), KeyModifierMask::CMD);
#define SEND_GUI_ACTION(m_object, m_action) \ #define SEND_GUI_ACTION(m_object, m_action) \
{ \ { \
@ -143,7 +145,7 @@ int register_test_command(String p_command, TestFunc p_function);
const List<Ref<InputEvent>>::Element *first_event = events->front(); \ const List<Ref<InputEvent>>::Element *first_event = events->front(); \
Ref<InputEventKey> event = first_event->get(); \ Ref<InputEventKey> event = first_event->get(); \
event->set_pressed(true); \ event->set_pressed(true); \
m_object->gui_input(event); \ m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \ MessageQueue::get_singleton()->flush(); \
} }
@ -151,33 +153,66 @@ int register_test_command(String p_command, TestFunc p_function);
{ \ { \
Ref<InputEventKey> event = InputEventKey::create_reference(m_input); \ Ref<InputEventKey> event = InputEventKey::create_reference(m_input); \
event->set_pressed(true); \ event->set_pressed(true); \
m_object->gui_input(event); \ m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \ MessageQueue::get_singleton()->flush(); \
} }
#define _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask) \ #define _UPDATE_EVENT_MODIFERS(m_event, m_modifers) \
m_event->set_shift_pressed(((m_modifers)&KeyModifierMask::SHIFT) != Key::NONE); \
m_event->set_alt_pressed(((m_modifers)&KeyModifierMask::ALT) != Key::NONE); \
m_event->set_ctrl_pressed(((m_modifers)&KeyModifierMask::CTRL) != Key::NONE); \
m_event->set_command_pressed(((m_modifers)&KeyModifierMask::CMD) != Key::NONE); \
m_event->set_meta_pressed(((m_modifers)&KeyModifierMask::META) != Key::NONE);
#define _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
Ref<InputEventMouseButton> event; \ Ref<InputEventMouseButton> event; \
event.instantiate(); \ event.instantiate(); \
event->set_position(m_local_pos); \ event->set_position(m_local_pos); \
event->set_button_index(m_input); \ event->set_button_index(m_input); \
event->set_button_mask(m_mask); \ event->set_button_mask(m_mask); \
event->set_factor(1); \
_UPDATE_EVENT_MODIFERS(event, m_modifers); \
event->set_pressed(true); event->set_pressed(true);
#define SEND_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask) \ #define SEND_GUI_MOUSE_BUTTON_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
{ \ { \
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask); \ _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers); \
m_object->get_viewport()->push_input(event); \ m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \ MessageQueue::get_singleton()->flush(); \
} }
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos) \ #define SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
{ \ { \
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, MouseButton::LEFT); \ _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers); \
event->set_pressed(false); \
m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \
}
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos, m_modifers) \
{ \
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, MouseButton::LEFT, m_modifers); \
event->set_double_click(true); \ event->set_double_click(true); \
m_object->get_viewport()->push_input(event); \ m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \ MessageQueue::get_singleton()->flush(); \
} }
// We toogle _print_error_enabled to prevent display server not supported warnings.
#define SEND_GUI_MOUSE_MOTION_EVENT(m_object, m_local_pos, m_mask, m_modifers) \
{ \
bool errors_enabled = _print_error_enabled; \
_print_error_enabled = false; \
Ref<InputEventMouseMotion> event; \
event.instantiate(); \
event->set_position(m_local_pos); \
event->set_button_mask(m_mask); \
event->set_relative(Vector2(10, 10)); \
_UPDATE_EVENT_MODIFERS(event, m_modifers); \
m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \
_print_error_enabled = errors_enabled; \
}
// Utility class / macros for testing signals // Utility class / macros for testing signals
// //
// Use SIGNAL_WATCH(*object, "signal_name") to start watching // Use SIGNAL_WATCH(*object, "signal_name") to start watching

View file

@ -175,6 +175,8 @@ struct GodotTestCaseListener : public doctest::IReporter {
GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
memnew(Input);
Error err = OK; Error err = OK;
OS::get_singleton()->set_has_server_feature_callback(nullptr); OS::get_singleton()->set_has_server_feature_callback(nullptr);
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
@ -244,6 +246,10 @@ struct GodotTestCaseListener : public doctest::IReporter {
physics_2d_server = nullptr; physics_2d_server = nullptr;
} }
if (Input::get_singleton()) {
memdelete(Input::get_singleton());
}
if (RenderingServer::get_singleton()) { if (RenderingServer::get_singleton()) {
RenderingServer::get_singleton()->sync(); RenderingServer::get_singleton()->sync();
RenderingServer::get_singleton()->global_variables_clear(); RenderingServer::get_singleton()->global_variables_clear();