From 04b36df56793689a48796a7bbedef2590b06d950 Mon Sep 17 00:00:00 2001
From: Arthur Sonzogni <sonzogniarthur@gmail.com>
Date: Tue, 26 Apr 2022 17:04:34 +0200
Subject: [PATCH] Coverage decorator (#384)

Add code coverage for colors and decorators.
---
 .github/workflows/build.yaml      |   1 +
 README.md                         |   4 ++
 cmake/ftxui_test.cmake            |  13 +++-
 include/ftxui/screen/terminal.hpp |   2 +
 src/ftxui/dom/blink_test.cpp      |  21 ++++++
 src/ftxui/dom/bold_test.cpp       |  21 ++++++
 src/ftxui/dom/border_test.cpp     |  96 +++++++++++++++++++++++++
 src/ftxui/dom/color_test.cpp      |  30 ++++++++
 src/ftxui/dom/dim_test.cpp        |  21 ++++++
 src/ftxui/dom/separator_test.cpp  | 114 ++++++++++++++++++++++++++++++
 src/ftxui/dom/underlined_test.cpp |  21 ++++++
 src/ftxui/screen/color.cpp        |   4 +-
 src/ftxui/screen/color_test.cpp   |  47 ++++++++++++
 src/ftxui/screen/terminal.cpp     |  27 ++++---
 14 files changed, 410 insertions(+), 12 deletions(-)
 create mode 100644 src/ftxui/dom/blink_test.cpp
 create mode 100644 src/ftxui/dom/bold_test.cpp
 create mode 100644 src/ftxui/dom/border_test.cpp
 create mode 100644 src/ftxui/dom/color_test.cpp
 create mode 100644 src/ftxui/dom/dim_test.cpp
 create mode 100644 src/ftxui/dom/separator_test.cpp
 create mode 100644 src/ftxui/dom/underlined_test.cpp
 create mode 100644 src/ftxui/screen/color_test.cpp

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 @@
   <a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
   <a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/ArthurSonzogni/FTXUI"></img></a>
   <a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors"><img src="https://img.shields.io/github/contributors/arthursonzogni/FTXUI?color=blue"></img></a>
+  <a href="https://codecov.io/gh/ArthurSonzogni/FTXUI">
+    <img src="https://codecov.io/gh/ArthurSonzogni/FTXUI/branch/master/graph/badge.svg?token=C41FdRpNVA"/>
+  </a>
+
   
   <br/>
   <a href="https://arthursonzogni.github.io/FTXUI/">Documentation</a> ·
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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for SuiteApiResolver, TestFactoryImpl, TestPartResult
+#include "gtest/gtest_pred_impl.h"       // for Test, EXPECT_EQ, TEST
+#include <string>                   // 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 <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // 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.
-- 
GitLab