Files
FTXUI/src/ftxui/component/input_test.cpp
Arthur Sonzogni 455998d759 Remove Ref<XxxOption> and add new interfaces. (#686)
1. Stop taking Ref<XxxOption> in Component constructors. Instead, use
   the XxxOption directly. Passing by copy avoid problems developers had
   where one was shared in between multiple component, causing issues.

2. Add variants of most component constructors taking a struct only.

This replaces:
https://github.com/ArthurSonzogni/FTXUI/pull/670

This fixes:
https://github.com/ArthurSonzogni/FTXUI/issues/426
2023-06-25 17:22:05 +02:00

759 lines
23 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <memory> // for __shared_ptr_access, shared_ptr, allocator
#include <string> // for string
#include "ftxui/component/component.hpp" // for Input
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
#include "ftxui/component/component_options.hpp" // for InputOption
#include "ftxui/component/event.hpp" // for Event, Event::ArrowRightCtrl, Event::ArrowLeftCtrl, Event::ArrowLeft, Event::ArrowRight, Event::ArrowDown, Event::ArrowUp, Event::Delete, Event::Backspace, Event::Return, Event::End, Event::Home
#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Button, Mouse::Left, Mouse::Motion, Mouse::Pressed
#include "ftxui/dom/elements.hpp" // for Fit
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/screen.hpp" // for Fixed, Screen, Pixel
#include "ftxui/util/ref.hpp" // for Ref
#include "gtest/gtest.h" // for AssertionResult, Message, TestPartResult, EXPECT_EQ, EXPECT_TRUE, Test, EXPECT_FALSE, TEST
namespace ftxui {
TEST(InputTest, Init) {
std::string content;
int cursor_position = 0;
auto option = InputOption();
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_EQ(cursor_position, 0);
}
TEST(InputTest, Type) {
std::string content;
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
input->OnEvent(Event::Character("a"));
EXPECT_EQ(content, "a");
EXPECT_EQ(cursor_position, 1);
input->OnEvent(Event::Character('b'));
EXPECT_EQ(content, "ab");
EXPECT_EQ(cursor_position, 2);
input->OnEvent(Event::Return);
EXPECT_EQ(content, "ab\n");
EXPECT_EQ(cursor_position, 3);
input->OnEvent(Event::Character('c'));
EXPECT_EQ(content, "ab\nc");
EXPECT_EQ(cursor_position, 4);
auto document = input->Render();
auto screen = Screen::Create(Dimension::Fixed(10), Dimension::Fixed(2));
Render(screen, document);
EXPECT_EQ(screen.PixelAt(0, 0).character, "a");
EXPECT_EQ(screen.PixelAt(1, 0).character, "b");
EXPECT_EQ(screen.PixelAt(0, 1).character, "c");
EXPECT_EQ(screen.PixelAt(1, 1).character, " ");
}
TEST(InputTest, ArrowLeftRight) {
std::string content = "abc测测a测\na测\n";
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_EQ(cursor_position, 0);
EXPECT_FALSE(input->OnEvent(Event::ArrowLeft));
EXPECT_EQ(cursor_position, 0);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 1);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_EQ(cursor_position, 0);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 1);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 2);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 3);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 6);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 9);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 10);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 13);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 14);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 15);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 18);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 19);
EXPECT_FALSE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 19);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_EQ(cursor_position, 18);
}
TEST(InputTest, ArrowUpDown) {
std::string content =
"\n"
"\n"
"\n"
"a\n"
"\n"
"\n"
"";
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 4);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 11);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 21);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 29);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 36);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 40);
EXPECT_FALSE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 40);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 36);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 29);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 21);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 11);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 4);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 0);
EXPECT_FALSE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 0);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_EQ(cursor_position, 3);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 7);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 14);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 24);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 32);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 39);
EXPECT_TRUE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 40);
EXPECT_FALSE(input->OnEvent(Event::ArrowDown));
EXPECT_EQ(cursor_position, 40);
cursor_position = 39;
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 32);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 24);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 14);
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_EQ(cursor_position, 7);
}
TEST(InputTest, Insert) {
std::string content;
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::Character('a')));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_EQ(content, "abc");
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Character('-')));
EXPECT_EQ(content, "a-bc");
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Character('-')));
EXPECT_EQ(content, "a--bc");
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Character('-')));
EXPECT_EQ(content, "-a--bc");
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_EQ(content, "-测a--bc");
EXPECT_TRUE(input->OnEvent(Event::Character("a")));
EXPECT_EQ(content, "-测aa--bc");
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_EQ(content, "-测a测a--bc");
}
TEST(InputTest, Home) {
std::string content;
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::Character('a')));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_TRUE(input->OnEvent(Event::Return));
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 9u);
EXPECT_TRUE(input->OnEvent(Event::Home));
EXPECT_EQ(cursor_position, 0u);
EXPECT_TRUE(input->OnEvent(Event::Character('-')));
EXPECT_EQ(cursor_position, 1u);
EXPECT_EQ(content, "-abc\n测bc");
}
TEST(InputTest, End) {
std::string content;
int cursor_position = 0;
Component input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::Character('a')));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_TRUE(input->OnEvent(Event::Return));
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_TRUE(input->OnEvent(Event::ArrowUp));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 2u);
input->OnEvent(Event::End);
EXPECT_EQ(cursor_position, 9u);
}
TEST(InputTest, Delete) {
std::string content;
int cursor_position = 0;
auto input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::Character('a')));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_TRUE(input->OnEvent(Event::Return));
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 9u);
EXPECT_FALSE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 9u);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 8u);
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abc\n测b");
EXPECT_EQ(cursor_position, 8u);
EXPECT_FALSE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abc\n测b");
EXPECT_EQ(cursor_position, 8u);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abc\nb");
EXPECT_EQ(cursor_position, 4u);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abcb");
EXPECT_EQ(cursor_position, 3u);
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "abc");
EXPECT_EQ(cursor_position, 3u);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_TRUE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "");
EXPECT_FALSE(input->OnEvent(Event::Delete));
EXPECT_EQ(content, "");
}
TEST(InputTest, Backspace) {
std::string content;
int cursor_position = 0;
auto input = Input(&content, {
.cursor_position = &cursor_position,
});
EXPECT_TRUE(input->OnEvent(Event::Character('a')));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_TRUE(input->OnEvent(Event::Return));
EXPECT_TRUE(input->OnEvent(Event::Character("")));
EXPECT_TRUE(input->OnEvent(Event::Character('b')));
EXPECT_TRUE(input->OnEvent(Event::Character('c')));
EXPECT_EQ(content, "abc\n测bc");
EXPECT_EQ(cursor_position, 9u);
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "abc\n测b");
EXPECT_EQ(cursor_position, 8u);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeft));
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "abc\nb");
EXPECT_EQ(cursor_position, 4u);
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "abcb");
EXPECT_EQ(cursor_position, 3u);
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "abb");
EXPECT_EQ(cursor_position, 2u);
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "ab");
EXPECT_EQ(cursor_position, 1u);
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "b");
EXPECT_EQ(cursor_position, 0u);
EXPECT_FALSE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "b");
EXPECT_EQ(cursor_position, 0u);
EXPECT_TRUE(input->OnEvent(Event::ArrowRight));
EXPECT_TRUE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "");
EXPECT_EQ(cursor_position, 0u);
EXPECT_FALSE(input->OnEvent(Event::Backspace));
EXPECT_EQ(content, "");
EXPECT_EQ(cursor_position, 0u);
}
TEST(InputTest, CtrlArrow) {
std::string content =
"word word 测ord wo测d word\n"
"coucou coucou coucou\n"
"coucou coucou coucou\n";
int cursor_position = 1000;
auto input = Input(&content, {
.cursor_position = &cursor_position,
});
// Use CTRL+Left several time
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 67);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 60);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 53);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 46);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 39);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 29);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 24);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 17);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 10);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 5);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 0);
EXPECT_FALSE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 0);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 4);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 9);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 16);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 23);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 28);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 35);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 45);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 52);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 59);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 66);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 73);
}
TEST(InputTest, CtrlArrowLeft2) {
std::string content = " word word 测ord wo测d word ";
int cursor_position = 33;
auto input = Input(&content, {
.cursor_position = &cursor_position,
});
// Use CTRL+Left several time
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 31);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 23);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 15);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 9);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 3);
EXPECT_TRUE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 0);
EXPECT_FALSE(input->OnEvent(Event::ArrowLeftCtrl));
EXPECT_EQ(cursor_position, 0);
}
TEST(InputTest, CtrlArrowRight) {
std::string content =
"word word 测ord wo测d word\n"
"coucou dfqdsf jmlkjm";
int cursor_position = 2;
auto input = Input(&content, {.cursor_position = &cursor_position});
// Use CTRL+Left several time
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 4);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 9);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 16);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 23);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 28);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 35);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 42);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 49);
EXPECT_FALSE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 49);
}
TEST(InputTest, CtrlArrowRight2) {
std::string content = " word word 测ord wo测d word ";
int cursor_position = 0;
auto input = Input(&content, {.cursor_position = &cursor_position});
// Use CTRL+Left several time
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 7);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 13);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 21);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 29);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 35);
EXPECT_TRUE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 38);
EXPECT_FALSE(input->OnEvent(Event::ArrowRightCtrl));
EXPECT_EQ(cursor_position, 38);
}
TEST(InputTest, TypePassword) {
std::string content;
std::string placeholder;
int cursor_position = 0;
Component input = Input(&content, &placeholder,
{
.password = true,
.cursor_position = &cursor_position,
});
input->OnEvent(Event::Character('a'));
EXPECT_EQ(content, "a");
EXPECT_EQ(cursor_position, 1u);
input->OnEvent(Event::Character('b'));
EXPECT_EQ(content, "ab");
EXPECT_EQ(cursor_position, 2u);
auto document = input->Render();
auto screen = Screen::Create(Dimension::Fit(document));
Render(screen, document);
EXPECT_EQ(screen.PixelAt(0, 0).character, "");
EXPECT_EQ(screen.PixelAt(1, 0).character, "");
}
TEST(InputTest, MouseClick) {
std::string content;
int cursor_position = 0;
auto input = Input(&content, {.cursor_position = &cursor_position});
input->OnEvent(Event::Character("a"));
input->OnEvent(Event::Character("b"));
input->OnEvent(Event::Character("c"));
input->OnEvent(Event::Character("d"));
input->OnEvent(Event::Return);
input->OnEvent(Event::Character("a"));
input->OnEvent(Event::Character("b"));
input->OnEvent(Event::Character("c"));
input->OnEvent(Event::Character("d"));
input->OnEvent(Event::Return);
EXPECT_EQ(content, "abcd\nabcd\n");
EXPECT_EQ(cursor_position, 10u);
auto render = [&] {
auto document = input->Render();
auto screen = Screen::Create(Dimension::Fixed(10), Dimension::Fixed(3));
Render(screen, document);
};
render();
EXPECT_EQ(cursor_position, 10u);
Mouse mouse;
mouse.button = Mouse::Button::Left;
mouse.motion = Mouse::Motion::Pressed;
mouse.shift = false;
mouse.meta = false;
mouse.control = false;
mouse.x = 0;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 0u);
mouse.x = 2;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 2u);
mouse.x = 2;
mouse.y = 0;
EXPECT_FALSE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 2u);
mouse.x = 1;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 1u);
mouse.x = 3;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 3u);
mouse.x = 4;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 4u);
mouse.x = 5;
mouse.y = 0;
EXPECT_FALSE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 4u);
mouse.x = 5;
mouse.y = 1;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 9u);
mouse.x = 1;
mouse.y = 1;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 6u);
mouse.x = 4;
mouse.y = 2;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 10u);
}
TEST(InputTest, MouseClickComplex) {
std::string content;
int cursor_position = 0;
auto input = Input(&content, {.cursor_position = &cursor_position});
input->OnEvent(Event::Character(""));
input->OnEvent(Event::Character(""));
input->OnEvent(Event::Character("a⃒"));
input->OnEvent(Event::Character(""));
input->OnEvent(Event::Return);
input->OnEvent(Event::Character(""));
input->OnEvent(Event::Character(""));
input->OnEvent(Event::Character("a⃒"));
input->OnEvent(Event::Character(""));
EXPECT_EQ(cursor_position, 27u);
auto render = [&] {
auto document = input->Render();
auto screen = Screen::Create(Dimension::Fixed(100), Dimension::Fixed(4));
Render(screen, document);
};
render();
Mouse mouse;
mouse.button = Mouse::Button::Left;
mouse.motion = Mouse::Motion::Pressed;
mouse.shift = false;
mouse.meta = false;
mouse.control = false;
mouse.x = 0;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 0);
mouse.x = 0;
mouse.y = 1;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 14);
mouse.x = 1;
mouse.y = 0;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 3);
mouse.x = 1;
mouse.y = 1;
EXPECT_TRUE(input->OnEvent(Event::Mouse("", mouse)));
render();
EXPECT_EQ(cursor_position, 17);
}
TEST(InputTest, OnEnter) {
std::string content;
auto option = InputOption();
bool on_enter_called = false;
option.on_enter = [&] { on_enter_called = true; };
Component input = Input(&content, option);
EXPECT_FALSE(on_enter_called);
EXPECT_TRUE(input->OnEvent(Event::Return));
EXPECT_TRUE(on_enter_called);
}
} // namespace ftxui
// Copyright 2023 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.