From fdaecdb113752f6ed65a33263d37519f9c0ab4c3 Mon Sep 17 00:00:00 2001 From: patrick96 Date: Sat, 5 Mar 2022 13:00:05 +0100 Subject: [PATCH] tests: Use fake renderer for dispatch test --- include/tags/context.hpp | 18 ++-- include/tags/dispatch.hpp | 1 + src/tags/dispatch.cpp | 14 +-- tests/unit_tests/tags/dispatch.cpp | 154 ++++++++++++----------------- 4 files changed, 79 insertions(+), 108 deletions(-) diff --git a/include/tags/context.hpp b/include/tags/context.hpp index 798e5c9e..47965547 100644 --- a/include/tags/context.hpp +++ b/include/tags/context.hpp @@ -47,39 +47,39 @@ namespace tags { /** * Background color */ - rgba m_bg; + rgba m_bg{}; /** * Foreground color */ - rgba m_fg; + rgba m_fg{}; /** * Overline color */ - rgba m_ol; + rgba m_ol{}; /** * Underline color */ - rgba m_ul; + rgba m_ul{}; /** * Font index (1-based) */ - int m_font; + int m_font{0}; /** * Is overline enabled? */ - bool m_attr_overline; + bool m_attr_overline{false}; /** * Is underline enabled? */ - bool m_attr_underline; + bool m_attr_underline{false}; /** * Alignment block */ - alignment m_align; + alignment m_align{alignment::NONE}; private: const bar_settings& m_settings; }; -} // namespace tags +} // namespace tags POLYBAR_NS_END diff --git a/include/tags/dispatch.hpp b/include/tags/dispatch.hpp index 3e9453b5..db6deb7e 100644 --- a/include/tags/dispatch.hpp +++ b/include/tags/dispatch.hpp @@ -32,6 +32,7 @@ namespace tags { void handle_text(renderer_interface& renderer, string&& data); void handle_action(renderer_interface& renderer, mousebtn btn, bool closing, const string&& cmd); void handle_offset(renderer_interface& renderer, extent_val offset); + void handle_alignment(renderer_interface& renderer, alignment a); void handle_control(controltag ctrl); private: diff --git a/src/tags/dispatch.cpp b/src/tags/dispatch.cpp index 0a1a3f43..f2174664 100644 --- a/src/tags/dispatch.cpp +++ b/src/tags/dispatch.cpp @@ -77,16 +77,13 @@ namespace tags { handle_control(el.tag_data.ctrl); break; case tags::syntaxtag::l: - m_ctxt->apply_alignment(alignment::LEFT); - renderer.change_alignment(*m_ctxt); + handle_alignment(renderer, alignment::LEFT); break; case tags::syntaxtag::r: - m_ctxt->apply_alignment(alignment::RIGHT); - renderer.change_alignment(*m_ctxt); + handle_alignment(renderer, alignment::RIGHT); break; case tags::syntaxtag::c: - m_ctxt->apply_alignment(alignment::CENTER); - renderer.change_alignment(*m_ctxt); + handle_alignment(renderer, alignment::CENTER); break; default: throw runtime_error( @@ -150,6 +147,11 @@ namespace tags { renderer.render_offset(*m_ctxt, offset); } + void dispatch::handle_alignment(renderer_interface& renderer, alignment a) { + m_ctxt->apply_alignment(a); + renderer.change_alignment(*m_ctxt); + } + void dispatch::handle_control(controltag ctrl) { switch (ctrl) { case controltag::R: diff --git a/tests/unit_tests/tags/dispatch.cpp b/tests/unit_tests/tags/dispatch.cpp index 309e4002..2ead75b1 100644 --- a/tests/unit_tests/tags/dispatch.cpp +++ b/tests/unit_tests/tags/dispatch.cpp @@ -21,15 +21,69 @@ namespace polybar { } } // namespace polybar +/** + * Fake renderer that just tracks the current x-position per alignment. + * + * Each text character and point is treated as a single pixel. + */ +class FakeRenderer : public renderer_interface { + public: + FakeRenderer(action_context& action_ctxt) : renderer_interface(action_ctxt){}; + + void render_offset(const tags::context& ctxt, const extent_val offset) override { + block_x[ctxt.get_alignment()] += offset.value; + }; + + void render_text(const tags::context& ctxt, const string&& str) override { + block_x[ctxt.get_alignment()] += str.size(); + }; + + void change_alignment(const tags::context&) override{}; + + double get_x(const tags::context& ctxt) const override { + return block_x.at(ctxt.get_alignment()); + }; + + double get_alignment_start(const alignment) const override { + return 0; + }; + + private: + map block_x = { + {alignment::LEFT, 0}, + {alignment::CENTER, 0}, + {alignment::RIGHT, 0}, + }; +}; + class MockRenderer : public renderer_interface { public: - MockRenderer(action_context& action_ctxt) : renderer_interface(action_ctxt){}; + MockRenderer(action_context& action_ctxt) : renderer_interface(action_ctxt), fake(action_ctxt){}; MOCK_METHOD(void, render_offset, (const context& ctxt, const extent_val offset), (override)); MOCK_METHOD(void, render_text, (const context& ctxt, const string&& str), (override)); MOCK_METHOD(void, change_alignment, (const context& ctxt), (override)); MOCK_METHOD(double, get_x, (const context& ctxt), (const, override)); MOCK_METHOD(double, get_alignment_start, (const alignment align), (const, override)); + + void DelegateToFake() { + ON_CALL(*this, render_offset).WillByDefault([this](const context& ctxt, const extent_val offset) { + fake.render_offset(ctxt, offset); + }); + + ON_CALL(*this, render_text).WillByDefault([this](const context& ctxt, const string&& str) { + fake.render_text(ctxt, std::forward(str)); + }); + + ON_CALL(*this, get_x).WillByDefault([this](const context& ctxt) { return fake.get_x(ctxt); }); + + ON_CALL(*this, get_alignment_start).WillByDefault([this](const alignment a) { + return fake.get_alignment_start(a); + }); + } + + private: + FakeRenderer fake; }; static auto match_fg = [](rgba c) { return Property("get_fg", &context::get_fg, c); }; @@ -45,15 +99,16 @@ static auto match_left_align = match_align(alignment::LEFT); static auto match_center_align = match_align(alignment::CENTER); static auto match_right_align = match_align(alignment::RIGHT); -class TestableDispatch : public dispatch {}; - class DispatchTest : public ::testing::Test { protected: unique_ptr m_action_ctxt = make_unique(); unique_ptr m_dispatch = make_unique(logger(loglevel::NONE), *m_action_ctxt); - MockRenderer r{*m_action_ctxt}; + ::testing::NiceMock r{*m_action_ctxt}; + void SetUp() override { + r.DelegateToFake(); + } }; TEST_F(DispatchTest, ignoreFormatting) { @@ -122,35 +177,17 @@ TEST_F(DispatchTest, formattingAttributes) { .Times(1); } - m_dispatch->parse(settings, r, "%{u#0000ff o#f0f0f0 +o +u}123%{-u -o}456%{!u !o}789%{PR}0"); + m_dispatch->parse(settings, r, "%{l}%{u#0000ff o#f0f0f0 +o +u}123%{-u -o}456%{!u !o}789%{PR}0"); } TEST_F(DispatchTest, unclosedActions) { { InSequence seq; } bar_settings settings; - EXPECT_THROW(m_dispatch->parse(settings, r, "%{A1:cmd:}foo"), runtime_error); + EXPECT_THROW(m_dispatch->parse(settings, r, "%{l}%{A1:cmd:}foo"), runtime_error); } TEST_F(DispatchTest, actions) { - { - InSequence seq; - // Called for 'foo' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - // Called for '%{A1:cmd:}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - // Called for 'bar' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(6)); - // Called for '%{A}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(6)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(6)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(6)); - } - bar_settings settings; m_dispatch->parse(settings, r, "%{l}foo%{A1:cmd:}bar%{A}"); @@ -168,27 +205,6 @@ TEST_F(DispatchTest, actions) { } TEST_F(DispatchTest, actionOffsetStart) { - { - InSequence seq; - // Called for 'a' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{A1:cmd:}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{O-1}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - // Called for 'bar' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - // Called for '%{A}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(3)); - } - bar_settings settings; m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}%{O-1}bar%{A}"); @@ -206,27 +222,6 @@ TEST_F(DispatchTest, actionOffsetStart) { } TEST_F(DispatchTest, actionOffsetEnd) { - { - InSequence seq; - // Called for 'a' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{A1:cmd:}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for 'bar' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(4)); - // Called for '%{O-3}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(4)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{A}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - } - bar_settings settings; m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}bar%{O-3}%{A}"); @@ -244,33 +239,6 @@ TEST_F(DispatchTest, actionOffsetEnd) { } TEST_F(DispatchTest, actionOffsetBefore) { - { - InSequence seq; - // Called for 'a' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(0)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{O100}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(101)); - // Called for '%{O-100}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(101)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{A1:cmd:}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for 'bar' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(4)); - // Called for '%{O-3}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(4)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - // Called for '%{A}' - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - EXPECT_CALL(r, get_x(_)).WillOnce(Return(1)); - } - bar_settings settings; m_dispatch->parse(settings, r, "%{l}%{O100 O-100}a%{A1:cmd:}bar%{O-3}%{A}");