diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4faaef07..18b5514b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -15,6 +15,7 @@ jobs: test: name: "Tests" strategy: + fail-fast: false matrix: include: - name: Linux GCC diff --git a/README.md b/README.md index 2312fecf..47781f80 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ + + + +
Documentation · diff --git a/cmake/ftxui_test.cmake b/cmake/ftxui_test.cmake index 2ed92bad..fd1dd79e 100644 --- a/cmake/ftxui_test.cmake +++ b/cmake/ftxui_test.cmake @@ -32,6 +32,12 @@ add_executable(tests src/ftxui/component/screen_interactive_test.cpp src/ftxui/component/terminal_input_parser_test.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/separator_test.cpp + src/ftxui/dom/color_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 @@ -39,7 +45,9 @@ add_executable(tests src/ftxui/dom/hbox_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 ) @@ -54,7 +62,10 @@ target_include_directories(tests ftxui_set_options(tests) include(GoogleTest) -gtest_discover_tests(tests) +gtest_discover_tests(tests + DISCOVERY_TIMEOUT 600 +) + include(cmake/ftxui_benchmark.cmake) diff --git a/include/ftxui/screen/terminal.hpp b/include/ftxui/screen/terminal.hpp index 91574d88..2ec3bbb7 100644 --- a/include/ftxui/screen/terminal.hpp +++ b/include/ftxui/screen/terminal.hpp @@ -18,6 +18,8 @@ enum Color { TrueColor, }; Color ColorSupport(); +void SetColorSupport(Color color); + } // namespace Terminal } // namespace ftxui diff --git a/src/ftxui/dom/blink_test.cpp b/src/ftxui/dom/blink_test.cpp new file mode 100644 index 00000000..1b02a4fe --- /dev/null +++ b/src/ftxui/dom/blink_test.cpp @@ -0,0 +1,21 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(BlinkTest, Basic) { + auto element = text("text") | blink; + Screen screen(5, 1); + Render(screen, element); + EXPECT_TRUE(screen.PixelAt(0,0).blink); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/bold_test.cpp b/src/ftxui/dom/bold_test.cpp new file mode 100644 index 00000000..d1f87cab --- /dev/null +++ b/src/ftxui/dom/bold_test.cpp @@ -0,0 +1,21 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(BoldTest, Basic) { + auto element = text("text") | bold; + Screen screen(5, 1); + Render(screen, element); + EXPECT_TRUE(screen.PixelAt(0,0).bold); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/border_test.cpp b/src/ftxui/dom/border_test.cpp new file mode 100644 index 00000000..153de6be --- /dev/null +++ b/src/ftxui/dom/border_test.cpp @@ -0,0 +1,96 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(BorderTest, Default) { + auto element = text("text") | border; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "╭───╮\r\n" + "│tex│\r\n" + "╰───╯"); +} + +TEST(BorderTest, Light) { + auto element = text("text") | borderLight; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "┌───┐\r\n" + "│tex│\r\n" + "└───┘"); +} + +TEST(BorderTest, Double) { + auto element = text("text") | borderDouble; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "╔═══╗\r\n" + "║tex║\r\n" + "╚═══╝"); +} + +TEST(BorderTest, Rounded) { + auto element = text("text") | borderRounded; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "╭───╮\r\n" + "│tex│\r\n" + "╰───╯"); +} + +TEST(BorderTest, Heavy) { + auto element = text("text") | borderHeavy; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "┏━━━┓\r\n" + "┃tex┃\r\n" + "┗━━━┛"); +} + +TEST(BorderTest, Empty) { + auto element = text("text") | borderEmpty; + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + " \r\n" + " tex \r\n" + " "); +} + +TEST(BorderTest, Styled) { + auto element = text("text") | borderStyled(DOUBLE); + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "╔═══╗\r\n" + "║tex║\r\n" + "╚═══╝"); +} + +TEST(BorderTest, WithPixel) { + Pixel pixel; + pixel.character = "o"; + auto element = text("text") | borderWith(pixel); + Screen screen(5, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "ooooo\r\n" + "otexo\r\n" + "ooooo"); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/color_test.cpp b/src/ftxui/dom/color_test.cpp new file mode 100644 index 00000000..b49306e8 --- /dev/null +++ b/src/ftxui/dom/color_test.cpp @@ -0,0 +1,30 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(ColorTest, Foreground) { + auto element = text("text") | color(Color::Red); + Screen screen(5, 1); + Render(screen, element); + EXPECT_EQ(screen.PixelAt(0, 0).foreground_color, Color::Red); + EXPECT_EQ(screen.PixelAt(0, 0).background_color, Color()); +} + +TEST(ColorTest, Background) { + auto element = text("text") | bgcolor(Color::Red); + Screen screen(5, 1); + Render(screen, element); + EXPECT_EQ(screen.PixelAt(0, 0).foreground_color, Color()); + EXPECT_EQ(screen.PixelAt(0, 0).background_color, Color::Red); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/dim_test.cpp b/src/ftxui/dom/dim_test.cpp new file mode 100644 index 00000000..b0e0056a --- /dev/null +++ b/src/ftxui/dom/dim_test.cpp @@ -0,0 +1,21 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(DimTest, Basic) { + auto element = text("text") | dim; + Screen screen(5, 1); + Render(screen, element); + EXPECT_TRUE(screen.PixelAt(0,0).dim); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/separator_test.cpp b/src/ftxui/dom/separator_test.cpp new file mode 100644 index 00000000..f678da91 --- /dev/null +++ b/src/ftxui/dom/separator_test.cpp @@ -0,0 +1,114 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(SeparatorTest, Default) { + auto element = vbox({ + text("top"), + separator(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "────\r\n" + "down"); +} + +TEST(SeparatorTest, Light) { + auto element = vbox({ + text("top"), + separatorLight(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "────\r\n" + "down"); +} + +TEST(SeparatorTest, Double) { + auto element = vbox({ + text("top"), + separatorDouble(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "════\r\n" + "down"); +} + +TEST(SeparatorTest, Heavy) { + auto element = vbox({ + text("top"), + separatorHeavy(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "━━━━\r\n" + "down"); +} + +TEST(SeparatorTest, Empty) { + auto element = vbox({ + text("top"), + separatorEmpty(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + " \r\n" + "down"); +} + +TEST(SeparatorTest, Styled) { + auto element = vbox({ + text("top"), + separatorStyled(DOUBLE), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "════\r\n" + "down"); +} + +TEST(SeparatorTest, WithPixel) { + Pixel pixel; + pixel.character = "o"; + auto element = vbox({ + text("top"), + separator(pixel), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "oooo\r\n" + "down"); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/dom/underlined_test.cpp b/src/ftxui/dom/underlined_test.cpp new file mode 100644 index 00000000..2b0e6b88 --- /dev/null +++ b/src/ftxui/dom/underlined_test.cpp @@ -0,0 +1,21 @@ +#include // for Message +#include // for SuiteApiResolver, TestFactoryImpl, TestPartResult +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include // for allocator +#include "ftxui/dom/elements.hpp" // for text, flexbox +#include "ftxui/screen/screen.hpp" // for Screen + +namespace ftxui { + +TEST(UnderlinedTest, Basic) { + auto element = text("text") | underlined; + Screen screen(5, 1); + Render(screen, element); + EXPECT_TRUE(screen.PixelAt(0,0).underlined); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/screen/color.cpp b/src/ftxui/screen/color.cpp index 0394f40a..33e1d075 100644 --- a/src/ftxui/screen/color.cpp +++ b/src/ftxui/screen/color.cpp @@ -53,12 +53,12 @@ std::string Color::Print(bool is_background_color) const { return (is_background_color ? "48;5;"s : "38;5;"s) + std::to_string(red_); case ColorType::TrueColor: + default: return (is_background_color ? "48;2;"s : "38;2;"s) // + std::to_string(red_) + ";" // + std::to_string(green_) + ";" // + std::to_string(blue_); // } - return ""; } /// @brief Build a transparent color. @@ -96,7 +96,7 @@ Color::Color(uint8_t red, uint8_t green, uint8_t blue) return; } - // Find the closest coor from the database: + // Find the closest Color from the database: const int max_distance = 256 * 256 * 3; int closest = max_distance; int best = 0; diff --git a/src/ftxui/screen/color_test.cpp b/src/ftxui/screen/color_test.cpp new file mode 100644 index 00000000..07c771d6 --- /dev/null +++ b/src/ftxui/screen/color_test.cpp @@ -0,0 +1,47 @@ +#include "ftxui/screen/color.hpp" +#include // for Message +#include // for TestPartResult, SuiteApiResolver, TestFactoryImpl +#include "ftxui/screen/terminal.hpp" +#include "gtest/gtest_pred_impl.h" // for EXPECT_EQ, Test, TEST + +namespace ftxui { + +TEST(ColorTest, PrintTransparent) { + Terminal::SetColorSupport(Terminal::Color::TrueColor); + EXPECT_EQ(Color().Print(false), "39"); + EXPECT_EQ(Color().Print(true), "49"); +} + +TEST(ColorTest, PrintColor16) { + Terminal::SetColorSupport(Terminal::Color::TrueColor); + EXPECT_EQ(Color(Color::Red).Print(false), "31"); + EXPECT_EQ(Color(Color::Red).Print(true), "41"); +} + +TEST(ColorTest, PrintColor256) { + Terminal::SetColorSupport(Terminal::Color::TrueColor); + EXPECT_EQ(Color(Color::DarkRed).Print(false), "38;5;52"); + EXPECT_EQ(Color(Color::DarkRed).Print(true), "48;5;52"); +} + +TEST(ColorTest, PrintTrueCOlor) { + Terminal::SetColorSupport(Terminal::Color::TrueColor); + EXPECT_EQ(Color::RGB(1,2,3).Print(false), "38;2;1;2;3"); + EXPECT_EQ(Color::RGB(1,2,3).Print(true), "48;2;1;2;3"); +} + +TEST(ColorTest, FallbackTo256) { + Terminal::SetColorSupport(Terminal::Color::Palette256); + EXPECT_EQ(Color::RGB(1,2,3).Print(false), "38;5;16"); +} + +TEST(ColorTest, FallbackTo16) { + Terminal::SetColorSupport(Terminal::Color::Palette16); + EXPECT_EQ(Color::RGB(1,2,3).Print(false), "30"); +} + +} // namespace ftxui + +// 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. diff --git a/src/ftxui/screen/terminal.cpp b/src/ftxui/screen/terminal.cpp index e6341eaa..971db344 100644 --- a/src/ftxui/screen/terminal.cpp +++ b/src/ftxui/screen/terminal.cpp @@ -19,6 +19,10 @@ namespace ftxui { namespace { + +bool g_cached = false; +Terminal::Color g_cached_supported_color; + Dimensions& FallbackSize() { #if defined(__EMSCRIPTEN__) // This dimension was chosen arbitrarily to be able to display: @@ -76,7 +80,8 @@ Terminal::Color ComputeColorSupport() { } // namespace -Dimensions Terminal::Size() { +namespace Terminal { +Dimensions Size() { #if defined(__EMSCRIPTEN__) // This dimension was chosen arbitrarily to be able to display: // https://arthursonzogni.com/FTXUI/examples @@ -106,20 +111,24 @@ Dimensions Terminal::Size() { /// @brief Override terminal size in case auto-detection fails /// @param fallbackSize Terminal dimensions to fallback to -void Terminal::SetFallbackSize(const Dimensions& fallbackSize) { +void SetFallbackSize(const Dimensions& fallbackSize) { FallbackSize() = fallbackSize; } -Terminal::Color Terminal::ColorSupport() { - static bool cached = false; - static Terminal::Color cached_supported_color; - if (!cached) { - cached = true; - cached_supported_color = ComputeColorSupport(); +Color ColorSupport() { + if (!g_cached) { + g_cached = true; + g_cached_supported_color = ComputeColorSupport(); } - return cached_supported_color; + return g_cached_supported_color; } +void SetColorSupport(Color color) { + g_cached = true; + g_cached_supported_color = color; +} + +} // namespace Terminal } // namespace ftxui // Copyright 2020 Arthur Sonzogni. All rights reserved.