Extract XCUI text input controller to common layer
This commit is contained in:
@@ -7,6 +7,7 @@ set(UI_TEST_SOURCES
|
||||
test_layout_engine.cpp
|
||||
test_ui_runtime.cpp
|
||||
test_ui_text_editing.cpp
|
||||
test_ui_text_input_controller.cpp
|
||||
)
|
||||
|
||||
add_executable(core_ui_tests ${UI_TEST_SOURCES})
|
||||
|
||||
115
tests/Core/UI/test_ui_text_input_controller.cpp
Normal file
115
tests/Core/UI/test_ui_text_input_controller.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/Input/InputTypes.h>
|
||||
#include <XCEngine/UI/Text/UITextInputController.h>
|
||||
|
||||
namespace {
|
||||
|
||||
namespace UIText = XCEngine::UI::Text;
|
||||
using XCEngine::Input::KeyCode;
|
||||
|
||||
TEST(UITextInputControllerTest, InsertCharacterTracksUtf8CaretMovement) {
|
||||
UIText::UITextInputState state = {};
|
||||
|
||||
EXPECT_TRUE(UIText::InsertCharacter(state, 'A'));
|
||||
EXPECT_TRUE(UIText::InsertCharacter(state, 0x4F60u));
|
||||
EXPECT_EQ(state.value, std::string("A") + "\xE4\xBD\xA0");
|
||||
EXPECT_EQ(state.caret, state.value.size());
|
||||
}
|
||||
|
||||
TEST(UITextInputControllerTest, BackspaceAndArrowKeysUseUtf8Boundaries) {
|
||||
UIText::UITextInputState state = {};
|
||||
state.value = std::string("A") + "\xE4\xBD\xA0" + "B";
|
||||
state.caret = state.value.size();
|
||||
|
||||
const auto moveLeft = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Left),
|
||||
{},
|
||||
{});
|
||||
EXPECT_TRUE(moveLeft.handled);
|
||||
EXPECT_EQ(state.caret, 4u);
|
||||
|
||||
const auto backspace = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Backspace),
|
||||
{},
|
||||
{});
|
||||
EXPECT_TRUE(backspace.handled);
|
||||
EXPECT_TRUE(backspace.valueChanged);
|
||||
EXPECT_EQ(state.value, "AB");
|
||||
EXPECT_EQ(state.caret, 1u);
|
||||
}
|
||||
|
||||
TEST(UITextInputControllerTest, SingleLineEnterRequestsSubmitWithoutMutatingValue) {
|
||||
UIText::UITextInputState state = {};
|
||||
state.value = "prompt";
|
||||
state.caret = state.value.size();
|
||||
|
||||
const auto result = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Enter),
|
||||
{},
|
||||
{});
|
||||
EXPECT_TRUE(result.handled);
|
||||
EXPECT_FALSE(result.valueChanged);
|
||||
EXPECT_TRUE(result.submitRequested);
|
||||
EXPECT_EQ(state.value, "prompt");
|
||||
}
|
||||
|
||||
TEST(UITextInputControllerTest, MultilineEnterAndVerticalMovementStayInController) {
|
||||
UIText::UITextInputState state = {};
|
||||
state.value = std::string("A") + "\xE4\xBD\xA0" + "Z\nBC";
|
||||
state.caret = 4u;
|
||||
|
||||
const UIText::UITextInputOptions options = { true, 4u };
|
||||
|
||||
const auto moveDown = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Down),
|
||||
{},
|
||||
options);
|
||||
EXPECT_TRUE(moveDown.handled);
|
||||
EXPECT_EQ(state.caret, 8u);
|
||||
|
||||
const auto enter = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Enter),
|
||||
{},
|
||||
options);
|
||||
EXPECT_TRUE(enter.handled);
|
||||
EXPECT_TRUE(enter.valueChanged);
|
||||
EXPECT_EQ(state.value, std::string("A") + "\xE4\xBD\xA0" + "Z\nBC\n");
|
||||
}
|
||||
|
||||
TEST(UITextInputControllerTest, MultilineTabAndShiftTabIndentAndOutdentCurrentLine) {
|
||||
UIText::UITextInputState state = {};
|
||||
state.value = "root\nnode";
|
||||
state.caret = 5u;
|
||||
|
||||
const UIText::UITextInputOptions options = { true, 4u };
|
||||
|
||||
const auto indent = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Tab),
|
||||
{},
|
||||
options);
|
||||
EXPECT_TRUE(indent.handled);
|
||||
EXPECT_TRUE(indent.valueChanged);
|
||||
EXPECT_EQ(state.value, "root\n node");
|
||||
EXPECT_EQ(state.caret, 9u);
|
||||
|
||||
XCEngine::UI::UIInputModifiers modifiers = {};
|
||||
modifiers.shift = true;
|
||||
const auto outdent = UIText::HandleKeyDown(
|
||||
state,
|
||||
static_cast<std::int32_t>(KeyCode::Tab),
|
||||
modifiers,
|
||||
options);
|
||||
EXPECT_TRUE(outdent.handled);
|
||||
EXPECT_TRUE(outdent.valueChanged);
|
||||
EXPECT_EQ(state.value, "root\nnode");
|
||||
EXPECT_EQ(state.caret, 5u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user