Commit bcbd8c862bdfa9546f144118f9a21e410f1e0b8c
Committed by
Henry Schreiner
1 parent
65493d64
Using -N for up-to N
Showing
3 changed files
with
48 additions
and
20 deletions
CHANGELOG.md
| @@ -15,7 +15,8 @@ | @@ -15,7 +15,8 @@ | ||
| 15 | * The order is now preserved for subcommands (list and callbacks) [#49](https://github.com/CLIUtils/CLI11/pull/49) | 15 | * The order is now preserved for subcommands (list and callbacks) [#49](https://github.com/CLIUtils/CLI11/pull/49) |
| 16 | * Tests now run individually, utilizing CMake 3.10 additions if possible [#50](https://github.com/CLIUtils/CLI11/pull/50) | 16 | * Tests now run individually, utilizing CMake 3.10 additions if possible [#50](https://github.com/CLIUtils/CLI11/pull/50) |
| 17 | * Failure messages are now customizable, with a shorter default [#52](https://github.com/CLIUtils/CLI11/pull/52) | 17 | * Failure messages are now customizable, with a shorter default [#52](https://github.com/CLIUtils/CLI11/pull/52) |
| 18 | - | 18 | +* `require_subcommand` now offers a two-argument form and negative values on the one-argument form are more useful [#51](https://github.com/CLIUtils/CLI11/pull/51) |
| 19 | +* Subcommands no longer match after the max required number is obtained [#51](https://github.com/CLIUtils/CLI11/pull/51) | ||
| 19 | 20 | ||
| 20 | ## Version 1.2 | 21 | ## Version 1.2 |
| 21 | 22 |
include/CLI/App.hpp
| @@ -245,13 +245,20 @@ class App { | @@ -245,13 +245,20 @@ class App { | ||
| 245 | /// This allows the subcommand to be directly checked. | 245 | /// This allows the subcommand to be directly checked. |
| 246 | operator bool() const { return parsed_; } | 246 | operator bool() const { return parsed_; } |
| 247 | 247 | ||
| 248 | + /// The argumentless form of require subcommand requires 1 or more subcommands | ||
| 249 | + App *require_subcommand() { | ||
| 250 | + require_subcommand_min_ = 1; | ||
| 251 | + require_subcommand_max_ = 0; | ||
| 252 | + return this; | ||
| 253 | + } | ||
| 254 | + | ||
| 248 | /// Require a subcommand to be given (does not affect help call) | 255 | /// Require a subcommand to be given (does not affect help call) |
| 249 | /// The number required can be given. Negative values indicate maximum | 256 | /// The number required can be given. Negative values indicate maximum |
| 250 | /// number allowed (0 for any number). | 257 | /// number allowed (0 for any number). |
| 251 | - App *require_subcommand(int value = -1) { | 258 | + App *require_subcommand(int value) { |
| 252 | if(value < 0) { | 259 | if(value < 0) { |
| 253 | - require_subcommand_min_ = static_cast<size_t>(-value); | ||
| 254 | - require_subcommand_max_ = 0; | 260 | + require_subcommand_min_ = 0; |
| 261 | + require_subcommand_max_ = static_cast<size_t>(-value); | ||
| 255 | } else { | 262 | } else { |
| 256 | require_subcommand_min_ = static_cast<size_t>(value); | 263 | require_subcommand_min_ = static_cast<size_t>(value); |
| 257 | require_subcommand_max_ = static_cast<size_t>(value); | 264 | require_subcommand_max_ = static_cast<size_t>(value); |
tests/SubcommandTest.cpp
| @@ -653,51 +653,71 @@ struct ManySubcommands : public TApp { | @@ -653,51 +653,71 @@ struct ManySubcommands : public TApp { | ||
| 653 | CLI::App *sub4; | 653 | CLI::App *sub4; |
| 654 | 654 | ||
| 655 | ManySubcommands() { | 655 | ManySubcommands() { |
| 656 | + app.allow_extras(); | ||
| 656 | sub1 = app.add_subcommand("sub1"); | 657 | sub1 = app.add_subcommand("sub1"); |
| 657 | sub2 = app.add_subcommand("sub2"); | 658 | sub2 = app.add_subcommand("sub2"); |
| 658 | sub3 = app.add_subcommand("sub3"); | 659 | sub3 = app.add_subcommand("sub3"); |
| 659 | sub4 = app.add_subcommand("sub4"); | 660 | sub4 = app.add_subcommand("sub4"); |
| 661 | + args = {"sub1", "sub2", "sub3"}; | ||
| 660 | } | 662 | } |
| 661 | }; | 663 | }; |
| 662 | 664 | ||
| 663 | -TEST_F(ManySubcommands, RequiredExact) { | ||
| 664 | - | 665 | +TEST_F(ManySubcommands, Required1Exact) { |
| 665 | app.require_subcommand(1); | 666 | app.require_subcommand(1); |
| 666 | 667 | ||
| 667 | - sub1->allow_extras(); | ||
| 668 | - | ||
| 669 | - args = {"sub1", "sub2", "sub3"}; | ||
| 670 | run(); | 668 | run(); |
| 671 | - | ||
| 672 | EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); | 669 | EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); |
| 670 | + EXPECT_EQ(app.remaining(true), vs_t({"sub2", "sub3"})); | ||
| 671 | +} | ||
| 673 | 672 | ||
| 674 | - app.reset(); | ||
| 675 | - | 673 | +TEST_F(ManySubcommands, Required2Exact) { |
| 676 | app.require_subcommand(2); | 674 | app.require_subcommand(2); |
| 677 | - sub2->allow_extras(); | ||
| 678 | 675 | ||
| 679 | run(); | 676 | run(); |
| 680 | - | ||
| 681 | EXPECT_EQ(sub2->remaining(), vs_t({"sub3"})); | 677 | EXPECT_EQ(sub2->remaining(), vs_t({"sub3"})); |
| 682 | } | 678 | } |
| 683 | 679 | ||
| 684 | -TEST_F(ManySubcommands, RequiredFuzzy) { | 680 | +TEST_F(ManySubcommands, Required1Fuzzy) { |
| 685 | 681 | ||
| 686 | app.require_subcommand(0, 1); | 682 | app.require_subcommand(0, 1); |
| 687 | 683 | ||
| 688 | - sub1->allow_extras(); | ||
| 689 | - | ||
| 690 | - args = {"sub1", "sub2", "sub3"}; | ||
| 691 | run(); | 684 | run(); |
| 692 | - | ||
| 693 | EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); | 685 | EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); |
| 694 | 686 | ||
| 695 | app.reset(); | 687 | app.reset(); |
| 688 | + app.require_subcommand(-1); | ||
| 696 | 689 | ||
| 690 | + run(); | ||
| 691 | + EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); | ||
| 692 | +} | ||
| 693 | + | ||
| 694 | +TEST_F(ManySubcommands, Required2Fuzzy) { | ||
| 697 | app.require_subcommand(0, 2); | 695 | app.require_subcommand(0, 2); |
| 698 | - sub2->allow_extras(); | ||
| 699 | 696 | ||
| 700 | run(); | 697 | run(); |
| 698 | + EXPECT_EQ(sub2->remaining(), vs_t({"sub3"})); | ||
| 699 | + EXPECT_EQ(app.remaining(true), vs_t({"sub3"})); | ||
| 701 | 700 | ||
| 701 | + app.reset(); | ||
| 702 | + app.require_subcommand(-2); | ||
| 703 | + | ||
| 704 | + run(); | ||
| 702 | EXPECT_EQ(sub2->remaining(), vs_t({"sub3"})); | 705 | EXPECT_EQ(sub2->remaining(), vs_t({"sub3"})); |
| 703 | } | 706 | } |
| 707 | + | ||
| 708 | +TEST_F(ManySubcommands, Unlimited) { | ||
| 709 | + run(); | ||
| 710 | + EXPECT_EQ(app.remaining(true), vs_t()); | ||
| 711 | + | ||
| 712 | + app.reset(); | ||
| 713 | + app.require_subcommand(); | ||
| 714 | + | ||
| 715 | + run(); | ||
| 716 | + EXPECT_EQ(app.remaining(true), vs_t()); | ||
| 717 | + | ||
| 718 | + app.reset(); | ||
| 719 | + app.require_subcommand(2, 0); // 2 or more | ||
| 720 | + | ||
| 721 | + run(); | ||
| 722 | + EXPECT_EQ(app.remaining(true), vs_t()); | ||
| 723 | +} |