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}");