#include "colormanager.h" #include #include #include #include "3rd-party/catch.hpp" #include "confighandlerexception.h" using namespace newsboat; TEST_CASE( "colors_loaded() signals if any \"color\" actions have been processed", "[ColorManager]") { ColorManager c; { INFO("By default, no colors are loaded"); REQUIRE_FALSE(c.colors_loaded()); } { INFO("Processing \"color\" action makes it return `true`"); c.handle_action("color", {"listnormal", "default", "default"}); REQUIRE(c.colors_loaded()); } { INFO("Processing more \"color\" actions doesn't affect the " "return value"); c.handle_action("color", {"listfocus", "default", "default"}); REQUIRE(c.colors_loaded()); c.handle_action( "color", {"listfocus_unread", "default", "cyan"}); REQUIRE(c.colors_loaded()); } } TEST_CASE( "get_fgcolors() returns foreground colors for each element that " "was processed", "[ColorManager]") { using results = std::map; ColorManager c; { INFO("By default, the list is empty"); REQUIRE(c.get_fgcolors().empty()); } { INFO("Each processed action adds corresponding entry to return " "value"); c.handle_action("color", {"listnormal", "default", "default"}); results expected{{"listnormal", "default"}}; REQUIRE(c.get_fgcolors() == expected); c.handle_action("color", {"listfocus", "cyan", "default"}); expected.emplace("listfocus", "cyan"); REQUIRE(c.get_fgcolors() == expected); c.handle_action("color", {"background", "red", "default"}); expected.emplace("background", "red"); REQUIRE(c.get_fgcolors() == expected); } } TEST_CASE( "get_bgcolors() returns foreground colors for each element that " "was processed", "[ColorManager]") { using results = std::map; ColorManager c; { INFO("By default, the list is empty"); REQUIRE(c.get_bgcolors().empty()); } { INFO("Each processed action adds corresponding entry to return " "value"); c.handle_action("color", {"listnormal", "default", "default"}); results expected{{"listnormal", "default"}}; REQUIRE(c.get_bgcolors() == expected); c.handle_action("color", {"listfocus", "cyan", "yellow"}); expected.emplace("listfocus", "yellow"); REQUIRE(c.get_bgcolors() == expected); c.handle_action("color", {"background", "red", "green"}); expected.emplace("background", "green"); REQUIRE(c.get_bgcolors() == expected); } } TEST_CASE("register_commands() registers ColorManager with ConfigParser", "[ColorManager]") { ConfigParser cfg; ColorManager clr; REQUIRE_NOTHROW(clr.register_commands(cfg)); REQUIRE_FALSE(clr.colors_loaded()); cfg.parse("data/config-with-colors"); REQUIRE(clr.colors_loaded()); } TEST_CASE( "handle_action() throws ConfigHandlerException if there aren't " "enough parameters", "[ColorManager]") { ColorManager c; CHECK_THROWS_AS(c.handle_action("color", {}), ConfigHandlerException); CHECK_THROWS_AS( c.handle_action("color", {"one"}), ConfigHandlerException); CHECK_THROWS_AS(c.handle_action("color", {"one", "two"}), ConfigHandlerException); } TEST_CASE( "handle_action() throws ConfigHandlerException if foreground color " "is invalid", "[ColorManager]") { ColorManager c; const std::vector non_colors{ {"awesome", "but", "nonexistent", "colors"}}; for (const auto& color : non_colors) { CHECK_THROWS_AS(c.handle_action("color", {"listfocus", color, "default"}), ConfigHandlerException); } } TEST_CASE( "handle_action() throws ConfigHandlerException if background color " "is invalid", "[ColorManager]") { ColorManager c; const std::vector non_colors{ {"awesome", "but", "nonexistent", "colors"}}; for (const auto& color : non_colors) { CHECK_THROWS_AS(c.handle_action("color", {"listfocus", "default", color}), ConfigHandlerException); } } TEST_CASE( "handle_action() throws ConfigHandlerException if color attribute " "is invalid", "[ColorManager]") { ColorManager c; const std::vector non_attributes{ {"awesome", "but", "nonexistent", "attributes"}}; for (const auto& attr : non_attributes) { CHECK_THROWS_AS(c.handle_action("color", {"listfocus", "red", "red", attr}), ConfigHandlerException); } } TEST_CASE( "handle_action() throws ConfigHandlerException if color is applied " "to non-existent element", "[ColorManager]") { ColorManager c; const std::vector non_elements{ {"awesome", "but", "nonexistent", "elements"}}; for (const auto& element : non_elements) { CHECK_THROWS_AS( c.handle_action("color", {element, "red", "green"}), ConfigHandlerException); } } TEST_CASE( "handle_action() throws ConfigHandlerException if it's passed a " "command other than \"color\"", "[ColorManager]") { ColorManager c; const std::vector other_commands{ {"browser", "include", "auto-reload", "ocnews-flag-star"}}; for (const auto& command : other_commands) { CHECK_THROWS_AS( c.handle_action(command, {}), ConfigHandlerException); } } TEST_CASE("dump_config() returns everything we put into ColorManager", "[ColorManager]") { ColorManager c; std::unordered_set expected; std::vector config; // Checks that `expected` contains the same lines as `config` contains, // and nothing more. auto equivalent = [&]() -> bool { std::size_t found = 0; for (const auto& line : config) { if (expected.find(line) == expected.end()) return false; found++; } return found == expected.size(); }; { INFO("Empty ColorManager outputs nothing"); c.dump_config(config); REQUIRE(config.empty()); REQUIRE(equivalent()); } expected.emplace("color listfocus default red"); c.handle_action("color", {"listfocus", "default", "red"}); config.clear(); c.dump_config(config); REQUIRE(config.size() == 1); REQUIRE(equivalent()); expected.emplace("color background green cyan bold"); c.handle_action("color", {"background", "green", "cyan", "bold"}); config.clear(); c.dump_config(config); REQUIRE(config.size() == 2); REQUIRE(equivalent()); expected.emplace("color listnormal black yellow underline standout"); c.handle_action("color", {"listnormal", "black", "yellow", "underline", "standout"}); config.clear(); c.dump_config(config); REQUIRE(config.size() == 3); REQUIRE(equivalent()); }