tests: Use fake renderer for dispatch test

This commit is contained in:
patrick96 2022-03-05 13:00:05 +01:00 committed by Patrick Ziegler
parent 219171cf79
commit fdaecdb113
4 changed files with 79 additions and 108 deletions

View File

@ -47,39 +47,39 @@ namespace tags {
/** /**
* Background color * Background color
*/ */
rgba m_bg; rgba m_bg{};
/** /**
* Foreground color * Foreground color
*/ */
rgba m_fg; rgba m_fg{};
/** /**
* Overline color * Overline color
*/ */
rgba m_ol; rgba m_ol{};
/** /**
* Underline color * Underline color
*/ */
rgba m_ul; rgba m_ul{};
/** /**
* Font index (1-based) * Font index (1-based)
*/ */
int m_font; int m_font{0};
/** /**
* Is overline enabled? * Is overline enabled?
*/ */
bool m_attr_overline; bool m_attr_overline{false};
/** /**
* Is underline enabled? * Is underline enabled?
*/ */
bool m_attr_underline; bool m_attr_underline{false};
/** /**
* Alignment block * Alignment block
*/ */
alignment m_align; alignment m_align{alignment::NONE};
private: private:
const bar_settings& m_settings; const bar_settings& m_settings;
}; };
} // namespace tags } // namespace tags
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -32,6 +32,7 @@ namespace tags {
void handle_text(renderer_interface& renderer, string&& data); void handle_text(renderer_interface& renderer, string&& data);
void handle_action(renderer_interface& renderer, mousebtn btn, bool closing, const string&& cmd); void handle_action(renderer_interface& renderer, mousebtn btn, bool closing, const string&& cmd);
void handle_offset(renderer_interface& renderer, extent_val offset); void handle_offset(renderer_interface& renderer, extent_val offset);
void handle_alignment(renderer_interface& renderer, alignment a);
void handle_control(controltag ctrl); void handle_control(controltag ctrl);
private: private:

View File

@ -77,16 +77,13 @@ namespace tags {
handle_control(el.tag_data.ctrl); handle_control(el.tag_data.ctrl);
break; break;
case tags::syntaxtag::l: case tags::syntaxtag::l:
m_ctxt->apply_alignment(alignment::LEFT); handle_alignment(renderer, alignment::LEFT);
renderer.change_alignment(*m_ctxt);
break; break;
case tags::syntaxtag::r: case tags::syntaxtag::r:
m_ctxt->apply_alignment(alignment::RIGHT); handle_alignment(renderer, alignment::RIGHT);
renderer.change_alignment(*m_ctxt);
break; break;
case tags::syntaxtag::c: case tags::syntaxtag::c:
m_ctxt->apply_alignment(alignment::CENTER); handle_alignment(renderer, alignment::CENTER);
renderer.change_alignment(*m_ctxt);
break; break;
default: default:
throw runtime_error( throw runtime_error(
@ -150,6 +147,11 @@ namespace tags {
renderer.render_offset(*m_ctxt, offset); 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) { void dispatch::handle_control(controltag ctrl) {
switch (ctrl) { switch (ctrl) {
case controltag::R: case controltag::R:

View File

@ -21,15 +21,69 @@ namespace polybar {
} }
} // 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<alignment, int> block_x = {
{alignment::LEFT, 0},
{alignment::CENTER, 0},
{alignment::RIGHT, 0},
};
};
class MockRenderer : public renderer_interface { class MockRenderer : public renderer_interface {
public: 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_offset, (const context& ctxt, const extent_val offset), (override));
MOCK_METHOD(void, render_text, (const context& ctxt, const string&& str), (override)); MOCK_METHOD(void, render_text, (const context& ctxt, const string&& str), (override));
MOCK_METHOD(void, change_alignment, (const context& ctxt), (override)); MOCK_METHOD(void, change_alignment, (const context& ctxt), (override));
MOCK_METHOD(double, get_x, (const context& ctxt), (const, override)); MOCK_METHOD(double, get_x, (const context& ctxt), (const, override));
MOCK_METHOD(double, get_alignment_start, (const alignment align), (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<const string>(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); }; 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_center_align = match_align(alignment::CENTER);
static auto match_right_align = match_align(alignment::RIGHT); static auto match_right_align = match_align(alignment::RIGHT);
class TestableDispatch : public dispatch {};
class DispatchTest : public ::testing::Test { class DispatchTest : public ::testing::Test {
protected: protected:
unique_ptr<action_context> m_action_ctxt = make_unique<action_context>(); unique_ptr<action_context> m_action_ctxt = make_unique<action_context>();
unique_ptr<dispatch> m_dispatch = make_unique<dispatch>(logger(loglevel::NONE), *m_action_ctxt); unique_ptr<dispatch> m_dispatch = make_unique<dispatch>(logger(loglevel::NONE), *m_action_ctxt);
MockRenderer r{*m_action_ctxt}; ::testing::NiceMock<MockRenderer> r{*m_action_ctxt};
void SetUp() override {
r.DelegateToFake();
}
}; };
TEST_F(DispatchTest, ignoreFormatting) { TEST_F(DispatchTest, ignoreFormatting) {
@ -122,35 +177,17 @@ TEST_F(DispatchTest, formattingAttributes) {
.Times(1); .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) { TEST_F(DispatchTest, unclosedActions) {
{ InSequence seq; } { InSequence seq; }
bar_settings settings; 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) { 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; bar_settings settings;
m_dispatch->parse(settings, r, "%{l}foo%{A1:cmd:}bar%{A}"); m_dispatch->parse(settings, r, "%{l}foo%{A1:cmd:}bar%{A}");
@ -168,27 +205,6 @@ TEST_F(DispatchTest, actions) {
} }
TEST_F(DispatchTest, actionOffsetStart) { 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; bar_settings settings;
m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}%{O-1}bar%{A}"); 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) { 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; bar_settings settings;
m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}bar%{O-3}%{A}"); 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) { 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; bar_settings settings;
m_dispatch->parse(settings, r, "%{l}%{O100 O-100}a%{A1:cmd:}bar%{O-3}%{A}"); m_dispatch->parse(settings, r, "%{l}%{O100 O-100}a%{A1:cmd:}bar%{O-3}%{A}");