diff --git a/Hazelnupp/Hazelnupp.cpp b/Hazelnupp/Hazelnupp.cpp index 1e09648..0595dbc 100644 --- a/Hazelnupp/Hazelnupp.cpp +++ b/Hazelnupp/Hazelnupp.cpp @@ -320,25 +320,35 @@ void Hazelnp::Hazelnupp::RegisterDescription(const std::string& parameter, const return; } -const std::string Hazelnp::Hazelnupp::GetDescription(const std::string& parameter) const +std::string Hazelnp::Hazelnupp::GetDescription(const std::string& parameter) const { // Do we already have a description for this parameter? - const auto par = parameterDescriptions.find(parameter); - if (par == parameterDescriptions.end()) + if (!HasDescription(parameter)) // No? Then return "" return ""; // We do? Then return it - return par->second; + return parameterDescriptions.find(parameter)->second; } -void Hazelnp::Hazelnupp::ClearDescription(const std::string& parameter) +bool Hazelnupp::HasDescription(const std::string& parameter) const +{ + return parameterDescriptions.find(parameter) != parameterDescriptions.end(); +} + +void Hazelnupp::ClearDescription(const std::string& parameter) { // This will just do nothing if the entry does not exist parameterDescriptions.erase(parameter); return; } +void Hazelnp::Hazelnupp::ClearDescriptions() +{ + parameterDescriptions.clear(); + return; +} + std::string Hazelnupp::GenerateDocumentation() const { std::stringstream ss; @@ -482,6 +492,17 @@ void Hazelnupp::ApplyConstraints() return; } +ParamConstraint Hazelnupp::GetConstraint(const std::string& parameter) const +{ + return constraints.find(parameter)->second; +} + +void Hazelnupp::ClearConstraint(const std::string& parameter) +{ + constraints.erase(parameter); + return; +} + const std::string& Hazelnupp::GetExecutableName() const { return executableName; @@ -502,8 +523,11 @@ void Hazelnupp::RegisterAbbreviation(const std::string& abbrev, const std::strin return; } -const std::string& Hazelnupp::GetAbbreviation(const std::string& abbrev) const +std::string Hazelnupp::GetAbbreviation(const std::string& abbrev) const { + if (!HasAbbreviation(abbrev)) + return ""; + return abbreviations.find(abbrev)->second; } @@ -512,6 +536,12 @@ bool Hazelnupp::HasAbbreviation(const std::string& abbrev) const return abbreviations.find(abbrev) != abbreviations.end(); } +void Hazelnupp::ClearAbbreviation(const std::string& abbrevation) +{ + abbreviations.erase(abbrevation); + return; +} + void Hazelnupp::ClearAbbreviations() { abbreviations.clear(); diff --git a/Hazelnupp/Hazelnupp.h b/Hazelnupp/Hazelnupp.h index 96e2dc6..ca93e02 100644 --- a/Hazelnupp/Hazelnupp.h +++ b/Hazelnupp/Hazelnupp.h @@ -32,18 +32,29 @@ namespace Hazelnp //! Will register an abbreviation (like -f for --force) void RegisterAbbreviation(const std::string& abbrev, const std::string& target); - //! Will return the long form of an abbreviation (like --force for -f) - const std::string& GetAbbreviation(const std::string& abbrev) const; + //! Will return the long form of an abbreviation (like --force for -f) + //! Returns "" if no match is found + std::string GetAbbreviation(const std::string& abbrev) const; //! Will check wether or not an abbreviation is registered bool HasAbbreviation(const std::string& abbrev) const; + //! Will delete the abbreviation for a given parameter. + //! IMPORTANT: This parameter is the abbreviation! Not the long form! + void ClearAbbreviation(const std::string& abbrevation); + //! Will delete all abbreviations void ClearAbbreviations(); //! Will register parameter constraints void RegisterConstraints(const std::vector& constraints); + //! Will return the constraint information for a specific parameter + ParamConstraint GetConstraint(const std::string& parameter) const; + + //! Will the constraint of a specific parameter + void ClearConstraint(const std::string& parameter); + //! Will delete all constraints void ClearConstraints(); @@ -72,11 +83,17 @@ namespace Hazelnp //! Will return a short description for a parameter, if it exists. //! Empty string if it does not exist. - const std::string GetDescription(const std::string& parameter) const; + std::string GetDescription(const std::string& parameter) const; + + //! Returns whether or not a given parameter has a registered description + bool HasDescription(const std::string& parameter) const; //! Will delete the description of a parameter if it exists. void ClearDescription(const std::string& parameter); + //! Will delete all parameter descriptions + void ClearDescriptions(); + //! Will generate a text-based documentation suited to show the user, for example on --help. std::string GenerateDocumentation() const; @@ -112,6 +129,7 @@ namespace Hazelnp std::vector rawArgs; //! Short descriptions for parameters + //! First member is the abbreviation std::unordered_map parameterDescriptions; //! A brief description of the application to be added to the generated documentation. Optional. diff --git a/Test_Hazelnupp/Abbreviations.cpp b/Test_Hazelnupp/Abbreviations.cpp index d5b817b..e4e7b2e 100644 --- a/Test_Hazelnupp/Abbreviations.cpp +++ b/Test_Hazelnupp/Abbreviations.cpp @@ -158,5 +158,126 @@ namespace TestHazelnupp return; } + + // Tests that abbreviations can be queried + TEST_METHOD(Get_Abbreviation) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterAbbreviation("-ms", "--my_string"); + nupp.RegisterAbbreviation("-mv", "--my_void"); + nupp.RegisterAbbreviation("-mi", "--my_int"); + nupp.RegisterAbbreviation("-mf", "--my_float"); + nupp.RegisterAbbreviation("-mnl", "--my_num_list"); + nupp.RegisterAbbreviation("-msl", "--my_str_list"); + + // Exercise, verify + Assert::AreEqual(std::string("--my_num_list"), nupp.GetAbbreviation("-mnl")); + Assert::AreEqual(std::string("--my_void"), nupp.GetAbbreviation("-mv")); + + return; + } + + // Tests that getting an unknown abbreviation will ersult in an empty string + TEST_METHOD(Unknown_Abbrevation_Is_Empty_String) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterAbbreviation("-ms", "--my_string"); + nupp.RegisterAbbreviation("-mv", "--my_void"); + nupp.RegisterAbbreviation("-mi", "--my_int"); + nupp.RegisterAbbreviation("-mf", "--my_float"); + nupp.RegisterAbbreviation("-mnl", "--my_num_list"); + nupp.RegisterAbbreviation("-msl", "--my_str_list"); + + // Exercise + nupp.ClearAbbreviations(); + + // Verify + Assert::AreEqual(std::string(), nupp.GetAbbreviation("-t")); + + return; + } + + // Tests that HasAbbreviation works + TEST_METHOD(Has_Abbreviation) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise, verify + Assert::IsFalse(nupp.HasAbbreviation("-f")); + Assert::IsFalse(nupp.HasAbbreviation("-m")); + + nupp.RegisterAbbreviation("-f", "--force"); + + Assert::IsTrue(nupp.HasAbbreviation("-f")); + Assert::IsFalse(nupp.HasAbbreviation("-m")); + + return; + } + + // Tests that abbreviations can be deleted individually + TEST_METHOD(Clear_Abbreviation) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterAbbreviation("-ms", "--my_string"); + nupp.RegisterAbbreviation("-mv", "--my_void"); + nupp.RegisterAbbreviation("-mi", "--my_int"); + nupp.RegisterAbbreviation("-mf", "--my_float"); + nupp.RegisterAbbreviation("-mnl", "--my_num_list"); + nupp.RegisterAbbreviation("-msl", "--my_str_list"); + + // Exercise + nupp.ClearAbbreviation("-mv"); + nupp.ClearAbbreviation("-mf"); + nupp.ClearAbbreviation("-msl"); + + // Verify + Assert::IsTrue(nupp.HasAbbreviation("-ms")); + Assert::IsFalse(nupp.HasAbbreviation("-mv")); + Assert::IsTrue(nupp.HasAbbreviation("-mi")); + Assert::IsFalse(nupp.HasAbbreviation("-mf")); + Assert::IsTrue(nupp.HasAbbreviation("-mnl")); + Assert::IsFalse(nupp.HasAbbreviation("-msl")); + + return; + } + + // Tests that all abbreviations can be deleted at once + TEST_METHOD(Clear_Abbreviations) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterAbbreviation("-ms" , "--my_string"); + nupp.RegisterAbbreviation("-mv" , "--my_void"); + nupp.RegisterAbbreviation("-mi" , "--my_int"); + nupp.RegisterAbbreviation("-mf" , "--my_float"); + nupp.RegisterAbbreviation("-mnl", "--my_num_list"); + nupp.RegisterAbbreviation("-msl", "--my_str_list"); + + // Exercise + nupp.ClearAbbreviations(); + + // Verify + Assert::IsFalse(nupp.HasAbbreviation("-ms" )); + Assert::IsFalse(nupp.HasAbbreviation("-mv" )); + Assert::IsFalse(nupp.HasAbbreviation("-mi" )); + Assert::IsFalse(nupp.HasAbbreviation("-mf" )); + Assert::IsFalse(nupp.HasAbbreviation("-mnl")); + Assert::IsFalse(nupp.HasAbbreviation("-msl")); + + return; + } }; } diff --git a/Test_Hazelnupp/Constraints.cpp b/Test_Hazelnupp/Constraints.cpp index ca307b7..918cabe 100644 --- a/Test_Hazelnupp/Constraints.cpp +++ b/Test_Hazelnupp/Constraints.cpp @@ -317,5 +317,125 @@ namespace TestHazelnupp return; } + + // Tests that constraints can cleared invidivually + TEST_METHOD(Can_Clear_Constraints_Individually) + { + // Setup + ArgList args({ + "/my/fake/path/wahoo.out", + "--dummy", + "--empty-list", + }); + + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterConstraints({ + ParamConstraint::Require("--not-there", {}, true), + ParamConstraint::Require("--default-val", {"32"}, true), + }); + + // Exercise + nupp.ClearConstraint("--not-there"); + + + // Verify + nupp.Parse(C_Ify(args)); + + // Also verifies that parse does not throw an exception for --not-there + + Assert::IsTrue(nupp.HasParam("--default-val"), L"Default value is missing"); + Assert::AreEqual(32, nupp["--default-val"].GetInt32(), L"Default value has wrong value"); + + return; + } + + // Tests that constraints can cleared invidivually + TEST_METHOD(Can_Clear_All_Constraints) + { + // Setup + ArgList args({ + "/my/fake/path/wahoo.out", + "--dummy", + "--empty-list", + }); + + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterConstraints({ + ParamConstraint::Require("--not-there", {}, true) + }); + + // Exercise + nupp.ClearConstraints(); + + // Verify + nupp.Parse(C_Ify(args)); + + return; + } + + // Tests that setting a constraint for a parameter again will overwrite the existing one + TEST_METHOD(Can_Override_Constraints) + { + // Setup + ArgList args({ + "/my/fake/path/wahoo.out", + "--dummy", + "--empty-list", + }); + + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + nupp.RegisterConstraints({ + ParamConstraint::Require("--not-there", {}, true) + }); + + //Exercise + nupp.RegisterConstraints({ + ParamConstraint::Require("--not-there", {}, false) + }); + + // Verify + nupp.Parse(C_Ify(args)); + + return; + } + + // Tests that the GetConstraint returns the correct constraint information + TEST_METHOD(Get_Constraint) + { + // Setup + ArgList args({ + "/my/fake/path/wahoo.out", + "--dummy", + "--empty-list", + }); + + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + ParamConstraint dftvalConst_expected = ParamConstraint::Require("--default-val", {"32"}, true); + nupp.RegisterConstraints({ + ParamConstraint::Require("--not-there", {}, true), + dftvalConst_expected, + ParamConstraint::Require("--another-one", {"bites"}, true), + }); + + // Exercise + ParamConstraint dftvalConst = nupp.GetConstraint("--default-val"); + + // Verify + Assert::IsTrue(dftvalConst_expected.key == dftvalConst.key, L"key"); + Assert::IsTrue(dftvalConst_expected.required == dftvalConst.required, L"required"); + Assert::IsTrue(dftvalConst_expected.defaultValue == dftvalConst.defaultValue, L"defaultValue"); + Assert::IsTrue(dftvalConst_expected.wantedType == dftvalConst.wantedType, L"wantedType"); + Assert::IsTrue(dftvalConst_expected.constrainType == dftvalConst.constrainType, L"constrainType"); + + return; + } }; } diff --git a/Test_Hazelnupp/Descriptions.cpp b/Test_Hazelnupp/Descriptions.cpp new file mode 100644 index 0000000..a67f6fe --- /dev/null +++ b/Test_Hazelnupp/Descriptions.cpp @@ -0,0 +1,139 @@ +#include "CppUnitTest.h" +#include "helper.h" +#include "../Hazelnupp/Hazelnupp.h" +#include "../Hazelnupp/HazelnuppException.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; +using namespace Hazelnp; + +namespace TestHazelnupp +{ + TEST_CLASS(_Descriptions) + { + public: + + // Tests that the application description can be set and returned + TEST_METHOD(Set_Get_Application_Brief) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + std::string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse in quam tincidunt sapien euismod egestas eget vel dolor. Duis non turpis porttitor, convallis velit at."; + + // Exercise + nupp.SetBriefDescription(text); + + // Verify + Assert::AreEqual(text, nupp.GetBriefDescription()); + + return; + } + + // Tests that a parameters description can be set and returned + TEST_METHOD(Can_Set_Parameter_Description) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise + nupp.RegisterDescription("--force", "Just force it"); + nupp.RegisterDescription("--lose", "Just lose it"); + nupp.RegisterDescription("--crazy", "Go crazy"); + + // Verify + Assert::AreEqual(std::string("Just force it"), nupp.GetDescription("--force")); + Assert::AreEqual(std::string("Go crazy"), nupp.GetDescription("--crazy")); + Assert::AreEqual(std::string("Just lose it"), nupp.GetDescription("--lose")); + + return; + } + + //! Tests that HasDescription works + TEST_METHOD(Has_Description) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise, verify + Assert::IsFalse(nupp.HasDescription("--force")); + Assert::IsFalse(nupp.HasDescription("--main")); + + nupp.RegisterDescription("--force", "Just force it"); + + Assert::IsTrue(nupp.HasDescription("--force")); + Assert::IsFalse(nupp.HasDescription("--main")); + + return; + } + + // Tests that an unknown parameter returns an empty string + TEST_METHOD(No_Description_Is_Empty_String) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise + nupp.RegisterDescription("--force", "Just force it"); + nupp.RegisterDescription("--lose", "Just lose it"); + nupp.RegisterDescription("--crazy", "Go crazy"); + + // Verify + Assert::AreEqual(std::string(), nupp.GetDescription("--man")); + + return; + } + + // Tests that a description can be deleted + TEST_METHOD(ClearDescription) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise + nupp.RegisterDescription("--force", "Just force it"); + nupp.RegisterDescription("--lose", "Just lose it"); + nupp.RegisterDescription("--crazy", "Go crazy"); + + nupp.ClearDescription("--lose"); + + // Verify + + // These two should still work + Assert::AreEqual(std::string("Just force it"), nupp.GetDescription("--force")); + Assert::AreEqual(std::string("Go crazy"), nupp.GetDescription("--crazy")); + + Assert::IsFalse(nupp.HasDescription("--lose")); + + return; + } + + // Tests that all descriptions can be deleted at once + TEST_METHOD(ClearDescriptions) + { + // Setup + Hazelnupp nupp; + nupp.SetCrashOnFail(false); + + // Exercise + nupp.RegisterDescription("--force", "Just force it"); + nupp.RegisterDescription("--lose", "Just lose it"); + nupp.RegisterDescription("--crazy", "Go crazy"); + + nupp.ClearDescriptions(); + + // Verify + + // These two should still work + Assert::IsFalse(nupp.HasDescription("--force")); + Assert::IsFalse(nupp.HasDescription("--crazy")); + Assert::IsFalse(nupp.HasDescription("--lose")); + + return; + } + }; +} diff --git a/Test_Hazelnupp/Test_Hazelnupp.vcxproj b/Test_Hazelnupp/Test_Hazelnupp.vcxproj index a59b932..faa8969 100644 --- a/Test_Hazelnupp/Test_Hazelnupp.vcxproj +++ b/Test_Hazelnupp/Test_Hazelnupp.vcxproj @@ -160,6 +160,7 @@ + diff --git a/Test_Hazelnupp/Test_Hazelnupp.vcxproj.filters b/Test_Hazelnupp/Test_Hazelnupp.vcxproj.filters index 87cbe39..effe988 100644 --- a/Test_Hazelnupp/Test_Hazelnupp.vcxproj.filters +++ b/Test_Hazelnupp/Test_Hazelnupp.vcxproj.filters @@ -32,5 +32,8 @@ Quelldateien + + Quelldateien + \ No newline at end of file