mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
Add support for multiply calling lambda parsers in Clara
Previously a lambda parser in Clara could only be invoked once, even if it internally was ok with being invoked multiple times. With this change, a lambda parser can mark itself as `accept_many`, in which case it will be invoked multiple times if the appropriate flag was supplied multiple times by the user.
This commit is contained in:
parent
f17725a186
commit
12d14a3c63
@ -29,14 +29,17 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/internal/catch_void_type.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace Catch {
|
||||
@ -53,7 +56,25 @@ namespace Catch {
|
||||
ShortCircuitSame
|
||||
};
|
||||
|
||||
struct accept_many_t {};
|
||||
constexpr accept_many_t accept_many {};
|
||||
|
||||
namespace Detail {
|
||||
struct fake_arg {
|
||||
template <typename T>
|
||||
operator T();
|
||||
};
|
||||
|
||||
template <typename F, typename = void>
|
||||
struct is_unary_function : std::false_type {};
|
||||
|
||||
template <typename F>
|
||||
struct is_unary_function<
|
||||
F,
|
||||
Catch::Detail::void_t<decltype(
|
||||
std::declval<F>()( fake_arg() ) )
|
||||
>
|
||||
> : std::true_type {};
|
||||
|
||||
// Traits for extracting arg and return type of lambdas (for single
|
||||
// argument lambdas)
|
||||
@ -393,6 +414,11 @@ namespace Catch {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L> struct BoundManyLambda : BoundLambda<L> {
|
||||
explicit BoundManyLambda( L const& lambda ): BoundLambda<L>( lambda ) {}
|
||||
bool isContainer() const override { return true; }
|
||||
};
|
||||
|
||||
template <typename L> struct BoundFlagLambda : BoundFlagRefBase {
|
||||
L m_lambda;
|
||||
|
||||
@ -447,12 +473,23 @@ namespace Catch {
|
||||
m_ref( ref ) {}
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
template <typename LambdaT>
|
||||
ParserRefImpl( accept_many_t,
|
||||
LambdaT const& ref,
|
||||
std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
ParserRefImpl( T& ref, std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
template <typename LambdaT>
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
ParserRefImpl( LambdaT const& ref, std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
@ -513,11 +550,19 @@ namespace Catch {
|
||||
|
||||
explicit Opt(bool& ref);
|
||||
|
||||
template <typename LambdaT>
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
Opt( LambdaT const& ref, std::string const& hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
template <typename T>
|
||||
template <typename LambdaT>
|
||||
Opt( accept_many_t, LambdaT const& ref, std::string const& hint ):
|
||||
ParserRefImpl( accept_many, ref, hint ) {}
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
Opt( T& ref, std::string const& hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
|
@ -102,6 +102,7 @@ Nor would this
|
||||
:test-result: PASS Capture and info messages
|
||||
:test-result: PASS Character pretty printing
|
||||
:test-result: PASS Clara::Arg supports single-arg parse the way Opt does
|
||||
:test-result: PASS Clara::Opt supports accept-many lambdas
|
||||
:test-result: PASS Combining MatchAllOfGeneric does not nest
|
||||
:test-result: PASS Combining MatchAnyOfGeneric does not nest
|
||||
:test-result: PASS Combining MatchNotOfGeneric does not nest
|
||||
@ -297,6 +298,7 @@ Message from section two
|
||||
:test-result: FAIL first tag
|
||||
loose text artifact
|
||||
:test-result: FAIL has printf
|
||||
:test-result: PASS is_unary_function
|
||||
:test-result: FAIL just failure
|
||||
:test-result: FAIL just failure after unscoped info
|
||||
:test-result: FAIL just info
|
||||
|
@ -350,6 +350,9 @@ ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 5 == 5
|
||||
Clara.tests.cpp:<line number>: passed: name.empty() for: true
|
||||
Clara.tests.cpp:<line number>: passed: name == "foo" for: "foo" == "foo"
|
||||
Clara.tests.cpp:<line number>: passed: !(parse_result) for: !{?}
|
||||
Clara.tests.cpp:<line number>: passed: parse_result for: {?}
|
||||
Clara.tests.cpp:<line number>: passed: res == std::vector<std::string>{ "aaa", "bbb" } for: { "aaa", "bbb" } == { "aaa", "bbb" }
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype( ( MatcherA() && MatcherB() ) && MatcherC() ), Catch::Matchers::Detail:: MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>>::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, ( MatcherA() && MatcherB() ) && MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype( MatcherA() && ( MatcherB() && MatcherC() ) ), Catch::Matchers::Detail:: MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>>::value'
|
||||
@ -2111,6 +2114,18 @@ Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
loose text artifact
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary3)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary4)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary5)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary6)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(binary1)>::value)'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(binary2)>::value)'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(nullary1)>::value)'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(nullary2)>::value)'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<int>::value)'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: '!(Catch::Clara::Detail::is_unary_function<std::string const&>::value)'
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Previous info should not be seen'
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'previous unscoped info SHOULD not be seen'
|
||||
Misc.tests.cpp:<line number>: passed: l == std::numeric_limits<long long>::max() for: 9223372036854775807 (0x<hex digits>)
|
||||
|
@ -1426,6 +1426,6 @@ due to unexpected exception with message:
|
||||
Why would you throw a std::string?
|
||||
|
||||
===============================================================================
|
||||
test cases: 374 | 297 passed | 70 failed | 7 failed as expected
|
||||
assertions: 2127 | 1971 passed | 129 failed | 27 failed as expected
|
||||
test cases: 376 | 299 passed | 70 failed | 7 failed as expected
|
||||
assertions: 2142 | 1986 passed | 129 failed | 27 failed as expected
|
||||
|
||||
|
@ -2908,6 +2908,35 @@ Clara.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
"foo" == "foo"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Clara::Opt supports accept-many lambdas
|
||||
Parsing fails on multiple options without accept_many
|
||||
-------------------------------------------------------------------------------
|
||||
Clara.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
CHECK_FALSE( parse_result )
|
||||
with expansion:
|
||||
!{?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Clara::Opt supports accept-many lambdas
|
||||
Parsing succeeds on multiple options with accept_many
|
||||
-------------------------------------------------------------------------------
|
||||
Clara.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
CHECK( parse_result )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
CHECK( res == std::vector<std::string>{ "aaa", "bbb" } )
|
||||
with expansion:
|
||||
{ "aaa", "bbb" } == { "aaa", "bbb" }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining MatchAllOfGeneric does not nest
|
||||
-------------------------------------------------------------------------------
|
||||
@ -14962,6 +14991,60 @@ Tricky.tests.cpp:<line number>
|
||||
|
||||
No assertions in test case 'has printf'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
is_unary_function
|
||||
-------------------------------------------------------------------------------
|
||||
Clara.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary3)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary4)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary5)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
Catch::Clara::Detail::is_unary_function<decltype(unary6)>::value
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<decltype(binary1)>::value)
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<decltype(binary2)>::value)
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<decltype(nullary1)>::value)
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<decltype(nullary2)>::value)
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<int>::value)
|
||||
|
||||
Clara.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
!(Catch::Clara::Detail::is_unary_function<std::string const&>::value)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
just failure
|
||||
-------------------------------------------------------------------------------
|
||||
@ -17144,6 +17227,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 374 | 281 passed | 86 failed | 7 failed as expected
|
||||
assertions: 2144 | 1971 passed | 146 failed | 27 failed as expected
|
||||
test cases: 376 | 283 passed | 86 failed | 7 failed as expected
|
||||
assertions: 2159 | 1986 passed | 146 failed | 27 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="17" failures="129" tests="2144" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="17" failures="129" tests="2159" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<properties>
|
||||
<property name="random-seed" value="1"/>
|
||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
|
||||
@ -382,6 +382,8 @@ Exception.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Character pretty printing/General chars" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Character pretty printing/Low ASCII" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Clara::Arg supports single-arg parse the way Opt does" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Clara::Opt supports accept-many lambdas/Parsing fails on multiple options without accept_many" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Clara::Opt supports accept-many lambdas/Parsing succeeds on multiple options with accept_many" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchAllOfGeneric does not nest" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchAnyOfGeneric does not nest" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchNotOfGeneric does not nest" time="{duration}" status="run"/>
|
||||
@ -1601,6 +1603,7 @@ Misc.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="even more nested SECTION tests/c/d (leaf)" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="even more nested SECTION tests/c/e (leaf)" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="even more nested SECTION tests/f (leaf)" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="is_unary_function" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="just failure" time="{duration}" status="run">
|
||||
<failure type="FAIL">
|
||||
FAILED:
|
||||
|
@ -3,6 +3,9 @@
|
||||
>
|
||||
<file path="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp">
|
||||
<testCase name="Clara::Arg supports single-arg parse the way Opt does" duration="{duration}"/>
|
||||
<testCase name="Clara::Opt supports accept-many lambdas/Parsing fails on multiple options without accept_many" duration="{duration}"/>
|
||||
<testCase name="Clara::Opt supports accept-many lambdas/Parsing succeeds on multiple options with accept_many" duration="{duration}"/>
|
||||
<testCase name="is_unary_function" duration="{duration}"/>
|
||||
</file>
|
||||
<file path="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp">
|
||||
<testCase name="#1905 -- test spec parser properly clears internal state between compound tests" duration="{duration}"/>
|
||||
|
@ -698,6 +698,12 @@ ok {test-number} - c == i for: 5 == 5
|
||||
ok {test-number} - name.empty() for: true
|
||||
# Clara::Arg supports single-arg parse the way Opt does
|
||||
ok {test-number} - name == "foo" for: "foo" == "foo"
|
||||
# Clara::Opt supports accept-many lambdas
|
||||
ok {test-number} - !(parse_result) for: !{?}
|
||||
# Clara::Opt supports accept-many lambdas
|
||||
ok {test-number} - parse_result for: {?}
|
||||
# Clara::Opt supports accept-many lambdas
|
||||
ok {test-number} - res == std::vector<std::string>{ "aaa", "bbb" } for: { "aaa", "bbb" } == { "aaa", "bbb" }
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype( ( MatcherA() && MatcherB() ) && MatcherC() ), Catch::Matchers::Detail:: MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>>::value'
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
@ -3786,6 +3792,30 @@ ok {test-number} -
|
||||
# even more nested SECTION tests
|
||||
ok {test-number} -
|
||||
loose text artifact
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary3)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary4)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary5)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary6)>::value'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(binary1)>::value)'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(binary2)>::value)'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(nullary1)>::value)'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<decltype(nullary2)>::value)'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<int>::value)'
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: '!(Catch::Clara::Detail::is_unary_function<std::string const&>::value)'
|
||||
# just failure
|
||||
not ok {test-number} - explicitly with 1 message: 'Previous info should not be seen'
|
||||
# just failure after unscoped info
|
||||
@ -4290,5 +4320,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..2144
|
||||
1..2159
|
||||
|
||||
|
@ -237,6 +237,8 @@ Exception.tests.cpp:<line number>|nunexpected exception with message:|n "unexpe
|
||||
##teamcity[testFinished name='Character pretty printing' duration="{duration}"]
|
||||
##teamcity[testStarted name='Clara::Arg supports single-arg parse the way Opt does']
|
||||
##teamcity[testFinished name='Clara::Arg supports single-arg parse the way Opt does' duration="{duration}"]
|
||||
##teamcity[testStarted name='Clara::Opt supports accept-many lambdas']
|
||||
##teamcity[testFinished name='Clara::Opt supports accept-many lambdas' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining MatchAllOfGeneric does not nest']
|
||||
##teamcity[testFinished name='Combining MatchAllOfGeneric does not nest' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining MatchAnyOfGeneric does not nest']
|
||||
@ -723,6 +725,8 @@ Misc.tests.cpp:<line number>|nexpression failed|n REQUIRE( testCheckedIf( false
|
||||
##teamcity[testStarted name='has printf']
|
||||
loose text artifact
|
||||
##teamcity[testFinished name='has printf' duration="{duration}"]
|
||||
##teamcity[testStarted name='is_unary_function']
|
||||
##teamcity[testFinished name='is_unary_function' duration="{duration}"]
|
||||
##teamcity[testStarted name='just failure']
|
||||
Message.tests.cpp:<line number>|nexplicit failure with message:|n "Previous info should not be seen"']
|
||||
##teamcity[testFinished name='just failure' duration="{duration}"]
|
||||
|
@ -3156,6 +3156,39 @@ Nor would this
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Clara::Opt supports accept-many lambdas" tags="[clara][opt]" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Section name="Parsing fails on multiple options without accept_many" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Original>
|
||||
!(parse_result)
|
||||
</Original>
|
||||
<Expanded>
|
||||
!{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Parsing succeeds on multiple options with accept_many" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Original>
|
||||
parse_result
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<Original>
|
||||
res == std::vector<std::string>{ "aaa", "bbb" }
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ "aaa", "bbb" } == { "aaa", "bbb" }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining MatchAllOfGeneric does not nest" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
@ -17633,6 +17666,9 @@ There is no extra whitespace here
|
||||
loose text artifact
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="is_unary_function" tags="[clara][compilation]" filename="tests/<exe-name>/IntrospectiveTests/Clara.tests.cpp" >
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="just failure" tags="[.][fail][isolated info][messages]" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||
<Failure filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||
Previous info should not be seen
|
||||
@ -20147,6 +20183,6 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="1971" failures="146" expectedFailures="27"/>
|
||||
<OverallResultsCases successes="281" failures="86" expectedFailures="7"/>
|
||||
<OverallResults successes="1986" failures="146" expectedFailures="27"/>
|
||||
<OverallResultsCases successes="283" failures="86" expectedFailures="7"/>
|
||||
</Catch2TestRun>
|
||||
|
@ -11,6 +11,35 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("is_unary_function", "[clara][compilation]") {
|
||||
auto unary1 = [](int) {};
|
||||
auto unary2 = [](std::string const&) {};
|
||||
auto const unary3 = [](std::string const&) {};
|
||||
auto unary4 = [](int) { return 42; };
|
||||
void unary5(char);
|
||||
double unary6(long);
|
||||
|
||||
double binary1(long, int);
|
||||
auto binary2 = [](int, char) {};
|
||||
auto nullary1 = []() {};
|
||||
auto nullary2 = []() {return 42;};
|
||||
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value);
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value);
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary3)>::value);
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary4)>::value);
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary5)>::value);
|
||||
STATIC_REQUIRE(Catch::Clara::Detail::is_unary_function<decltype(unary6)>::value);
|
||||
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<decltype(binary1)>::value);
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<decltype(binary2)>::value);
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<decltype(nullary1)>::value);
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<decltype(nullary2)>::value);
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<int>::value);
|
||||
STATIC_REQUIRE_FALSE(Catch::Clara::Detail::is_unary_function<std::string const&>::value);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Clara::Arg supports single-arg parse the way Opt does", "[clara][arg][compilation]") {
|
||||
std::string name;
|
||||
auto p = Catch::Clara::Arg(name, "just one arg");
|
||||
@ -20,3 +49,25 @@ TEST_CASE("Clara::Arg supports single-arg parse the way Opt does", "[clara][arg]
|
||||
p.parse( Catch::Clara::Args{ "UnitTest", "foo" } );
|
||||
REQUIRE(name == "foo");
|
||||
}
|
||||
|
||||
TEST_CASE("Clara::Opt supports accept-many lambdas", "[clara][opt]") {
|
||||
std::string name;
|
||||
using namespace Catch::Clara;
|
||||
std::vector<std::string> res;
|
||||
const auto push_to_res = [&](std::string const& s) {
|
||||
res.push_back(s);
|
||||
return ParserResult::ok();
|
||||
};
|
||||
|
||||
SECTION("Parsing fails on multiple options without accept_many") {
|
||||
auto p = Parser() | Opt(push_to_res, "value")["-o"];
|
||||
auto parse_result = p.parse( Args{ "UnitTest", "-o", "aaa", "-o", "bbb" } );
|
||||
CHECK_FALSE(parse_result);
|
||||
}
|
||||
SECTION("Parsing succeeds on multiple options with accept_many") {
|
||||
auto p = Parser() | Opt(accept_many, push_to_res, "value")["-o"];
|
||||
auto parse_result = p.parse( Args{ "UnitTest", "-o", "aaa", "-o", "bbb" } );
|
||||
CHECK(parse_result);
|
||||
CHECK(res == std::vector<std::string>{ "aaa", "bbb" });
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user