mirror of
https://github.com/CLIUtils/CLI11.git
synced 2026-01-19 04:52:08 +00:00
Add some controls to manipulate option string formatting, including disabling the default values, disabling default flag values, disabling type names. Fixes #857 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
359 lines
12 KiB
C++
359 lines
12 KiB
C++
// Copyright (c) 2017-2025, University of Cincinnati, developed by Henry Schreiner
|
|
// under NSF AWARD 1414736 and by the respective contributors.
|
|
// All rights reserved.
|
|
//
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
#ifdef CLI11_SINGLE_FILE
|
|
#include "CLI11.hpp"
|
|
#else
|
|
#include "CLI/CLI.hpp"
|
|
#endif
|
|
|
|
#include "catch.hpp"
|
|
#include <fstream>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
class SimpleFormatter : public CLI::FormatterBase {
|
|
public:
|
|
SimpleFormatter() : FormatterBase() {}
|
|
|
|
std::string make_help(const CLI::App *, std::string, CLI::AppFormatMode) const override {
|
|
return "This is really simple";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("Formatter: Nothing", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.formatter(std::make_shared<SimpleFormatter>());
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK("This is really simple" == help);
|
|
}
|
|
|
|
TEST_CASE("Formatter: NothingLambda", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.formatter_fn(
|
|
[](const CLI::App *, std::string, CLI::AppFormatMode) { return std::string("This is really simple"); });
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK("This is really simple" == help);
|
|
}
|
|
|
|
TEST_CASE("Formatter: OptCustomize", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
auto optfmt = std::make_shared<CLI::Formatter>();
|
|
optfmt->column_width(25);
|
|
optfmt->label("REQUIRED", "(MUST HAVE)");
|
|
app.formatter(optfmt);
|
|
|
|
int v{0};
|
|
app.add_option("--opt", v, "Something")->required();
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("(MUST HAVE)"));
|
|
CHECK_THAT(help, Contains("Something"));
|
|
CHECK_THAT(help, Contains("--opt INT"));
|
|
CHECK_THAT(help, Contains("-h, --help Print"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: OptCustomizeSimple", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
app.get_formatter()->label("REQUIRED", "(MUST HAVE)");
|
|
|
|
int v{0};
|
|
app.add_option("--opt", v, "Something")->required();
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("(MUST HAVE)"));
|
|
CHECK_THAT(help, Contains("(MUST HAVE)"));
|
|
CHECK_THAT(help, Contains("Something"));
|
|
CHECK_THAT(help, Contains("--opt INT"));
|
|
CHECK_THAT(help, Contains("-h, --help Print"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: OptCustomizeOptionText", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
|
|
int v{0};
|
|
app.add_option("--opt", v, "Something")->option_text("(ARG)");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("(ARG)"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: OptBaseExample", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
|
|
std::string v{};
|
|
app.add_option("--opt", v)->default_str("DEFFFF");
|
|
|
|
int v2{0};
|
|
app.add_option("-o,--opt2", v2, "this is a description for opt2");
|
|
|
|
double v3{0.0};
|
|
app.add_option("-f,-n,--opt3,--option-double", v3, "this is a description for option3");
|
|
|
|
app.add_flag("--flag,!--no_flag", "a flag option with a negative flag as well");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("DEFFFF"));
|
|
CHECK_THAT(help, Contains("{false"));
|
|
}
|
|
TEST_CASE("Formatter: OptDefaults", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
|
|
std::string v{};
|
|
app.add_option("--opt", v)->default_str("DEFFFF");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("[DEFFFF]"));
|
|
app.get_formatter()->enable_option_defaults(false);
|
|
|
|
help = app.help();
|
|
CHECK_THAT(help, !Contains("[DEFFFF]"));
|
|
CHECK(!app.get_formatter()->is_option_defaults_enabled());
|
|
}
|
|
|
|
TEST_CASE("Formatter: OptTypes", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
|
|
std::string v{};
|
|
app.add_option("--opt", v);
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("TEXT"));
|
|
app.get_formatter()->enable_option_type_names(false);
|
|
|
|
help = app.help();
|
|
CHECK_THAT(help, !Contains("TEXT"));
|
|
CHECK(!app.get_formatter()->is_option_type_names_enabled());
|
|
}
|
|
|
|
TEST_CASE("Formatter: FalseFlagExample", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
app.get_formatter()->label("REQUIRED", "(MUST HAVE)");
|
|
|
|
int v{0};
|
|
app.add_flag("--opt,!--no_opt", v, "Something");
|
|
|
|
bool flag{false};
|
|
app.add_flag("!-O,--opt2,--no_opt2{false}", flag, "Something else");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("--no_opt{false}"));
|
|
CHECK_THAT(help, Contains("--no_opt2{false}"));
|
|
CHECK_THAT(help, Contains("-O{false}"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: FalseFlagExampleDisable", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->column_width(25);
|
|
|
|
int v{0};
|
|
app.add_flag("--opt,!--no_opt", v, "Something");
|
|
|
|
bool flag{false};
|
|
app.add_flag("!-O,--opt2,--no_opt2{false}", flag, "Something else");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("--no_opt{false}"));
|
|
CHECK_THAT(help, Contains("--no_opt2{false}"));
|
|
CHECK_THAT(help, Contains("-O{false}"));
|
|
|
|
app.get_formatter()->enable_default_flag_values(false);
|
|
CHECK(!app.get_formatter()->is_default_flag_values_enabled());
|
|
|
|
help = app.help();
|
|
CHECK_THAT(help, !Contains("{false}"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: AppCustomize", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
app.add_subcommand("subcom1", "This");
|
|
|
|
auto appfmt = std::make_shared<CLI::Formatter>();
|
|
appfmt->column_width(20);
|
|
appfmt->label("Usage", "Run");
|
|
app.formatter(appfmt);
|
|
|
|
app.add_subcommand("subcom2", "That");
|
|
|
|
std::string help = app.help();
|
|
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMANDS]\n\n"));
|
|
CHECK_THAT(help, Contains("\nSUBCOMMANDS:\n"));
|
|
CHECK_THAT(help, Contains(" subcom1 This \n"));
|
|
CHECK_THAT(help, Contains(" subcom2 That \n"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: AppCustomizeSimple", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
app.add_subcommand("subcom1", "This");
|
|
|
|
app.get_formatter()->column_width(20);
|
|
app.get_formatter()->label("Usage", "Run");
|
|
|
|
app.add_subcommand("subcom2", "That");
|
|
|
|
std::string help = app.help();
|
|
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMANDS]\n\n"));
|
|
CHECK_THAT(help, Contains("\nSUBCOMMANDS:\n"));
|
|
CHECK_THAT(help, Contains(" subcom1 This \n"));
|
|
CHECK_THAT(help, Contains(" subcom2 That \n"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: AllSub", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
CLI::App *sub = app.add_subcommand("subcom", "This");
|
|
sub->add_flag("--insub", "MyFlag");
|
|
|
|
std::string help = app.help("", CLI::AppFormatMode::All);
|
|
CHECK_THAT(help, Contains("--insub"));
|
|
CHECK_THAT(help, Contains("subcom"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: AllSubRequired", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
CLI::App *sub = app.add_subcommand("subcom", "This");
|
|
sub->add_flag("--insub", "MyFlag");
|
|
sub->required();
|
|
std::string help = app.help("", CLI::AppFormatMode::All);
|
|
CHECK_THAT(help, Contains("--insub"));
|
|
CHECK_THAT(help, Contains("subcom"));
|
|
CHECK_THAT(help, Contains("REQUIRED"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: NamelessSub", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
CLI::App *sub = app.add_subcommand("", "This subcommand");
|
|
sub->add_flag("--insub", "MyFlag");
|
|
|
|
std::string help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, Contains("--insub"));
|
|
CHECK_THAT(help, Contains("This subcommand"));
|
|
}
|
|
|
|
TEST_CASE("Formatter: NamelessSubInGroup", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
CLI::App *sub = app.add_subcommand("", "This subcommand");
|
|
CLI::App *sub2 = app.add_subcommand("sub2", "subcommand2");
|
|
sub->add_flag("--insub", "MyFlag");
|
|
int val{0};
|
|
sub2->add_option("pos", val, "positional");
|
|
sub->group("group1");
|
|
sub2->group("group1");
|
|
std::string help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, Contains("--insub"));
|
|
CHECK_THAT(help, Contains("This subcommand"));
|
|
CHECK_THAT(help, Contains("group1"));
|
|
CHECK_THAT(help, Contains("sub2"));
|
|
CHECK(help.find("pos") == std::string::npos);
|
|
}
|
|
|
|
TEST_CASE("Formatter: Footer", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
std::string footer_string{"this is a test of the footer "
|
|
"systemsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss to Pr e s "
|
|
" e r v e SPA C ES"};
|
|
app.footer(footer_string);
|
|
app.add_flag("--option", "MyFlag");
|
|
app.get_formatter()->footer_paragraph_width(50);
|
|
app.get_formatter()->enable_footer_formatting(false);
|
|
CHECK(!app.get_formatter()->is_footer_paragraph_formatting_enabled());
|
|
std::string help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, Contains("is a"));
|
|
CHECK_THAT(help, Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, Contains(footer_string));
|
|
|
|
help = app.help("", CLI::AppFormatMode::Sub);
|
|
CHECK_THAT(help, Contains("is a"));
|
|
CHECK_THAT(help, Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, Contains(footer_string));
|
|
|
|
app.get_formatter()->enable_footer_formatting(true);
|
|
CHECK(app.get_formatter()->is_footer_paragraph_formatting_enabled());
|
|
help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, !Contains("is a"));
|
|
CHECK_THAT(help, !Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, !Contains(footer_string));
|
|
|
|
help = app.help("", CLI::AppFormatMode::Sub);
|
|
CHECK_THAT(help, !Contains("is a"));
|
|
CHECK_THAT(help, !Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, !Contains(footer_string));
|
|
}
|
|
|
|
TEST_CASE("Formatter: Description", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
std::string desc_string{"this is a test of the footer "
|
|
"systemsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss to Pr e s "
|
|
"e r v e SPA C ES"};
|
|
app.description(desc_string);
|
|
app.add_flag("--option", "MyFlag");
|
|
app.get_formatter()->description_paragraph_width(50);
|
|
app.get_formatter()->enable_description_formatting(false);
|
|
CHECK(!app.get_formatter()->is_description_paragraph_formatting_enabled());
|
|
std::string help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, Contains("is a"));
|
|
CHECK_THAT(help, Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, Contains(desc_string));
|
|
|
|
help = app.help("", CLI::AppFormatMode::Sub);
|
|
CHECK_THAT(help, Contains("is a"));
|
|
CHECK_THAT(help, Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, Contains(desc_string));
|
|
|
|
app.get_formatter()->enable_description_formatting(true);
|
|
CHECK(app.get_formatter()->is_description_paragraph_formatting_enabled());
|
|
help = app.help("", CLI::AppFormatMode::Normal);
|
|
CHECK_THAT(help, !Contains("is a"));
|
|
CHECK_THAT(help, !Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, !Contains(desc_string));
|
|
|
|
help = app.help("", CLI::AppFormatMode::Sub);
|
|
CHECK_THAT(help, !Contains("is a"));
|
|
CHECK_THAT(help, !Contains("to Pr e s e r v e SPA C ES"));
|
|
CHECK_THAT(help, !Contains(desc_string));
|
|
}
|
|
|
|
TEST_CASE("Formatter: LongOptionAlignment", "[formatter]") {
|
|
CLI::App app{"My prog"};
|
|
|
|
app.get_formatter()->long_option_alignment_ratio(6 / 30.f);
|
|
|
|
int v{0};
|
|
app.add_option("--opt", v, "Something");
|
|
|
|
std::string help = app.help();
|
|
|
|
CHECK_THAT(help, Contains("\n -h, --help Print"));
|
|
CHECK_THAT(help, Contains("\n --opt INT Something"));
|
|
}
|