GUI Button Element with Unit Tests Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?
Why not send Voyager 3 and 4 following up the paths taken by Voyager 1 and 2 to re-transmit signals of later as they fly away from Earth?
The Nth Gryphon Number
Putting class ranking in CV, but against dept guidelines
Is it dangerous to install hacking tools on my private linux machine?
Why is std::move not [[nodiscard]] in C++20?
"klopfte jemand" or "jemand klopfte"?
How does light 'choose' between wave and particle behaviour?
How to ask rejected full-time candidates to apply to teach individual courses?
Why complex landing gears are used instead of simple,reliability and light weight muscle wire or shape memory alloys?
Sally's older brother
What would you call this weird metallic apparatus that allows you to lift people?
Is there hard evidence that the grant peer review system performs significantly better than random?
I got rid of Mac OSX and replaced it with linux but now I can't change it back to OSX or windows
The test team as an enemy of development? And how can this be avoided?
How can I prevent/balance waiting and turtling as a response to cooldown mechanics
Does the Black Tentacles spell do damage twice at the start of turn to an already restrained creature?
How to change the tick of the color bar legend to black
What does it mean that physics no longer uses mechanical models to describe phenomena?
Tips to organize LaTeX presentations for a semester
Did Mueller's report provide an evidentiary basis for the claim of Russian govt election interference via social media?
Co-worker has annoying ringtone
How were pictures turned from film to a big picture in a picture frame before digital scanning?
How can I save and copy a screenhot at the same time?
Why do early math courses focus on the cross sections of a cone and not on other 3D objects?
GUI Button Element with Unit Tests
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Announcing the arrival of Valued Associate #679: Cesar Manara
Unicorn Meta Zoo #1: Why another podcast?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
I would like a review on just a single class today. More important to me than a review on the class itself, however, is a review of the unit-tests I wrote for it. You see this is my first attempt at writing unit tests with a full test framework.
The class in question is called UpgradeButton
and is exactly that. It is a button for representing upgrades in my resource management game. The buttons look like this:
The boxes along the bottom are updated programatically through the input()
and update()
functions that indicate what level you are at and what you can purchase. The number of tiers is assigned in the constructor, as is the label.
UpgradeButton.h
#pragma once
#include "Expressions.h"
#include <SFMLGraphics.hpp>
#include <string>
namespace fleet
class UpgradeButton : public sf::Drawable
public:
explicit UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades);
void setPosition(float x, float y);
void setPosition(const sf::Vector2f& position);
void setLabelString(const std::string& string);
void setCharacterSize(unsigned newSize);
void setTextFillColor(const sf::Color& color);
const sf::Vector2f& getPosition() const return button.getPosition();
const sf::String& getLabelString() const return label.getString();
unsigned getCharacterSize() const return label.getCharacterSize();
const sf::Color& getTextFillColor() const return label.getFillColor();
bool input(const sf::Vector2f& mousePos, bool canAfford);
void update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford);
private:
sf::RectangleShape button sf::Vector2f(default_upgrade_width, default_upgrade_height) ;
sf::Text label;
std::vector<sf::RectangleShape> indicators;
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
;
Expressions.h
is just a header of constexpr
for replacing magic numbers, and as you can see I am using SFML. Version 2.4.2 if it matters.
UpgradeButton.cpp
#include "UpgradeButton.h"
namespace fleet
UpgradeButton::UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades) :
label newLabel, font
float indicatorWidth = default_upgrade_width / numUpgrades;
for (unsigned i = 0; i < numUpgrades; ++i)
indicators.emplace_back(sf::RectangleShape(sf::Vector2f(indicatorWidth, default_indicator_height)));
button.setFillColor(sf::Color::Cyan);
button.setOutlineThickness(upgrade_button_outline);
for (auto& indicator : indicators)
indicator.setFillColor(sf::Color::Cyan);
indicator.setOutlineThickness(upgrade_button_outline);
void UpgradeButton::setPosition(float x, float y)
button.setPosition(x, y);
float indicatorX = x;
float indicatorY = y + (default_upgrade_height - default_indicator_height);
for (auto& indicator : indicators)
indicator.setPosition(indicatorX, indicatorY);
indicatorX += indicator.getSize().x;
float labelY = y + default_upgrade_height + upgrade_label_y_offset;
label.setPosition(x, labelY);
void UpgradeButton::setPosition(const sf::Vector2f& position)
setPosition(position.x, position.y);
void UpgradeButton::setLabelString(const std::string& string)
label.setString(string);
void UpgradeButton::setCharacterSize(unsigned newSize)
label.setCharacterSize(newSize);
void UpgradeButton::setTextFillColor(const sf::Color& color)
label.setFillColor(color);
bool UpgradeButton::input(const sf::Vector2f& mousePos, bool canAfford)
return canAfford && button.getGlobalBounds().contains(mousePos);
void UpgradeButton::update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford)
for (unsigned i = 0; i < currentLevel && i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Green);
for (unsigned i = currentLevel; i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Cyan);
if (currentLevel == indicators.size()) return;
if (button.getGlobalBounds().contains(mousePos))
if (canAfford)
indicators[currentLevel].setFillColor(sf::Color::Green);
else
indicators[currentLevel].setFillColor(sf::Color::Red);
else
indicators[currentLevel].setFillColor(sf::Color::Cyan);
void UpgradeButton::draw(sf::RenderTarget& target, sf::RenderStates states) const
target.draw(button, states);
for (auto& indicator : indicators)
target.draw(indicator, states);
target.draw(label, states);
Lastly are the tests. I tried to test each of the public functions. The exception was the update()
function. It's entire purpose is to update internal unexposed implementation details, so I was unsure how to test it. Or rather uncertain if I even should. I'm using Google Test for my framework and I'm using a test fixture class to construct a default object to test on. My tests all pass.
UpgradeButtonTests.cpp
#include "gtest/gtest.h"
#include "UpgradeButton.h"
#include <SFMLGraphics.hpp>
namespace fleet
class UpgradeButtonTest : public testing::Test
protected:
sf::Font font;
UpgradeButton button "Test Button", sf::Font(), 5 ;
;
TEST_F(UpgradeButtonTest, setPosition)
sf::Vector2f position 0.F, 0.F ;
button.setPosition(position);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(0.f, 0.f);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(sf::Vector2f());
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(200.F, 200.F);
ASSERT_NE(position.x, button.getPosition().x);
ASSERT_NE(position.y, button.getPosition().y);
TEST_F(UpgradeButtonTest, setLabelString)
std::string test_string "Test Pass" ;
ASSERT_STREQ("Test Button", button.getLabelString().toAnsiString().c_str()) << "Not named Test Button";
button.setLabelString(test_string);
ASSERT_STREQ("Test Pass", button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly";
ASSERT_STREQ(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly pt2";
button.setLabelString("");
ASSERT_STREQ("",button.getLabelString().toAnsiString().c_str()) << "Breaking on empty string";
ASSERT_STRNE(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << "Breaking on inequality test";
TEST_F(UpgradeButtonTest, setCharacterSize)
unsigned test_size 52 ;
ASSERT_EQ(30, button.getCharacterSize());
ASSERT_NE(test_size, button.getCharacterSize());
button.setCharacterSize(test_size);
ASSERT_EQ(52, button.getCharacterSize());
TEST_F(UpgradeButtonTest, setTextFillColor)
sf::Color color sf::Color::Green ;
ASSERT_NE(color, button.getTextFillColor());
ASSERT_EQ(sf::Color::White, button.getTextFillColor());
button.setTextFillColor(color);
ASSERT_EQ(sf::Color::Green, button.getTextFillColor());
button.setTextFillColor(sf::Color());
ASSERT_EQ(sf::Color::Black, button.getTextFillColor());
TEST_F(UpgradeButtonTest, input)
ASSERT_TRUE(button.input(sf::Vector2f(), true));
ASSERT_FALSE(button.input(sf::Vector2f(), false));
ASSERT_FALSE(button.input(sf::Vector2f(500.F, 900.F), true));
c++ unit-testing gui sfml
$endgroup$
add a comment |
$begingroup$
I would like a review on just a single class today. More important to me than a review on the class itself, however, is a review of the unit-tests I wrote for it. You see this is my first attempt at writing unit tests with a full test framework.
The class in question is called UpgradeButton
and is exactly that. It is a button for representing upgrades in my resource management game. The buttons look like this:
The boxes along the bottom are updated programatically through the input()
and update()
functions that indicate what level you are at and what you can purchase. The number of tiers is assigned in the constructor, as is the label.
UpgradeButton.h
#pragma once
#include "Expressions.h"
#include <SFMLGraphics.hpp>
#include <string>
namespace fleet
class UpgradeButton : public sf::Drawable
public:
explicit UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades);
void setPosition(float x, float y);
void setPosition(const sf::Vector2f& position);
void setLabelString(const std::string& string);
void setCharacterSize(unsigned newSize);
void setTextFillColor(const sf::Color& color);
const sf::Vector2f& getPosition() const return button.getPosition();
const sf::String& getLabelString() const return label.getString();
unsigned getCharacterSize() const return label.getCharacterSize();
const sf::Color& getTextFillColor() const return label.getFillColor();
bool input(const sf::Vector2f& mousePos, bool canAfford);
void update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford);
private:
sf::RectangleShape button sf::Vector2f(default_upgrade_width, default_upgrade_height) ;
sf::Text label;
std::vector<sf::RectangleShape> indicators;
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
;
Expressions.h
is just a header of constexpr
for replacing magic numbers, and as you can see I am using SFML. Version 2.4.2 if it matters.
UpgradeButton.cpp
#include "UpgradeButton.h"
namespace fleet
UpgradeButton::UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades) :
label newLabel, font
float indicatorWidth = default_upgrade_width / numUpgrades;
for (unsigned i = 0; i < numUpgrades; ++i)
indicators.emplace_back(sf::RectangleShape(sf::Vector2f(indicatorWidth, default_indicator_height)));
button.setFillColor(sf::Color::Cyan);
button.setOutlineThickness(upgrade_button_outline);
for (auto& indicator : indicators)
indicator.setFillColor(sf::Color::Cyan);
indicator.setOutlineThickness(upgrade_button_outline);
void UpgradeButton::setPosition(float x, float y)
button.setPosition(x, y);
float indicatorX = x;
float indicatorY = y + (default_upgrade_height - default_indicator_height);
for (auto& indicator : indicators)
indicator.setPosition(indicatorX, indicatorY);
indicatorX += indicator.getSize().x;
float labelY = y + default_upgrade_height + upgrade_label_y_offset;
label.setPosition(x, labelY);
void UpgradeButton::setPosition(const sf::Vector2f& position)
setPosition(position.x, position.y);
void UpgradeButton::setLabelString(const std::string& string)
label.setString(string);
void UpgradeButton::setCharacterSize(unsigned newSize)
label.setCharacterSize(newSize);
void UpgradeButton::setTextFillColor(const sf::Color& color)
label.setFillColor(color);
bool UpgradeButton::input(const sf::Vector2f& mousePos, bool canAfford)
return canAfford && button.getGlobalBounds().contains(mousePos);
void UpgradeButton::update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford)
for (unsigned i = 0; i < currentLevel && i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Green);
for (unsigned i = currentLevel; i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Cyan);
if (currentLevel == indicators.size()) return;
if (button.getGlobalBounds().contains(mousePos))
if (canAfford)
indicators[currentLevel].setFillColor(sf::Color::Green);
else
indicators[currentLevel].setFillColor(sf::Color::Red);
else
indicators[currentLevel].setFillColor(sf::Color::Cyan);
void UpgradeButton::draw(sf::RenderTarget& target, sf::RenderStates states) const
target.draw(button, states);
for (auto& indicator : indicators)
target.draw(indicator, states);
target.draw(label, states);
Lastly are the tests. I tried to test each of the public functions. The exception was the update()
function. It's entire purpose is to update internal unexposed implementation details, so I was unsure how to test it. Or rather uncertain if I even should. I'm using Google Test for my framework and I'm using a test fixture class to construct a default object to test on. My tests all pass.
UpgradeButtonTests.cpp
#include "gtest/gtest.h"
#include "UpgradeButton.h"
#include <SFMLGraphics.hpp>
namespace fleet
class UpgradeButtonTest : public testing::Test
protected:
sf::Font font;
UpgradeButton button "Test Button", sf::Font(), 5 ;
;
TEST_F(UpgradeButtonTest, setPosition)
sf::Vector2f position 0.F, 0.F ;
button.setPosition(position);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(0.f, 0.f);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(sf::Vector2f());
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(200.F, 200.F);
ASSERT_NE(position.x, button.getPosition().x);
ASSERT_NE(position.y, button.getPosition().y);
TEST_F(UpgradeButtonTest, setLabelString)
std::string test_string "Test Pass" ;
ASSERT_STREQ("Test Button", button.getLabelString().toAnsiString().c_str()) << "Not named Test Button";
button.setLabelString(test_string);
ASSERT_STREQ("Test Pass", button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly";
ASSERT_STREQ(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly pt2";
button.setLabelString("");
ASSERT_STREQ("",button.getLabelString().toAnsiString().c_str()) << "Breaking on empty string";
ASSERT_STRNE(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << "Breaking on inequality test";
TEST_F(UpgradeButtonTest, setCharacterSize)
unsigned test_size 52 ;
ASSERT_EQ(30, button.getCharacterSize());
ASSERT_NE(test_size, button.getCharacterSize());
button.setCharacterSize(test_size);
ASSERT_EQ(52, button.getCharacterSize());
TEST_F(UpgradeButtonTest, setTextFillColor)
sf::Color color sf::Color::Green ;
ASSERT_NE(color, button.getTextFillColor());
ASSERT_EQ(sf::Color::White, button.getTextFillColor());
button.setTextFillColor(color);
ASSERT_EQ(sf::Color::Green, button.getTextFillColor());
button.setTextFillColor(sf::Color());
ASSERT_EQ(sf::Color::Black, button.getTextFillColor());
TEST_F(UpgradeButtonTest, input)
ASSERT_TRUE(button.input(sf::Vector2f(), true));
ASSERT_FALSE(button.input(sf::Vector2f(), false));
ASSERT_FALSE(button.input(sf::Vector2f(500.F, 900.F), true));
c++ unit-testing gui sfml
$endgroup$
add a comment |
$begingroup$
I would like a review on just a single class today. More important to me than a review on the class itself, however, is a review of the unit-tests I wrote for it. You see this is my first attempt at writing unit tests with a full test framework.
The class in question is called UpgradeButton
and is exactly that. It is a button for representing upgrades in my resource management game. The buttons look like this:
The boxes along the bottom are updated programatically through the input()
and update()
functions that indicate what level you are at and what you can purchase. The number of tiers is assigned in the constructor, as is the label.
UpgradeButton.h
#pragma once
#include "Expressions.h"
#include <SFMLGraphics.hpp>
#include <string>
namespace fleet
class UpgradeButton : public sf::Drawable
public:
explicit UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades);
void setPosition(float x, float y);
void setPosition(const sf::Vector2f& position);
void setLabelString(const std::string& string);
void setCharacterSize(unsigned newSize);
void setTextFillColor(const sf::Color& color);
const sf::Vector2f& getPosition() const return button.getPosition();
const sf::String& getLabelString() const return label.getString();
unsigned getCharacterSize() const return label.getCharacterSize();
const sf::Color& getTextFillColor() const return label.getFillColor();
bool input(const sf::Vector2f& mousePos, bool canAfford);
void update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford);
private:
sf::RectangleShape button sf::Vector2f(default_upgrade_width, default_upgrade_height) ;
sf::Text label;
std::vector<sf::RectangleShape> indicators;
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
;
Expressions.h
is just a header of constexpr
for replacing magic numbers, and as you can see I am using SFML. Version 2.4.2 if it matters.
UpgradeButton.cpp
#include "UpgradeButton.h"
namespace fleet
UpgradeButton::UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades) :
label newLabel, font
float indicatorWidth = default_upgrade_width / numUpgrades;
for (unsigned i = 0; i < numUpgrades; ++i)
indicators.emplace_back(sf::RectangleShape(sf::Vector2f(indicatorWidth, default_indicator_height)));
button.setFillColor(sf::Color::Cyan);
button.setOutlineThickness(upgrade_button_outline);
for (auto& indicator : indicators)
indicator.setFillColor(sf::Color::Cyan);
indicator.setOutlineThickness(upgrade_button_outline);
void UpgradeButton::setPosition(float x, float y)
button.setPosition(x, y);
float indicatorX = x;
float indicatorY = y + (default_upgrade_height - default_indicator_height);
for (auto& indicator : indicators)
indicator.setPosition(indicatorX, indicatorY);
indicatorX += indicator.getSize().x;
float labelY = y + default_upgrade_height + upgrade_label_y_offset;
label.setPosition(x, labelY);
void UpgradeButton::setPosition(const sf::Vector2f& position)
setPosition(position.x, position.y);
void UpgradeButton::setLabelString(const std::string& string)
label.setString(string);
void UpgradeButton::setCharacterSize(unsigned newSize)
label.setCharacterSize(newSize);
void UpgradeButton::setTextFillColor(const sf::Color& color)
label.setFillColor(color);
bool UpgradeButton::input(const sf::Vector2f& mousePos, bool canAfford)
return canAfford && button.getGlobalBounds().contains(mousePos);
void UpgradeButton::update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford)
for (unsigned i = 0; i < currentLevel && i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Green);
for (unsigned i = currentLevel; i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Cyan);
if (currentLevel == indicators.size()) return;
if (button.getGlobalBounds().contains(mousePos))
if (canAfford)
indicators[currentLevel].setFillColor(sf::Color::Green);
else
indicators[currentLevel].setFillColor(sf::Color::Red);
else
indicators[currentLevel].setFillColor(sf::Color::Cyan);
void UpgradeButton::draw(sf::RenderTarget& target, sf::RenderStates states) const
target.draw(button, states);
for (auto& indicator : indicators)
target.draw(indicator, states);
target.draw(label, states);
Lastly are the tests. I tried to test each of the public functions. The exception was the update()
function. It's entire purpose is to update internal unexposed implementation details, so I was unsure how to test it. Or rather uncertain if I even should. I'm using Google Test for my framework and I'm using a test fixture class to construct a default object to test on. My tests all pass.
UpgradeButtonTests.cpp
#include "gtest/gtest.h"
#include "UpgradeButton.h"
#include <SFMLGraphics.hpp>
namespace fleet
class UpgradeButtonTest : public testing::Test
protected:
sf::Font font;
UpgradeButton button "Test Button", sf::Font(), 5 ;
;
TEST_F(UpgradeButtonTest, setPosition)
sf::Vector2f position 0.F, 0.F ;
button.setPosition(position);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(0.f, 0.f);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(sf::Vector2f());
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(200.F, 200.F);
ASSERT_NE(position.x, button.getPosition().x);
ASSERT_NE(position.y, button.getPosition().y);
TEST_F(UpgradeButtonTest, setLabelString)
std::string test_string "Test Pass" ;
ASSERT_STREQ("Test Button", button.getLabelString().toAnsiString().c_str()) << "Not named Test Button";
button.setLabelString(test_string);
ASSERT_STREQ("Test Pass", button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly";
ASSERT_STREQ(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly pt2";
button.setLabelString("");
ASSERT_STREQ("",button.getLabelString().toAnsiString().c_str()) << "Breaking on empty string";
ASSERT_STRNE(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << "Breaking on inequality test";
TEST_F(UpgradeButtonTest, setCharacterSize)
unsigned test_size 52 ;
ASSERT_EQ(30, button.getCharacterSize());
ASSERT_NE(test_size, button.getCharacterSize());
button.setCharacterSize(test_size);
ASSERT_EQ(52, button.getCharacterSize());
TEST_F(UpgradeButtonTest, setTextFillColor)
sf::Color color sf::Color::Green ;
ASSERT_NE(color, button.getTextFillColor());
ASSERT_EQ(sf::Color::White, button.getTextFillColor());
button.setTextFillColor(color);
ASSERT_EQ(sf::Color::Green, button.getTextFillColor());
button.setTextFillColor(sf::Color());
ASSERT_EQ(sf::Color::Black, button.getTextFillColor());
TEST_F(UpgradeButtonTest, input)
ASSERT_TRUE(button.input(sf::Vector2f(), true));
ASSERT_FALSE(button.input(sf::Vector2f(), false));
ASSERT_FALSE(button.input(sf::Vector2f(500.F, 900.F), true));
c++ unit-testing gui sfml
$endgroup$
I would like a review on just a single class today. More important to me than a review on the class itself, however, is a review of the unit-tests I wrote for it. You see this is my first attempt at writing unit tests with a full test framework.
The class in question is called UpgradeButton
and is exactly that. It is a button for representing upgrades in my resource management game. The buttons look like this:
The boxes along the bottom are updated programatically through the input()
and update()
functions that indicate what level you are at and what you can purchase. The number of tiers is assigned in the constructor, as is the label.
UpgradeButton.h
#pragma once
#include "Expressions.h"
#include <SFMLGraphics.hpp>
#include <string>
namespace fleet
class UpgradeButton : public sf::Drawable
public:
explicit UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades);
void setPosition(float x, float y);
void setPosition(const sf::Vector2f& position);
void setLabelString(const std::string& string);
void setCharacterSize(unsigned newSize);
void setTextFillColor(const sf::Color& color);
const sf::Vector2f& getPosition() const return button.getPosition();
const sf::String& getLabelString() const return label.getString();
unsigned getCharacterSize() const return label.getCharacterSize();
const sf::Color& getTextFillColor() const return label.getFillColor();
bool input(const sf::Vector2f& mousePos, bool canAfford);
void update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford);
private:
sf::RectangleShape button sf::Vector2f(default_upgrade_width, default_upgrade_height) ;
sf::Text label;
std::vector<sf::RectangleShape> indicators;
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
;
Expressions.h
is just a header of constexpr
for replacing magic numbers, and as you can see I am using SFML. Version 2.4.2 if it matters.
UpgradeButton.cpp
#include "UpgradeButton.h"
namespace fleet
UpgradeButton::UpgradeButton(const std::string& newLabel, const sf::Font& font, unsigned short numUpgrades) :
label newLabel, font
float indicatorWidth = default_upgrade_width / numUpgrades;
for (unsigned i = 0; i < numUpgrades; ++i)
indicators.emplace_back(sf::RectangleShape(sf::Vector2f(indicatorWidth, default_indicator_height)));
button.setFillColor(sf::Color::Cyan);
button.setOutlineThickness(upgrade_button_outline);
for (auto& indicator : indicators)
indicator.setFillColor(sf::Color::Cyan);
indicator.setOutlineThickness(upgrade_button_outline);
void UpgradeButton::setPosition(float x, float y)
button.setPosition(x, y);
float indicatorX = x;
float indicatorY = y + (default_upgrade_height - default_indicator_height);
for (auto& indicator : indicators)
indicator.setPosition(indicatorX, indicatorY);
indicatorX += indicator.getSize().x;
float labelY = y + default_upgrade_height + upgrade_label_y_offset;
label.setPosition(x, labelY);
void UpgradeButton::setPosition(const sf::Vector2f& position)
setPosition(position.x, position.y);
void UpgradeButton::setLabelString(const std::string& string)
label.setString(string);
void UpgradeButton::setCharacterSize(unsigned newSize)
label.setCharacterSize(newSize);
void UpgradeButton::setTextFillColor(const sf::Color& color)
label.setFillColor(color);
bool UpgradeButton::input(const sf::Vector2f& mousePos, bool canAfford)
return canAfford && button.getGlobalBounds().contains(mousePos);
void UpgradeButton::update(const sf::Vector2f& mousePos, unsigned currentLevel, bool canAfford)
for (unsigned i = 0; i < currentLevel && i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Green);
for (unsigned i = currentLevel; i < indicators.size(); ++i)
indicators[i].setFillColor(sf::Color::Cyan);
if (currentLevel == indicators.size()) return;
if (button.getGlobalBounds().contains(mousePos))
if (canAfford)
indicators[currentLevel].setFillColor(sf::Color::Green);
else
indicators[currentLevel].setFillColor(sf::Color::Red);
else
indicators[currentLevel].setFillColor(sf::Color::Cyan);
void UpgradeButton::draw(sf::RenderTarget& target, sf::RenderStates states) const
target.draw(button, states);
for (auto& indicator : indicators)
target.draw(indicator, states);
target.draw(label, states);
Lastly are the tests. I tried to test each of the public functions. The exception was the update()
function. It's entire purpose is to update internal unexposed implementation details, so I was unsure how to test it. Or rather uncertain if I even should. I'm using Google Test for my framework and I'm using a test fixture class to construct a default object to test on. My tests all pass.
UpgradeButtonTests.cpp
#include "gtest/gtest.h"
#include "UpgradeButton.h"
#include <SFMLGraphics.hpp>
namespace fleet
class UpgradeButtonTest : public testing::Test
protected:
sf::Font font;
UpgradeButton button "Test Button", sf::Font(), 5 ;
;
TEST_F(UpgradeButtonTest, setPosition)
sf::Vector2f position 0.F, 0.F ;
button.setPosition(position);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(0.f, 0.f);
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(sf::Vector2f());
ASSERT_FLOAT_EQ(position.x, button.getPosition().x);
ASSERT_FLOAT_EQ(position.y, button.getPosition().y);
button.setPosition(200.F, 200.F);
ASSERT_NE(position.x, button.getPosition().x);
ASSERT_NE(position.y, button.getPosition().y);
TEST_F(UpgradeButtonTest, setLabelString)
std::string test_string "Test Pass" ;
ASSERT_STREQ("Test Button", button.getLabelString().toAnsiString().c_str()) << "Not named Test Button";
button.setLabelString(test_string);
ASSERT_STREQ("Test Pass", button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly";
ASSERT_STREQ(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << test_string << " not assigned properly pt2";
button.setLabelString("");
ASSERT_STREQ("",button.getLabelString().toAnsiString().c_str()) << "Breaking on empty string";
ASSERT_STRNE(test_string.c_str(), button.getLabelString().toAnsiString().c_str()) << "Breaking on inequality test";
TEST_F(UpgradeButtonTest, setCharacterSize)
unsigned test_size 52 ;
ASSERT_EQ(30, button.getCharacterSize());
ASSERT_NE(test_size, button.getCharacterSize());
button.setCharacterSize(test_size);
ASSERT_EQ(52, button.getCharacterSize());
TEST_F(UpgradeButtonTest, setTextFillColor)
sf::Color color sf::Color::Green ;
ASSERT_NE(color, button.getTextFillColor());
ASSERT_EQ(sf::Color::White, button.getTextFillColor());
button.setTextFillColor(color);
ASSERT_EQ(sf::Color::Green, button.getTextFillColor());
button.setTextFillColor(sf::Color());
ASSERT_EQ(sf::Color::Black, button.getTextFillColor());
TEST_F(UpgradeButtonTest, input)
ASSERT_TRUE(button.input(sf::Vector2f(), true));
ASSERT_FALSE(button.input(sf::Vector2f(), false));
ASSERT_FALSE(button.input(sf::Vector2f(500.F, 900.F), true));
c++ unit-testing gui sfml
c++ unit-testing gui sfml
asked 3 mins ago
bruglescobruglesco
1,6562824
1,6562824
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217810%2fgui-button-element-with-unit-tests%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217810%2fgui-button-element-with-unit-tests%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown