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 | 15 | * The order is now preserved for subcommands (list and callbacks) [#49](https://github.com/CLIUtils/CLI11/pull/49) |
| 16 | 16 | * Tests now run individually, utilizing CMake 3.10 additions if possible [#50](https://github.com/CLIUtils/CLI11/pull/50) |
| 17 | 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 | 21 | ## Version 1.2 |
| 21 | 22 | ... | ... |
include/CLI/App.hpp
| ... | ... | @@ -245,13 +245,20 @@ class App { |
| 245 | 245 | /// This allows the subcommand to be directly checked. |
| 246 | 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 | 255 | /// Require a subcommand to be given (does not affect help call) |
| 249 | 256 | /// The number required can be given. Negative values indicate maximum |
| 250 | 257 | /// number allowed (0 for any number). |
| 251 | - App *require_subcommand(int value = -1) { | |
| 258 | + App *require_subcommand(int value) { | |
| 252 | 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 | 262 | } else { |
| 256 | 263 | require_subcommand_min_ = static_cast<size_t>(value); |
| 257 | 264 | require_subcommand_max_ = static_cast<size_t>(value); | ... | ... |
tests/SubcommandTest.cpp
| ... | ... | @@ -653,51 +653,71 @@ struct ManySubcommands : public TApp { |
| 653 | 653 | CLI::App *sub4; |
| 654 | 654 | |
| 655 | 655 | ManySubcommands() { |
| 656 | + app.allow_extras(); | |
| 656 | 657 | sub1 = app.add_subcommand("sub1"); |
| 657 | 658 | sub2 = app.add_subcommand("sub2"); |
| 658 | 659 | sub3 = app.add_subcommand("sub3"); |
| 659 | 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 | 666 | app.require_subcommand(1); |
| 666 | 667 | |
| 667 | - sub1->allow_extras(); | |
| 668 | - | |
| 669 | - args = {"sub1", "sub2", "sub3"}; | |
| 670 | 668 | run(); |
| 671 | - | |
| 672 | 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 | 674 | app.require_subcommand(2); |
| 677 | - sub2->allow_extras(); | |
| 678 | 675 | |
| 679 | 676 | run(); |
| 680 | - | |
| 681 | 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 | 682 | app.require_subcommand(0, 1); |
| 687 | 683 | |
| 688 | - sub1->allow_extras(); | |
| 689 | - | |
| 690 | - args = {"sub1", "sub2", "sub3"}; | |
| 691 | 684 | run(); |
| 692 | - | |
| 693 | 685 | EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"})); |
| 694 | 686 | |
| 695 | 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 | 695 | app.require_subcommand(0, 2); |
| 698 | - sub2->allow_extras(); | |
| 699 | 696 | |
| 700 | 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 | 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 | +} | ... | ... |