diff options
Diffstat (limited to 'tests/scene')
-rw-r--r-- | tests/scene/test_animation.h | 314 | ||||
-rw-r--r-- | tests/scene/test_code_edit.h | 111 |
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 |