fix: fix clap and its test.
- fix clap test compile and running issue. - fix unexpected output in console for clap manual. - remove duplicated program name in clap manual. - fix there is no default ctor for clap validator. - fix fatal scoped pointer return in clap parser and resolver.
This commit is contained in:
@ -90,7 +90,7 @@ namespace yycc::carton::binstore::storage {
|
|||||||
public:
|
public:
|
||||||
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
|
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
|
||||||
NS_YYCC_BINSTORE_TYPES::BinstoreResult<std::pair<GetValueState, NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>>> get_value(
|
NS_YYCC_BINSTORE_TYPES::BinstoreResult<std::pair<GetValueState, NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>>> get_value(
|
||||||
NS_YYCC_BINSTORE_TYPES::Token token, const T& serdes = T()) {
|
NS_YYCC_BINSTORE_TYPES::Token token, const T& serdes = T{}) {
|
||||||
// If we have value, we fetch it first
|
// If we have value, we fetch it first
|
||||||
if (this->has_value(token)) {
|
if (this->has_value(token)) {
|
||||||
// Get raw value.
|
// Get raw value.
|
||||||
@ -129,7 +129,7 @@ namespace yycc::carton::binstore::storage {
|
|||||||
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
|
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
|
||||||
NS_YYCC_BINSTORE_TYPES::BinstoreResult<SetValueState> set_value(NS_YYCC_BINSTORE_TYPES::Token token,
|
NS_YYCC_BINSTORE_TYPES::BinstoreResult<SetValueState> set_value(NS_YYCC_BINSTORE_TYPES::Token token,
|
||||||
const NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>& value,
|
const NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>& value,
|
||||||
const T& serdes = T()) {
|
const T& serdes = T{}) {
|
||||||
// First we try assign it.
|
// First we try assign it.
|
||||||
{
|
{
|
||||||
// Convert it into raw format.
|
// Convert it into raw format.
|
||||||
|
|||||||
@ -20,7 +20,7 @@ namespace yycc::carton::clap::manual {
|
|||||||
#pragma region Manual Translation
|
#pragma region Manual Translation
|
||||||
|
|
||||||
ManualTr::ManualTr() :
|
ManualTr::ManualTr() :
|
||||||
author_and_version(u8"Invented by {0}. Version {1}."), usage_title(u8"Usage:"), usage_body(u8"{0} <options> ..."),
|
author_and_version(u8"Built by {0} with version {1}."), usage_title(u8"Usage:"), usage_body(u8"{0} <options> ..."),
|
||||||
avail_opt(u8"Available options:"), avail_var(u8"Available environment variables:") {}
|
avail_opt(u8"Available options:"), avail_var(u8"Available environment variables:") {}
|
||||||
|
|
||||||
ManualTr::~ManualTr() {}
|
ManualTr::~ManualTr() {}
|
||||||
@ -100,14 +100,13 @@ namespace yycc::carton::clap::manual {
|
|||||||
const auto &summary = this->app.get_summary();
|
const auto &summary = this->app.get_summary();
|
||||||
|
|
||||||
TERMCOLOR::cprintln(summary.get_name(), TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst);
|
TERMCOLOR::cprintln(summary.get_name(), TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst);
|
||||||
dst << summary.get_name() << std::endl;
|
|
||||||
dst << FORMAT::format(trctx.author_and_version, summary.get_author(), summary.get_version()) << std::endl;
|
dst << FORMAT::format(trctx.author_and_version, summary.get_author(), summary.get_version()) << std::endl;
|
||||||
dst << summary.get_description() << std::endl;
|
dst << summary.get_description() << std::endl;
|
||||||
dst << std::endl;
|
dst << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manual::print_help(std::ostream &dst) const {
|
void Manual::print_help(std::ostream &dst) const {
|
||||||
this->print_version();
|
this->print_version(dst);
|
||||||
|
|
||||||
// only print usage if we can fetch the name of executable
|
// only print usage if we can fetch the name of executable
|
||||||
auto executable = ENV::current_exe();
|
auto executable = ENV::current_exe();
|
||||||
|
|||||||
@ -185,7 +185,7 @@ namespace yycc::carton::clap::parser {
|
|||||||
else return std::unexpected(rv.error());
|
else return std::unexpected(rv.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(decltype(Parser::values)&& value) : values(std::move(values)) {}
|
Parser::Parser(decltype(Parser::values)&& values) : values(std::move(values)) {}
|
||||||
|
|
||||||
Parser::~Parser() {}
|
Parser::~Parser() {}
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ namespace yycc::carton::clap::parser {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Found.
|
// Found.
|
||||||
auto val = finder->second;
|
const auto& val = finder->second;
|
||||||
if (val.has_value()) throw std::logic_error("get flag option as value option.");
|
if (val.has_value()) throw std::logic_error("get flag option as value option.");
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ namespace yycc::carton::clap::parser {
|
|||||||
return std::unexpected(TYPES::ClapError::NotCaptured);
|
return std::unexpected(TYPES::ClapError::NotCaptured);
|
||||||
} else {
|
} else {
|
||||||
// Found.
|
// Found.
|
||||||
auto val = finder->second;
|
const auto& val = finder->second;
|
||||||
if (val.has_value()) return std::u8string_view(val.value());
|
if (val.has_value()) return std::u8string_view(val.value());
|
||||||
else throw std::logic_error("get value option as flag option.");
|
else throw std::logic_error("get value option as flag option.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ namespace yycc::carton::clap::parser {
|
|||||||
static NS_YYCC_CLAP_TYPES::ClapResult<Parser> from_system(const NS_YYCC_CLAP_APPLICATION::Application& app);
|
static NS_YYCC_CLAP_TYPES::ClapResult<Parser> from_system(const NS_YYCC_CLAP_APPLICATION::Application& app);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Parser(decltype(Parser::values)&& value);
|
Parser(decltype(Parser::values)&& values);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Parser();
|
~Parser();
|
||||||
@ -46,7 +46,7 @@ namespace yycc::carton::clap::parser {
|
|||||||
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||||
template<NS_YYCC_CLAP_VALIDATOR::Validator T>
|
template<NS_YYCC_CLAP_VALIDATOR::Validator T>
|
||||||
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(NS_YYCC_CLAP_TYPES::Token token,
|
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(NS_YYCC_CLAP_TYPES::Token token,
|
||||||
const T& validator = T()) const {
|
const T& validator = T{}) const {
|
||||||
auto raw_value = this->get_raw_value_option(token);
|
auto raw_value = this->get_raw_value_option(token);
|
||||||
if (raw_value.has_value()) {
|
if (raw_value.has_value()) {
|
||||||
auto value = validator.validate(raw_value.value());
|
auto value = validator.validate(raw_value.value());
|
||||||
|
|||||||
@ -77,7 +77,7 @@ namespace yycc::carton::clap::resolver {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Found.
|
// Found.
|
||||||
auto val = finder->second;
|
const auto& val = finder->second;
|
||||||
if (val.has_value()) throw std::logic_error("get flag variable as value variable.");
|
if (val.has_value()) throw std::logic_error("get flag variable as value variable.");
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ namespace yycc::carton::clap::resolver {
|
|||||||
return std::unexpected(TYPES::ClapError::NotCaptured);
|
return std::unexpected(TYPES::ClapError::NotCaptured);
|
||||||
} else {
|
} else {
|
||||||
// Found.
|
// Found.
|
||||||
auto val = finder->second;
|
const auto& val = finder->second;
|
||||||
if (val.has_value()) return std::u8string_view(val.value());
|
if (val.has_value()) return std::u8string_view(val.value());
|
||||||
else throw std::logic_error("get value variable as flag variable.");
|
else throw std::logic_error("get value variable as flag variable.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ namespace yycc::carton::clap::validator {
|
|||||||
|
|
||||||
template<std::integral T, auto TMin = std::numeric_limits<T>::min(), auto TMax = std::numeric_limits<T>::max()>
|
template<std::integral T, auto TMin = std::numeric_limits<T>::min(), auto TMax = std::numeric_limits<T>::max()>
|
||||||
struct IntegralValidator {
|
struct IntegralValidator {
|
||||||
|
IntegralValidator() = default;
|
||||||
YYCC_DEFAULT_COPY_MOVE(IntegralValidator)
|
YYCC_DEFAULT_COPY_MOVE(IntegralValidator)
|
||||||
|
|
||||||
static_assert(TMin <= TMax);
|
static_assert(TMin <= TMax);
|
||||||
@ -59,9 +60,14 @@ namespace yycc::carton::clap::validator {
|
|||||||
|
|
||||||
template<std::floating_point T, auto TMin = std::numeric_limits<T>::lowest(), auto TMax = std::numeric_limits<T>::max()>
|
template<std::floating_point T, auto TMin = std::numeric_limits<T>::lowest(), auto TMax = std::numeric_limits<T>::max()>
|
||||||
struct FloatingPointValidator {
|
struct FloatingPointValidator {
|
||||||
|
FloatingPointValidator() {
|
||||||
|
// TODO: Remove this and make it "= default" when 3 common STL make std::isfinite become constexpr.
|
||||||
|
if (!std::isfinite(TMin)) throw std::logic_error("invalid float minimum value.");
|
||||||
|
if (!std::isfinite(TMax)) throw std::logic_error("invalid float maximum value.");
|
||||||
|
}
|
||||||
YYCC_DEFAULT_COPY_MOVE(FloatingPointValidator)
|
YYCC_DEFAULT_COPY_MOVE(FloatingPointValidator)
|
||||||
|
|
||||||
// TODO: Use static_assert once 3 common STL make this become constexpr.
|
// TODO: Use static_assert once 3 common STL make std::isfinite become constexpr.
|
||||||
//static_assert(std::isfinite<T>(TMin));
|
//static_assert(std::isfinite<T>(TMin));
|
||||||
//static_assert(std::isfinite<T>(TMax));
|
//static_assert(std::isfinite<T>(TMax));
|
||||||
static_assert(TMin <= TMax);
|
static_assert(TMin <= TMax);
|
||||||
@ -78,6 +84,7 @@ namespace yycc::carton::clap::validator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BoolValidator {
|
struct BoolValidator {
|
||||||
|
BoolValidator() = default;
|
||||||
YYCC_DEFAULT_COPY_MOVE(BoolValidator)
|
YYCC_DEFAULT_COPY_MOVE(BoolValidator)
|
||||||
|
|
||||||
using ReturnType = bool;
|
using ReturnType = bool;
|
||||||
@ -89,6 +96,7 @@ namespace yycc::carton::clap::validator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct StringValidator {
|
struct StringValidator {
|
||||||
|
StringValidator() = default;
|
||||||
YYCC_DEFAULT_COPY_MOVE(StringValidator)
|
YYCC_DEFAULT_COPY_MOVE(StringValidator)
|
||||||
|
|
||||||
using ReturnType = std::u8string;
|
using ReturnType = std::u8string;
|
||||||
|
|||||||
@ -216,7 +216,7 @@ namespace yycc::carton::termcolor {
|
|||||||
dst << colored(words, foreground, background, styles);
|
dst << colored(words, foreground, background, styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecprint(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
void ceprint(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
||||||
cprint(words, foreground, background, styles, std::cerr);
|
cprint(words, foreground, background, styles, std::cerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ namespace yycc::carton::termcolor {
|
|||||||
dst << std::endl;
|
dst << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecprintln(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
void ceprintln(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
||||||
cprintln(words, foreground, background, styles, std::cerr);
|
cprintln(words, foreground, background, styles, std::cerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,18 +10,21 @@ namespace yycctest::carton::clap {
|
|||||||
using Token = CLAP::types::Token;
|
using Token = CLAP::types::Token;
|
||||||
namespace validator = CLAP::validator;
|
namespace validator = CLAP::validator;
|
||||||
|
|
||||||
TEST(CartonClap, BadOption) {
|
// YYC MARK:
|
||||||
|
// GoogleTest do not allow use TEST and TEST_F in the same test suite
|
||||||
|
// So I was forcely split following builder checker into independent test suit.
|
||||||
|
|
||||||
|
TEST(CartonClapOption, BadOption) {
|
||||||
// No short name and long name.
|
// No short name and long name.
|
||||||
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(std::nullopt, std::nullopt, std::nullopt, u8""));
|
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(std::nullopt, std::nullopt, std::nullopt, u8""));
|
||||||
// Empty short name or long name.
|
// Empty short name or long name.
|
||||||
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(u8"", std::nullopt, std::nullopt, u8""));
|
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(u8"", std::nullopt, std::nullopt, u8""));
|
||||||
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(std::nullopt, u8"", std::nullopt, u8""));
|
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(std::nullopt, u8"", std::nullopt, u8""));
|
||||||
// Bad short name
|
// Bad short name
|
||||||
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(u8"fuck", std::nullopt, std::nullopt, u8""));
|
|
||||||
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(u8"-", std::nullopt, std::nullopt, u8""));
|
EXPECT_ANY_THROW(auto opt = CLAP::option::Option(u8"-", std::nullopt, std::nullopt, u8""));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CartonClap, BadOptions) {
|
TEST(CartonClapOption, BadOptions) {
|
||||||
// Duplicated.
|
// Duplicated.
|
||||||
{
|
{
|
||||||
auto options = CLAP::option::OptionCollection();
|
auto options = CLAP::option::OptionCollection();
|
||||||
@ -36,12 +39,12 @@ namespace yycctest::carton::clap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CartonClap, BadVariable) {
|
TEST(CartonClapVariable, BadVariable) {
|
||||||
// Empty name
|
// Empty name
|
||||||
EXPECT_ANY_THROW(auto var = CLAP::variable::Variable(u8"", u8"", true));
|
EXPECT_ANY_THROW(auto var = CLAP::variable::Variable(u8"", u8"", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CartonClap, BadVariables) {
|
TEST(CartonClapVariable, BadVariables) {
|
||||||
// Duplicated.
|
// Duplicated.
|
||||||
{
|
{
|
||||||
auto variables = CLAP::variable::VariableCollection();
|
auto variables = CLAP::variable::VariableCollection();
|
||||||
|
|||||||
Reference in New Issue
Block a user