Skip to content

Commit

Permalink
working primary and secondary name refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
SpectraL519 committed Apr 8, 2024
1 parent c181619 commit 124e338
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 19 deletions.
15 changes: 8 additions & 7 deletions include/ap/argument_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,17 +371,17 @@ struct argument_name {

/**
* @brief Matches the given argument name to the argument_name instance.
* @param arg_name The name string to match.
* @param arg_name The argument_name instance to match.
* @return True if arg_name's primary or secondary value matches the argument_name instance.
*/
[[nodiscard]] bool match(const argument_name arg_name) const noexcept {
if (not this->match(arg_name.primary))
return false;
[[nodiscard]] bool match(const argument_name& arg_name) const noexcept {
if (this->match(arg_name.primary))
return true;

if (arg_name.secondary)
return this->match(arg_name.secondary.value());

return true;
return false;
}

/**
Expand Down Expand Up @@ -1490,6 +1490,7 @@ class argument_parser {
cmd_argument(const cmd_argument&) = default;
cmd_argument(cmd_argument&&) = default;
cmd_argument& operator=(const cmd_argument&) = default;
cmd_argument& operator=(cmd_argument&&) = default;

/**
* @brief Constructor of a command-line argument.
Expand Down Expand Up @@ -1530,7 +1531,7 @@ class argument_parser {
* @return Argument predicate based on the provided name.
*/
[[nodiscard]] argument_predicate_type _name_match_predicate(std::string_view arg_name) const noexcept {
return [&arg_name](const argument_ptr_type& arg) { return arg->name().match(arg_name); };
return [arg_name](const argument_ptr_type& arg) { return arg->name().match(arg_name); };
}

/**
Expand Down Expand Up @@ -1712,7 +1713,7 @@ class argument_parser {
* @param arg_name The name of the argument.
* @return The argument with the specified name, if found; otherwise, std::nullopt.
*/
argument_opt_type _get_argument(const std::string_view& arg_name) const noexcept {
argument_opt_type _get_argument(std::string_view arg_name) const noexcept {
const auto predicate = this->_name_match_predicate(arg_name);

if (auto pos_arg_it = std::ranges::find_if(this->_positional_args, predicate);
Expand Down
59 changes: 56 additions & 3 deletions test/source/test_argument_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ TEST_CASE("argument_name::match(string_view) should return true if the given str
}
}

TEST_CASE("argument_name::match(string_view) should "
"return false if no primary name matches") {
TEST_CASE("argument_name::match(string_view) should return false if the given string dosn't match any name") {
SUBCASE("argument_name with primary name only") {
const auto arg_name = default_argument_name_primary();

Expand All @@ -94,7 +93,61 @@ TEST_CASE("argument_name::match(string_view) should "
}
}

// TODO: match for argument_name
TEST_CASE("argument_name::match(argument_name) should return true if either the primary or the secondary name "
"of the passed argument_name matches at least one name") {
SUBCASE("argument_name with primary name only") {
const auto arg_name = default_argument_name_primary();

SUBCASE("matching primary to primary") {
const auto arg_name_to_match = argument_name{primary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}

SUBCASE("matching secondary to primary") {
const auto arg_name_to_match = argument_name{other_primary_name, primary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}
}

SUBCASE("argument_name with both names") {
const auto arg_name = default_argument_name_primary_and_secondary();

SUBCASE("matching primary to primary") {
const auto arg_name_to_match = argument_name{primary_name, other_secondary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}

SUBCASE("matching primary to secondary") {
const auto arg_name_to_match = argument_name{secondary_name, primary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}

SUBCASE("matching secondary to primary") {
const auto arg_name_to_match = argument_name{other_primary_name, primary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}

SUBCASE("matching secondary to secondary") {
const auto arg_name_to_match = argument_name{other_primary_name, secondary_name};
REQUIRE(arg_name.match(arg_name_to_match));
}
}
}

TEST_CASE("argument_name::match(argument_name) should return false if neither the primary nor the secondary name "
"of the passed argument_name matches at least one name") {
const auto arg_name_to_match = argument_name{other_primary_name, other_secondary_name};

SUBCASE("argument_name with primary name only") {
const auto arg_name = default_argument_name_primary();
REQUIRE_FALSE(arg_name.match(arg_name_to_match));
}

SUBCASE("argument_name with both names") {
const auto arg_name = default_argument_name_primary_and_secondary();
REQUIRE_FALSE(arg_name.match(arg_name_to_match));
}
}

TEST_CASE("operator<< should push correct data to the output stream") {
std::stringstream ss, expected_ss;
Expand Down
33 changes: 24 additions & 9 deletions test/source/test_argument_parser_add_argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include <ap/argument_parser.hpp>

#include <iostream>

using namespace ap_testing;
using namespace ap::argument;

Expand Down Expand Up @@ -44,20 +42,37 @@ TEST_CASE_FIXTURE(argument_parser_test_fixture, "default_optional_arguments shou
ap::default_argument::optional::output }
);

const auto help_arg = sut_get_argument("help");
std::string help_flag;
std::string input_flag;
std::string output_flag;

SUBCASE("using primary flags") {
help_flag = "help";
input_flag = "input";
output_flag = "output";
}

SUBCASE("using secondary flags") {
help_flag = "h";
input_flag = "i";
output_flag = "o";
}

CAPTURE(help_flag);
CAPTURE(input_flag);
CAPTURE(output_flag);

const auto help_arg = sut_get_argument(help_flag);
REQUIRE(help_arg);
REQUIRE(help_arg->get().is_optional());
// TODO: secondary flag

const auto input_arg = sut_get_argument("help");
const auto input_arg = sut_get_argument(input_flag);
REQUIRE(input_arg);
REQUIRE(input_arg->get().is_optional());
// TODO: secondary flag

const auto output_arg = sut_get_argument("output");
const auto output_arg = sut_get_argument(output_flag);
REQUIRE(output_arg);
REQUIRE_FALSE(output_arg->get().is_optional());
// TODO: secondary flag
REQUIRE(output_arg->get().is_optional());
}

TEST_CASE_FIXTURE(argument_parser_test_fixture, "add_positional_argument should return a positional argument reference") {
Expand Down

0 comments on commit 124e338

Please sign in to comment.