mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14:39 +00:00
Merge pull request #142 from skrobinson/wip-deactivatable-defaults
Actions with nonary arguments, removable defaults, and some clean ups
This commit is contained in:
commit
b98bf25a34
82
README.md
82
README.md
@ -27,7 +27,7 @@ Simply include argparse.hpp and you're good to go.
|
|||||||
To start parsing command-line arguments, create an ```ArgumentParser```.
|
To start parsing command-line arguments, create an ```ArgumentParser```.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
argparse::ArgumentParser program("program name");
|
argparse::ArgumentParser program("program_name");
|
||||||
```
|
```
|
||||||
|
|
||||||
**NOTE:** There is an optional second argument to the `ArgumentParser` which is the program version. Example: `argparse::ArgumentParser program("libfoo", "1.9.0");`
|
**NOTE:** There is an optional second argument to the `ArgumentParser` which is the program version. Example: `argparse::ArgumentParser program("libfoo", "1.9.0");`
|
||||||
@ -49,7 +49,7 @@ Here's an example of a ***positional argument***:
|
|||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
argparse::ArgumentParser program("program name");
|
argparse::ArgumentParser program("program_name");
|
||||||
|
|
||||||
program.add_argument("square")
|
program.add_argument("square")
|
||||||
.help("display the square of a given integer")
|
.help("display the square of a given integer")
|
||||||
@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input = program.get<int>("square");
|
auto input = program.get<int>("square");
|
||||||
@ -103,7 +103,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program["--verbose"] == true) {
|
if (program["--verbose"] == true) {
|
||||||
@ -169,7 +169,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto color = program.get<std::string>("--color"); // "orange"
|
auto color = program.get<std::string>("--color"); // "orange"
|
||||||
@ -192,7 +192,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto colors = program.get<std::vector<std::string>>("--color"); // {"red", "green", "blue"}
|
auto colors = program.get<std::vector<std::string>>("--color"); // {"red", "green", "blue"}
|
||||||
@ -200,6 +200,24 @@ auto colors = program.get<std::vector<std::string>>("--color"); // {"red", "gre
|
|||||||
|
|
||||||
Notice that ```.default_value``` is given an explicit template parameter to match the type you want to ```.get```.
|
Notice that ```.default_value``` is given an explicit template parameter to match the type you want to ```.get```.
|
||||||
|
|
||||||
|
#### Repeating an argument to increase a value
|
||||||
|
|
||||||
|
A common pattern is to repeat an argument to indicate a greater value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int verbosity = 0;
|
||||||
|
program.add_argument("-V", "--verbose")
|
||||||
|
.action([&](const auto &) { ++verbosity; })
|
||||||
|
.append()
|
||||||
|
.default_value(false)
|
||||||
|
.implicit_value(true)
|
||||||
|
.nargs(0);
|
||||||
|
|
||||||
|
program.parse_args(argc, argv); // Example: ./main -VVVV
|
||||||
|
|
||||||
|
std::cout << "verbose level: " << verbosity << std::endl; // verbose level: 4
|
||||||
|
```
|
||||||
|
|
||||||
### Negative Numbers
|
### Negative Numbers
|
||||||
|
|
||||||
Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes!
|
Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes!
|
||||||
@ -222,7 +240,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some code to print arguments
|
// Some code to print arguments
|
||||||
@ -239,7 +257,7 @@ As you can see here, ```argparse``` supports negative integers, negative floats
|
|||||||
### Combining Positional and Optional Arguments
|
### Combining Positional and Optional Arguments
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
argparse::ArgumentParser program("test");
|
argparse::ArgumentParser program("main");
|
||||||
|
|
||||||
program.add_argument("square")
|
program.add_argument("square")
|
||||||
.help("display the square of a given number")
|
.help("display the square of a given number")
|
||||||
@ -255,7 +273,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int input = program.get<int>("square");
|
int input = program.get<int>("square");
|
||||||
@ -285,14 +303,15 @@ The square of 4 is 16
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ ./main --help
|
$ ./main --help
|
||||||
Usage: ./main [options] square
|
Usage: main [options] square
|
||||||
|
|
||||||
Positional arguments:
|
Positional arguments:
|
||||||
square display a square of a given number
|
square display the square of a given number
|
||||||
|
|
||||||
Optional arguments:
|
Optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h --help shows help message and exits [default: false]
|
||||||
-v, --verbose enable verbose logging
|
-v --version prints version information and exits [default: false]
|
||||||
|
--verbose [default: false]
|
||||||
```
|
```
|
||||||
|
|
||||||
You may also get the help message in string via `program.help().str()`.
|
You may also get the help message in string via `program.help().str()`.
|
||||||
@ -314,7 +333,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto files = program.get<std::vector<std::string>>("--input_files"); // {"config.yml", "System.xml"}
|
auto files = program.get<std::vector<std::string>>("--input_files"); // {"config.yml", "System.xml"}
|
||||||
@ -343,7 +362,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto query_point = program.get<std::vector<double>>("--query_point"); // {3.5, 4.7, 9.2}
|
auto query_point = program.get<std::vector<double>>("--query_point"); // {3.5, 4.7, 9.2}
|
||||||
@ -375,7 +394,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto a = program.get<bool>("-a"); // true
|
auto a = program.get<bool>("-a"); // true
|
||||||
@ -437,6 +456,27 @@ The grammar follows `std::from_chars`, but does not exactly duplicate it. For ex
|
|||||||
| 'u' | decimal (unsigned) |
|
| 'u' | decimal (unsigned) |
|
||||||
| 'x' or 'X' | hexadecimal (unsigned) |
|
| 'x' or 'X' | hexadecimal (unsigned) |
|
||||||
|
|
||||||
|
### Default Arguments
|
||||||
|
|
||||||
|
`argparse` provides predefined arguments and actions for `-h`/`--help` and `-v`/`--version`. These default actions exit the program after displaying a help or version message, respectively. These defaults arguments can be disabled during `ArgumentParser` creation so that you can handle these arguments in your own way. (Note that a program name and version must be included when choosing default arguments.)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
argparse::ArgumentParser program("test", "1.0", default_arguments::none);
|
||||||
|
|
||||||
|
program.add_argument("-h", "--help")
|
||||||
|
.action([=](const std::string& s) {
|
||||||
|
std::cout << help().str();
|
||||||
|
})
|
||||||
|
.default_value(false)
|
||||||
|
.help("shows help message")
|
||||||
|
.implicit_value(true)
|
||||||
|
.nargs(0);
|
||||||
|
```
|
||||||
|
|
||||||
|
The above code snippet outputs a help message and continues to run. It does not support a `--version` argument.
|
||||||
|
|
||||||
|
The default is `default_arguments::all` for included arguments. No default arguments will be added with `default_arguments::none`. `default_arguments::help` and `default_arguments::version` will individually add `--help` and `--version`.
|
||||||
|
|
||||||
### Gathering Remaining Arguments
|
### Gathering Remaining Arguments
|
||||||
|
|
||||||
`argparse` supports gathering "remaining" arguments at the end of the command, e.g., for use in a compiler:
|
`argparse` supports gathering "remaining" arguments at the end of the command, e.g., for use in a compiler:
|
||||||
@ -459,7 +499,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -506,7 +546,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output_filename = program.get<std::string>("-o");
|
auto output_filename = program.get<std::string>("-o");
|
||||||
@ -588,7 +628,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json config = program.get<nlohmann::json>("config");
|
nlohmann::json config = program.get<nlohmann::json>("config");
|
||||||
@ -624,7 +664,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto numbers = program.get<std::vector<int>>("numbers"); // {1, 2, 3}
|
auto numbers = program.get<std::vector<int>>("numbers"); // {1, 2, 3}
|
||||||
@ -666,7 +706,7 @@ try {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
std::cout << program;
|
std::cout << program;
|
||||||
exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input = program.get("input");
|
auto input = program.get("input");
|
||||||
|
@ -312,6 +312,17 @@ template <class T> struct parse_number<T, chars_format::fixed> {
|
|||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
|
enum class default_arguments : unsigned int {
|
||||||
|
none = 0,
|
||||||
|
help = 1,
|
||||||
|
version = 2,
|
||||||
|
all = help | version,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator& (const default_arguments &a, const default_arguments &b) {
|
||||||
|
return static_cast<unsigned int>(a) & static_cast<unsigned int>(b);
|
||||||
|
}
|
||||||
|
|
||||||
class ArgumentParser;
|
class ArgumentParser;
|
||||||
|
|
||||||
class Argument {
|
class Argument {
|
||||||
@ -442,6 +453,7 @@ public:
|
|||||||
mUsedName = usedName;
|
mUsedName = usedName;
|
||||||
if (mNumArgs == 0) {
|
if (mNumArgs == 0) {
|
||||||
mValues.emplace_back(mImplicitValue);
|
mValues.emplace_back(mImplicitValue);
|
||||||
|
std::visit([](auto &aAction) { aAction({}); }, mAction);
|
||||||
return start;
|
return start;
|
||||||
} else if (mNumArgs <= std::distance(start, end)) {
|
} else if (mNumArgs <= std::distance(start, end)) {
|
||||||
if (auto expected = maybe_nargs()) {
|
if (auto expected = maybe_nargs()) {
|
||||||
@ -453,18 +465,18 @@ public:
|
|||||||
|
|
||||||
struct action_apply {
|
struct action_apply {
|
||||||
void operator()(valued_action &f) {
|
void operator()(valued_action &f) {
|
||||||
std::transform(start, end, std::back_inserter(self.mValues), f);
|
std::transform(first, last, std::back_inserter(self.mValues), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(void_action &f) {
|
void operator()(void_action &f) {
|
||||||
std::for_each(start, end, f);
|
std::for_each(first, last, f);
|
||||||
if (!self.mDefaultValue.has_value()) {
|
if (!self.mDefaultValue.has_value()) {
|
||||||
if (auto expected = self.maybe_nargs())
|
if (auto expected = self.maybe_nargs())
|
||||||
self.mValues.resize(*expected);
|
self.mValues.resize(*expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator start, end;
|
Iterator first, last;
|
||||||
Argument &self;
|
Argument &self;
|
||||||
};
|
};
|
||||||
std::visit(action_apply{start, end, *this}, mAction);
|
std::visit(action_apply{start, end, *this}, mAction);
|
||||||
@ -813,16 +825,31 @@ private:
|
|||||||
class ArgumentParser {
|
class ArgumentParser {
|
||||||
public:
|
public:
|
||||||
explicit ArgumentParser(std::string aProgramName = {},
|
explicit ArgumentParser(std::string aProgramName = {},
|
||||||
std::string aVersion = "1.0")
|
std::string aVersion = "1.0",
|
||||||
|
default_arguments aArgs = default_arguments::all)
|
||||||
: mProgramName(std::move(aProgramName)), mVersion(std::move(aVersion)) {
|
: mProgramName(std::move(aProgramName)), mVersion(std::move(aVersion)) {
|
||||||
add_argument("-h", "--help").help("shows help message and exits").nargs(0);
|
if (aArgs & default_arguments::help) {
|
||||||
#ifndef ARGPARSE_LONG_VERSION_ARG_ONLY
|
add_argument("-h", "--help")
|
||||||
add_argument("-v", "--version")
|
.action([&](const auto &) {
|
||||||
#else
|
std::cout << help().str();
|
||||||
add_argument("--version")
|
std::exit(0);
|
||||||
#endif
|
})
|
||||||
.help("prints version information and exits")
|
.default_value(false)
|
||||||
|
.help("shows help message and exits")
|
||||||
|
.implicit_value(true)
|
||||||
.nargs(0);
|
.nargs(0);
|
||||||
|
}
|
||||||
|
if (aArgs & default_arguments::version) {
|
||||||
|
add_argument("-v", "--version")
|
||||||
|
.action([&](const auto &) {
|
||||||
|
std::cout << mVersion;
|
||||||
|
std::exit(0);
|
||||||
|
})
|
||||||
|
.default_value(false)
|
||||||
|
.help("prints version information and exits")
|
||||||
|
.implicit_value(true)
|
||||||
|
.nargs(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentParser(ArgumentParser &&) noexcept = default;
|
ArgumentParser(ArgumentParser &&) noexcept = default;
|
||||||
@ -1050,18 +1077,6 @@ private:
|
|||||||
auto tIterator = mArgumentMap.find(tCurrentArgument);
|
auto tIterator = mArgumentMap.find(tCurrentArgument);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (tIterator != mArgumentMap.end()) {
|
||||||
auto tArgument = tIterator->second;
|
auto tArgument = tIterator->second;
|
||||||
|
|
||||||
// the first optional argument is --help
|
|
||||||
if (tArgument == mOptionalArguments.begin()) {
|
|
||||||
std::cout << *this;
|
|
||||||
std::exit(0);
|
|
||||||
}
|
|
||||||
// the second optional argument is --version
|
|
||||||
else if (tArgument == std::next(mOptionalArguments.begin(), 1)) {
|
|
||||||
std::cout << mVersion << "\n";
|
|
||||||
std::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
it = tArgument->consume(std::next(it), end, tIterator->first);
|
it = tArgument->consume(std::next(it), end, tIterator->first);
|
||||||
} else if (const auto &tCompoundArgument = tCurrentArgument;
|
} else if (const auto &tCompoundArgument = tCurrentArgument;
|
||||||
tCompoundArgument.size() > 1 && tCompoundArgument[0] == '-' &&
|
tCompoundArgument.size() > 1 && tCompoundArgument[0] == '-' &&
|
||||||
|
@ -30,6 +30,7 @@ file(GLOB ARGPARSE_TEST_SOURCES
|
|||||||
test_compound_arguments.cpp
|
test_compound_arguments.cpp
|
||||||
test_container_arguments.cpp
|
test_container_arguments.cpp
|
||||||
test_const_correct.cpp
|
test_const_correct.cpp
|
||||||
|
test_default_args.cpp
|
||||||
test_get.cpp
|
test_get.cpp
|
||||||
test_help.cpp
|
test_help.cpp
|
||||||
test_invalid_arguments.cpp
|
test_invalid_arguments.cpp
|
||||||
|
@ -133,3 +133,27 @@ TEST_CASE("Users can use actions on remaining arguments" *
|
|||||||
program.parse_args({"sum", "42", "100", "-3", "-20"});
|
program.parse_args({"sum", "42", "100", "-3", "-20"});
|
||||||
REQUIRE(result == 119);
|
REQUIRE(result == 119);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Users can run actions on parameterless optional arguments" *
|
||||||
|
test_suite("actions")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
|
||||||
|
GIVEN("a flag argument with a counting action") {
|
||||||
|
int count = 0;
|
||||||
|
program.add_argument("-V", "--verbose")
|
||||||
|
.action([&](const auto &) { ++count; })
|
||||||
|
.append()
|
||||||
|
.default_value(false)
|
||||||
|
.implicit_value(true)
|
||||||
|
.nargs(0);
|
||||||
|
|
||||||
|
WHEN("the flag is repeated") {
|
||||||
|
program.parse_args({"test", "-VVVV"});
|
||||||
|
|
||||||
|
THEN("the count increments once per use") {
|
||||||
|
REQUIRE(program.get<bool>("-V"));
|
||||||
|
REQUIRE(count == 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
19
test/test_default_args.cpp
Normal file
19
test/test_default_args.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <argparse/argparse.hpp>
|
||||||
|
#include <doctest.hpp>
|
||||||
|
|
||||||
|
using doctest::test_suite;
|
||||||
|
|
||||||
|
TEST_CASE("Include all default arguments" * test_suite("default_args")) {
|
||||||
|
argparse::ArgumentParser parser("test");
|
||||||
|
auto help_msg { parser.help().str() };
|
||||||
|
REQUIRE(help_msg.find("shows help message") != std::string::npos);
|
||||||
|
REQUIRE(help_msg.find("prints version information") != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Do not include default arguments" * test_suite("default_args")) {
|
||||||
|
argparse::ArgumentParser parser("test", "1.0",
|
||||||
|
argparse::default_arguments::none);
|
||||||
|
parser.parse_args({"test"});
|
||||||
|
REQUIRE_THROWS_AS(parser.get("--help"), std::logic_error);
|
||||||
|
REQUIRE_THROWS_AS(parser.get("--version"), std::logic_error);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
#include <doctest.hpp>
|
#include <doctest.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using doctest::test_suite;
|
using doctest::test_suite;
|
||||||
|
|
||||||
@ -51,3 +52,26 @@ TEST_CASE("Users can override the help options" * test_suite("help")) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Users can disable default -h/--help" * test_suite("help")) {
|
||||||
|
argparse::ArgumentParser program("test", "1.0",
|
||||||
|
argparse::default_arguments::version);
|
||||||
|
REQUIRE_THROWS_AS(program.parse_args({"test", "-h"}), std::runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Users can replace default -h/--help" * test_suite("help")) {
|
||||||
|
argparse::ArgumentParser program("test", "1.0",
|
||||||
|
argparse::default_arguments::version);
|
||||||
|
std::stringstream buffer;
|
||||||
|
program.add_argument("-h", "--help")
|
||||||
|
.action([&](const auto &) {
|
||||||
|
buffer << program;
|
||||||
|
})
|
||||||
|
.default_value(false)
|
||||||
|
.implicit_value(true)
|
||||||
|
.nargs(0);
|
||||||
|
|
||||||
|
REQUIRE(buffer.str().empty());
|
||||||
|
program.parse_args({"test", "--help"});
|
||||||
|
REQUIRE_FALSE(buffer.str().empty());
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <doctest.hpp>
|
#include <doctest.hpp>
|
||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using doctest::test_suite;
|
using doctest::test_suite;
|
||||||
|
|
||||||
@ -11,3 +12,28 @@ TEST_CASE("Users can print version and exit" * test_suite("version")
|
|||||||
program.parse_args( { "test", "--version" });
|
program.parse_args( { "test", "--version" });
|
||||||
REQUIRE(program.get("--version") == "1.9.0");
|
REQUIRE(program.get("--version") == "1.9.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Users can disable default -v/--version" * test_suite("version")) {
|
||||||
|
argparse::ArgumentParser program("test", "1.0",
|
||||||
|
argparse::default_arguments::help);
|
||||||
|
REQUIRE_THROWS_AS(program.parse_args({"test", "--version"}),
|
||||||
|
std::runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Users can replace default -v/--version" * test_suite("version")) {
|
||||||
|
std::string version { "3.1415" };
|
||||||
|
argparse::ArgumentParser program("test", version,
|
||||||
|
argparse::default_arguments::help);
|
||||||
|
std::stringstream buffer;
|
||||||
|
program.add_argument("-v", "--version")
|
||||||
|
.action([&](const auto &) {
|
||||||
|
buffer << version;
|
||||||
|
})
|
||||||
|
.default_value(true)
|
||||||
|
.implicit_value(false)
|
||||||
|
.nargs(0);
|
||||||
|
|
||||||
|
REQUIRE(buffer.str().empty());
|
||||||
|
program.parse_args({"test", "--version"});
|
||||||
|
REQUIRE_FALSE(buffer.str().empty());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user