From e8e9904de331d129086cd014bb6f5f4d22736ffb Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Sat, 22 Apr 2023 00:32:17 -0700 Subject: [PATCH] Implements freebies and tests. --- Makefile | 2 +- sbf-cpp/Freebies._test.cpp | 0 sbf-cpp/Freebies.cpp | 37 ++++++++ sbf-cpp/Freebies.h | 138 ++++++++++++++++++++++++++++ sbf-cpp/Freebies_test.cpp | 182 +++++++++++++++++++++++++++++++++++++ 5 files changed, 358 insertions(+), 1 deletion(-) delete mode 100644 sbf-cpp/Freebies._test.cpp create mode 100644 sbf-cpp/Freebies_test.cpp diff --git a/Makefile b/Makefile index b9142d2..d1aaea9 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ BUNDLEIDENTIFIER = com.majinnaibu.test.$(APPNAME) BUNDLESIGNATURE = SBF_ RESOURCES_DIR = Resources #APP_OBJECTS = Character.o Colors.o Menus.o -MODULES = Abilities Archetypes Attributes Backgrounds Character Clans Colors Derangements Disciplines Genders Ranks Utils Virtues +MODULES = Abilities Archetypes Attributes Backgrounds Character Clans Colors Derangements Disciplines Freebies Genders Ranks Utils Virtues APP_OBJECTS = $(patsubst %, $(BUILD_DIR)/%.o, $(MODULES)) FAT_LIBS = ncurses FAT_LIB_OBJECTS = $(patsubst %, $(LIB_DIR)/lib%.a, $(FAT_LIBS)) diff --git a/sbf-cpp/Freebies._test.cpp b/sbf-cpp/Freebies._test.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/sbf-cpp/Freebies.cpp b/sbf-cpp/Freebies.cpp index e69de29..aa761e4 100644 --- a/sbf-cpp/Freebies.cpp +++ b/sbf-cpp/Freebies.cpp @@ -0,0 +1,37 @@ +#include "Freebies.h" + +#include + +namespace SBF { +namespace { +using std::ostream; +} // End namespace + +ostream& operator<<(ostream& os, const FreebieType& freebie) { + os << "Freebie: {id: " << freebie.id << ", cost: " << freebie.cost << ", name: \"" << freebie.name << "\", label: \"" + << freebie.label << "\"}"; + return os; +} + +bool operator==(const FreebieType& left, const FreebieType& right) { + return left.id == right.id && left.cost == right.cost && left.name == right.name && left.label == right.label; +} + +bool operator!=(const FreebieType& left, const FreebieType& right) { + return !(left == right); +} + +FreebieType GetFreebie(int freebie_id) { + if (freebie_id > 0 && freebie_id <= kFreebiesCount) { + return kFreebies[freebie_id]; + } + return kFreebieUnknown; +} + +void FillFreebies(std::vector& freebies) { + freebies.clear(); + for (int id = 1; id <= kFreebiesCount; id++) { + freebies.push_back(GetFreebie(id)); + } +} +} // End namespace SBF diff --git a/sbf-cpp/Freebies.h b/sbf-cpp/Freebies.h index 0a04275..68ec00d 100644 --- a/sbf-cpp/Freebies.h +++ b/sbf-cpp/Freebies.h @@ -2,6 +2,7 @@ #define FREEBIES_H__ #include +#include namespace SBF { struct FreebieType { @@ -10,6 +11,143 @@ struct FreebieType { std::string name; std::string label; }; + +const int kFreebiesCount = 7; + +const FreebieType kFreebieUnknown = {0, 0, "", ""}; + +const int kFreebieDisciplineId = 1; +const int kFreebieDisciplineCost = 7; +const std::string kFreebieDisciplineName = "Discipline"; +const std::string kFreebieDisciplineLabel = "Add a discipline dot 7 points"; +const FreebieType kFreebieDiscipline = { + kFreebieDisciplineId, kFreebieDisciplineCost, kFreebieDisciplineName, kFreebieDisciplineLabel}; + +const int kFreebieAttributeId = 2; +const int kFreebieAttributeCost = 5; +const std::string kFreebieAttributeName = "Attribute"; +const std::string kFreebieAttributeLabel = "Add an attribute dot 5 points"; +const FreebieType kFreebieAttribute = { + kFreebieAttributeId, kFreebieAttributeCost, kFreebieAttributeName, kFreebieAttributeLabel}; + +const int kFreebieAbilityId = 3; +const int kFreebieAbilityCost = 2; +const std::string kFreebieAbilityName = "Ability"; +const std::string kFreebieAbilityLabel = "Add an ability dot 2 points"; +const FreebieType kFreebieAbility = {kFreebieAbilityId, kFreebieAbilityCost, kFreebieAbilityName, kFreebieAbilityLabel}; + +const int kFreebieVirtueId = 4; +const int kFreebieVirtueCost = 2; +const std::string kFreebieVirtueName = "Virtue"; +const std::string kFreebieVirtueLabel = "Add a virtue dot 2 points"; +const FreebieType kFreebieVirtue = {kFreebieVirtueId, kFreebieVirtueCost, kFreebieVirtueName, kFreebieVirtueLabel}; + +// TODO: Make this configurable for VtDA +const int kFreebieHumanityId = 5; +const int kFreebieHumanityCost = 1; +const std::string kFreebieHumanityName = "Humanity"; +const std::string kFreebieHumanityLabel = "Add a humanity dot 1 point"; +const FreebieType kFreebieHumanity = { + kFreebieHumanityId, kFreebieHumanityCost, kFreebieHumanityName, kFreebieHumanityLabel}; + +const int kFreebieBackgroundId = 6; +const int kFreebieBackgroundCost = 1; +const std::string kFreebieBackgroundName = "Background"; +const std::string kFreebieBackgroundLabel = "Add a background dot 1 point"; +const FreebieType kFreebieBackground = { + kFreebieBackgroundId, kFreebieBackgroundCost, kFreebieBackgroundName, kFreebieBackgroundLabel}; + +const int kFreebieShowCharacterSheetId = 7; +const int kFreebieShowCharacterSheetCost = 0; +const std::string kFreebieShowCharacterSheetName = "Show character sheet"; +const std::string kFreebieShowCharacterSheetLabel = "Show character sheet"; +const FreebieType kFreebieShowCharacterSheet = {kFreebieShowCharacterSheetId, + kFreebieShowCharacterSheetCost, + kFreebieShowCharacterSheetName, + kFreebieShowCharacterSheetLabel}; + +const int kFreebieIds[] = { + 0, + kFreebieDisciplineId, + kFreebieAttributeId, + kFreebieAbilityId, + kFreebieVirtueId, + kFreebieHumanityId, + kFreebieBackgroundId, + kFreebieShowCharacterSheetId, +}; + +const int kFreebieCosts[] = { + 0, + kFreebieDisciplineCost, + kFreebieAttributeCost, + kFreebieAbilityCost, + kFreebieVirtueCost, + kFreebieHumanityCost, + kFreebieBackgroundCost, + kFreebieShowCharacterSheetCost, +}; + +const std::string kFreebieNames[] = { + "", + kFreebieDisciplineName, + kFreebieAttributeName, + kFreebieAbilityName, + kFreebieVirtueName, + kFreebieHumanityName, + kFreebieBackgroundName, + kFreebieShowCharacterSheetName, +}; + +const std::string kFreebieLabels[] = { + "", + kFreebieDisciplineLabel, + kFreebieAttributeLabel, + kFreebieAbilityLabel, + kFreebieVirtueLabel, + kFreebieHumanityLabel, + kFreebieBackgroundLabel, + kFreebieShowCharacterSheetLabel, +}; + +const FreebieType kFreebies[] = { + kFreebieUnknown, + kFreebieDiscipline, + kFreebieAttribute, + kFreebieAbility, + kFreebieVirtue, + kFreebieHumanity, + kFreebieBackground, + kFreebieShowCharacterSheet, +}; + +/// @brief Writes a freebie to an ostream. +/// @param os The ostream to write to. +/// @param freebie The freebie to write. +/// @return The provided ostream for chaining. +std::ostream& operator<<(std::ostream& os, const FreebieType& freebie); + +/// @brief Determines if two freebies are equal. +/// @param left A freebie to compare. +/// @param right A freebie to compare. +/// @return True if both freebies are equal and false otherwise. +bool operator==(const FreebieType& left, const FreebieType& right); + +/// @brief Determines if two freebies are unequal. +/// @param left A freebie to compare. +/// @param right A freebie to compare. +/// @return True if both freebies are unequal and false otherwise. +bool operator!=(const FreebieType& left, const FreebieType& right); + +/// @brief Gets a freebie with a specific id. +/// @param freebie_id The id of the freebie to get. +/// @return The freebie with id == freebie_id or the unknown freebie kFreebieUnknown if freebie_id is invalid. +FreebieType GetFreebie(int freebie_id); + +/// @brief Fills the provided vector with all valid freebies. +/// @param freebies The vector to fill. It will be cleared first. +void FillFreebies(std::vector& freebies); + } // End namespace SBF #endif diff --git a/sbf-cpp/Freebies_test.cpp b/sbf-cpp/Freebies_test.cpp new file mode 100644 index 0000000..87bcf6d --- /dev/null +++ b/sbf-cpp/Freebies_test.cpp @@ -0,0 +1,182 @@ +#include "Freebies.h" + +#include +#include +#include +#include + +#include "test.h" + +using namespace SBF; +using namespace Test; +using namespace std; + +namespace Test::Freebies { +TestResults test_FreebieType_operator_extract(); +TestResults test_FreebieType_operator_equal_to(); +TestResults test_FreebieType_operator_not_equal_to(); +TestResults test_GetFreebie(); +TestResults test_FillFreebies(); +} // End namespace Test::Freebies + +using namespace Test::Freebies; + +TestResults main_test_Freebies(int argc, char* argv[]) { + TestResults results; + + results += test_FreebieType_operator_extract(); + results += test_FreebieType_operator_equal_to(); + results += test_FreebieType_operator_not_equal_to(); + results += test_GetFreebie(); + results += test_FillFreebies(); + + return results; +} + +namespace Test::Freebies { +TestResults test_FreebieType_operator_extract() { + auto fnToTest = [](const FreebieType& freebie) -> string { + ostringstream os; + os << freebie; + return os.str(); + }; + return execute_suite(make_test_suite( + "SBF::FreebieType::operator<<", + fnToTest, + vector>({ + make_test("should print an invalid freebie", + "Freebie: {id: 16, cost: 42, name: \"asdf\", label: \"fdsa\"}", + make_tuple((FreebieType){16, 42, "asdf", "fdsa"})), + make_test("should print the unknown freebie", + "Freebie: {id: 0, cost: 0, name: \"\", label: \"\"}", + make_tuple(kFreebieUnknown)), + make_test( + "should print the discipline freebie", + "Freebie: {id: 1, cost: 7, name: \"Discipline\", label: \"Add a discipline dot 7 points\"}", + make_tuple(kFreebieDiscipline)), + make_test( + "should print the attribute freebie", + "Freebie: {id: 2, cost: 5, name: \"Attribute\", label: \"Add an attribute dot 5 points\"}", + make_tuple(kFreebieAttribute)), + make_test( + "should print the ability freebie", + "Freebie: {id: 3, cost: 2, name: \"Ability\", label: \"Add an ability dot 2 points\"}", + make_tuple(kFreebieAbility)), + make_test( + "should print the virtue freebie", + "Freebie: {id: 4, cost: 2, name: \"Virtue\", label: \"Add a virtue dot 2 points\"}", + make_tuple(kFreebieVirtue)), + make_test( + "should print the humanity freebie", + "Freebie: {id: 5, cost: 1, name: \"Humanity\", label: \"Add a humanity dot 1 point\"}", + make_tuple(kFreebieHumanity)), + make_test( + "should print the background freebie", + "Freebie: {id: 6, cost: 1, name: \"Background\", label: \"Add a background dot 1 point\"}", + make_tuple(kFreebieBackground)), + make_test( + "should print the show character sheet freebie", + "Freebie: {id: 7, cost: 0, name: \"Show character sheet\", label: \"Show character sheet\"}", + make_tuple(kFreebieShowCharacterSheet)), + }))); +} + +TestResults test_FreebieType_operator_equal_to() { + return execute_suite(make_test_suite( + "SBF::FreebieType::operator==", + [](const FreebieType& left, const FreebieType& right) -> bool { return left == right; }, + vector>({ + make_test("should return true when comparing a freebie to itself", + true, + make_tuple(kFreebieBackground, kFreebieBackground)), + make_test( + "should return true when comparing two different instances created with the same values", + true, + make_tuple( + kFreebieAbility, + (FreebieType){kFreebieAbilityId, kFreebieAbilityCost, kFreebieAbilityName, kFreebieAbilityLabel})), + make_test("should return false when comparing two different freebies", + false, + make_tuple(kFreebieHumanity, kFreebieVirtue)), + }))); +} + +TestResults test_FreebieType_operator_not_equal_to() { + return execute_suite(make_test_suite( + "SBF::FreebieType::operator!=", + [](const FreebieType& left, const FreebieType& right) -> bool { return left != right; }, + vector>({ + make_test("should return false when comparing a freebie to itself", + false, + make_tuple(kFreebieBackground, kFreebieBackground)), + make_test( + "should return false when comparing two different instances created with the same values", + false, + make_tuple( + kFreebieAbility, + (FreebieType){kFreebieAbilityId, kFreebieAbilityCost, kFreebieAbilityName, kFreebieAbilityLabel})), + make_test("should return true when comparing two different freebies", + true, + make_tuple(kFreebieHumanity, kFreebieVirtue)), + }))); +} + +TestResults test_GetFreebie() { + return execute_suite(make_test_suite( + "SBF::GetFreebie", + GetFreebie, + vector>({ + make_test("should get the unknown freebie for invalid id 0", {0, 0, "", ""}, make_tuple(0)), + make_test("should get the discipline freebie for id 1", + {1, 7, "Discipline", "Add a discipline dot 7 points"}, + make_tuple(1)), + make_test("should get the attribute freebie for id 2", + {2, 5, "Attribute", "Add an attribute dot 5 points"}, + make_tuple(2)), + make_test("should get the ability freebie for id 3", + {3, 2, "Ability", "Add an ability dot 2 points"}, + make_tuple(3)), + make_test("should get the virtue freebie for id 4", + {4, 2, "Virtue", "Add a virtue dot 2 points"}, + make_tuple(4)), + make_test("should get the humanity freebie for id 5", + {5, 1, "Humanity", "Add a humanity dot 1 point"}, + make_tuple(5)), + make_test("should get the background freebie for id 6", + {6, 1, "Background", "Add a background dot 1 point"}, + make_tuple(6)), + make_test("should get the show character sheet freebie for id 7", + {7, 0, "Show character sheet", "Show character sheet"}, + make_tuple(7)), + make_test("should get the unknown freebie for invalid id 8", {0, 0, "", ""}, make_tuple(8)), + }))); +} + +TestResults test_FillFreebies() { + auto fnToTest = []() -> string { + ostringstream error_message; + vector expected = { + kFreebieDiscipline, + kFreebieAttribute, + kFreebieAbility, + kFreebieVirtue, + kFreebieHumanity, + kFreebieBackground, + kFreebieShowCharacterSheet, + }; + vector actual = {{-1, -2, "This should be removed.", "This should be removed"}}; + FillFreebies(actual); + compare(error_message, expected, actual); + string error = error_message.str(); + if (error.size() > 0) { + return error; + } + return "no errors"; + }; + return execute_suite(make_test_suite( + "SBF::FillFreebies", + fnToTest, + vector>({make_test("should fill freebies", "no errors", make_tuple())}))); +} + +} // End namespace Test::Freebies