summaryrefslogtreecommitdiff
path: root/tests/scene
diff options
context:
space:
mode:
Diffstat (limited to 'tests/scene')
-rw-r--r--tests/scene/test_animation.h314
-rw-r--r--tests/scene/test_code_edit.h111
2 files changed, 417 insertions, 8 deletions
diff --git a/tests/scene/test_animation.h b/tests/scene/test_animation.h
new file mode 100644
index 0000000000..9199713fd9
--- /dev/null
+++ b/tests/scene/test_animation.h
@@ -0,0 +1,314 @@
+/*************************************************************************/
+/* test_animation.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_ANIMATION_H
+#define TEST_ANIMATION_H
+
+#include "scene/resources/animation.h"
+
+#include "tests/test_macros.h"
+
+namespace TestAnimation {
+
+TEST_CASE("[Animation] Empty animation getters") {
+ const Ref<Animation> animation = memnew(Animation);
+
+ CHECK(Math::is_equal_approx(animation->get_length(), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->get_step(), real_t(0.1)));
+}
+
+TEST_CASE("[Animation] Create value track") {
+ // This creates an animation that makes the node "Enemy" move to the right by
+ // 100 pixels in 0.5 seconds.
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_VALUE);
+ CHECK(track_index == 0);
+ animation->track_set_path(track_index, NodePath("Enemy:position:x"));
+ animation->track_insert_key(track_index, 0.0, 0);
+ animation->track_insert_key(track_index, 0.5, 100);
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+ CHECK(int(animation->track_get_key_value(0, 0)) == 0);
+ CHECK(int(animation->track_get_key_value(0, 1)) == 100);
+
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, -0.2), 0.0));
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.0), 0.0));
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.2), 40.0));
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.4), 80.0));
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.5), 100.0));
+ CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.6), 100.0));
+
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+
+ ERR_PRINT_OFF;
+ // Nonexistent keys.
+ CHECK(animation->track_get_key_value(0, 2).is_null());
+ CHECK(animation->track_get_key_value(0, -1).is_null());
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 2), real_t(-1.0)));
+ // Nonexistent track (and keys).
+ CHECK(animation->track_get_key_value(1, 0).is_null());
+ CHECK(animation->track_get_key_value(1, 1).is_null());
+ CHECK(animation->track_get_key_value(1, 2).is_null());
+ CHECK(animation->track_get_key_value(1, -1).is_null());
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(1, 0), real_t(-1.0)));
+
+ // This is a value track, so the methods below should return errors.
+ CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Animation] Create 3D position track") {
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_POSITION_3D);
+ animation->track_set_path(track_index, NodePath("Enemy:position"));
+ animation->position_track_insert_key(track_index, 0.0, Vector3(0, 1, 2));
+ animation->position_track_insert_key(track_index, 0.5, Vector3(3.5, 4, 5));
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+ CHECK(Vector3(animation->track_get_key_value(0, 0)).is_equal_approx(Vector3(0, 1, 2)));
+ CHECK(Vector3(animation->track_get_key_value(0, 1)).is_equal_approx(Vector3(3.5, 4, 5)));
+
+ Vector3 r_interpolation;
+
+ CHECK(animation->position_track_interpolate(0, -0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2)));
+
+ CHECK(animation->position_track_interpolate(0, 0.0, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2)));
+
+ CHECK(animation->position_track_interpolate(0, 0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(1.4, 2.2, 3.2)));
+
+ CHECK(animation->position_track_interpolate(0, 0.4, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(2.8, 3.4, 4.4)));
+
+ CHECK(animation->position_track_interpolate(0, 0.5, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
+
+ CHECK(animation->position_track_interpolate(0, 0.6, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
+
+ // 3D position tracks always use linear interpolation for performance reasons.
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+
+ // This is a 3D position track, so the methods below should return errors.
+ ERR_PRINT_OFF;
+ CHECK(animation->value_track_interpolate(0, 0.0).is_null());
+ CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Animation] Create 3D rotation track") {
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_ROTATION_3D);
+ animation->track_set_path(track_index, NodePath("Enemy:rotation"));
+ animation->rotation_track_insert_key(track_index, 0.0, Quaternion(Vector3(0, 1, 2)));
+ animation->rotation_track_insert_key(track_index, 0.5, Quaternion(Vector3(3.5, 4, 5)));
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+ CHECK(Quaternion(animation->track_get_key_value(0, 0)).is_equal_approx(Quaternion(Vector3(0, 1, 2))));
+ CHECK(Quaternion(animation->track_get_key_value(0, 1)).is_equal_approx(Quaternion(Vector3(3.5, 4, 5))));
+
+ Quaternion r_interpolation;
+
+ CHECK(animation->rotation_track_interpolate(0, -0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.403423, 0.259035, 0.73846, 0.47416)));
+
+ CHECK(animation->rotation_track_interpolate(0, 0.0, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.403423, 0.259035, 0.73846, 0.47416)));
+
+ CHECK(animation->rotation_track_interpolate(0, 0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.336182, 0.30704, 0.751515, 0.477425)));
+
+ CHECK(animation->rotation_track_interpolate(0, 0.4, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.266585, 0.352893, 0.759303, 0.477344)));
+
+ CHECK(animation->rotation_track_interpolate(0, 0.5, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048)));
+
+ CHECK(animation->rotation_track_interpolate(0, 0.6, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048)));
+
+ // 3D rotation tracks always use linear interpolation for performance reasons.
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+
+ // This is a 3D rotation track, so the methods below should return errors.
+ ERR_PRINT_OFF;
+ CHECK(animation->value_track_interpolate(0, 0.0).is_null());
+ CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Animation] Create 3D scale track") {
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_SCALE_3D);
+ animation->track_set_path(track_index, NodePath("Enemy:scale"));
+ animation->scale_track_insert_key(track_index, 0.0, Vector3(0, 1, 2));
+ animation->scale_track_insert_key(track_index, 0.5, Vector3(3.5, 4, 5));
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+ CHECK(Vector3(animation->track_get_key_value(0, 0)).is_equal_approx(Vector3(0, 1, 2)));
+ CHECK(Vector3(animation->track_get_key_value(0, 1)).is_equal_approx(Vector3(3.5, 4, 5)));
+
+ Vector3 r_interpolation;
+
+ CHECK(animation->scale_track_interpolate(0, -0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2)));
+
+ CHECK(animation->scale_track_interpolate(0, 0.0, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2)));
+
+ CHECK(animation->scale_track_interpolate(0, 0.2, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(1.4, 2.2, 3.2)));
+
+ CHECK(animation->scale_track_interpolate(0, 0.4, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(2.8, 3.4, 4.4)));
+
+ CHECK(animation->scale_track_interpolate(0, 0.5, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
+
+ CHECK(animation->scale_track_interpolate(0, 0.6, &r_interpolation) == OK);
+ CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
+
+ // 3D scale tracks always use linear interpolation for performance reasons.
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+
+ // This is a 3D scale track, so the methods below should return errors.
+ ERR_PRINT_OFF;
+ CHECK(animation->value_track_interpolate(0, 0.0).is_null());
+ CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Animation] Create blend shape track") {
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_BLEND_SHAPE);
+ animation->track_set_path(track_index, NodePath("Enemy:scale"));
+ // Negative values for blend shapes should work as expected.
+ animation->blend_shape_track_insert_key(track_index, 0.0, -1.0);
+ animation->blend_shape_track_insert_key(track_index, 0.5, 1.0);
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+
+ float r_blend = 0.0f;
+
+ CHECK(animation->blend_shape_track_get_key(0, 0, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, -1.0f));
+
+ CHECK(animation->blend_shape_track_get_key(0, 1, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, 1.0f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, -0.2, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, -1.0f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, -1.0f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, 0.2, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, -0.2f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, 0.4, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, 0.6f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, 0.5, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, 1.0f));
+
+ CHECK(animation->blend_shape_track_interpolate(0, 0.6, &r_blend) == OK);
+ CHECK(Math::is_equal_approx(r_blend, 1.0f));
+
+ // Blend shape tracks always use linear interpolation for performance reasons.
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+
+ // This is a blend shape track, so the methods below should return errors.
+ ERR_PRINT_OFF;
+ CHECK(animation->value_track_interpolate(0, 0.0).is_null());
+ CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Animation] Create Bezier track") {
+ Ref<Animation> animation = memnew(Animation);
+ const int track_index = animation->add_track(Animation::TYPE_BEZIER);
+ animation->track_set_path(track_index, NodePath("Enemy:scale"));
+ animation->bezier_track_insert_key(track_index, 0.0, -1.0, Vector2(-1, -1), Vector2(1, 1));
+ animation->bezier_track_insert_key(track_index, 0.5, 1.0, Vector2(0, 1), Vector2(1, 0.5));
+
+ CHECK(animation->get_track_count() == 1);
+ CHECK(!animation->track_is_compressed(0));
+
+ CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 0), real_t(-1.0)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 1), real_t(1.0)));
+
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, -0.2), real_t(-1.0)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.0), real_t(-1.0)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.2), real_t(-0.76057207584381)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.4), real_t(-0.39975279569626)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.5), real_t(1.0)));
+ CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.6), real_t(1.0)));
+
+ // This is a bezier track, so the methods below should return errors.
+ ERR_PRINT_OFF;
+ CHECK(animation->value_track_interpolate(0, 0.0).is_null());
+ CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
+ ERR_PRINT_ON;
+}
+
+} // namespace TestAnimation
+
+#endif // TEST_ANIMATION_H
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index 53ae01f9c7..8bd35df107 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -2786,6 +2786,52 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
SEND_GUI_KEY_EVENT(code_edit, Key::QUOTEDBL);
CHECK(code_edit->get_line(0) == "'\"'");
+
+ /* Wrap single line selection with brackets */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+ CHECK(code_edit->get_line(0) == "[abc]");
+
+ /* Caret should be after the last character of the single line selection */
+ CHECK(code_edit->get_caret_column() == 4);
+
+ /* Wrap multi line selection with brackets */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc\nabc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+ CHECK(code_edit->get_text() == "[abc\nabc]");
+
+ /* Caret should be after the last character of the multi line selection */
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 3);
+
+ /* If inserted character is not a auto brace completion open key, replace selected text with the inserted character */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::KEY_1);
+ CHECK(code_edit->get_text() == "1");
+
+ /* If potential multichar and single brace completion is matched, it should wrap the single. */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("\'\'abc");
+ code_edit->select(0, 2, 0, 5);
+ SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+ CHECK(code_edit->get_text() == "\'\'\'abc\'");
+
+ /* If only the potential multichar brace completion is matched, it does not wrap or complete. */
+ auto_brace_completion_pairs.erase("\'");
+ code_edit->set_auto_brace_completion_pairs(auto_brace_completion_pairs);
+ CHECK_FALSE(code_edit->has_auto_brace_completion_open_key("\'"));
+
+ code_edit->clear();
+ code_edit->insert_text_at_caret("\'\'abc");
+ code_edit->select(0, 2, 0, 5);
+ SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+ CHECK(code_edit->get_text() == "\'\'\'");
}
SUBCASE("[CodeEdit] autocomplete") {
@@ -2812,7 +2858,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
}
SUBCASE("[CodeEdit] autocomplete request") {
- SIGNAL_WATCH(code_edit, "request_code_completion");
+ SIGNAL_WATCH(code_edit, "code_completion_requested");
code_edit->set_code_completion_enabled(true);
Array signal_args;
@@ -2820,13 +2866,13 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
/* Force request. */
code_edit->request_code_completion();
- SIGNAL_CHECK_FALSE("request_code_completion");
+ SIGNAL_CHECK_FALSE("code_completion_requested");
code_edit->request_code_completion(true);
- SIGNAL_CHECK("request_code_completion", signal_args);
+ SIGNAL_CHECK("code_completion_requested", signal_args);
/* Manual request should force. */
SEND_GUI_ACTION(code_edit, "ui_text_completion_query");
- SIGNAL_CHECK("request_code_completion", signal_args);
+ SIGNAL_CHECK("code_completion_requested", signal_args);
/* Insert prefix. */
TypedArray<String> completion_prefixes;
@@ -2835,12 +2881,12 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->insert_text_at_caret(".");
code_edit->request_code_completion();
- SIGNAL_CHECK("request_code_completion", signal_args);
+ SIGNAL_CHECK("code_completion_requested", signal_args);
/* Should work with space too. */
code_edit->insert_text_at_caret(" ");
code_edit->request_code_completion();
- SIGNAL_CHECK("request_code_completion", signal_args);
+ SIGNAL_CHECK("code_completion_requested", signal_args);
/* Should work when complete ends with prefix. */
code_edit->clear();
@@ -2849,9 +2895,9 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "test.");
- SIGNAL_CHECK("request_code_completion", signal_args);
+ SIGNAL_CHECK("code_completion_requested", signal_args);
- SIGNAL_UNWATCH(code_edit, "request_code_completion");
+ SIGNAL_UNWATCH(code_edit, "code_completion_requested");
}
SUBCASE("[CodeEdit] autocomplete completion") {
@@ -3248,6 +3294,55 @@ TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
memdelete(code_edit);
}
+TEST_CASE("[SceneTree][CodeEdit] New Line") {
+ CodeEdit *code_edit = memnew(CodeEdit);
+ SceneTree::get_singleton()->get_root()->add_child(code_edit);
+
+ /* Add a new line. */
+ code_edit->set_text("");
+ code_edit->insert_text_at_caret("test new line");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(13);
+ SEND_GUI_ACTION(code_edit, "ui_text_newline");
+ CHECK(code_edit->get_line(0) == "test new line");
+ CHECK(code_edit->get_line(1) == "");
+
+ /* Split line with new line. */
+ code_edit->set_text("");
+ code_edit->insert_text_at_caret("test new line");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+ SEND_GUI_ACTION(code_edit, "ui_text_newline");
+ CHECK(code_edit->get_line(0) == "test ");
+ CHECK(code_edit->get_line(1) == "new line");
+
+ /* Delete selection and split with new line. */
+ code_edit->set_text("");
+ code_edit->insert_text_at_caret("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION(code_edit, "ui_text_newline");
+ CHECK(code_edit->get_line(0) == "");
+ CHECK(code_edit->get_line(1) == "new line");
+
+ /* Blank new line below with selection should not split. */
+ code_edit->set_text("");
+ code_edit->insert_text_at_caret("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION(code_edit, "ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == "test new line");
+ CHECK(code_edit->get_line(1) == "");
+
+ /* Blank new line above with selection should not split. */
+ code_edit->set_text("");
+ code_edit->insert_text_at_caret("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION(code_edit, "ui_text_newline_above");
+ CHECK(code_edit->get_line(0) == "");
+ CHECK(code_edit->get_line(1) == "test new line");
+
+ memdelete(code_edit);
+}
+
} // namespace TestCodeEdit
#endif // TEST_CODE_EDIT_H