From 45bf24f8ea0e227e9277e39ccc70e36f906546c4 Mon Sep 17 00:00:00 2001 From: ArthurSonzogni Date: Thu, 24 Apr 2025 03:02:10 +0200 Subject: [PATCH] Add workflow + examples + tests --- .github/workflows/build.yaml | 6 + BUILD.bazel | 450 ++++++++++----------- CMakeLists.txt | 4 +- MODULE.bazel | 18 +- WORKSPACE | 1 - examples/component/slider_direction.cpp | 2 +- examples/dom/color_truecolor_RGB.cpp | 1 - include/ftxui/component/component_base.hpp | 4 +- src/ftxui/component/menu_test.cpp | 2 +- src/ftxui/component/selection_test.cpp | 222 ---------- 10 files changed, 243 insertions(+), 467 deletions(-) delete mode 100644 WORKSPACE delete mode 100644 src/ftxui/component/selection_test.cpp diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f9149b74..8bebbd87 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -55,6 +55,12 @@ jobs: gcovr: "5.0" opencppcoverage: true + - name: "Install Bazel" + uses: bazelbuild/setup-bazel@v5 + + - name: "Tests with Bazel" + run: bazel run test + # make sure coverage is only enabled for Debug builds, since it sets -O0 # to make sure coverage has meaningful results - name: "Configure CMake" diff --git a/BUILD.bazel b/BUILD.bazel index a4978a3d..d180a7c8 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,235 +1,193 @@ -load( - "@rules_cc//cc:defs.bzl", - "cc_library", - "cc_test", - "cc_binary", -) +# Copyright 2025 Arthur Sonzogni. All rights reserved. +# Use of this source code is governed by the MIT license that can be found in +# the LICENSE file. + +# TODO: +# - Windows/MSVC support. +# - Pass /utf-8 to MSVC users depending on FTXUI. +# - Pass "FTXUI_MICROSOFT_TERMINAL_FALLBACK" to windows users. +# - Support building benchmark. +# - Support building examples. +# - Support building fuzzer. +# - Support building documentation. +# - Enable the two tests timing out. +# - Support WebAssembly + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") +load(":bazel/ftxui.bzl", "ftxui_cc_library", "generate_examples") package(default_visibility = ["//visibility:public"]) -cc_library( - name = "screen", - srcs = [ - "src/ftxui/screen/box.cpp", - "src/ftxui/screen/color.cpp", - "src/ftxui/screen/color_info.cpp", - "src/ftxui/screen/image.cpp", - "src/ftxui/screen/screen.cpp", - "src/ftxui/screen/string.cpp", - "src/ftxui/screen/string_internal.hpp", - "src/ftxui/screen/terminal.cpp", - "src/ftxui/screen/util.hpp", - ], - hdrs = [ - "include/ftxui/screen/box.hpp", - "include/ftxui/screen/color.hpp", - "include/ftxui/screen/color_info.hpp", - "include/ftxui/screen/deprecated.hpp", - "include/ftxui/screen/image.hpp", - "include/ftxui/screen/pixel.hpp", - "include/ftxui/screen/screen.hpp", - "include/ftxui/screen/string.hpp", - "include/ftxui/screen/terminal.hpp", - "include/ftxui/util/autoreset.hpp", - "include/ftxui/util/ref.hpp", - ], - includes = ["include", "src"], - strip_include_prefix = "", - copts = ["-std=c++17"], +# A meta target that depends on all the ftxui sub modules. +alias( + name = "ftxui", + actual = ":component", # Note that :component depends on :dom, which depends + # on :screen. Bazel doesn't really support "public" + # and "private" dependencies. They are all public. + visibility = ["//visibility:public"], ) -cc_test( - name = "screen_test", - srcs = [ - "src/ftxui/screen/string_test.cpp", - "src/ftxui/screen/color_test.cpp", - ], - deps = [ - "//:screen", - "@googletest//:gtest_main", - ], - includes = ["include", "src"], - copts = ["-std=c++20"], - testonly = True, -) - -cc_library( - name = "dom", - srcs = [ - "src/ftxui/dom/automerge.cpp", - "src/ftxui/dom/blink.cpp", - "src/ftxui/dom/bold.cpp", - "src/ftxui/dom/border.cpp", - "src/ftxui/dom/box_helper.cpp", - "src/ftxui/dom/box_helper.hpp", - "src/ftxui/dom/canvas.cpp", - "src/ftxui/dom/clear_under.cpp", - "src/ftxui/dom/color.cpp", - "src/ftxui/dom/composite_decorator.cpp", - "src/ftxui/dom/dbox.cpp", - "src/ftxui/dom/dim.cpp", - "src/ftxui/dom/flex.cpp", - "src/ftxui/dom/flexbox.cpp", - "src/ftxui/dom/flexbox_config.cpp", - "src/ftxui/dom/flexbox_helper.cpp", - "src/ftxui/dom/flexbox_helper.hpp", - "src/ftxui/dom/focus.cpp", - "src/ftxui/dom/frame.cpp", - "src/ftxui/dom/gauge.cpp", - "src/ftxui/dom/graph.cpp", - "src/ftxui/dom/gridbox.cpp", - "src/ftxui/dom/hbox.cpp", - "src/ftxui/dom/hyperlink.cpp", - "src/ftxui/dom/inverted.cpp", - "src/ftxui/dom/italic.cpp", - "src/ftxui/dom/linear_gradient.cpp", - "src/ftxui/dom/node.cpp", - "src/ftxui/dom/node_decorator.cpp", - "src/ftxui/dom/node_decorator.hpp", - "src/ftxui/dom/paragraph.cpp", - "src/ftxui/dom/reflect.cpp", - "src/ftxui/dom/scroll_indicator.cpp", - "src/ftxui/dom/selection.cpp", - "src/ftxui/dom/selection_style.cpp", - "src/ftxui/dom/separator.cpp", - "src/ftxui/dom/size.cpp", - "src/ftxui/dom/spinner.cpp", - "src/ftxui/dom/strikethrough.cpp", - "src/ftxui/dom/table.cpp", - "src/ftxui/dom/text.cpp", - "src/ftxui/dom/underlined.cpp", - "src/ftxui/dom/underlined_double.cpp", - "src/ftxui/dom/util.cpp", - "src/ftxui/dom/vbox.cpp", +# ftxui:screen is a module that provides a screen buffer and color management +# for terminal applications. A screen is a 2D array of cells, each cell can +# contain a glyph, a color, and other attributes. The library also provides +# functions to manipulate the screen. +ftxui_cc_library( + name = "screen", + srcs = [ + "src/ftxui/screen/box.cpp", + "src/ftxui/screen/color.cpp", + "src/ftxui/screen/color_info.cpp", + "src/ftxui/screen/image.cpp", + "src/ftxui/screen/screen.cpp", + "src/ftxui/screen/string.cpp", + "src/ftxui/screen/string_internal.hpp", + "src/ftxui/screen/terminal.cpp", + "src/ftxui/screen/util.hpp", ], - hdrs = [ - "include/ftxui/dom/canvas.hpp", - "include/ftxui/dom/deprecated.hpp", - "include/ftxui/dom/direction.hpp", - "include/ftxui/dom/elements.hpp", - "include/ftxui/dom/flexbox_config.hpp", - "include/ftxui/dom/linear_gradient.hpp", - "include/ftxui/dom/node.hpp", - "include/ftxui/dom/requirement.hpp", - "include/ftxui/dom/selection.hpp", - "include/ftxui/dom/table.hpp", - "include/ftxui/dom/take_any_args.hpp", + hdrs = [ + "include/ftxui/screen/box.hpp", + "include/ftxui/screen/color.hpp", + "include/ftxui/screen/color_info.hpp", + "include/ftxui/screen/deprecated.hpp", + "include/ftxui/screen/image.hpp", + "include/ftxui/screen/pixel.hpp", + "include/ftxui/screen/screen.hpp", + "include/ftxui/screen/string.hpp", + "include/ftxui/screen/terminal.hpp", + "include/ftxui/util/autoreset.hpp", + "include/ftxui/util/ref.hpp", ], - includes = ["include", "src"], - deps = [":screen"], ) +# ftxui:dom is a library that provides a way to create and manipulate a +# "document" that can be rendered to a screen. The document is a tree of nodes. +# Nodes can be text, layouts, or various decorators. Users needs to compose +# nodes to create a document. A document is responsive to the size of the +# screen. +ftxui_cc_library( + name = "dom", + srcs = [ + "src/ftxui/dom/automerge.cpp", + "src/ftxui/dom/blink.cpp", + "src/ftxui/dom/bold.cpp", + "src/ftxui/dom/border.cpp", + "src/ftxui/dom/box_helper.cpp", + "src/ftxui/dom/box_helper.hpp", + "src/ftxui/dom/canvas.cpp", + "src/ftxui/dom/clear_under.cpp", + "src/ftxui/dom/color.cpp", + "src/ftxui/dom/composite_decorator.cpp", + "src/ftxui/dom/dbox.cpp", + "src/ftxui/dom/dim.cpp", + "src/ftxui/dom/flex.cpp", + "src/ftxui/dom/flexbox.cpp", + "src/ftxui/dom/flexbox_config.cpp", + "src/ftxui/dom/flexbox_helper.cpp", + "src/ftxui/dom/flexbox_helper.hpp", + "src/ftxui/dom/focus.cpp", + "src/ftxui/dom/frame.cpp", + "src/ftxui/dom/gauge.cpp", + "src/ftxui/dom/graph.cpp", + "src/ftxui/dom/gridbox.cpp", + "src/ftxui/dom/hbox.cpp", + "src/ftxui/dom/hyperlink.cpp", + "src/ftxui/dom/inverted.cpp", + "src/ftxui/dom/italic.cpp", + "src/ftxui/dom/linear_gradient.cpp", + "src/ftxui/dom/node.cpp", + "src/ftxui/dom/node_decorator.cpp", + "src/ftxui/dom/node_decorator.hpp", + "src/ftxui/dom/paragraph.cpp", + "src/ftxui/dom/reflect.cpp", + "src/ftxui/dom/scroll_indicator.cpp", + "src/ftxui/dom/selection.cpp", + "src/ftxui/dom/selection_style.cpp", + "src/ftxui/dom/separator.cpp", + "src/ftxui/dom/size.cpp", + "src/ftxui/dom/spinner.cpp", + "src/ftxui/dom/strikethrough.cpp", + "src/ftxui/dom/table.cpp", + "src/ftxui/dom/text.cpp", + "src/ftxui/dom/underlined.cpp", + "src/ftxui/dom/underlined_double.cpp", + "src/ftxui/dom/util.cpp", + "src/ftxui/dom/vbox.cpp", + ], + hdrs = [ + "include/ftxui/dom/canvas.hpp", + "include/ftxui/dom/deprecated.hpp", + "include/ftxui/dom/direction.hpp", + "include/ftxui/dom/elements.hpp", + "include/ftxui/dom/flexbox_config.hpp", + "include/ftxui/dom/linear_gradient.hpp", + "include/ftxui/dom/node.hpp", + "include/ftxui/dom/requirement.hpp", + "include/ftxui/dom/selection.hpp", + "include/ftxui/dom/table.hpp", + "include/ftxui/dom/take_any_args.hpp", + ], + deps = [":screen"], +) + +# ftxui:component is a library to create "dynamic" component renderering and +# updating a ftxui::dom document on the screen. It is a higher level API than +# ftxui:dom. +# +# The module is required if your program needs to respond to user input. It +# defines a set of ftxui::Component. These components can be utilized to +# navigate using the arrow keys and/or cursor. There are several builtin widgets +# like checkbox/inputbox/etc to interact with. You can combine them, or even +# define your own custom components. +ftxui_cc_library( + name = "component", + srcs = [ + "src/ftxui/component/animation.cpp", + "src/ftxui/component/button.cpp", + "src/ftxui/component/catch_event.cpp", + "src/ftxui/component/checkbox.cpp", + "src/ftxui/component/collapsible.cpp", + "src/ftxui/component/component.cpp", + "src/ftxui/component/component_options.cpp", + "src/ftxui/component/container.cpp", + "src/ftxui/component/dropdown.cpp", + "src/ftxui/component/event.cpp", + "src/ftxui/component/hoverable.cpp", + "src/ftxui/component/input.cpp", + "src/ftxui/component/loop.cpp", + "src/ftxui/component/maybe.cpp", + "src/ftxui/component/menu.cpp", + "src/ftxui/component/modal.cpp", + "src/ftxui/component/radiobox.cpp", + "src/ftxui/component/renderer.cpp", + "src/ftxui/component/resizable_split.cpp", + "src/ftxui/component/screen_interactive.cpp", + "src/ftxui/component/slider.cpp", + "src/ftxui/component/terminal_input_parser.cpp", + "src/ftxui/component/terminal_input_parser.hpp", + "src/ftxui/component/util.cpp", + "src/ftxui/component/window.cpp", + ], + hdrs = [ + "include/ftxui/component/animation.hpp", + "include/ftxui/component/captured_mouse.hpp", + "include/ftxui/component/component.hpp", + "include/ftxui/component/component_base.hpp", + "include/ftxui/component/component_options.hpp", + "include/ftxui/component/event.hpp", + "include/ftxui/component/loop.hpp", + "include/ftxui/component/mouse.hpp", + "include/ftxui/component/receiver.hpp", + "include/ftxui/component/screen_interactive.hpp", + "include/ftxui/component/task.hpp", + ], + linkopts = ["-lpthread"], + deps = [":dom"], +) + +# FTXUI's tests cc_test( - name = "dom_test", - srcs = [ - "src/ftxui/dom/blink_test.cpp", - "src/ftxui/dom/bold_test.cpp", - "src/ftxui/dom/border_test.cpp", - "src/ftxui/dom/canvas_test.cpp", - "src/ftxui/dom/color_test.cpp", - "src/ftxui/dom/dbox_test.cpp", - "src/ftxui/dom/dim_test.cpp", - "src/ftxui/dom/flexbox_helper_test.cpp", - "src/ftxui/dom/flexbox_test.cpp", - "src/ftxui/dom/gauge_test.cpp", - "src/ftxui/dom/gridbox_test.cpp", - "src/ftxui/dom/hbox_test.cpp", - "src/ftxui/dom/hyperlink_test.cpp", - "src/ftxui/dom/italic_test.cpp", - "src/ftxui/dom/linear_gradient_test.cpp", - "src/ftxui/dom/scroll_indicator_test.cpp", - "src/ftxui/dom/separator_test.cpp", - "src/ftxui/dom/spinner_test.cpp", - "src/ftxui/dom/table_test.cpp", - "src/ftxui/dom/text_test.cpp", - "src/ftxui/dom/underlined_test.cpp", - "src/ftxui/dom/vbox_test.cpp", - ], - deps = [ - "//:dom", - "@googletest//:gtest_main", - ], - includes = ["include", "src"], - copts = ["-std=c++20"], - testonly = True, -) - -#"src/ftxui/dom/benchmark_test.cpp", -cc_library( - name = "component", - srcs = [ - "src/ftxui/component/maybe.cpp", - "src/ftxui/component/hoverable.cpp", - "src/ftxui/component/collapsible.cpp", - "src/ftxui/component/screen_interactive.cpp", - "src/ftxui/component/modal.cpp", - "src/ftxui/component/util.cpp", - "src/ftxui/component/animation.cpp", - "src/ftxui/component/button.cpp", - "src/ftxui/component/dropdown.cpp", - "src/ftxui/component/loop.cpp", - "src/ftxui/component/slider.cpp", - "src/ftxui/component/container.cpp", - "src/ftxui/component/renderer.cpp", - "src/ftxui/component/terminal_input_parser.cpp", - "src/ftxui/component/component_options.cpp", - "src/ftxui/component/resizable_split.cpp", - "src/ftxui/component/component.cpp", - "src/ftxui/component/event.cpp", - "src/ftxui/component/catch_event.cpp", - "src/ftxui/component/input.cpp", - "src/ftxui/component/menu.cpp", - "src/ftxui/component/window.cpp", - "src/ftxui/component/checkbox.cpp", - "src/ftxui/component/radiobox.cpp", - "src/ftxui/component/terminal_input_parser.hpp", - ], - hdrs = [ - "include/ftxui/component/animation.hpp", - "include/ftxui/component/captured_mouse.hpp", - "include/ftxui/component/component.hpp", - "include/ftxui/component/component_base.hpp", - "include/ftxui/component/component_options.hpp", - "include/ftxui/component/event.hpp", - "include/ftxui/component/loop.hpp", - "include/ftxui/component/mouse.hpp", - "include/ftxui/component/receiver.hpp", - "include/ftxui/component/screen_interactive.hpp", - "include/ftxui/component/task.hpp", - ], - includes = [ - "include", - "src", - ], - strip_include_prefix = "", - include_prefix = "", - deps = [":dom"], - linkopts = ["-lpthread"], -) - - #"src/ftxui/component/component_fuzzer.cpp", - #"src/ftxui/component/terminal_input_parser_test_fuzzer.cpp", - #"src/ftxui/component/hoverable_test.cpp", - #"src/ftxui/component/collapsible_test.cpp", - #"src/ftxui/component/toggle_test.cpp", - #"src/ftxui/component/screen_interactive_test.cpp", - #"src/ftxui/component/modal_test.cpp", - #"src/ftxui/component/animation_test.cpp", - #"src/ftxui/component/★ selection_test.cpp", - #"src/ftxui/component/button_test.cpp", - #"src/ftxui/component/dropdown_test.cpp", - #"src/ftxui/component/slider_test.cpp", - #"src/ftxui/component/container_test.cpp", - #"src/ftxui/component/terminal_input_parser_test.cpp", - #"src/ftxui/component/receiver_test.cpp", - #"src/ftxui/component/resizable_split_test.cpp", - #"src/ftxui/component/component_test.cpp", - #"src/ftxui/component/input_test.cpp", - #"src/ftxui/component/menu_test.cpp", - #"src/ftxui/component/radiobox_test.cpp", - -cc_test( - name = "component_test", + name = "tests", + testonly = True, srcs = [ "src/ftxui/component/animation_test.cpp", "src/ftxui/component/button_test.cpp", @@ -242,17 +200,51 @@ cc_test( "src/ftxui/component/menu_test.cpp", "src/ftxui/component/modal_test.cpp", "src/ftxui/component/radiobox_test.cpp", + "src/ftxui/component/receiver_test.cpp", "src/ftxui/component/resizable_split_test.cpp", - "src/ftxui/component/screen_interactive_test.cpp", - "src/ftxui/component/selection_test.cpp", "src/ftxui/component/slider_test.cpp", + "src/ftxui/component/terminal_input_parser_test.cpp", + "src/ftxui/component/terminal_input_parser_test_fuzzer.cpp", "src/ftxui/component/toggle_test.cpp", + "src/ftxui/dom/blink_test.cpp", + "src/ftxui/dom/bold_test.cpp", + "src/ftxui/dom/border_test.cpp", + "src/ftxui/dom/canvas_test.cpp", + "src/ftxui/dom/color_test.cpp", + "src/ftxui/dom/dbox_test.cpp", + "src/ftxui/dom/dim_test.cpp", + "src/ftxui/dom/flexbox_helper_test.cpp", + "src/ftxui/dom/flexbox_test.cpp", + "src/ftxui/dom/gauge_test.cpp", + "src/ftxui/dom/gridbox_test.cpp", + "src/ftxui/dom/hbox_test.cpp", + "src/ftxui/dom/hyperlink_test.cpp", + "src/ftxui/dom/italic_test.cpp", + "src/ftxui/dom/linear_gradient_test.cpp", + "src/ftxui/dom/scroll_indicator_test.cpp", + "src/ftxui/dom/separator_test.cpp", + "src/ftxui/dom/spinner_test.cpp", + "src/ftxui/dom/table_test.cpp", + "src/ftxui/dom/text_test.cpp", + "src/ftxui/dom/underlined_test.cpp", + "src/ftxui/dom/vbox_test.cpp", + "src/ftxui/screen/color_test.cpp", + "src/ftxui/screen/string_test.cpp", + "src/ftxui/util/ref_test.cpp", + + # TODO: Enable the two tests timing out with Bazel: + # - "src/ftxui/component/screen_interactive_test.cpp", + # - "src/ftxui/dom/selection_test.cpp", + ], + copts = ["-std=c++20"], + includes = [ + "include", + "src", ], deps = [ - "//:component", + "//:ftxui", "@googletest//:gtest_main", ], - includes = ["include", "src"], - copts = ["-std=c++20"], - testonly = True, - ) +) + +generate_examples() diff --git a/CMakeLists.txt b/CMakeLists.txt index 0af94e52..1401920e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12) project(ftxui LANGUAGES CXX - VERSION 6.0.2 + VERSION 6.0.3 DESCRIPTION "C++ Functional Terminal User Interface." ) @@ -17,7 +17,7 @@ option(FTXUI_ENABLE_COVERAGE "Execute code coverage" OFF) option(FTXUI_DEV_WARNINGS "Enable more compiler warnings and warnings as errors" OFF) set(FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT "On windows, assume the \ -terminal used will be one of Microsoft and use a set of reasonnable fallback \ +terminal used will be one of Microsoft and use a set of reasonable fallback \ to counteract its implementations problems.") if (WIN32) option(FTXUI_MICROSOFT_TERMINAL_FALLBACK diff --git a/MODULE.bazel b/MODULE.bazel index 8284154f..af988d1e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,18 +1,20 @@ -# Module. +# FTXUI Module. module( - name = "ftxui", - version = "6.0.2", + name = "ftxui", + version = "6.0.3", ) # Build deps. bazel_dep(name = "rules_cc", version = "0.0.17") +bazel_dep(name = "platforms", version = "0.0.10") +bazel_dep(name = "bazel_skylib", version = "1.7.1") # Test deps. bazel_dep(name = "googletest", version = "1.15.2") # Toolchain deps. -cc_configure = use_extension( - "@rules_cc//bzlmod:extensions.bzl", - "cc_configure", -) -use_repo(cc_configure, "local_config_cc_toolchains") +#cc_configure = use_extension( +#"@rules_cc//bzlmod:extensions.bzl", +#"cc_configure", +#) +#use_repo(cc_configure, "local_config_cc_toolchains") diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index 945e96dd..00000000 --- a/WORKSPACE +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "ftxui") diff --git a/examples/component/slider_direction.cpp b/examples/component/slider_direction.cpp index 4a6c3bad..77f466c8 100644 --- a/examples/component/slider_direction.cpp +++ b/examples/component/slider_direction.cpp @@ -19,7 +19,7 @@ using namespace ftxui; int main() { auto screen = ScreenInteractive::TerminalOutput(); std::array values; - for (int i = 0; i < values.size(); ++i) { + for (size_t i = 0; i < values.size(); ++i) { values[i] = 50 + 20 * std::sin(i * 0.3); } diff --git a/examples/dom/color_truecolor_RGB.cpp b/examples/dom/color_truecolor_RGB.cpp index 6a8d1f3c..5f0985ba 100644 --- a/examples/dom/color_truecolor_RGB.cpp +++ b/examples/dom/color_truecolor_RGB.cpp @@ -12,7 +12,6 @@ int main() { using namespace ftxui; - int saturation = 255; Elements red_line; Elements green_line; Elements blue_line; diff --git a/include/ftxui/component/component_base.hpp b/include/ftxui/component/component_base.hpp index e0fd527e..fcc67e16 100644 --- a/include/ftxui/component/component_base.hpp +++ b/include/ftxui/component/component_base.hpp @@ -42,8 +42,8 @@ class ComponentBase { // Component hierarchy: ComponentBase* Parent() const; - Component& ChildAt(int i); - int ChildCount() const; + Component& ChildAt(size_t i); + size_t ChildCount() const; int Index() const; void Add(Component children); void Detach(); diff --git a/src/ftxui/component/menu_test.cpp b/src/ftxui/component/menu_test.cpp index ca099468..de3182ab 100644 --- a/src/ftxui/component/menu_test.cpp +++ b/src/ftxui/component/menu_test.cpp @@ -266,7 +266,7 @@ TEST(MenuTest, MenuEntryIndex) { menu->OnEvent(Event::ArrowDown); menu->OnEvent(Event::ArrowDown); menu->OnEvent(Event::Return); - for (int index = 0; index < menu->ChildCount(); index++) { + for (size_t index = 0; index < menu->ChildCount(); index++) { EXPECT_EQ(menu->ChildAt(index)->Index(), index); } } diff --git a/src/ftxui/component/selection_test.cpp b/src/ftxui/component/selection_test.cpp deleted file mode 100644 index 8f29c177..00000000 --- a/src/ftxui/component/selection_test.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2022 Arthur Sonzogni. All rights reserved. -// Use of this source code is governed by the MIT license that can be found in -// the LICENSE file. -#include -#include // for raise, SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM - -#include "ftxui/component/component.hpp" // for Input, Renderer, Vertical -#include "ftxui/component/event.hpp" // for Event -#include "ftxui/component/loop.hpp" // for Loop -#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed, Mouse::Released -#include "ftxui/component/screen_interactive.hpp" -#include "ftxui/dom/elements.hpp" // for text -#include "ftxui/dom/node.hpp" // for Render -#include "ftxui/screen/screen.hpp" // for Screen - -// NOLINTBEGIN -namespace ftxui { - -namespace { -Event MousePressed(int x, int y) { - Mouse mouse; - mouse.button = Mouse::Left; - mouse.motion = Mouse::Pressed; - mouse.shift = false; - mouse.meta = false; - mouse.control = false; - mouse.x = x; - mouse.y = y; - return Event::Mouse("", mouse); -} - -Event MouseReleased(int x, int y) { - Mouse mouse; - mouse.button = Mouse::Left; - mouse.motion = Mouse::Released; - mouse.shift = false; - mouse.meta = false; - mouse.control = false; - mouse.x = x; - mouse.y = y; - return Event::Mouse("", mouse); -} - -Event MouseMove(int x, int y) { - Mouse mouse; - mouse.button = Mouse::Left; - mouse.motion = Mouse::Moved; - mouse.shift = false; - mouse.meta = false; - mouse.control = false; - mouse.x = x; - mouse.y = y; - return Event::Mouse("", mouse); -} - -} // namespace - -TEST(SelectionTest, DefaultSelection) { - auto component = Renderer([&] { return text("Lorem ipsum dolor"); }); - auto screen = ScreenInteractive::FixedSize(20, 1); - EXPECT_EQ(screen.GetSelection(), ""); - Loop loop(&screen, component); - screen.PostEvent(MousePressed(3, 1)); - screen.PostEvent(MouseReleased(10, 1)); - loop.RunOnce(); - - EXPECT_EQ(screen.GetSelection(), "rem ipsu"); -} - -TEST(SelectionTest, SelectionChange) { - int selectionChangeCounter = 0; - auto component = Renderer([&] { return text("Lorem ipsum dolor"); }); - auto screen = ScreenInteractive::FixedSize(20, 1); - screen.SelectionChange([&] { selectionChangeCounter++; }); - - Loop loop(&screen, component); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 0); - - screen.PostEvent(MousePressed(3, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 0); - - screen.PostEvent(MouseMove(5, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 1); - - screen.PostEvent(MouseMove(7, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 2); - - screen.PostEvent(MouseReleased(10, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 3); - - screen.PostEvent(MouseMove(10, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 3); - - EXPECT_EQ(screen.GetSelection(), "rem ipsu"); -} - -// Check that submitting multiple mouse events quickly doesn't trigger multiple -// selection change events. -TEST(SelectionTest, SelectionOnChangeSquashedEvents) { - int selectionChangeCounter = 0; - auto component = Renderer([&] { return text("Lorem ipsum dolor"); }); - auto screen = ScreenInteractive::FixedSize(20, 1); - screen.SelectionChange([&] { selectionChangeCounter++; }); - - Loop loop(&screen, component); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 0); - - screen.PostEvent(MousePressed(3, 1)); - screen.PostEvent(MouseMove(5, 1)); - screen.PostEvent(MouseMove(7, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 1); - - screen.PostEvent(MouseReleased(10, 1)); - screen.PostEvent(MouseMove(10, 1)); - loop.RunOnce(); - EXPECT_EQ(selectionChangeCounter, 2); - - EXPECT_EQ(screen.GetSelection(), "rem ipsu"); -} - -TEST(SelectionTest, StyleSelection) { - auto element = hbox({ - text("Lorem "), - text("ipsum") | selectionColor(Color::Red), - text(" dolor"), - }); - - auto screen = ScreenInteractive::FixedSize(20, 1); - Selection selection(2, 0, 9, 0); - - Render(screen, element.get(), selection); - for (int i = 0; i < 20; i++) { - if (i >= 2 && i <= 9) { - EXPECT_EQ(screen.PixelAt(i, 0).inverted, true); - } else { - EXPECT_EQ(screen.PixelAt(i, 0).inverted, false); - } - - if (i >= 6 && i <= 9) { - EXPECT_EQ(screen.PixelAt(i, 0).foreground_color, Color::Red); - } else { - EXPECT_EQ(screen.PixelAt(i, 0).foreground_color, Color::Default); - } - } -} - -TEST(SelectionTest, VBoxSelection) { - auto element = vbox({ - text("Lorem ipsum dolor"), - text("Ut enim ad minim"), - }); - - auto screen = ScreenInteractive::FixedSize(20, 2); - - Selection selection(2, 0, 2, 1); - Render(screen, element.get(), selection); - - EXPECT_EQ(selection.GetParts(), "rem ipsum dolor\nUt "); - EXPECT_EQ(screen.ToString(), - "Lo\x1B[7mrem ipsum dolor\x1B[27m \r\n" - "\x1B[7mUt \x1B[27menim ad minim "); -} - -TEST(SelectionTest, VBoxSaturatedSelection) { - auto element = vbox({ - text("Lorem ipsum dolor"), - text("Ut enim ad minim"), - text("Duis aute irure"), - }); - - auto screen = ScreenInteractive::FixedSize(20, 3); - Selection selection(2, 0, 2, 2); - Render(screen, element.get(), selection); - EXPECT_EQ(selection.GetParts(), "rem ipsum dolor\nUt enim ad minim\nDui"); - - EXPECT_EQ(screen.ToString(), - "Lo\x1B[7mrem ipsum dolor\x1B[27m \r\n" - "\x1B[7mUt enim ad minim\x1B[27m \r\n" - "\x1B[7mDui\x1B[27ms aute irure "); -} - -TEST(SelectionTest, HBoxSelection) { - auto element = hbox({ - text("Lorem ipsum dolor"), - text("Ut enim ad minim"), - }); - - auto screen = ScreenInteractive::FixedSize(40, 1); - Selection selection(2, 0, 20, 0); - Render(screen, element.get(), selection); - EXPECT_EQ(selection.GetParts(), "rem ipsum dolorUt e"); - EXPECT_EQ(screen.ToString(), - "Lo\x1B[7mrem ipsum dolorUt e\x1B[27mnim ad minim "); -} - -TEST(SelectionTest, HBoxSaturatedSelection) { - auto element = hbox({ - text("Lorem ipsum dolor"), - text("Ut enim ad minim"), - text("Duis aute irure"), - }); - - auto screen = ScreenInteractive::FixedSize(60, 1); - - Selection selection(2, 0, 35, 0); - Render(screen, element.get(), selection); - EXPECT_EQ(selection.GetParts(), "rem ipsum dolorUt enim ad minimDui"); - EXPECT_EQ(screen.ToString(), - "Lo\x1B[7mrem ipsum dolorUt enim ad minimDui\x1B[27ms aute irure " - " "); -} - -} // namespace ftxui -// NOLINTEND