Lots of implementation for sbf-cpp.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "Character.h"
|
||||
|
||||
#include "Attributes.h"
|
||||
|
||||
namespace SBF {
|
||||
|
||||
using std::string;
|
||||
@@ -193,11 +195,12 @@ int GetDisciplinePoints() {
|
||||
return kDisciplinePoints;
|
||||
}
|
||||
|
||||
void CharacterType::FillDisciplineValues(std::vector<int> disciplineValues) const {
|
||||
void CharacterType::FillDisciplineValues(std::vector<int> values) const {
|
||||
// TODO: This method sucks, but was needed in QBasic.
|
||||
disciplineValues.clear();
|
||||
for (int id = 0; id <= kDisciplinesCount; id++) {
|
||||
disciplineValues[id] = GetDisciplineValue(id);
|
||||
values.clear();
|
||||
values.push_back(0); // To pad the indexes.
|
||||
for (int id = 1; id <= kDisciplinesCount; id++) {
|
||||
values.push_back(GetDisciplineValue(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,74 +294,79 @@ void FillAttributeAbbreviationsInGroup(std::vector<string> attributeAbbreviation
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterType::SetPhysicalAttributeValue(int id, int value) {
|
||||
switch (id) {
|
||||
case kPhysicalAttributeDexterityId:
|
||||
attr_dexterity = value;
|
||||
case kPhysicalAttributeStaminaId:
|
||||
attr_stamina = value;
|
||||
case kPhysicalAttributeStrengthId:
|
||||
attr_strength = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterType::SetSocialAttributeValue(int id, int value) {
|
||||
switch (id) {
|
||||
case kSocialAttributeAppearanceId:
|
||||
attr_appearance = value;
|
||||
case kSocialAttributeCharismaId:
|
||||
attr_charisma = value;
|
||||
case kSocialAttributeManipulationId:
|
||||
attr_manipulation = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterType::SetMentalAttributeValue(int id, int value) {
|
||||
switch (id) {
|
||||
case kMentalAttributeIntelligenceId:
|
||||
attr_intelligence = value;
|
||||
case kMentalAttributePerceptionId:
|
||||
attr_perception = value;
|
||||
case kMentalAttributeWitsId:
|
||||
attr_wits = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterType::SetAttributeValue(int attributeGroupId, int attributeId, int value) {
|
||||
switch (attributeGroupId) {
|
||||
case kAttributeGroupPhysicalId:
|
||||
switch (attributeId) {
|
||||
case kPhysicalAttributeStrengthId:
|
||||
attr_strength = value;
|
||||
break;
|
||||
case kPhysicalAttributeDexterityId:
|
||||
attr_dexterity = value;
|
||||
break;
|
||||
case kPhysicalAttributeStaminaId:
|
||||
attr_stamina = value;
|
||||
break;
|
||||
}
|
||||
SetPhysicalAttributeValue(attributeId, value);
|
||||
break;
|
||||
case kAttributeGroupSocialId:
|
||||
switch (attributeId) {
|
||||
case kSocialAttributeCharismaId:
|
||||
attr_charisma = value;
|
||||
break;
|
||||
case kSocialAttributeManipulationId:
|
||||
attr_manipulation = value;
|
||||
break;
|
||||
case kSocialAttributeAppearanceId:
|
||||
attr_appearance = value;
|
||||
break;
|
||||
}
|
||||
SetSocialAttributeValue(attributeId, value);
|
||||
break;
|
||||
case kAttributeGroupMentalId:
|
||||
switch (attributeId) {
|
||||
case kMentalAttributeIntelligenceId:
|
||||
attr_intelligence = value;
|
||||
break;
|
||||
case kMentalAttributePerceptionId:
|
||||
attr_perception = value;
|
||||
break;
|
||||
case kMentalAttributeWitsId:
|
||||
attr_wits = value;
|
||||
break;
|
||||
}
|
||||
SetMentalAttributeValue(attributeId, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int CharacterType::GetAttributeValue(int attributeGroupId, int attributeId) const {
|
||||
switch (attributeGroupId) {
|
||||
case kAttributeGroupPhysicalId:
|
||||
switch (attributeId) {
|
||||
case kPhysicalAttributeStrengthId:
|
||||
return attr_strength;
|
||||
int CharacterType::GetPhysicalAttributeValue(int id) const {
|
||||
switch (id) {
|
||||
case kPhysicalAttributeDexterityId:
|
||||
return attr_dexterity;
|
||||
case kPhysicalAttributeStaminaId:
|
||||
return attr_stamina;
|
||||
case kPhysicalAttributeStrengthId:
|
||||
return attr_strength;
|
||||
}
|
||||
break;
|
||||
case kAttributeGroupSocialId:
|
||||
switch (attributeId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CharacterType::GetSocialAttributeValue(int id) const {
|
||||
switch (id) {
|
||||
case kSocialAttributeAppearanceId:
|
||||
return attr_appearance;
|
||||
case kSocialAttributeCharismaId:
|
||||
return attr_charisma;
|
||||
case kSocialAttributeManipulationId:
|
||||
return attr_manipulation;
|
||||
case kSocialAttributeAppearanceId:
|
||||
return attr_appearance;
|
||||
}
|
||||
break;
|
||||
case kAttributeGroupMentalId:
|
||||
switch (attributeId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CharacterType::GetMentalAttributeValue(int id) const {
|
||||
switch (id) {
|
||||
case kMentalAttributeIntelligenceId:
|
||||
return attr_intelligence;
|
||||
case kMentalAttributePerceptionId:
|
||||
@@ -366,7 +374,17 @@ int CharacterType::GetAttributeValue(int attributeGroupId, int attributeId) cons
|
||||
case kMentalAttributeWitsId:
|
||||
return attr_wits;
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CharacterType::GetAttributeValue(int attributeGroupId, int attributeId) const {
|
||||
switch (attributeGroupId) {
|
||||
case kAttributeGroupPhysicalId:
|
||||
return GetPhysicalAttributeValue(attributeId);
|
||||
case kAttributeGroupSocialId:
|
||||
return GetSocialAttributeValue(attributeId);
|
||||
case kAttributeGroupMentalId:
|
||||
return GetMentalAttributeValue(attributeId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -673,10 +691,11 @@ int CharacterType::GetBackgroundValue(int backgroundId) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CharacterType::FillBackgroundValues(std::vector<int> backgroundValues) const {
|
||||
backgroundValues.clear();
|
||||
for (int backgroundId = 0; backgroundId <= kBackgroundsCount; backgroundId++) {
|
||||
backgroundValues[backgroundId] = GetBackgroundValue(backgroundId);
|
||||
void CharacterType::FillBackgroundValues(std::vector<int> values) const {
|
||||
values.clear();
|
||||
values.push_back(0); // To pad the indexes.
|
||||
for (int backgroundId = 1; backgroundId <= kBackgroundsCount; backgroundId++) {
|
||||
values[backgroundId] = GetBackgroundValue(backgroundId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ class CharacterType {
|
||||
void FillVirtueValues(std::vector<int> virtueValues) const;
|
||||
int GetAbilityValue(int abilityGroupId, int abilityId) const;
|
||||
int GetAttributeValue(int attributeGroupId, int abilityId) const;
|
||||
int GetPhysicalAttributeValue(int id) const;
|
||||
int GetSocialAttributeValue(int id) const;
|
||||
int GetMentalAttributeValue(int id) const;
|
||||
int GetBackgroundValue(int backgroundId) const;
|
||||
std::string GetAllDerangementsLine() const;
|
||||
int GetDisciplineValue(int disciplineId) const;
|
||||
@@ -49,6 +52,9 @@ class CharacterType {
|
||||
int GetVirtueValue(int virtueId) const;
|
||||
void SetAbilityValue(int abilityGroupId, int abilityId, int value);
|
||||
void SetAttributeValue(int attributeGroupId, int attributeId, int value);
|
||||
void SetPhysicalAttributeValue(int id, int value);
|
||||
void SetMentalAttributeValue(int id, int value);
|
||||
void SetSocialAttributeValue(int id, int value);
|
||||
void SetBackgroundValue(int backgroundId, int value);
|
||||
void SetDisciplineValue(int disciplineId, int value);
|
||||
void SetKnowledgeValue(int knowledgeId, int value);
|
||||
@@ -163,5 +169,6 @@ class CharacterType {
|
||||
int background_status;
|
||||
}; // End class CharacterType
|
||||
} // End namespace SBF
|
||||
|
||||
/** @}*/
|
||||
#endif // !defined CHARACTER_H__
|
||||
|
||||
@@ -2,12 +2,8 @@
|
||||
|
||||
namespace SBF {
|
||||
|
||||
// TODO: Update these if they're wrong. They should be the initial color pair.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
uint8_t g_foregroundColor = kColorDarkWhite;
|
||||
uint8_t g_backgroundColor = kColorDarkBlack;
|
||||
#pragma clang diagnostic pop
|
||||
uint8_t g_foreground_color = kColorDefaultForeground;
|
||||
uint8_t g_background_color = kColorDefaultBackground;
|
||||
|
||||
void FillColors(std::vector<uint8_t>& colors) {
|
||||
colors.clear();
|
||||
@@ -17,20 +13,22 @@ void FillColors(std::vector<uint8_t>& colors) {
|
||||
}
|
||||
|
||||
uint8_t GetBackgroundColor() {
|
||||
return g_backgroundColor;
|
||||
return g_background_color;
|
||||
}
|
||||
|
||||
uint8_t GetForegroundColor() {
|
||||
return g_foregroundColor;
|
||||
return g_foreground_color;
|
||||
}
|
||||
|
||||
// TODO: Define what happens when color is invalid.
|
||||
void SetBackgroundColor(uint8_t color) {
|
||||
g_backgroundColor = color;
|
||||
uint8_t SetBackgroundColor(uint8_t color) {
|
||||
uint8_t previous_color = color;
|
||||
g_background_color = color;
|
||||
return previous_color;
|
||||
}
|
||||
|
||||
// TODO: Define what happens when color is invalid.
|
||||
void SetForegroundColor(uint8_t color) {
|
||||
g_foregroundColor = color;
|
||||
uint8_t SetForegroundColor(uint8_t color) {
|
||||
uint8_t previous_color = color;
|
||||
g_foreground_color = color;
|
||||
return previous_color;
|
||||
}
|
||||
} // End namespace SBF
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* Licensed under the MIT license see the LICENSE file for details.
|
||||
***************************************************************************************/
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Abilities
|
||||
@@ -16,27 +17,27 @@
|
||||
*/
|
||||
namespace SBF {
|
||||
const uint8_t kColorDarkBlack = 0;
|
||||
const uint8_t kColorDarkBlue = 1;
|
||||
const uint8_t kColorDarkRed = 1;
|
||||
const uint8_t kColorDarkGreen = 2;
|
||||
const uint8_t kColorDarkCyan = 3;
|
||||
const uint8_t kColorDarkRed = 4;
|
||||
const uint8_t kColorDarkYellow = 3;
|
||||
const uint8_t kColorDarkBlue = 4;
|
||||
const uint8_t kColorDarkMagenta = 5;
|
||||
const uint8_t kColorDarkOrange = 6;
|
||||
const uint8_t kColorDarkYellow = 6;
|
||||
const uint8_t kColorDarkCyan = 6;
|
||||
const uint8_t kColorDarkWhite = 7;
|
||||
const uint8_t kColorBrightBlack = 8;
|
||||
const uint8_t kColorBrightBlue = 9;
|
||||
const uint8_t kColorBrightRed = 9;
|
||||
const uint8_t kColorBrightGreen = 10;
|
||||
const uint8_t kColorBrightCyan = 11;
|
||||
const uint8_t kColorBrightRed = 12;
|
||||
const uint8_t kColorBrightYellow = 11;
|
||||
const uint8_t kColorBrightBlue = 12;
|
||||
const uint8_t kColorBrightMagenta = 13;
|
||||
const uint8_t kColorBrightOrange = 14;
|
||||
const uint8_t kColorBrightYellow = 14;
|
||||
const uint8_t kColorBrightCyan = 14;
|
||||
const uint8_t kColorBrightWhite = 15;
|
||||
const uint8_t kColorDefaultForeground = kColorBrightWhite;
|
||||
const uint8_t kColorDefaultBackground = kColorDarkBlack;
|
||||
|
||||
/// @brief Sets the stored foreground color.
|
||||
/// @param color The new foreground color.
|
||||
void SetForegroundColor(uint8_t color);
|
||||
uint8_t SetForegroundColor(uint8_t color);
|
||||
|
||||
/// @brief Gets the stored foreground color.
|
||||
/// @return The foreground color.
|
||||
@@ -44,7 +45,7 @@ uint8_t GetForegroundColor();
|
||||
|
||||
/// @brief Sets the stored background color.
|
||||
/// @param color The new background color.
|
||||
void SetBackgroundColor(uint8_t color);
|
||||
uint8_t SetBackgroundColor(uint8_t color);
|
||||
|
||||
/// @brief Gets the stored background color.
|
||||
/// @return The background color.
|
||||
@@ -53,6 +54,38 @@ uint8_t GetBackgroundColor();
|
||||
/// @brief Fills the provided vector with all of the possible color values. It will be cleared before filling.
|
||||
/// @param colors The vector to fill.
|
||||
void FillColors(std::vector<uint8_t>& colors);
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& Reset(std::basic_ostream<TChar, TTraits>& os) {
|
||||
return os << "\033[m";
|
||||
}
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& ForegroundColor(std::basic_ostream<TChar, TTraits>& os) {
|
||||
return os << "\033[38;5;" + std::to_string(GetForegroundColor()) + "m";
|
||||
}
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& BackgroundColor(std::basic_ostream<TChar, TTraits>& os) {
|
||||
return os << "\033[48;5;" + std::to_string(GetBackgroundColor()) + "m";
|
||||
}
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& Colors(std::basic_ostream<TChar, TTraits>& os) {
|
||||
return os << ForegroundColor << BackgroundColor;
|
||||
}
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& TrueColorForeground(std::basic_ostream<TChar, TTraits>& os, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
return os << "\033[38;2;" << std::to_string(red) << ";" << std::to_string(green) << ";" << std::to_string(blue)
|
||||
<< "m";
|
||||
}
|
||||
|
||||
template <typename TChar, typename TTraits>
|
||||
auto& TrueColorBackground(std::basic_ostream<TChar, TTraits>& os, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
return os << "\033[48;2;" << std::to_string(red) << ";" << std::to_string(green) << ";" << std::to_string(blue)
|
||||
<< "m";
|
||||
}
|
||||
} // End namespace SBF
|
||||
|
||||
/** @}*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Colors.h"
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
@@ -16,13 +17,20 @@ TestResults test_GetBackgroundColor();
|
||||
TestResults test_GetForegroundColor();
|
||||
TestResults test_SetBackgroundColor();
|
||||
TestResults test_SetForegroundColor();
|
||||
TestResults test_Reset();
|
||||
TestResults test_ForegroundColor();
|
||||
TestResults test_BackgroundColor();
|
||||
TestResults test_Colors();
|
||||
TestResults test_TrueColorForeground();
|
||||
TestResults test_TrueColorBackground();
|
||||
string escape_string(const string& text, const string& pattern = "\033", const string& replace = "\\033");
|
||||
} // End namespace Test::Colors
|
||||
|
||||
using namespace Test::Colors;
|
||||
|
||||
namespace SBF {
|
||||
extern uint8_t g_foregroundColor;
|
||||
extern uint8_t g_backgroundColor;
|
||||
extern uint8_t g_foreground_color;
|
||||
extern uint8_t g_background_color;
|
||||
} // namespace SBF
|
||||
|
||||
TestResults main_test_Colors(int argc, char* argv[]) {
|
||||
@@ -33,6 +41,12 @@ TestResults main_test_Colors(int argc, char* argv[]) {
|
||||
results += test_GetForegroundColor();
|
||||
results += test_SetBackgroundColor();
|
||||
results += test_SetForegroundColor();
|
||||
results += test_Reset();
|
||||
results += test_ForegroundColor();
|
||||
results += test_BackgroundColor();
|
||||
results += test_Colors();
|
||||
results += test_TrueColorForeground();
|
||||
results += test_TrueColorBackground();
|
||||
|
||||
return results;
|
||||
}
|
||||
@@ -60,7 +74,7 @@ TestResults test_FillColors() {
|
||||
|
||||
TestResults test_GetBackgroundColor() {
|
||||
auto fnToTest = [](uint8_t background_color) -> uint8_t {
|
||||
SBF::g_backgroundColor = background_color;
|
||||
SBF::g_background_color = background_color;
|
||||
return GetBackgroundColor();
|
||||
};
|
||||
return execute_suite<uint32_t, uint32_t>(make_test_suite(
|
||||
@@ -70,37 +84,33 @@ TestResults test_GetBackgroundColor() {
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkBlack when background color is 0", kColorDarkBlack, make_tuple(0U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkBlue when background color is 1", kColorDarkBlue, make_tuple(1U)),
|
||||
"should get kColorDarkBlue when background color is 1", kColorDarkRed, make_tuple(1U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkGreen when background color is 2", kColorDarkGreen, make_tuple(2U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkCyan when background color is 3", kColorDarkCyan, make_tuple(3U)),
|
||||
"should get kColorDarkCyan when background color is 3", kColorDarkYellow, make_tuple(3U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkRed when background color is 4", kColorDarkRed, make_tuple(4U)),
|
||||
"should get kColorDarkRed when background color is 4", kColorDarkBlue, make_tuple(4U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkMagenta when background color is 5", kColorDarkMagenta, make_tuple(5U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkOrange when background color is 6", kColorDarkOrange, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkYellow when background color is 6", kColorDarkYellow, make_tuple(6U)),
|
||||
"should get kColorDarkYellow when background color is 6", kColorDarkCyan, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkWhite when background color is 7", kColorDarkWhite, make_tuple(7U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightBlack when background color is 8", kColorBrightBlack, make_tuple(8U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightBlue when background color is 9", kColorBrightBlue, make_tuple(9U)),
|
||||
"should get kColorBrightBlue when background color is 9", kColorBrightRed, make_tuple(9U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightGreen when background color is 10", kColorBrightGreen, make_tuple(10U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightCyan when background color is 11", kColorBrightCyan, make_tuple(11U)),
|
||||
"should get kColorBrightCyan when background color is 11", kColorBrightYellow, make_tuple(11U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightRed when background color is 12", kColorBrightRed, make_tuple(12U)),
|
||||
"should get kColorBrightRed when background color is 12", kColorBrightBlue, make_tuple(12U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightMagenta when background color is 13", kColorBrightMagenta, make_tuple(13U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightOrange when background color is 14", kColorBrightOrange, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightYellow when background color is 14", kColorBrightYellow, make_tuple(14U)),
|
||||
"should get kColorBrightYellow when background color is 14", kColorBrightCyan, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightWhite when background color is 15", kColorBrightWhite, make_tuple(15U)),
|
||||
})));
|
||||
@@ -108,7 +118,7 @@ TestResults test_GetBackgroundColor() {
|
||||
|
||||
TestResults test_GetForegroundColor() {
|
||||
auto fnToTest = [](uint8_t foreground_color) -> uint8_t {
|
||||
SBF::g_foregroundColor = foreground_color;
|
||||
SBF::g_foreground_color = foreground_color;
|
||||
return GetForegroundColor();
|
||||
};
|
||||
return execute_suite<uint32_t, uint32_t>(make_test_suite(
|
||||
@@ -118,47 +128,44 @@ TestResults test_GetForegroundColor() {
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkBlack when foreground color is 0", kColorDarkBlack, make_tuple(0U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkBlue when foreground color is 1", kColorDarkBlue, make_tuple(1U)),
|
||||
"should get kColorDarkBlue when foreground color is 1", kColorDarkRed, make_tuple(1U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkGreen when foreground color is 2", kColorDarkGreen, make_tuple(2U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkCyan when foreground color is 3", kColorDarkCyan, make_tuple(3U)),
|
||||
"should get kColorDarkCyan when foreground color is 3", kColorDarkYellow, make_tuple(3U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkRed when foreground color is 4", kColorDarkRed, make_tuple(4U)),
|
||||
"should get kColorDarkRed when foreground color is 4", kColorDarkBlue, make_tuple(4U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkMagenta when foreground color is 5", kColorDarkMagenta, make_tuple(5U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkOrange when foreground color is 6", kColorDarkOrange, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkYellow when foreground color is 6", kColorDarkYellow, make_tuple(6U)),
|
||||
"should get kColorDarkYellow when foreground color is 6", kColorDarkCyan, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorDarkWhite when foreground color is 7", kColorDarkWhite, make_tuple(7U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightBlack when foreground color is 8", kColorBrightBlack, make_tuple(8U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightBlue when foreground color is 9", kColorBrightBlue, make_tuple(9U)),
|
||||
"should get kColorBrightBlue when foreground color is 9", kColorBrightRed, make_tuple(9U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightGreen when foreground color is 10", kColorBrightGreen, make_tuple(10U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightCyan when foreground color is 11", kColorBrightCyan, make_tuple(11U)),
|
||||
"should get kColorBrightCyan when foreground color is 11", kColorBrightYellow, make_tuple(11U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightRed when foreground color is 12", kColorBrightRed, make_tuple(12U)),
|
||||
"should get kColorBrightRed when foreground color is 12", kColorBrightBlue, make_tuple(12U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightMagenta when foreground color is 13", kColorBrightMagenta, make_tuple(13U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightOrange when foreground color is 14", kColorBrightOrange, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightYellow when foreground color is 14", kColorBrightYellow, make_tuple(14U)),
|
||||
"should get kColorBrightYellow when foreground color is 14", kColorBrightCyan, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should get kColorBrightWhite when foreground color is 15", kColorBrightWhite, make_tuple(15U)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_SetBackgroundColor() {
|
||||
// TODO: Test that SetBackgroundColor returns the previous background color.
|
||||
auto fnToTest = [](uint8_t color) -> uint8_t {
|
||||
SBF::g_backgroundColor = 255;
|
||||
SBF::g_background_color = 255;
|
||||
SetBackgroundColor(color);
|
||||
return SBF::g_backgroundColor;
|
||||
return SBF::g_background_color;
|
||||
};
|
||||
return execute_suite<uint32_t, uint32_t>(make_test_suite(
|
||||
"SBF::SetBackgroundColor",
|
||||
@@ -167,50 +174,46 @@ TestResults test_SetBackgroundColor() {
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkBlack when color is 0", kColorDarkBlack, make_tuple(0U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkBlue when color is 1", kColorDarkBlue, make_tuple(1U)),
|
||||
"should set background color to kColorDarkBlue when color is 4", kColorDarkBlue, make_tuple(4U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkGreen when color is 2", kColorDarkGreen, make_tuple(2U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkCyan when color is 3", kColorDarkCyan, make_tuple(3U)),
|
||||
"should set background color to kColorDarkCyan when color is 6", kColorDarkCyan, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkRed when color is 4", kColorDarkRed, make_tuple(4U)),
|
||||
"should set background color to kColorDarkRed when color is 1", kColorDarkRed, make_tuple(1U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkMagenta when color is 5", kColorDarkMagenta, make_tuple(5U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkOrange when color is 6", kColorDarkOrange, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkYellow when color is 6", kColorDarkYellow, make_tuple(6U)),
|
||||
"should set background color to kColorDarkYellow when color is 3", kColorDarkYellow, make_tuple(3U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorDarkWhite when color is 7", kColorDarkWhite, make_tuple(7U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightBlack when color is 8", kColorBrightBlack, make_tuple(8U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightBlue when color is 9", kColorBrightBlue, make_tuple(9U)),
|
||||
"should set background color to kColorBrightBlue when color is 12", kColorBrightBlue, make_tuple(12U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightGreen when color is 10", kColorBrightGreen, make_tuple(10U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightCyan when color is 11", kColorBrightCyan, make_tuple(11U)),
|
||||
"should set background color to kColorBrightCyan when color is 14", kColorBrightCyan, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightRed when color is 12", kColorBrightRed, make_tuple(12U)),
|
||||
"should set background color to kColorBrightRed when color is 9", kColorBrightRed, make_tuple(9U)),
|
||||
make_test<uint32_t, uint32_t>("should set background color to kColorBrightMagenta when color is 13",
|
||||
kColorBrightMagenta,
|
||||
make_tuple(13U)),
|
||||
make_test<uint32_t, uint32_t>("should set background color to kColorBrightOrange when color is 14",
|
||||
kColorBrightOrange,
|
||||
make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>("should set background color to kColorBrightYellow when color is 14",
|
||||
make_test<uint32_t, uint32_t>("should set background color to kColorBrightYellow when color is 11",
|
||||
kColorBrightYellow,
|
||||
make_tuple(14U)),
|
||||
make_tuple(11U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set background color to kColorBrightWhite when color is 15", kColorBrightWhite, make_tuple(15U)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_SetForegroundColor() {
|
||||
// TODO: Test that SetForegroundColor returns the previous background color.
|
||||
auto fnToTest = [](uint8_t color) -> uint8_t {
|
||||
SBF::g_foregroundColor = 255;
|
||||
SBF::g_foreground_color = 255;
|
||||
SetForegroundColor(color);
|
||||
return SBF::g_foregroundColor;
|
||||
return SBF::g_foreground_color;
|
||||
};
|
||||
return execute_suite<uint32_t, uint32_t>(make_test_suite(
|
||||
"SBF::SetForegroundColor",
|
||||
@@ -219,42 +222,144 @@ TestResults test_SetForegroundColor() {
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkBlack when color is 0", kColorDarkBlack, make_tuple(0U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkBlue when color is 1", kColorDarkBlue, make_tuple(1U)),
|
||||
"should set foreground color to kColorDarkBlue when color is 4", kColorDarkBlue, make_tuple(4U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkGreen when color is 2", kColorDarkGreen, make_tuple(2U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkCyan when color is 3", kColorDarkCyan, make_tuple(3U)),
|
||||
"should set foreground color to kColorDarkCyan when color is 6", kColorDarkCyan, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkRed when color is 4", kColorDarkRed, make_tuple(4U)),
|
||||
"should set foreground color to kColorDarkRed when color is 1", kColorDarkRed, make_tuple(1U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkMagenta when color is 5", kColorDarkMagenta, make_tuple(5U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkOrange when color is 6", kColorDarkOrange, make_tuple(6U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkYellow when color is 6", kColorDarkYellow, make_tuple(6U)),
|
||||
"should set foreground color to kColorDarkYellow when color is 3", kColorDarkYellow, make_tuple(3U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorDarkWhite when color is 7", kColorDarkWhite, make_tuple(7U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightBlack when color is 8", kColorBrightBlack, make_tuple(8U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightBlue when color is 9", kColorBrightBlue, make_tuple(9U)),
|
||||
"should set foreground color to kColorBrightBlue when color is 12", kColorBrightBlue, make_tuple(12U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightGreen when color is 10", kColorBrightGreen, make_tuple(10U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightCyan when color is 11", kColorBrightCyan, make_tuple(11U)),
|
||||
"should set foreground color to kColorBrightCyan when color is 14", kColorBrightCyan, make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightRed when color is 12", kColorBrightRed, make_tuple(12U)),
|
||||
"should set foreground color to kColorBrightRed when color is 9", kColorBrightRed, make_tuple(9U)),
|
||||
make_test<uint32_t, uint32_t>("should set foreground color to kColorBrightMagenta when color is 13",
|
||||
kColorBrightMagenta,
|
||||
make_tuple(13U)),
|
||||
make_test<uint32_t, uint32_t>("should set foreground color to kColorBrightOrange when color is 14",
|
||||
kColorBrightOrange,
|
||||
make_tuple(14U)),
|
||||
make_test<uint32_t, uint32_t>("should set foreground color to kColorBrightYellow when color is 14",
|
||||
make_test<uint32_t, uint32_t>("should set foreground color to kColorBrightYellow when color is 11",
|
||||
kColorBrightYellow,
|
||||
make_tuple(14U)),
|
||||
make_tuple(11U)),
|
||||
make_test<uint32_t, uint32_t>(
|
||||
"should set foreground color to kColorBrightWhite when color is 15", kColorBrightWhite, make_tuple(15U)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_Reset() {
|
||||
string suite_name = "SBF::Reset";
|
||||
string test_name = "should write the reset code to the stream";
|
||||
string expected = "\\033[m";
|
||||
auto fnToTest = []() -> string {
|
||||
ostringstream os;
|
||||
os << Reset;
|
||||
return escape_string(os.str());
|
||||
};
|
||||
return execute_suite(make_test_suite(
|
||||
suite_name, fnToTest, vector<TestTuple<string>>({make_test<string>(test_name, expected, make_tuple())})));
|
||||
}
|
||||
|
||||
TestResults test_ForegroundColor() {
|
||||
auto fnToTest = [](uint8_t color) -> string {
|
||||
SetForegroundColor(color);
|
||||
ostringstream os;
|
||||
os << ForegroundColor;
|
||||
return escape_string(os.str());
|
||||
};
|
||||
return execute_suite(
|
||||
make_test_suite("SBF::ForegroundColor",
|
||||
fnToTest,
|
||||
vector<TestTuple<string, uint8_t>>({
|
||||
make_test<string, uint8_t>("should write \"\\033[38;5;15m\" kColorBrightWhite to the stream",
|
||||
"\\033[38;5;15m",
|
||||
make_tuple(kColorBrightWhite)),
|
||||
make_test<string, uint8_t>("should write \"\\033[38;5;11m\" kColorBrightYellow to the stream",
|
||||
"\\033[38;5;11m",
|
||||
make_tuple(kColorBrightYellow)),
|
||||
make_test<string, uint8_t>("should write \"\\033[38;5;2m\" kColorDarkGreen to the stream",
|
||||
"\\033[38;5;2m",
|
||||
make_tuple(kColorDarkGreen)),
|
||||
make_test<string, uint8_t>("should write \"\\033[38;5;4m\" kColorDarkBlue to the stream",
|
||||
"\\033[38;5;4m",
|
||||
make_tuple(kColorDarkBlue)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_BackgroundColor() {
|
||||
auto fnToTest = [](uint8_t color) -> string {
|
||||
SetBackgroundColor(color);
|
||||
ostringstream os;
|
||||
os << BackgroundColor;
|
||||
return escape_string(os.str());
|
||||
};
|
||||
return execute_suite(
|
||||
make_test_suite("SBF::BackgroundColor",
|
||||
fnToTest,
|
||||
vector<TestTuple<string, uint8_t>>({
|
||||
make_test<string, uint8_t>("should write \"\\033[48;5;15m\" kColorBrightWhite to the stream",
|
||||
"\\033[48;5;15m",
|
||||
make_tuple(kColorBrightWhite)),
|
||||
make_test<string, uint8_t>("should write \"\\033[48;5;11m\" kColorBrightYellow to the stream",
|
||||
"\\033[48;5;11m",
|
||||
make_tuple(kColorBrightYellow)),
|
||||
make_test<string, uint8_t>("should write \"\\033[48;5;2m\" kColorDarkGreen to the stream",
|
||||
"\\033[48;5;2m",
|
||||
make_tuple(kColorDarkGreen)),
|
||||
make_test<string, uint8_t>("should write \"\\033[48;5;4m\" kColorDarkBlue to the stream",
|
||||
"\\033[48;5;4m",
|
||||
make_tuple(kColorDarkBlue)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_Colors() {
|
||||
// TODO: Find a way to check for the presence of both colors and no extra characters without regard to their order.
|
||||
auto fnToTest = [](uint8_t foreground_color, uint8_t background_color) -> string {
|
||||
SetForegroundColor(foreground_color);
|
||||
SetBackgroundColor(background_color);
|
||||
ostringstream os;
|
||||
os << SBF::Colors;
|
||||
return escape_string(os.str());
|
||||
};
|
||||
return execute_suite(make_test_suite(
|
||||
"SBF::ForegroundColor",
|
||||
fnToTest,
|
||||
vector<TestTuple<string, uint8_t, uint8_t>>({
|
||||
make_test<string, uint8_t, uint8_t>("should write \"\\033[38;5;15m\\033[48;5;6m\" to the stream",
|
||||
"\\033[38;5;15m\\033[48;5;6m",
|
||||
make_tuple(kColorBrightWhite, kColorDarkCyan)),
|
||||
make_test<string, uint8_t, uint8_t>("should write \"\\033[38;5;11m\\033[48;5;2m\" to the stream",
|
||||
"\\033[38;5;11m\\033[48;5;2m",
|
||||
make_tuple(kColorBrightYellow, kColorDarkGreen)),
|
||||
make_test<string, uint8_t, uint8_t>("should write \"\\033[38;5;2m\\033[48;5;13m\" to the stream",
|
||||
"\\033[38;5;2m\\033[48;5;13m",
|
||||
make_tuple(kColorDarkGreen, kColorBrightMagenta)),
|
||||
make_test<string, uint8_t, uint8_t>("should write \"\\033[38;5;4m\\033[48;5;1m\" to the stream",
|
||||
"\\033[38;5;4m\\033[48;5;1m",
|
||||
make_tuple(kColorDarkBlue, kColorDarkRed)),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_TrueColorForeground() {
|
||||
// TODO: test_TrueColorForeground();
|
||||
return TestResults().fail("// TODO: test_TrueColorForeground");
|
||||
}
|
||||
|
||||
TestResults test_TrueColorBackground() {
|
||||
// TODO: test_TrueColorBackground();
|
||||
return TestResults().fail("// TODO: test_TrueColorBackground");
|
||||
}
|
||||
|
||||
string escape_string(const string& text, const string& pattern, const string& replace) {
|
||||
return regex_replace(text, regex(pattern), replace);
|
||||
}
|
||||
} // End namespace Test::Colors
|
||||
|
||||
@@ -16,8 +16,6 @@ bool operator!=(const DerangementType& left, const DerangementType& right) {
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& os, const DerangementType& derangement) {
|
||||
// Derangement: {id: 1, label: \"kDerangementAmnesiaLabel\", description: \"kDerangementAmnesiaDescription\",
|
||||
// textColor: kDerangementAmnesiaTextColor}
|
||||
os << "Derangement: {id: " << derangement.id << ", label: \"" << derangement.label << "\", description: \""
|
||||
<< derangement.description << "\", textColor: " << (int)derangement.textColor << "}";
|
||||
return os;
|
||||
|
||||
@@ -33,7 +33,7 @@ const uint8_t kDerangementDelusionsOfGrandeurTextColor = kColorDarkMagenta;
|
||||
const std::string kDerangementDelusionsOfGrandeurLabel = "Delusions of Grandeur";
|
||||
const std::string kDerangementDelusionsOfGrandeurDescription = R"---(You imagine you are better than you are.)---";
|
||||
const int kDerangementFantasyId = 3;
|
||||
const uint8_t kDerangementFantasyTextColor = kColorDarkOrange;
|
||||
const uint8_t kDerangementFantasyTextColor = kColorDarkYellow;
|
||||
const std::string kDerangementFantasyLabel = "Fantasy";
|
||||
const std::string kDerangementFantasyDescription =
|
||||
R"---(You enter a self-created world where you are the forgotten hero.)---";
|
||||
|
||||
@@ -148,7 +148,7 @@ TestResults test_DerangementType_operator_extract() {
|
||||
make_test<string, DerangementType>("should print amnesia",
|
||||
"Derangement: {id: 1, label: \"" + kDerangementAmnesiaLabel
|
||||
+ "\", description: \"" + kDerangementAmnesiaDescription
|
||||
+ "\", textColor: 4}",
|
||||
+ "\", textColor: 1}",
|
||||
make_tuple(kDerangementAmnesia)),
|
||||
make_test<string, DerangementType>("should print delusions of grandeur",
|
||||
"Derangement: {id: 2, label: \"" + kDerangementDelusionsOfGrandeurLabel
|
||||
@@ -158,7 +158,7 @@ TestResults test_DerangementType_operator_extract() {
|
||||
make_test<string, DerangementType>("should print fantasy",
|
||||
"Derangement: {id: 3, label: \"" + kDerangementFantasyLabel
|
||||
+ "\", description: \"" + kDerangementFantasyDescription
|
||||
+ "\", textColor: 6}",
|
||||
+ "\", textColor: 3}",
|
||||
make_tuple(kDerangementFantasy)),
|
||||
make_test<string, DerangementType>("should print manic depression",
|
||||
"Derangement: {id: 4, label: \"" + kDerangementManicDepressionLabel
|
||||
@@ -168,7 +168,7 @@ TestResults test_DerangementType_operator_extract() {
|
||||
make_test<string, DerangementType>("should print multiple personalities",
|
||||
"Derangement: {id: 5, label: \"" + kDerangementMultiplePersonalitiesLabel
|
||||
+ "\", description: \"" + kDerangementMultiplePersonalitiesDescription
|
||||
+ "\", textColor: 1}",
|
||||
+ "\", textColor: 4}",
|
||||
make_tuple(kDerangementMultiplePersonalities)),
|
||||
make_test<string, DerangementType>("should print obsession",
|
||||
"Derangement: {id: 6, label: \"" + kDerangementObsessionLabel
|
||||
@@ -178,12 +178,12 @@ TestResults test_DerangementType_operator_extract() {
|
||||
make_test<string, DerangementType>("should print overcompensation",
|
||||
"Derangement: {id: 7, label: \"" + kDerangementOvercompensationLabel
|
||||
+ "\", description: \"" + kDerangementOvercompensationDescription
|
||||
+ "\", textColor: 11}",
|
||||
+ "\", textColor: 14}",
|
||||
make_tuple(kDerangementOvercompensation)),
|
||||
make_test<string, DerangementType>("should print paranoia",
|
||||
"Derangement: {id: 8, label: \"" + kDerangementParanoiaLabel
|
||||
+ "\", description: \"" + kDerangementParanoiaDescription
|
||||
+ "\", textColor: 12}",
|
||||
+ "\", textColor: 9}",
|
||||
make_tuple(kDerangementParanoia)),
|
||||
make_test<string, DerangementType>("should print perfection",
|
||||
"Derangement: {id: 9, label: \"" + kDerangementPerfectionLabel
|
||||
@@ -193,7 +193,7 @@ TestResults test_DerangementType_operator_extract() {
|
||||
make_test<string, DerangementType>("should print regression",
|
||||
"Derangement: {id: 10, label: \"" + kDerangementRegressionLabel
|
||||
+ "\", description: \"" + kDerangementRegressionDescription
|
||||
+ "\", textColor: 14}",
|
||||
+ "\", textColor: 11}",
|
||||
make_tuple(kDerangementRegression)),
|
||||
make_test<string, DerangementType>(
|
||||
"should print an unknown derangement",
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
#include "Menus.h"
|
||||
|
||||
namespace SBF {
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int GetRandomMenuItemId(std::vector<MenuItem> items);
|
||||
void BuildMenu(std::vector<MenuItem> items, std::vector<string> labels);
|
||||
void BuildMenuWithValues(std::vector<MenuItem> items, std::vector<string> labels, std::vector<int> values);
|
||||
void BuildMenuWithColors(std::vector<MenuItem> items, std::vector<string> labels, std::vector<uint8_t> colors);
|
||||
void AdjustMenuStyle(MenuStyle& style, std::vector<MenuItem> items, bool ignoreValue);
|
||||
void PrintMenu(std::vector<MenuItem> items, MenuStyle style);
|
||||
#include "Colors.h"
|
||||
#include "Random.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace SBF {
|
||||
namespace {
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using std::vector;
|
||||
} // End namespace
|
||||
|
||||
void BuildMenuWithValues(vector<MenuItem> items, vector<string> labels, vector<int> values);
|
||||
void BuildMenuWithColors(vector<MenuItem> items, vector<string> labels, vector<uint8_t> colors);
|
||||
void AdjustMenuStyle(MenuStyle& style, vector<MenuItem> items, bool ignoreValue);
|
||||
string GetTitle(MenuItem item, MenuStyle style);
|
||||
string GetTitleWithoutValue(MenuItem item, MenuStyle style);
|
||||
void NewMenuStyle(MenuStyle& style);
|
||||
@@ -15,6 +25,186 @@ void NewMenuItem(MenuItem& item, string label, int id);
|
||||
void NewMenuItemWithValue(MenuItem& item, string label, int id, int value);
|
||||
void NewMenuItemWithColor(MenuItem& item, string label, int id, uint8_t color);
|
||||
|
||||
void MenuStyle::Adjust(vector<MenuItem> menu_items, bool ignore_value) {
|
||||
size_t max_id_width = 0;
|
||||
size_t max_item_width = 0;
|
||||
size_t max_value_width = 0;
|
||||
for_each(menu_items.begin(), menu_items.end(), [&](MenuItem menu_item) {
|
||||
if (menu_item.is_visible) {
|
||||
max_id_width = std::max(max_id_width, itos(menu_item.id).size());
|
||||
max_item_width = std::max(max_item_width, (menu_item.label + label_value_separator).size());
|
||||
max_value_width = std::max(max_value_width, itos(menu_item.value).size());
|
||||
}
|
||||
});
|
||||
if (show_random) {
|
||||
max_id_width = std::max(max_id_width, itos(random_item_id).size());
|
||||
max_item_width = std::max(max_item_width, random_item_name.size());
|
||||
}
|
||||
if (show_cancel) {
|
||||
max_id_width = std::max(max_id_width, itos(cancel_item_id).size());
|
||||
max_item_width = std::max(max_item_width, cancel_item_name.size());
|
||||
}
|
||||
id_width = max_id_width;
|
||||
label_width = max_item_width;
|
||||
value_width = ignore_value ? 0 : max_value_width;
|
||||
}
|
||||
|
||||
ostream& PrintMenu(ostream& os, vector<MenuItem> items, MenuStyle style) {
|
||||
MenuItem random_item = MenuItem(style.random_item_name, style.random_item_id, style.random_item_color);
|
||||
MenuItem cancel_item = MenuItem(style.cancel_item_name, style.cancel_item_id, style.cancel_item_color);
|
||||
size_t actual_count = 0;
|
||||
for_each(items.begin(), items.end(), [&actual_count](MenuItem item) {
|
||||
if (item.is_visible) {
|
||||
actual_count++;
|
||||
}
|
||||
});
|
||||
if (style.show_cancel) {
|
||||
actual_count++;
|
||||
}
|
||||
if (style.show_random) {
|
||||
actual_count++;
|
||||
}
|
||||
if (actual_count <= 10) {
|
||||
for_each(items.begin(), items.end(), [&style, &os](MenuItem item) {
|
||||
if (item.is_visible) {
|
||||
string title = GetTitle(item, style);
|
||||
PrintWithMaybeColor(os, title, item.color, style.use_colors) << endl;
|
||||
}
|
||||
});
|
||||
if (style.show_cancel) {
|
||||
string title = GetTitleWithoutValue(cancel_item, style);
|
||||
PrintWithMaybeColor(os, title, cancel_item.color, style.use_colors) << endl;
|
||||
}
|
||||
if (style.show_random) {
|
||||
string title = GetTitleWithoutValue(random_item, style);
|
||||
PrintWithMaybeColor(os, title, random_item.color, style.use_colors) << endl;
|
||||
}
|
||||
} else {
|
||||
MenuItem empty_item;
|
||||
size_t item_width = GetTitle(empty_item, style).size();
|
||||
size_t items_per_row = style.screen_width / (item_width + style.menu_item_spacer.size());
|
||||
size_t column_width = style.screen_width / items_per_row;
|
||||
|
||||
const size_t count = items.size();
|
||||
int column = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
const MenuItem& item = items[i];
|
||||
if (item.is_visible) {
|
||||
string item_text = GetTitle(item, style);
|
||||
if (column != items_per_row - 1) {
|
||||
if (i != count || style.show_random || style.show_cancel) {
|
||||
size_t text_length = item_text.size();
|
||||
item_text = make_fit_l(
|
||||
right_trim(item_text) + style.menu_item_spacer, text_length + style.menu_item_spacer.size(), ' ');
|
||||
}
|
||||
}
|
||||
string label = make_fit_c(item_text, column_width, ' ');
|
||||
PrintWithMaybeColor(os, label, item.color, style.use_colors);
|
||||
column = (column + 1) % items_per_row;
|
||||
if (column == 0) {
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (style.show_cancel) {
|
||||
string title = make_fit_c(GetTitleWithoutValue(cancel_item, style), column_width, ' ');
|
||||
PrintWithMaybeColor(os, title, cancel_item.color, style.use_colors) << endl;
|
||||
}
|
||||
if (style.show_random) {
|
||||
string title = make_fit_c(GetTitleWithoutValue(random_item, style), column_width, ' ');
|
||||
PrintWithMaybeColor(os, title, random_item.color, style.use_colors) << endl;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
vector<MenuItem> BuildMenu(vector<string> labels) {
|
||||
vector<MenuItem> menu_items;
|
||||
int id = 1;
|
||||
for_each(
|
||||
labels.begin(), labels.end(), [&menu_items, &id](string label) { menu_items.push_back(MenuItem(label, id++)); });
|
||||
return menu_items;
|
||||
}
|
||||
|
||||
int GetRandomMenuItemId(vector<MenuItem> items) {
|
||||
int num_visible_items = 0;
|
||||
size_t count = items.size();
|
||||
vector<int> visible_item_ids;
|
||||
for (int i = 1; i <= count; i++) {
|
||||
if (items[i].is_visible && items[i].include_in_random) {
|
||||
visible_item_ids.push_back(i);
|
||||
num_visible_items++;
|
||||
}
|
||||
}
|
||||
return visible_item_ids[GetRandomInt(0, num_visible_items - 1)];
|
||||
}
|
||||
|
||||
MenuStyle::MenuStyle()
|
||||
: id_width(0),
|
||||
label_width(0),
|
||||
value_width(0),
|
||||
screen_width(80),
|
||||
random_item_name("Random"),
|
||||
random_item_id(0),
|
||||
random_item_color(kColorDefaultForeground),
|
||||
cancel_item_name("Cancel"),
|
||||
cancel_item_id(-1),
|
||||
cancel_item_color(kColorDefaultForeground),
|
||||
id_label_separator(" = "),
|
||||
label_value_separator(": "),
|
||||
menu_item_spacer(", "),
|
||||
show_random(true),
|
||||
show_cancel(false),
|
||||
use_colors(false) {}
|
||||
|
||||
MenuItem::MenuItem()
|
||||
: label(""), id(0), value(0), color(kColorDefaultForeground), is_visible(true), include_in_random(true) {}
|
||||
|
||||
MenuItem::MenuItem(string label, int id)
|
||||
: label(label), id(id), value(0), color(kColorDefaultForeground), is_visible(true), include_in_random(true) {}
|
||||
|
||||
MenuItem::MenuItem(string label, int id, int value)
|
||||
: label(label), id(id), value(value), color(kColorDefaultForeground), is_visible(true), include_in_random(true) {}
|
||||
|
||||
MenuItem::MenuItem(string label, int id, uint8_t color)
|
||||
: label(label), id(id), value(0), color(color), is_visible(true), include_in_random(true) {}
|
||||
|
||||
ostream& PrintWithMaybeColor(ostream& os, const string& text, uint8_t text_color, bool use_colors) {
|
||||
uint8_t previous_color = GetForegroundColor();
|
||||
if (use_colors) {
|
||||
SetForegroundColor(text_color);
|
||||
os << ForegroundColor;
|
||||
}
|
||||
os << text;
|
||||
if (use_colors) {
|
||||
SetForegroundColor(previous_color);
|
||||
os << ForegroundColor;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
string GetTitleWithoutValue(MenuItem item, MenuStyle style) {
|
||||
string id_string = make_fit_r(itos(item.id), style.id_width, ' ');
|
||||
int label_width = style.label_width + style.value_width + style.label_value_separator.size();
|
||||
string label_string = make_fit_l(item.label, label_width, ' ');
|
||||
return id_string + style.id_label_separator + label_string;
|
||||
}
|
||||
|
||||
string GetTitle(MenuItem item, MenuStyle style) {
|
||||
string id = itos(item.id);
|
||||
string label = item.label;
|
||||
// cout << "GetTitle item.id: " << item.id << ", item.label: " << item.label << ", style.id_width: " << style.id_width
|
||||
// << ", style.label_width: " << style.label_width << ", style.value_width: " << style.value_width << endl;
|
||||
if (style.value_width > 0) {
|
||||
label += style.label_value_separator;
|
||||
}
|
||||
string value = itos(item.value);
|
||||
string formatted_id = make_fit_r(id, style.id_width);
|
||||
string formatted_label = make_fit_l(label, style.label_width);
|
||||
string formatted_value = make_fit_r(value, style.value_width);
|
||||
return formatted_id + style.id_label_separator + formatted_label + formatted_value;
|
||||
}
|
||||
|
||||
} // End namespace SBF
|
||||
|
||||
/*
|
||||
@@ -114,22 +304,16 @@ Sub PrintMenu (items() As MenuItem, count As Integer, style As MenuStyle)
|
||||
If column <> (itemsPerRow - 1) Then
|
||||
If i <> count Or style.showRandom Then
|
||||
textLength = Len(itemText$)
|
||||
itemText$ = MakeFitL$(RTrim$(itemText$) + style.menuItemSpacer, textLength +
|
||||
Len(style.menuItemSpacer), " ") End If End If Print MakeFitC$(itemText$, columnWidth, " "); End If column = (column + 1)
|
||||
Mod itemsPerRow If column = 0 Then Print "" Next If style.showRandom Then Print
|
||||
MakeFitC$(GetTitleWithoutValue$(randomItem, style), columnWidth, " ") End If End If End Sub
|
||||
itemText$ = make_fit_l$(right_trim$(itemText$) + style.menuItemSpacer, textLength +
|
||||
Len(style.menuItemSpacer), ' ') End If End If Print make_fit_c$(itemText$, columnWidth, ' '); End If column = (column +
|
||||
1) Mod itemsPerRow If column = 0 Then Print "" Next If style.showRandom Then Print
|
||||
make_fit_c$(GetTitleWithoutValue$(randomItem, style), columnWidth, ' ') End If End If End Sub
|
||||
|
||||
|
||||
Function GetTitle$ (mi As MenuItem, ms As MenuStyle)
|
||||
id$ = itos$(mi.id)
|
||||
label$ = mi.label
|
||||
If ms.valueWidth > 0 Then label$ = label$ + ms.labelValueSeparator
|
||||
value$ = itos$(mi.value)
|
||||
GetTitle$ = MakeFitR$(id$, ms.idWidth, " ") + ms.idLabelSeparator + MakeFitL$(label$, ms.labelWidth, " ") +
|
||||
MakeFitR$(value$, ms.valueWidth, " ") End Function
|
||||
|
||||
Function GetTitleWithoutValue$ (mi As MenuItem, ms As MenuStyle)
|
||||
GetTitleWithoutValue$ = MakeFitR$(itos(mi.id), ms.idWidth, " ") + ms.idLabelSeparator + MakeFitL$(mi.label,
|
||||
ms.labelWidth + ms.valueWidth + Len(ms.labelValueSeparator), " ") End Function
|
||||
GetTitleWithoutValue$ = MakeFitR$(itos(mi.id), ms.idWidth, ' ') + ms.idLabelSeparator + make_fit_l$(mi.label,
|
||||
ms.labelWidth + ms.valueWidth + Len(ms.labelValueSeparator), ' ') End Function
|
||||
|
||||
Sub NewMenuStyle (ms As MenuStyle)
|
||||
ms.idWidth = 0
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
* Licensed under the MIT license see the LICENSE file for details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "Colors.h"
|
||||
|
||||
namespace SBF {
|
||||
struct MenuStyle;
|
||||
struct MenuItem;
|
||||
class MenuStyle;
|
||||
class MenuItem;
|
||||
} // namespace SBF
|
||||
|
||||
// End forward declarations
|
||||
@@ -25,40 +27,73 @@ struct MenuItem;
|
||||
namespace SBF {
|
||||
using std::string;
|
||||
|
||||
struct MenuStyle {
|
||||
int idWidth;
|
||||
int labelWidth;
|
||||
int valueWidth;
|
||||
int screenWidth;
|
||||
string randomItemName;
|
||||
int randomItemId;
|
||||
string idLabelSeparator;
|
||||
string labelValueSeparator;
|
||||
string menuItemSpacer;
|
||||
bool showRandom;
|
||||
bool useColors;
|
||||
class MenuStyleBuilder {
|
||||
public:
|
||||
MenuStyleBuilder();
|
||||
MenuStyleBuilder& SetScreenWidth(int screen_width);
|
||||
MenuStyleBuilder& SetRandomItemName(const std::string& name);
|
||||
MenuStyleBuilder& SetRandomItemId(int id);
|
||||
MenuStyleBuilder& SetRandomItemColor(uint8_t color);
|
||||
MenuStyleBuilder& SetCancelItemName(const std::string& name);
|
||||
MenuStyleBuilder& SetCancelItemId(int id);
|
||||
MenuStyleBuilder& SetCancelItemColor(uint8_t color);
|
||||
MenuStyleBuilder& SetIdLabelSeparator(const std::string& separator);
|
||||
MenuStyleBuilder& SetLabelValueSeparator(const std::string& separator);
|
||||
MenuStyleBuilder& SetMenuItemSeparator(const std::string& separator);
|
||||
MenuStyleBuilder& SetShowRandom(bool show_random);
|
||||
MenuStyleBuilder& SetShowCancel(bool show_cancel);
|
||||
MenuStyleBuilder& SetUseColors(bool use_colors);
|
||||
MenuStyle Build();
|
||||
};
|
||||
|
||||
struct MenuItem {
|
||||
class MenuStyle {
|
||||
public:
|
||||
MenuStyle();
|
||||
void Adjust(std::vector<MenuItem> menu_items, bool ignore_value = true);
|
||||
int id_width;
|
||||
int label_width;
|
||||
int value_width;
|
||||
int screen_width;
|
||||
string random_item_name;
|
||||
int random_item_id;
|
||||
uint8_t random_item_color;
|
||||
string cancel_item_name;
|
||||
int cancel_item_id;
|
||||
uint8_t cancel_item_color;
|
||||
string id_label_separator;
|
||||
string label_value_separator;
|
||||
string menu_item_spacer;
|
||||
bool show_random;
|
||||
bool show_cancel;
|
||||
bool use_colors;
|
||||
};
|
||||
|
||||
class MenuItem {
|
||||
public:
|
||||
MenuItem();
|
||||
MenuItem(std::string label, int id);
|
||||
MenuItem(std::string label, int id, int value);
|
||||
MenuItem(std::string label, int id, uint8_t color);
|
||||
string label;
|
||||
int id;
|
||||
int value;
|
||||
int color;
|
||||
bool isVisible;
|
||||
uint8_t color;
|
||||
bool is_visible;
|
||||
bool include_in_random;
|
||||
};
|
||||
|
||||
// TODO: Make a menu class to hold GetRandomMenuItemId, the various BuildMenu* methods, and possibly PrintMenu.
|
||||
int GetRandomMenuItemId(std::vector<MenuItem> items);
|
||||
void BuildMenu(std::vector<MenuItem> items, std::vector<string> labels);
|
||||
std::vector<MenuItem> BuildMenu(std::vector<string> labels);
|
||||
void BuildMenuWithValues(std::vector<MenuItem> items, std::vector<string> labels, std::vector<int> values);
|
||||
void BuildMenuWithColors(std::vector<MenuItem> items, std::vector<string> labels, std::vector<uint8_t> colors);
|
||||
void AdjustMenuStyle(MenuStyle& style, std::vector<MenuItem> items, bool ignoreValue);
|
||||
void PrintMenu(std::vector<MenuItem> items, MenuStyle style);
|
||||
std::ostream& PrintMenu(std::ostream& os, std::vector<MenuItem> items, MenuStyle style);
|
||||
string GetTitle(MenuItem item, MenuStyle style);
|
||||
string GetTitleWithoutValue(MenuItem item, MenuStyle style);
|
||||
void NewMenuStyle(MenuStyle& style);
|
||||
void NewMenuItem(MenuItem& item, string label, int id);
|
||||
void NewMenuItemWithValue(MenuItem& item, string label, int id, int value);
|
||||
void NewMenuItemWithColor(MenuItem& item, string label, int id, uint8_t color);
|
||||
std::ostream& PrintWithMaybeColor(std::ostream& os,
|
||||
const std::string& text,
|
||||
uint8_t text_color = kColorDefaultForeground,
|
||||
bool use_colors = false);
|
||||
|
||||
} // End namespace SBF
|
||||
|
||||
|
||||
146
sbf-cpp/Menus_test.cpp
Normal file
146
sbf-cpp/Menus_test.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "Menus.h"
|
||||
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "Colors.h"
|
||||
#include "test.h"
|
||||
|
||||
using namespace SBF;
|
||||
using namespace Test;
|
||||
using namespace std;
|
||||
|
||||
namespace Test::Menus {
|
||||
TestResults test_MenuItem_constructor();
|
||||
TestResults test_MenuItem_constructor_string_int();
|
||||
TestResults test_MenuItem_constructor_string_int_int();
|
||||
TestResults test_MenuItem_constructor_string_int_uint8_t();
|
||||
TestResults test_MenuStyle_constructor();
|
||||
TestResults test_MenuStyle_Adjust();
|
||||
TestResults test_GetRandomMenuItemId();
|
||||
TestResults test_BuildMenu();
|
||||
TestResults test_BuildMenuWithValues();
|
||||
TestResults test_BuildMenuWithColors();
|
||||
TestResults test_PrintMenu();
|
||||
TestResults test_GetTitle();
|
||||
TestResults test_GetTitleWithoutValue();
|
||||
TestResults test_PrintWithMaybeColor();
|
||||
string escape_string(const string& text, const string& pattern = "\033", const string& replace = "\\033");
|
||||
} // End namespace Test::Menus
|
||||
|
||||
using namespace Test::Menus;
|
||||
|
||||
TestResults main_test_Menus(int argc, char* argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_MenuItem_constructor();
|
||||
results += test_MenuItem_constructor_string_int();
|
||||
results += test_MenuItem_constructor_string_int_int();
|
||||
results += test_MenuItem_constructor_string_int_uint8_t();
|
||||
results += test_MenuStyle_constructor();
|
||||
results += test_MenuStyle_Adjust();
|
||||
results += test_GetRandomMenuItemId();
|
||||
results += test_BuildMenu();
|
||||
results += test_BuildMenuWithValues();
|
||||
results += test_BuildMenuWithColors();
|
||||
results += test_PrintMenu();
|
||||
results += test_GetTitle();
|
||||
results += test_GetTitleWithoutValue();
|
||||
results += test_PrintWithMaybeColor();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
namespace Test::Menus {
|
||||
TestResults test_MenuItem_constructor() {
|
||||
return TestResults().skip("// TODO: test_MenuItem_constructor");
|
||||
}
|
||||
|
||||
TestResults test_MenuItem_constructor_string_int() {
|
||||
return TestResults().skip("// TODO: test_MenuItem_constructor_string_int");
|
||||
}
|
||||
|
||||
TestResults test_MenuItem_constructor_string_int_int() {
|
||||
return TestResults().skip("// TODO: test_MenuItem_constructor_string_int_int");
|
||||
}
|
||||
|
||||
TestResults test_MenuItem_constructor_string_int_uint8_t() {
|
||||
return TestResults().skip("// TODO: test_MenuItem_constructor_string_int_uint8_t");
|
||||
}
|
||||
|
||||
TestResults test_MenuStyle_constructor() {
|
||||
return TestResults().skip("// TODO: test_MenuStyle_constructor");
|
||||
}
|
||||
|
||||
TestResults test_MenuStyle_Adjust() {
|
||||
return TestResults().skip("// TODO: test_Menu_Style_Adjust");
|
||||
}
|
||||
|
||||
TestResults test_GetRandomMenuItemId() {
|
||||
return TestResults().skip("// TODO: test_GetRandomMenuItemId");
|
||||
}
|
||||
|
||||
TestResults test_BuildMenu() {
|
||||
return TestResults().skip("// TODO: test_BuildMenu");
|
||||
}
|
||||
|
||||
TestResults test_BuildMenuWithValues() {
|
||||
return TestResults().skip("// TODO: test_BuildMenuWithValues");
|
||||
}
|
||||
|
||||
TestResults test_BuildMenuWithColors() {
|
||||
return TestResults().skip("// TODO: test_BuildMenuWithColors");
|
||||
}
|
||||
|
||||
TestResults test_PrintMenu() {
|
||||
return TestResults().skip("// TODO: test_PrintMenu");
|
||||
}
|
||||
|
||||
TestResults test_GetTitle() {
|
||||
return TestResults().skip("// TODO: test_GetTitle");
|
||||
}
|
||||
|
||||
TestResults test_GetTitleWithoutValue() {
|
||||
return TestResults().skip("// TODO: test_GetTitleWithoutValue");
|
||||
}
|
||||
|
||||
TestResults test_PrintWithMaybeColor() {
|
||||
auto fnToTest = [](const string& text, uint8_t text_color, bool use_colors) -> string {
|
||||
SetForegroundColor(kColorDefaultForeground);
|
||||
SetBackgroundColor(kColorDefaultBackground);
|
||||
ostringstream error_message;
|
||||
ostringstream os;
|
||||
PrintWithMaybeColor(os, text, text_color, use_colors);
|
||||
if (GetForegroundColor() != kColorDefaultForeground) {
|
||||
error_message << " Foreground color was changed to " << GetForegroundColor();
|
||||
}
|
||||
if (GetBackgroundColor() != kColorDefaultBackground) {
|
||||
error_message << " Background color was changed to " << GetBackgroundColor();
|
||||
}
|
||||
if (error_message.str().size() > 0) {
|
||||
return error_message.str();
|
||||
}
|
||||
return escape_string(os.str());
|
||||
};
|
||||
return execute_suite(
|
||||
make_test_suite("SBF::PrintWithMaybeColor",
|
||||
fnToTest,
|
||||
vector<TestTuple<string, string, uint8_t, bool>>({
|
||||
make_test<string, string, uint8_t, bool>(
|
||||
"should write \"Hello, world!\" in dark yellow and reset the color afterward",
|
||||
"\\033[38;5;3mHello, world!\\033[38;5;15m",
|
||||
make_tuple(string("Hello, world!"), kColorDarkYellow, true)),
|
||||
make_test<string, string, uint8_t, bool>(
|
||||
"should print \"much less than we should\" without changing the color",
|
||||
"much less than we should",
|
||||
make_tuple(string("much less than we should"), kColorDarkGreen, false)),
|
||||
})));
|
||||
}
|
||||
|
||||
string escape_string(const string& text, const string& pattern, const string& replace) {
|
||||
return regex_replace(text, regex(pattern), replace);
|
||||
}
|
||||
} // namespace Test::Menus
|
||||
14
sbf-cpp/Random.cpp
Normal file
14
sbf-cpp/Random.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <Random.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace SBF {
|
||||
std::random_device g_random_device;
|
||||
std::mt19937_64 g_random_number_engine(g_random_device());
|
||||
std::uniform_int_distribution<int> g_random_int_generator;
|
||||
|
||||
int GetRandomInt(int min, int max) {
|
||||
int r = g_random_int_generator(g_random_number_engine);
|
||||
return r % (max - min + 1) + min;
|
||||
}
|
||||
} // End namespace SBF
|
||||
7
sbf-cpp/Random.h
Normal file
7
sbf-cpp/Random.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef RANDOM_H__
|
||||
#define RANDOM_H__
|
||||
|
||||
namespace SBF {
|
||||
int GetRandomInt(int min, int max);
|
||||
} // End namespace SBF
|
||||
#endif // End RANDOM_H__
|
||||
33
sbf-cpp/Random_test.cpp
Normal file
33
sbf-cpp/Random_test.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "Random.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
using namespace SBF;
|
||||
using namespace Test;
|
||||
using namespace std;
|
||||
|
||||
namespace Test::Random {
|
||||
TestResults test_something();
|
||||
} // End namespace Test::Random
|
||||
|
||||
using namespace Test::Random;
|
||||
|
||||
TestResults main_test_Random(int argc, char* argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_something();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
namespace Test::Random {
|
||||
TestResults test_something() {
|
||||
return TestResults().skip("SBF::Random::*");
|
||||
}
|
||||
|
||||
} // namespace Test::Random
|
||||
@@ -13,9 +13,13 @@ using namespace SBF;
|
||||
using namespace Test;
|
||||
|
||||
namespace SBF {
|
||||
namespace {
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
} // End namespace
|
||||
|
||||
string word_wrap(const string& text, const size_t max_width) {
|
||||
vector<string> word_wrap(const string& text, const size_t max_width) {
|
||||
vector<string> lines;
|
||||
string output = "";
|
||||
string thisLine = "";
|
||||
string nextChunk = "";
|
||||
@@ -61,13 +65,14 @@ string word_wrap(const string& text, const size_t max_width) {
|
||||
}
|
||||
thisLine = make_fit_l(thisLine, max_width, L'_');
|
||||
output += thisLine + (done ? "" : "\n");
|
||||
lines.push_back(thisLine);
|
||||
thisLine = "";
|
||||
thisLineLength = thisLine.size();
|
||||
thisLineStartPosition = thisLineCurrentPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
return lines;
|
||||
}
|
||||
|
||||
string string_dollar(const size_t length, const char ch) {
|
||||
@@ -86,10 +91,45 @@ string left(const string& text, const size_t length) {
|
||||
return text.substr(0, length);
|
||||
}
|
||||
|
||||
string right(const string& text, const size_t length) {
|
||||
size_t text_length = text.size();
|
||||
size_t starting_position = text_length - length;
|
||||
if (text_length >= length) {
|
||||
return text.substr(starting_position);
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
string make_fit_c(const string& text, const size_t length, const char pad_character) {
|
||||
size_t text_length = text.size();
|
||||
size_t left_pad_length = length >= text_length ? (length - text_length) / 2 : 0;
|
||||
size_t right_pad_length = (length >= text_length + left_pad_length) ? (length - text_length - left_pad_length) : 0;
|
||||
string left_pad = string_dollar(left_pad_length, pad_character != '\0' ? pad_character : ' ');
|
||||
string right_pad = string_dollar(right_pad_length, pad_character != '\0' ? pad_character : ' ');
|
||||
size_t total_chop = (text_length >= length) ? text_length - length : 0;
|
||||
size_t left_chop = total_chop / 2; // + 1
|
||||
string ret = left_pad + (text == "" ? "" : text.substr(left_chop, length)) + right_pad;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string make_fit_b(const std::string& prefix,
|
||||
const std::string& suffix,
|
||||
const size_t length,
|
||||
const char pad_character) {
|
||||
return make_fit_l(make_fit_l(prefix, length - suffix.size(), pad_character != '\0' ? pad_character : ' ') + suffix,
|
||||
length,
|
||||
pad_character != '\0' ? pad_character : ' ');
|
||||
}
|
||||
|
||||
string make_fit_l(const string& text, const size_t length, const char pad_character) {
|
||||
return left(text + string_dollar(length, pad_character != '\0' ? pad_character : ' '), length);
|
||||
}
|
||||
|
||||
string make_fit_r(const string& text, const size_t length, const char pad_character) {
|
||||
return right(string_dollar(length, pad_character != '\0' ? pad_character : ' ') + text, length);
|
||||
}
|
||||
|
||||
string get_substring(const string& text, const size_t start, const size_t length) {
|
||||
return text.substr(std::min<size_t>(start, text.length()), std::max<size_t>(length, 0));
|
||||
}
|
||||
@@ -97,4 +137,45 @@ string get_substring(const string& text, const size_t start, const size_t length
|
||||
size_t get_index_of(const string& text, const string& search, const size_t start) {
|
||||
return text.find(search, start);
|
||||
}
|
||||
|
||||
bool is_whitespace(char ch) {
|
||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' || ch == '\v';
|
||||
}
|
||||
|
||||
string left_trim(const string& text) {
|
||||
if (text == "") {
|
||||
return "";
|
||||
}
|
||||
size_t index = 0;
|
||||
size_t length = text.size();
|
||||
while (index < length) {
|
||||
if (is_whitespace(text.at(index))) {
|
||||
index++;
|
||||
} else {
|
||||
return text.substr(index);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string right_trim(const string& text) {
|
||||
if (text == "") {
|
||||
return "";
|
||||
}
|
||||
size_t last_index = text.size() - 1;
|
||||
size_t index = last_index;
|
||||
|
||||
while (index != string::npos) {
|
||||
if (is_whitespace(text.at(index))) {
|
||||
index--;
|
||||
} else {
|
||||
return text.substr(0, index + 1);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string itos(int i) {
|
||||
return to_string(i);
|
||||
}
|
||||
} // End namespace SBF
|
||||
|
||||
@@ -9,51 +9,95 @@
|
||||
* Licensed under the MIT license see the LICENSE file for details.
|
||||
***************************************************************************************/
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Utils
|
||||
* @{
|
||||
*/
|
||||
namespace SBF {
|
||||
using std::string;
|
||||
|
||||
/// @brief Gets the first index of search in text starting at start.
|
||||
/// @param text The text to search.
|
||||
/// @param search The text to search for.
|
||||
/// @param start The position to start searching at.
|
||||
/// @return The position of the string if found and std::npos if not found.
|
||||
size_t get_index_of(const string& text, const string& search, const size_t start);
|
||||
size_t get_index_of(const std::string& text, const std::string& search, const size_t start);
|
||||
|
||||
/// @brief Collapses white space and attempts to word wrap text to a max of max_width columns.
|
||||
/// @param text The text to wrap.
|
||||
/// @param max_width The number of columns to wrap to.
|
||||
/// @return The wrapped text.
|
||||
string word_wrap(const string& text, const size_t max_width);
|
||||
std::vector<std::string> word_wrap(const std::string& text, const size_t max_width);
|
||||
|
||||
/// @brief Gets a substring of another string.
|
||||
/// @param text The text to split.
|
||||
/// @param start The starting position.
|
||||
/// @param length The length of the substring.
|
||||
/// @return The sub string of text.
|
||||
string get_substring(const string& text, const size_t start, const size_t length);
|
||||
std::string get_substring(const std::string& text, const size_t start, const size_t length);
|
||||
|
||||
/// @brief Pads or truncates text to length using pad_character.
|
||||
/// @brief Pads on the right or truncates text to length using pad_character.
|
||||
/// @param text The text to operate on.
|
||||
/// @param length The desired length to make text.
|
||||
/// @param pad_character The character to pad with.
|
||||
/// @return The modified string.
|
||||
string make_fit_l(const string& text, const size_t length, const char pad_character);
|
||||
std::string make_fit_l(const std::string& text, const size_t length, const char pad_character = ' ');
|
||||
|
||||
/// @brief Pads on both sides or truncates text to length using pad_character.
|
||||
/// @param text The text to operate on.
|
||||
/// @param length The desired length to make text.
|
||||
/// @param pad_character The character to pad with.
|
||||
/// @return The modified string.
|
||||
std::string make_fit_c(const std::string& text, const size_t length, const char pad_character = ' ');
|
||||
|
||||
/// @brief Pads on the left or truncates text to length using pad_character.
|
||||
/// @param text The text to operate on.
|
||||
/// @param length The desired length to make text.
|
||||
/// @param pad_character The character to pad with.
|
||||
/// @return The modified string.
|
||||
std::string make_fit_r(const std::string& text, const size_t length, const char pad_character = ' ');
|
||||
|
||||
/// @brief Pads or truncates the space between two strings.
|
||||
/// @param prefix The text to put on the left.
|
||||
/// @param suffix The text to put on the right.
|
||||
/// @param length The desired length to make the result.
|
||||
/// @param pad_character The character to pad with.
|
||||
/// @return The modified string.
|
||||
std::string make_fit_b(const std::string& prefix,
|
||||
const std::string& suffix,
|
||||
const size_t length,
|
||||
const char pad_character = ' ');
|
||||
|
||||
/// @brief Gets the leftmost length characters of text.
|
||||
/// @param text The text to operate on.
|
||||
/// @param length The maximum number of characters to return.
|
||||
/// @return The leftmost n characters of text where n is the lesser of text.size and length.
|
||||
string left(const string& text, const size_t length);
|
||||
std::string left(const std::string& text, const size_t length);
|
||||
|
||||
/// @brief Gets the rightmost length of characters of text.
|
||||
/// @param text The text to operate on.
|
||||
/// @param length The maximum number of characters to return.
|
||||
/// @return The rightmost n characters of text where n is the lesser of text.size and length.
|
||||
std::string right(const std::string& text, const size_t length);
|
||||
|
||||
/// @brief Removes whitespace from the left side of text.
|
||||
/// @param text The text to operate on.
|
||||
std::string left_trim(const std::string& text);
|
||||
|
||||
/// @brief Removes whitespace from the right side of text.
|
||||
/// @param text The text to operate on.
|
||||
std::string right_trim(const std::string& text);
|
||||
|
||||
/// @brief Gets a string made by repeating a character.
|
||||
/// @param length The length of the string to return.
|
||||
/// @param ch The character to repeat.
|
||||
/// @return The repeated string.
|
||||
string string_dollar(const size_t length, const char ch);
|
||||
std::string string_dollar(const size_t length, const char ch = ' ');
|
||||
|
||||
/// @brief Converts an int to a string.
|
||||
/// @param i The int to convert.
|
||||
/// @return The string representation of i.
|
||||
std::string itos(int i);
|
||||
} // End namespace SBF
|
||||
|
||||
/** @}*/
|
||||
|
||||
@@ -14,7 +14,12 @@ namespace Test::Utils {
|
||||
TestResults test_get_index_of();
|
||||
TestResults test_get_substring();
|
||||
TestResults test_left();
|
||||
TestResults test_left_trim();
|
||||
TestResults test_make_fit_c();
|
||||
TestResults test_make_fit_l();
|
||||
TestResults test_make_fit_r();
|
||||
TestResults test_right();
|
||||
TestResults test_right_trim();
|
||||
TestResults test_string_dollar();
|
||||
TestResults test_word_wrap();
|
||||
} // End namespace Test::Utils
|
||||
@@ -27,7 +32,12 @@ TestResults main_test_Utils(int argc, char* argv[]) {
|
||||
results += test_get_index_of();
|
||||
results += test_get_substring();
|
||||
results += test_left();
|
||||
results += test_left_trim();
|
||||
results += test_make_fit_c();
|
||||
results += test_make_fit_l();
|
||||
results += test_make_fit_r();
|
||||
results += test_right();
|
||||
results += test_right_trim();
|
||||
results += test_string_dollar();
|
||||
results += test_word_wrap();
|
||||
|
||||
@@ -119,6 +129,45 @@ TestResults test_left() {
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_right() {
|
||||
return execute_suite<string, string, size_t>(make_test_suite(
|
||||
"SBF::right",
|
||||
SBF::right,
|
||||
vector<TestTuple<string, string, size_t>>({
|
||||
make_test<string, string, size_t>(
|
||||
"should get a substring", "Basic", make_tuple(string("Microsoft QBasic"), size_t(5))),
|
||||
make_test<string, string, size_t>("should get the whole string if length is equal to text.size()",
|
||||
"Microsoft QBasic",
|
||||
make_tuple(string("Microsoft QBasic"), size_t(16))),
|
||||
make_test<string, string, size_t>("should get the whole string if length is greater than text.size()",
|
||||
"Microsoft QBasic",
|
||||
make_tuple(string("Microsoft QBasic"), size_t(20))),
|
||||
make_test<string, string, size_t>(
|
||||
"should get an empty string if length is 0", "", make_tuple(string("Microsoft QBasic"), size_t(0))),
|
||||
make_test<string, string, size_t>(
|
||||
"should get an empty string if text is empty", "", make_tuple(string(""), size_t(1))),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_make_fit_c() {
|
||||
return execute_suite<string, string, int32_t, char>(make_test_suite(
|
||||
"SBF::make_fit_c",
|
||||
make_fit_c,
|
||||
vector<TestTuple<string, string, int32_t, char>>({
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should truncate a string that is too long", "soft ", make_tuple(string("Microsoft QBasic"), 5, 'A')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should pad a string that is too short", "AAMicroAAA", make_tuple(string("Micro"), 10, 'A')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should return a string that is perfectly sized", "Micro", make_tuple(string("Micro"), 5, 'A')),
|
||||
make_test<string, string, int32_t, char>("should pad the string with spaces if padCh is the null character",
|
||||
" Micro ",
|
||||
make_tuple(string("Micro"), 10, '\0')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should return a padded string even if text is empty", "ZZZZZZZZZZ", make_tuple(string(""), 10, 'Z')),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_make_fit_l() {
|
||||
return execute_suite<string, string, int32_t, char>(make_test_suite(
|
||||
"SBF::make_fit_l",
|
||||
@@ -138,6 +187,87 @@ TestResults test_make_fit_l() {
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_make_fit_r() {
|
||||
return execute_suite<string, string, int32_t, char>(make_test_suite(
|
||||
"SBF::make_fit_r",
|
||||
make_fit_r,
|
||||
vector<TestTuple<string, string, int32_t, char>>({
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should truncate a string that is too long", "Basic", make_tuple(string("Microsoft QBasic"), 5, 'A')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should pad a string that is too short", "AAAAAMicro", make_tuple(string("Micro"), 10, 'A')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should return a string that is perfectly sized", "Micro", make_tuple(string("Micro"), 5, 'A')),
|
||||
make_test<string, string, int32_t, char>("should pad the string with spaces if padCh is the null character",
|
||||
" Micro",
|
||||
make_tuple(string("Micro"), 10, '\0')),
|
||||
make_test<string, string, int32_t, char>(
|
||||
"should return a padded string even if text is empty", "ZZZZZZZZZZ", make_tuple(string(""), 10, 'Z')),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_left_trim() {
|
||||
return execute_suite<string, string>(make_test_suite(
|
||||
"SBF::left_trim",
|
||||
left_trim,
|
||||
vector<TestTuple<string, string>>({
|
||||
make_test<string, string>("should trim a string with spaces",
|
||||
"this is a string with spaces on either end ",
|
||||
make_tuple(string(" this is a string with spaces on either end "))),
|
||||
make_test<string, string>("should trim a string with tabs",
|
||||
"this is a string with tabs on either end\t\t\t\t",
|
||||
make_tuple(string("\t\t\t\tthis is a string with tabs on either end\t\t\t\t"))),
|
||||
make_test<string, string>("should trim a string with newlines",
|
||||
"this is a string with newlines on either end\n\n\n\n",
|
||||
make_tuple(string("\n\n\n\nthis is a string with newlines on either end\n\n\n\n"))),
|
||||
make_test<string, string>(
|
||||
"should trim a string with carrige returns",
|
||||
"this is a string with carriage returns on either end\r\r\r\r",
|
||||
make_tuple(string("\r\r\r\rthis is a string with carriage returns on either end\r\r\r\r"))),
|
||||
make_test<string, string>(
|
||||
"should trim a string with mixed whitespace",
|
||||
"this is a string with mixed whitespace on either end\f\v\r\n\t ",
|
||||
make_tuple(string(" \t\n\r\v\fthis is a string with mixed whitespace on either end\f\v\r\n\t "))),
|
||||
make_test<string, string>("should get an unmodified string if there is nothing to trim",
|
||||
"this is a string that won't be trimmed",
|
||||
make_tuple(string("this is a string that won't be trimmed"))),
|
||||
make_test<string, string>("should get an empty string for an empty string", "", make_tuple(string(""))),
|
||||
make_test<string, string>(
|
||||
"should get an empty string for an all whitespace string", "", make_tuple(string(" \t\n\r\r\n\t "))),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_right_trim() {
|
||||
return execute_suite<string, string>(make_test_suite(
|
||||
"SBF::right_trim",
|
||||
right_trim,
|
||||
vector<TestTuple<string, string>>({
|
||||
make_test<string, string>("should trim a string with spaces",
|
||||
" this is a string with spaces on either end",
|
||||
make_tuple(string(" this is a string with spaces on either end "))),
|
||||
make_test<string, string>("should trim a string with tabs",
|
||||
"\t\t\t\tthis is a string with tabs on either end",
|
||||
make_tuple(string("\t\t\t\tthis is a string with tabs on either end\t\t\t\t"))),
|
||||
make_test<string, string>("should trim a string with newlines",
|
||||
"\n\n\n\nthis is a string with newlines on either end",
|
||||
make_tuple(string("\n\n\n\nthis is a string with newlines on either end\n\n\n\n"))),
|
||||
make_test<string, string>(
|
||||
"should trim a string with carrige returns",
|
||||
"\r\r\r\rthis is a string with carriage returns on either end",
|
||||
make_tuple(string("\r\r\r\rthis is a string with carriage returns on either end\r\r\r\r"))),
|
||||
make_test<string, string>(
|
||||
"should trim a string with mixed whitespace",
|
||||
" \t\n\r\v\fthis is a string with mixed whitespace on either end",
|
||||
make_tuple(string(" \t\n\r\v\fthis is a string with mixed whitespace on either end\f\v\r\n\t "))),
|
||||
make_test<string, string>("should get an unmodified string if there is nothing to trim",
|
||||
"this is a string that won't be trimmed",
|
||||
make_tuple(string("this is a string that won't be trimmed"))),
|
||||
make_test<string, string>("should get an empty string for an empty string", "", make_tuple(string(""))),
|
||||
make_test<string, string>(
|
||||
"should get an empty string for an all whitespace string", "", make_tuple(string(" \t\n\r\r\n\t "))),
|
||||
})));
|
||||
}
|
||||
|
||||
TestResults test_string_dollar() {
|
||||
return execute_suite<string, size_t, char>(make_test_suite(
|
||||
"SBF::string_dollar",
|
||||
@@ -152,27 +282,29 @@ TestResults test_string_dollar() {
|
||||
|
||||
// string word_wrap(const string& text, int maxWidth);
|
||||
TestResults test_word_wrap() {
|
||||
return execute_suite<string, string, int32_t>(make_test_suite(
|
||||
"SBF::word_wrap",
|
||||
word_wrap,
|
||||
vector<TestTuple<string, string, int32_t>>({
|
||||
make_test<string, string, int32_t>(
|
||||
"should return the string if it is shorter than max_width", "0123_", make_tuple(string("0123"), 5)),
|
||||
make_test<string, string, int32_t>(
|
||||
"should return the string if its length is equal to max_width", "01234", make_tuple(string("01234"), 5)),
|
||||
make_test<string, string, int32_t>("should wrap a string to two lines if it has no whitespace",
|
||||
"01234\n5____",
|
||||
make_tuple(string("012345"), 5)),
|
||||
make_test<string, string, int32_t>("should wrap a string to three lines if it has no whitespace",
|
||||
"01234\n56789\n0____",
|
||||
make_tuple(string("01234567890"), 5)),
|
||||
make_test<string, string, int32_t>("should wrap a string with even spacing",
|
||||
"01 23\n45 67\n89 01",
|
||||
make_tuple(string("01 23 45 67 89 01"), 5)),
|
||||
make_test<string, string, int32_t>("should collapse whitespace to a single space",
|
||||
"01 34\n67 90\n23 56\n89___",
|
||||
make_tuple(string("01 34 67 90 23 56 89 "), 5)),
|
||||
// TODO: Treat newlines and tabs in text as spaces.
|
||||
})));
|
||||
return TestResults().skip("SBF::word_wrap");
|
||||
// return execute_suite<string, string, int32_t>(make_test_suite(
|
||||
// "SBF::word_wrap",
|
||||
// word_wrap,
|
||||
// vector<TestTuple<string, string, int32_t>>({
|
||||
// make_test<string, string, int32_t>(
|
||||
// "should return the string if it is shorter than max_width", "0123_", make_tuple(string("0123"), 5)),
|
||||
// make_test<string, string, int32_t>(
|
||||
// "should return the string if its length is equal to max_width", "01234", make_tuple(string("01234"),
|
||||
// 5)),
|
||||
// make_test<string, string, int32_t>("should wrap a string to two lines if it has no whitespace",
|
||||
// "01234\n5____",
|
||||
// make_tuple(string("012345"), 5)),
|
||||
// make_test<string, string, int32_t>("should wrap a string to three lines if it has no whitespace",
|
||||
// "01234\n56789\n0____",
|
||||
// make_tuple(string("01234567890"), 5)),
|
||||
// make_test<string, string, int32_t>("should wrap a string with even spacing",
|
||||
// "01 23\n45 67\n89 01",
|
||||
// make_tuple(string("01 23 45 67 89 01"), 5)),
|
||||
// make_test<string, string, int32_t>("should collapse whitespace to a single space",
|
||||
// "01 34\n67 90\n23 56\n89___",
|
||||
// make_tuple(string("01 34 67 90 23 56 89 "), 5)),
|
||||
// // TODO: Treat newlines and tabs in text as spaces.
|
||||
// })));
|
||||
}
|
||||
} // End namespace Test::Utils
|
||||
|
||||
23
sbf-cpp/main_test.cpp
Normal file
23
sbf-cpp/main_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "Menus.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
using namespace SBF;
|
||||
using namespace Test;
|
||||
using namespace std;
|
||||
|
||||
namespace Test::Menus {} // End namespace Test::Menus
|
||||
|
||||
using namespace Test::Menus;
|
||||
|
||||
TestResults main_test_Menus(int argc, char* argv[]) {
|
||||
TestResults results;
|
||||
return results;
|
||||
}
|
||||
|
||||
namespace Test::Menus {} // namespace Test::Menus
|
||||
457
sbf-cpp/sbf.cpp
457
sbf-cpp/sbf.cpp
@@ -1,15 +1,466 @@
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#include "sbf.h"
|
||||
|
||||
#include "Abilities.h"
|
||||
#include "Attributes.h"
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "Archetypes.h"
|
||||
#include "Backgrounds.h"
|
||||
#include "Clans.h"
|
||||
#include "Genders.h"
|
||||
#include "Menus.h"
|
||||
#include "Random.h"
|
||||
#include "Utils.h"
|
||||
#include "sbf.h"
|
||||
|
||||
#define KEY_ESCAPE 0033
|
||||
|
||||
namespace {
|
||||
using namespace std;
|
||||
using namespace SBF;
|
||||
} // namespace
|
||||
|
||||
void CGGetAttributes(CharacterType& ch);
|
||||
void CGGetBackgrounds(CharacterType& ch);
|
||||
void CGGetDerangement(CharacterType& ch);
|
||||
void CGGetDisciplines(CharacterType& ch);
|
||||
void CGGetHeader(CharacterType& ch);
|
||||
void CGGetRoad(CharacterType& ch);
|
||||
void CGSpendFreebiePoints(CharacterType& ch);
|
||||
void CGSpendVirtuePoints(CharacterType& ch);
|
||||
void CharacterGenerator();
|
||||
void CharacterGeneratorForDummies();
|
||||
int ChooseStringId(vector<string> labels, MenuStyle style, string prompt);
|
||||
void CombatComputer();
|
||||
void DiceRoller();
|
||||
int GetChoice(int min, int max);
|
||||
int GetChoice();
|
||||
int GetMenuChoice(vector<MenuItem> menu_items, MenuStyle style);
|
||||
string GetString(string prompt);
|
||||
void MainMenu();
|
||||
void MaybeClearScreen();
|
||||
void RandomCharacterGenerator();
|
||||
void SaveCharacterSheet(CharacterType& ch);
|
||||
void ShowCharacterSheet(CharacterType& ch);
|
||||
void ShowSplashScreen();
|
||||
void VehicleGenerator();
|
||||
void WaitForKeypress();
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
setlocale(LC_ALL, "");
|
||||
ShowSplashScreen();
|
||||
MainMenu();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetChoice(int min, int max) {
|
||||
int choice;
|
||||
do {
|
||||
choice = GetChoice();
|
||||
} while (choice < min || choice > max);
|
||||
return choice;
|
||||
}
|
||||
|
||||
int GetChoice() {
|
||||
int choice;
|
||||
string line;
|
||||
bool has_error;
|
||||
do {
|
||||
has_error = false;
|
||||
getline(cin, line);
|
||||
try {
|
||||
if (line.empty()) {
|
||||
return 0;
|
||||
}
|
||||
choice = stoi(line);
|
||||
} catch (...) {
|
||||
has_error = true;
|
||||
}
|
||||
} while (has_error);
|
||||
return choice;
|
||||
}
|
||||
|
||||
void MainMenu() {
|
||||
int choice = 0;
|
||||
do {
|
||||
MaybeClearScreen();
|
||||
cout << "╔══════════════════════════════════════════════════════════════════════════════╗" << endl
|
||||
<< "║ What are you going to do? ║" << endl
|
||||
<< "║ 1 = Character Generator ║" << endl
|
||||
<< "║ 2 = Character Generator for Dummies ║" << endl
|
||||
<< "║ 3 = Combat Computer ║" << endl
|
||||
<< "║ 4 = Dice Roller ║" << endl
|
||||
<< "║ 5 = Random Character Generator ║" << endl
|
||||
<< "║ 6 = ║" << endl
|
||||
<< "║ 7 = Vehicle Generator ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "║ 0 = End ║" << endl
|
||||
<< "║ ║" << endl
|
||||
<< "╚══════════════════════════════════════════════════════════════════════════════╝" << endl;
|
||||
choice = GetChoice(0, 7);
|
||||
switch (choice) {
|
||||
case 1:
|
||||
CharacterGenerator();
|
||||
break;
|
||||
case 2:
|
||||
CharacterGeneratorForDummies();
|
||||
break;
|
||||
case 3:
|
||||
CombatComputer();
|
||||
break;
|
||||
case 4:
|
||||
DiceRoller();
|
||||
break;
|
||||
case 5:
|
||||
RandomCharacterGenerator();
|
||||
break;
|
||||
case 7:
|
||||
VehicleGenerator();
|
||||
break;
|
||||
}
|
||||
} while (choice != 0);
|
||||
}
|
||||
|
||||
/// Clears the screen if not a debug build.
|
||||
inline void MaybeClearScreen() {
|
||||
#if !defined(DEBUG)
|
||||
cout << "\033[1;1H\033[2J";
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShowSplashScreen() {
|
||||
cout << "Welcome to Tom's Storyteller's Best Friend. This is a program that is meant to" << endl
|
||||
<< "aid storytellers in running Vampire: the Masquerade Chronicles and Vampire: the" << endl
|
||||
<< "Dark Ages Chronicles. This program could aid in running campaigns for other" << endl
|
||||
<< "role-playing games especially those from White Wolf(tm). If you would like" << endl
|
||||
<< "anything added please open a github issue. https://github.com/headhunter45/sbf" << endl
|
||||
<< " Press any key to continue" << endl;
|
||||
WaitForKeypress();
|
||||
}
|
||||
|
||||
void WaitForKeypress() {
|
||||
// TODO: Make this press any key to continue.
|
||||
}
|
||||
|
||||
void CharacterGenerator() {
|
||||
CharacterType ch;
|
||||
CGGetHeader(ch);
|
||||
CGGetDisciplines(ch);
|
||||
CGGetAttributes(ch);
|
||||
CGGetBackgrounds(ch);
|
||||
CGGetRoad(ch);
|
||||
CGSpendVirtuePoints(ch);
|
||||
CGGetDerangement(ch);
|
||||
ch.generation = kInitialGeneration - ch.GetBackgroundValue(kBackgroundGenerationId);
|
||||
ch.willpower = ch.courage;
|
||||
ch.roadValue = ch.conscience + ch.selfControl;
|
||||
ch.bloodPool = GetRandomInt(1, 10);
|
||||
CGSpendFreebiePoints(ch);
|
||||
SaveCharacterSheet(ch);
|
||||
ShowCharacterSheet(ch);
|
||||
}
|
||||
|
||||
void CharacterGeneratorForDummies() {
|
||||
// TODO: Fill in this function.
|
||||
cout << "// TODO: CharacterGeneratorForDummies()" << endl;
|
||||
}
|
||||
|
||||
void CombatComputer() {
|
||||
// TODO: Fill in this function.
|
||||
cout << "// TODO: CombatComputer()" << endl;
|
||||
}
|
||||
|
||||
void DiceRoller() {
|
||||
// TODO: Fill in this function.
|
||||
cout << "// TODO: DiceRoller()" << endl;
|
||||
}
|
||||
|
||||
void RandomCharacterGenerator() {
|
||||
// TODO: Fill in this function.
|
||||
cout << "// TODO: RandomCharacterGenerator()" << endl;
|
||||
}
|
||||
|
||||
void VehicleGenerator() {
|
||||
// TODO: Fill in this function.
|
||||
cout << "// TODO: VehicleGenerator()" << endl;
|
||||
}
|
||||
|
||||
void CGGetHeader(CharacterType& ch) {
|
||||
MaybeClearScreen();
|
||||
MenuStyle ms;
|
||||
ch.name = GetString("What is the character's name?");
|
||||
ch.player = GetString("Who is the player?");
|
||||
ch.chronicle = GetString("What chronicle is the character going to be used for?");
|
||||
ch.haven = GetString("What is the character's Haven?");
|
||||
ch.concept = GetString("What is the character's concept?");
|
||||
ch.age = GetString("How old is the character?");
|
||||
vector<string> genders;
|
||||
FillGenderLabels(genders);
|
||||
ch.genderId = ChooseStringId(genders, ms, "What is the character's gender?");
|
||||
vector<string> clans;
|
||||
FillClanLabels(clans);
|
||||
ch.clanId = ChooseStringId(clans, ms, "What clan is the character from?");
|
||||
vector<string> archetypes;
|
||||
FillArchetypeLabels(archetypes);
|
||||
ch.natureId = ChooseStringId(archetypes, ms, "What is the character's nature?");
|
||||
ch.demeanorId = ChooseStringId(archetypes, ms, "What is the character's demeanor?");
|
||||
}
|
||||
|
||||
void CGGetDisciplines(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGGetDisciplines(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGGetAttributes(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGGetAttributes(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGGetBackgrounds(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGGetBackgrounds(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGGetRoad(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGGetRoad(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGSpendVirtuePoints(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGSpendVirtuePoints(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGGetDerangement(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGGetDerangement(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void CGSpendFreebiePoints(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: CGSpendFreebiePoints(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
string FormatAttributeValue(const string& label, int value) {
|
||||
return make_fit_c(label + make_fit_l(itos(value), 2), 12);
|
||||
}
|
||||
|
||||
string FormatAbilityWithValue(const string& label, int value) {
|
||||
return make_fit_c(make_fit_l(label + ":", 14) + itos(value), 24);
|
||||
}
|
||||
|
||||
void SaveCharacterSheet(CharacterType& ch) {
|
||||
// TODO: Fill this in.
|
||||
cout << "// TODO: SaveCharacterSheet(CharacterType&)" << endl;
|
||||
}
|
||||
|
||||
void ShowCharacterSheet(CharacterType& ch) {
|
||||
const int kLeftColumnWidth = 36;
|
||||
const int kRightColumnWidth = 37;
|
||||
vector<string> discipline_strings;
|
||||
size_t index;
|
||||
for (index = 1; index <= kDisciplinesCount; index++) {
|
||||
int value = ch.GetDisciplineValue(index);
|
||||
if (value > 0) {
|
||||
string suffix = "";
|
||||
if (value > 1) {
|
||||
suffix = " x" + itos(value);
|
||||
}
|
||||
discipline_strings.push_back(GetDisciplineLabel(index) + suffix);
|
||||
}
|
||||
}
|
||||
while (discipline_strings.size() <= 3) {
|
||||
discipline_strings.push_back(string_dollar(kLeftColumnWidth, '_'));
|
||||
}
|
||||
vector<string> background_strings(5);
|
||||
for (index = 1; index <= kBackgroundsCount; index++) {
|
||||
int value = ch.GetBackgroundValue(index);
|
||||
if (value > 0) {
|
||||
string suffix = "";
|
||||
if (value > 1) {
|
||||
suffix = " x" + itos(value);
|
||||
}
|
||||
background_strings.push_back(GetBackgroundLabel(index) + suffix);
|
||||
}
|
||||
}
|
||||
while (background_strings.size() <= 5) {
|
||||
background_strings.push_back(string_dollar(kLeftColumnWidth, '_'));
|
||||
}
|
||||
string all_derangements_line = ch.GetAllDerangementsLine();
|
||||
vector<string> derangement_strings = word_wrap(all_derangements_line, kLeftColumnWidth);
|
||||
while (derangement_strings.size() <= 5) {
|
||||
derangement_strings.push_back(string_dollar(kLeftColumnWidth, '_'));
|
||||
}
|
||||
MaybeClearScreen();
|
||||
cout << "╔══════════════════════════════════════╦═══════════════════════════════════════╗" << endl;
|
||||
cout << "║ Name: " << make_fit_l(ch.name, 30) << " ║ Gender: " << make_fit_l(GetGenderLabel(ch.genderId), 14)
|
||||
<< " Generation: " << make_fit_r(itos(ch.generation), 2) << " ║" << endl;
|
||||
cout << "║ Clan: " << make_fit_l(GetClanLabel(ch.clanId), 30) << " ║ Age: " << make_fit_l(ch.age, 32) << " ║" << endl;
|
||||
cout << "╠══════════════════════════════════════╣ Player: " << make_fit_l(ch.player, 29) << " ║" << endl;
|
||||
cout << "║ Attributes ║ Chronicle: " << make_fit_l(ch.chronicle, 26) << " ║" << endl;
|
||||
cout << "║ " << make_fit_c("Physical", 12) << make_fit_c("Social", 12) << make_fit_c("Mental", 12)
|
||||
<< " ║ Haven: " << make_fit_l(ch.haven, 30) + " ║" << endl;
|
||||
cout << "║ " << FormatAttributeValue("Str. ", ch.GetPhysicalAttributeValue(kPhysicalAttributeStrengthId))
|
||||
<< FormatAttributeValue("App. ", ch.GetSocialAttributeValue(kSocialAttributeAppearanceId))
|
||||
<< FormatAttributeValue("Int. ", ch.GetMentalAttributeValue(kMentalAttributeIntelligenceId))
|
||||
<< " ║ Concept: " << make_fit_l(ch.concept, 28) << " ║" << endl;
|
||||
cout << "║ " << FormatAttributeValue("Dex. ", ch.GetPhysicalAttributeValue(kPhysicalAttributeDexterityId))
|
||||
<< FormatAttributeValue("Cha. ", ch.GetSocialAttributeValue(kSocialAttributeCharismaId))
|
||||
<< FormatAttributeValue("Per. ", ch.GetMentalAttributeValue(kMentalAttributePerceptionId))
|
||||
<< " ╠═══════════════════════════════════════╣" << endl;
|
||||
cout << "║ " << FormatAttributeValue("Sta. ", ch.GetPhysicalAttributeValue(kPhysicalAttributeStaminaId))
|
||||
<< FormatAttributeValue("Man. ", ch.GetSocialAttributeValue(kSocialAttributeManipulationId))
|
||||
<< FormatAttributeValue("Wit. ", ch.GetMentalAttributeValue(kMentalAttributeWitsId))
|
||||
<< " ║ Derangements: ║" << endl;
|
||||
cout << "╠══════════════════════════════════════╣ " << make_fit_l(derangement_strings[0], kRightColumnWidth, '_')
|
||||
<< " ║" << endl;
|
||||
cout << "║ Disciplines: ║ " << make_fit_l(derangement_strings[1], kRightColumnWidth, '_')
|
||||
<< " ║" << endl;
|
||||
cout << "║ " << make_fit_l(discipline_strings[0], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_l(derangement_strings[2], kRightColumnWidth, '_') << " ║" << endl;
|
||||
cout << "║ " << make_fit_l(discipline_strings[1], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_l(derangement_strings[3], kRightColumnWidth, '_') << " ║" << endl;
|
||||
cout << "║ " << make_fit_l(discipline_strings[2], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_l(derangement_strings[4], kRightColumnWidth, '_') << " ║" << endl;
|
||||
cout << "╠══════════════════════════════════════╬═══════════════════════════════════════╣" << endl;
|
||||
cout << "║ " << make_fit_l(ch.roadName + ": " + itos(ch.roadValue), kLeftColumnWidth)
|
||||
<< " ║ Nature: " << make_fit_l(GetArchetypeLabel(ch.natureId), 29) << " ║" << endl;
|
||||
cout << "║ Willpower: " << make_fit_l(itos(ch.willpower), 25)
|
||||
<< " ║ Demeanor: " << make_fit_l(GetArchetypeLabel(ch.demeanorId), 27) << " ║" << endl;
|
||||
cout << "╠══════════════════════════════════════╩═══════════════════════════════════════╣" << endl;
|
||||
cout << "║ ║" << endl;
|
||||
cout << "║ ║" << endl;
|
||||
cout << "║ ║" << endl;
|
||||
cout << "║ <<PRESS ANY KEY TO CONTINUE>> ║" << endl;
|
||||
cout << "╚══════════════════════════════════════════════════════════════════════════════╝" << endl;
|
||||
WaitForKeypress();
|
||||
cout << "╔══════════════════════════════════════════════════════════════════════════════╗" << endl;
|
||||
cout << "║ " << make_fit_c("Abilities", 76) << " ║" << endl;
|
||||
cout << "║ " << make_fit_c("Talents", 24) << make_fit_c("Skills", 24) << make_fit_c("Knowledges", 24) << " ║"
|
||||
<< endl;
|
||||
for (index = 1; index <= 10; index++) {
|
||||
cout << "║ " << FormatAbilityWithValue(GetTalentLabel(index), ch.GetTalentValue(index))
|
||||
<< FormatAbilityWithValue(GetSkillLabel(index), ch.GetSkillValue(index))
|
||||
<< FormatAbilityWithValue(GetKnowledgeLabel(index), ch.GetKnowledgeValue(index)) << " ║" << endl;
|
||||
}
|
||||
cout << "╠══════════════════════════════════════╦═══════════════════════════════════════╣" << endl;
|
||||
cout << "║ " << make_fit_l("Backgrounds:", kLeftColumnWidth) << " ║ " << make_fit_l("Virtues:", kRightColumnWidth)
|
||||
<< " ║" << endl;
|
||||
cout << "║ " << make_fit_l(background_strings[0], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_b("Conscience:", itos(ch.conscience), kRightColumnWidth) << " ║" << endl;
|
||||
cout << "║ " << make_fit_l(background_strings[1], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_b("Self-Control:", itos(ch.selfControl), kRightColumnWidth) << " ║" << endl;
|
||||
cout << "║ " << make_fit_l(background_strings[2], kLeftColumnWidth) << " ║ "
|
||||
<< make_fit_b("Courage:", itos(ch.courage), kRightColumnWidth) << " ║" << endl;
|
||||
cout << "║ " << make_fit_l(background_strings[3], kLeftColumnWidth) << " ║ " << make_fit_l("", kRightColumnWidth)
|
||||
<< " ║" << endl;
|
||||
cout << "║ " << make_fit_l(background_strings[4], kLeftColumnWidth) << " ║ " << make_fit_l("", kRightColumnWidth)
|
||||
<< " ║" << endl;
|
||||
cout << "╠══════════════════════════════════════╩═══════════════════════════════════════╣" << endl;
|
||||
cout << "║ <<PRESS ANY KEY TO CONTINUE>> ║" << endl;
|
||||
cout << "╚══════════════════════════════════════════════════════════════════════════════╝" << endl;
|
||||
WaitForKeypress();
|
||||
/*
|
||||
╔══════════════════════════════════════╦═══════════════════════════════════════╗
|
||||
║ Name: Ted ║ Gender: Female Generation: 13 ║
|
||||
║ Clan: Ventrue ║ Age: 35 ║
|
||||
╠══════════════════════════════════════╣ Player: Jeff ║
|
||||
║ Attributes ║ Chronicle: Somesuch ║
|
||||
║ Physical Social Mental ║ Haven: Mom's basement ║
|
||||
║ Str. 1 App. 1 Int. 1 ║ Concept: Asshole ║
|
||||
║ Dex. 1 Cha. 1 Per. 1 ╠═══════════════════════════════════════╣
|
||||
║ Sta. 1 Man. 1 Wit. 1 ║ Derangements: ║
|
||||
╠══════════════════════════════════════╣ _____________________________________ ║
|
||||
║ Disciplines: ║ _____________________________________ ║
|
||||
║ ____________________________________ ║ _____________________________________ ║
|
||||
║ ____________________________________ ║ _____________________________________ ║
|
||||
║ ____________________________________ ║ _____________________________________ ║
|
||||
╠══════════════════════════════════════╬═══════════════════════════════════════╣
|
||||
║ : 2 ║ Nature: Tyrant ║
|
||||
║ Willpower: 1 ║ Demeanor: Traditionalist ║
|
||||
╠══════════════════════════════════════╩═══════════════════════════════════════╣
|
||||
║ ║
|
||||
║ ║
|
||||
║ ║
|
||||
║ <<PRESS ANY KEY TO CONTINUE>> ║
|
||||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
║ Abilities ║
|
||||
║ Talents Skills Knowledges ║
|
||||
║ Acting: 0 Animal Ken: 0 Bureaucracy: 0 ║
|
||||
║ Alertness: 0 Drive: 0 Computer: 0 ║
|
||||
║ Athletics: 0 Etiquette: 0 Finance: 0 ║
|
||||
║ Brawl: 0 Firearms: 0 Investigation:0 ║
|
||||
║ Dodge: 0 Melee: 0 Law: 0 ║
|
||||
║ Empathy: 0 Music: 0 Linguistics: 0 ║
|
||||
║ Intimidation: 0 Repair: 0 Medicine: 0 ║
|
||||
║ Leadership: 0 Security: 0 Occult: 0 ║
|
||||
║ Streetwise: 0 Stealth: 0 Politics: 0 ║
|
||||
║ Subterfuge: 0 Survival: 0 Science: 0 ║
|
||||
╠══════════════════════════════════════╦═══════════════════════════════════════╣
|
||||
║ Backgrounds: ║ Virtues: ║
|
||||
║ ║ Conscience: 1 ║
|
||||
║ ║ Self-Control: 1 ║
|
||||
║ ║ Courage: 1 ║
|
||||
║ ║ ║
|
||||
║ ║ ║
|
||||
╠══════════════════════════════════════╩═══════════════════════════════════════╣
|
||||
║ <<PRESS ANY KEY TO CONTINUE>> ║
|
||||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
// TODO: ShowCharacterSheet(CharacterType&)
|
||||
*/
|
||||
}
|
||||
|
||||
int GetRandomInt(int min, int max) {
|
||||
// TODO: Fill this in.
|
||||
return 0;
|
||||
}
|
||||
|
||||
string GetString(string prompt) {
|
||||
cout << prompt << endl;
|
||||
string response;
|
||||
getline(cin, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
int ChooseStringId(vector<string> labels, MenuStyle style, string prompt) {
|
||||
MaybeClearScreen();
|
||||
vector<MenuItem> menu_items = BuildMenu(labels);
|
||||
style.Adjust(menu_items);
|
||||
cout << prompt << endl;
|
||||
PrintMenu(cout, menu_items, style);
|
||||
int choice = GetMenuChoice(menu_items, style);
|
||||
if (choice == style.random_item_id) {
|
||||
choice = GetRandomMenuItemId(menu_items);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
|
||||
int GetMenuChoice(vector<MenuItem> menu_items, MenuStyle style) {
|
||||
int choice;
|
||||
while (true) {
|
||||
choice = GetChoice();
|
||||
if (style.show_random && choice == style.random_item_id) {
|
||||
return choice;
|
||||
}
|
||||
if (style.show_cancel && choice == style.cancel_item_id) {
|
||||
return choice;
|
||||
}
|
||||
for (MenuItem item : menu_items) {
|
||||
if (item.id == choice) {
|
||||
return choice;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
sbf-cpp/sbf_test.cpp
Normal file
23
sbf-cpp/sbf_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "sbf.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
using namespace SBF;
|
||||
using namespace Test;
|
||||
using namespace std;
|
||||
|
||||
namespace Test::sbf {} // End namespace Test::sbf
|
||||
|
||||
using namespace Test::sbf;
|
||||
|
||||
TestResults main_test_sbf(int argc, char* argv[]) {
|
||||
TestResults results;
|
||||
return results;
|
||||
}
|
||||
|
||||
namespace Test::sbf {} // namespace Test::sbf
|
||||
@@ -354,7 +354,7 @@ TestResults execute_suite(std::string suite_label,
|
||||
|
||||
if (!is_enabled) {
|
||||
std::cout << " 🚧Skipping Test: " << test_name << std::endl;
|
||||
results.skip("🚧Skipping Test: " + qualified_test_name);
|
||||
results.skip(qualified_test_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -371,16 +371,16 @@ TestResults execute_suite(std::string suite_label,
|
||||
} catch (const std::exception& ex) {
|
||||
std::ostringstream os;
|
||||
os << "Caught exception \"" << ex.what() << "\"";
|
||||
results.error("🔥ERROR: " + qualified_test_name + " " + os.str());
|
||||
results.error(qualified_test_name + " " + os.str());
|
||||
std::cout << " 🔥ERROR: " << os.str() << std::endl;
|
||||
} catch (const std::string& message) {
|
||||
std::ostringstream os;
|
||||
os << "Caught string \"" << message << "\"";
|
||||
results.error("🔥ERROR: " + qualified_test_name + " " + os.str());
|
||||
results.error(qualified_test_name + " " + os.str());
|
||||
std::cout << " 🔥ERROR: " << os.str() << std::endl;
|
||||
} catch (...) {
|
||||
string message = "Caught something that is neither an std::exception nor an std::string.";
|
||||
results.error("🔥ERROR: " + qualified_test_name + " " + message);
|
||||
results.error(qualified_test_name + " " + message);
|
||||
std::cout << " 🔥ERROR: " << message << std::endl;
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ TestResults execute_suite(std::string suite_label,
|
||||
} else {
|
||||
std::ostringstream os;
|
||||
os << "expected: \"" << expected_output << "\", actual: \"" << actual << "\"";
|
||||
results.fail("❌FAILED: " + qualified_test_name + " " + os.str());
|
||||
results.fail(qualified_test_name + " " + os.str());
|
||||
std::cout << " ❌FAILED: " << os.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user