mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-03 22:05:39 +02:00
Feature: generic matchers (#1843)
This commit extends the Matchers feature with the ability to have type-independent (e.g. templated) matchers. This is done by adding a new base type that Matchers can extend, `MatcherGenericBase`, and overloads of operators `!`, `&&` and `||` that handle matchers extending `MatcherGenericBase` in a special manner. These new matchers can also take their arguments as values and non-const references. Closes #1307 Closes #1553 Closes #1554 Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
This commit is contained in:
@@ -263,6 +263,37 @@ ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 2 == 2
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 3 == 3
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 5 == 5
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::Matchers::Impl::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() && MatcherD()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() && MatcherB() && MatcherC() && MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 and equals: true )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() || MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() || MatcherC() || MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 or equals: true )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 0, !MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!MatcherA()), MatcherA const& >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, !!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 0, !!!MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!!!MatcherA()), MatcherA const & >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, !!!!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))), Catch::Matchers::Impl::MatchAnyOf<std::string> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() && MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric<MatcherB>> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || !MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or not equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: vec, Predicate<std::vector<int>>([](auto const& vec) { return std::all_of(vec.begin(), vec.end(), [](int elem) { return elem % 2 == 1; }); }, "All elements are odd") && !EqualsRange(a) for: { 1, 3, 5 } ( matches predicate: "All elements are odd" and not Equals: { 5, 3, 1 } )
|
||||
Matchers.tests.cpp:<line number>: passed: str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar")) for: "foobar" ( Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } or ( starts with: "foo" and ends with: "bar" ) )
|
||||
Matchers.tests.cpp:<line number>: passed: str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr) for: "foobar" ( ( starts with: "foo" and ends with: "bar" ) or Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } )
|
||||
Matchers.tests.cpp:<line number>: passed: container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c) for: { 1, 2, 3 } ( Equals: { 1, 2, 3 } or Equals: { 0, 1, 2 } or Equals: { 4, 5, 6 } )
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
|
||||
@@ -883,6 +914,10 @@ RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits>
|
||||
4261393167 (0x<hex digits>)
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section one'
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section two'
|
||||
Matchers.tests.cpp:<line number>: passed: (EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed
|
||||
Matchers.tests.cpp:<line number>: passed: &EvilMatcher(), EvilAddressOfOperatorUsed
|
||||
Matchers.tests.cpp:<line number>: passed: EvilMatcher() || EvilMatcher() && !EvilMatcher()
|
||||
Matchers.tests.cpp:<line number>: passed: (EvilMatcher() && EvilMatcher()) || !EvilMatcher()
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.hasFilters() == false for: false == false
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *tcA ) == false for: false == false
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *tcB ) == false for: false == false
|
||||
|
Reference in New Issue
Block a user