Added first vector matchers (Contains and Equals)

This commit is contained in:
Phil Nash 2017-02-21 16:05:04 +00:00
parent 45d4096756
commit 10dfca34ac
8 changed files with 569 additions and 7 deletions

View File

@ -157,6 +157,7 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_matchers.hpp
${HEADER_DIR}/internal/catch_matchers_string.h
${HEADER_DIR}/internal/catch_matchers_string.hpp
${HEADER_DIR}/internal/catch_matchers_vector.h
${HEADER_DIR}/internal/catch_message.h
${HEADER_DIR}/internal/catch_message.hpp
${HEADER_DIR}/internal/catch_notimplemented_exception.h

View File

@ -37,6 +37,7 @@
#include "internal/catch_interfaces_exception.h"
#include "internal/catch_approx.hpp"
#include "internal/catch_matchers_string.h"
#include "internal/catch_matchers_vector.h"
#include "internal/catch_compiler_capabilities.h"
#include "internal/catch_interfaces_tag_alias_registry.h"

View File

@ -0,0 +1,101 @@
/*
* Created by Phil Nash on 21/02/2017.
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
#include "catch_matchers.hpp"
namespace Catch {
namespace Matchers {
namespace Vector {
template<typename T>
struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
return std::find(v.begin(), v.end(), m_comparator) != v.end();
}
virtual std::string describe() const CATCH_OVERRIDE {
return "Contains: " + Catch::toString( m_comparator );
}
T const& m_comparator;
};
template<typename T>
struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
// !TBD: see note in EqualsMatcher
if (m_comparator.size() > v.size())
return false;
for (size_t i = 0; i < m_comparator.size(); ++i)
if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
return false;
return true;
}
virtual std::string describe() const CATCH_OVERRIDE {
return "Contains: " + Catch::toString( m_comparator );
}
std::vector<T> const& m_comparator;
};
template<typename T>
struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
// !TBD: This currently works if all elements can be compared using !=
// - a more general approach would be via a compare template that defaults
// to using !=. but could be specialised for, e.g. std::vector<T> etc
// - then just call that directly
if (m_comparator.size() != v.size())
return false;
for (size_t i = 0; i < v.size(); ++i)
if (m_comparator[i] != v[i])
return false;
return true;
}
virtual std::string describe() const CATCH_OVERRIDE {
return "Equals: " + Catch::toString( m_comparator );
}
std::vector<T> const& m_comparator;
};
} // namespace Vector
// The following functions create the actual matcher objects.
// This allows the types to be inferred
template<typename T>
Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
return Vector::ContainsMatcher<T>( comparator );
}
template<typename T>
Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
return Vector::ContainsElementMatcher<T>( comparator );
}
template<typename T>
Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
return Vector::EqualsMatcher<T>( comparator );
}
} // namespace Matchers
} // namespace Catch
#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED

View File

@ -602,6 +602,67 @@ ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
3.14
-------------------------------------------------------------------------------
Vector matchers that fail
Contains (element)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, VectorContains( -1 ) )
with expansion:
{ 1, 2, 3 } Contains: -1
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, VectorContains( 1 ) )
with expansion:
{ } Contains: 1
-------------------------------------------------------------------------------
Vector matchers that fail
Contains (vector)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, Contains( v) )
with expansion:
{ } Contains: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Contains( v2 ) )
with expansion:
{ 1, 2, 3 } Contains: { 1, 2, 4 }
-------------------------------------------------------------------------------
Vector matchers that fail
Equals
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Equals( v2 ) )
with expansion:
{ 1, 2, 3 } Equals: { 1, 2 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v2, Equals( v ) )
with expansion:
{ 1, 2 } Equals: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, Equals( v ) )
with expansion:
{ } Equals: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Equals( empty ) )
with expansion:
{ 1, 2, 3 } Equals: { }
-------------------------------------------------------------------------------
When unchecked exceptions are thrown directly they are always failures
-------------------------------------------------------------------------------
@ -829,6 +890,6 @@ with expansion:
"first" == "second"
===============================================================================
test cases: 160 | 116 passed | 42 failed | 2 failed as expected
assertions: 931 | 835 passed | 78 failed | 18 failed as expected
test cases: 162 | 117 passed | 43 failed | 2 failed as expected
assertions: 948 | 844 passed | 86 failed | 18 failed as expected

View File

@ -7880,6 +7880,142 @@ PASSED:
with message:
no assertions
-------------------------------------------------------------------------------
Vector matchers
Contains (element)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, VectorContains( 1 ) )
with expansion:
{ 1, 2, 3 } Contains: 1
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, VectorContains( 2 ) )
with expansion:
{ 1, 2, 3 } Contains: 2
-------------------------------------------------------------------------------
Vector matchers
Contains (vector)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, Contains( v2 ) )
with expansion:
{ 1, 2, 3 } Contains: { 1, 2 }
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, Contains( v2 ) )
with expansion:
{ 1, 2, 3 } Contains: { 1, 2, 3 }
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, Contains( empty) )
with expansion:
{ 1, 2, 3 } Contains: { }
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( empty, Contains( empty) )
with expansion:
{ } Contains: { }
-------------------------------------------------------------------------------
Vector matchers
Equals
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, Equals( v ) )
with expansion:
{ 1, 2, 3 } Equals: { 1, 2, 3 }
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( empty, Equals( empty ) )
with expansion:
{ } Equals: { }
MatchersTests.cpp:<line number>:
PASSED:
CHECK_THAT( v, Equals( v2 ) )
with expansion:
{ 1, 2, 3 } Equals: { 1, 2, 3 }
-------------------------------------------------------------------------------
Vector matchers that fail
Contains (element)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, VectorContains( -1 ) )
with expansion:
{ 1, 2, 3 } Contains: -1
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, VectorContains( 1 ) )
with expansion:
{ } Contains: 1
-------------------------------------------------------------------------------
Vector matchers that fail
Contains (vector)
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, Contains( v) )
with expansion:
{ } Contains: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Contains( v2 ) )
with expansion:
{ 1, 2, 3 } Contains: { 1, 2, 4 }
-------------------------------------------------------------------------------
Vector matchers that fail
Equals
-------------------------------------------------------------------------------
MatchersTests.cpp:<line number>
...............................................................................
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Equals( v2 ) )
with expansion:
{ 1, 2, 3 } Equals: { 1, 2 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v2, Equals( v ) )
with expansion:
{ 1, 2 } Equals: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( empty, Equals( v ) )
with expansion:
{ } Equals: { 1, 2, 3 }
MatchersTests.cpp:<line number>: FAILED:
CHECK_THAT( v, Equals( empty ) )
with expansion:
{ 1, 2, 3 } Equals: { }
-------------------------------------------------------------------------------
When checked exceptions are thrown they can be expected or unexpected
-------------------------------------------------------------------------------
@ -9152,6 +9288,6 @@ MiscTests.cpp:<line number>:
PASSED:
===============================================================================
test cases: 160 | 115 passed | 43 failed | 2 failed as expected
assertions: 933 | 835 passed | 80 failed | 18 failed as expected
test cases: 162 | 116 passed | 44 failed | 2 failed as expected
assertions: 950 | 844 passed | 88 failed | 18 failed as expected

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesspanner>
<testsuite name="<exe-name>" errors="13" failures="68" tests="934" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="13" failures="76" tests="951" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
<testcase classname="global" name="#542" time="{duration}"/>
<testcase classname="global" name="#809" time="{duration}"/>
@ -499,6 +499,39 @@ ExceptionTests.cpp:<line number>
</testcase>
<testcase classname="global" name="Use a custom approx" time="{duration}"/>
<testcase classname="Variadic macros" name="Section with one argument" time="{duration}"/>
<testcase classname="Vector matchers" name="Contains (element)" time="{duration}"/>
<testcase classname="Vector matchers" name="Contains (vector)" time="{duration}"/>
<testcase classname="Vector matchers" name="Equals" time="{duration}"/>
<testcase classname="Vector matchers that fail" name="Contains (element)" time="{duration}">
<failure message="{ 1, 2, 3 } Contains: -1" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
<failure message="{ } Contains: 1" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="Vector matchers that fail" name="Contains (vector)" time="{duration}">
<failure message="{ } Contains: { 1, 2, 3 }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
<failure message="{ 1, 2, 3 } Contains: { 1, 2, 4 }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="Vector matchers that fail" name="Equals" time="{duration}">
<failure message="{ 1, 2, 3 } Equals: { 1, 2 }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
<failure message="{ 1, 2 } Equals: { 1, 2, 3 }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
<failure message="{ } Equals: { 1, 2, 3 }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
<failure message="{ 1, 2, 3 } Equals: { }" type="CHECK_THAT">
MatchersTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="global" name="When checked exceptions are thrown they can be expected or unexpected" time="{duration}"/>
<testcase classname="global" name="When unchecked exceptions are thrown directly they are always failures" time="{duration}">
<error type="TEST_CASE">

View File

@ -8421,6 +8421,166 @@ there"
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Vector matchers" tags="[matchers][vector]" filename="projects/<exe-name>/MatchersTests.cpp" >
<Section name="Contains (element)" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, VectorContains( 1 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: 1
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, VectorContains( 2 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: 2
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Section name="Contains (vector)" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Contains( v2 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: { 1, 2 }
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Contains( v2 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: { 1, 2, 3 }
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Contains( empty)
</Original>
<Expanded>
{ 1, 2, 3 } Contains: { }
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
empty, Contains( empty)
</Original>
<Expanded>
{ } Contains: { }
</Expanded>
</Expression>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<Section name="Equals" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Equals( v )
</Original>
<Expanded>
{ 1, 2, 3 } Equals: { 1, 2, 3 }
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
empty, Equals( empty )
</Original>
<Expanded>
{ } Equals: { }
</Expanded>
</Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Equals( v2 )
</Original>
<Expanded>
{ 1, 2, 3 } Equals: { 1, 2, 3 }
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Vector matchers that fail" tags="[.][failing][hide][matchers][vector]" filename="projects/<exe-name>/MatchersTests.cpp" >
<Section name="Contains (element)" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, VectorContains( -1 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: -1
</Expanded>
</Expression>
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
empty, VectorContains( 1 )
</Original>
<Expanded>
{ } Contains: 1
</Expanded>
</Expression>
<OverallResults successes="0" failures="2" expectedFailures="0"/>
</Section>
<Section name="Contains (vector)" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
empty, Contains( v)
</Original>
<Expanded>
{ } Contains: { 1, 2, 3 }
</Expanded>
</Expression>
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Contains( v2 )
</Original>
<Expanded>
{ 1, 2, 3 } Contains: { 1, 2, 4 }
</Expanded>
</Expression>
<OverallResults successes="0" failures="2" expectedFailures="0"/>
</Section>
<Section name="Equals" filename="projects/<exe-name>/MatchersTests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Equals( v2 )
</Original>
<Expanded>
{ 1, 2, 3 } Equals: { 1, 2 }
</Expanded>
</Expression>
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v2, Equals( v )
</Original>
<Expanded>
{ 1, 2 } Equals: { 1, 2, 3 }
</Expanded>
</Expression>
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
empty, Equals( v )
</Original>
<Expanded>
{ } Equals: { 1, 2, 3 }
</Expanded>
</Expression>
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
<Original>
v, Equals( empty )
</Original>
<Expanded>
{ 1, 2, 3 } Equals: { }
</Expanded>
</Expression>
<OverallResults successes="0" failures="4" expectedFailures="0"/>
</Section>
<OverallResult success="false"/>
</TestCase>
<TestCase name="When checked exceptions are thrown they can be expected or unexpected" tags="[!throws]" filename="projects/<exe-name>/ExceptionTests.cpp" >
<Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/ExceptionTests.cpp" >
<Original>
@ -9682,7 +9842,7 @@ spanner <OverallResult success="true"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="835" failures="81" expectedFailures="18"/>
<OverallResults successes="844" failures="89" expectedFailures="18"/>
</Group>
<OverallResults successes="835" failures="80" expectedFailures="18"/>
<OverallResults successes="844" failures="88" expectedFailures="18"/>
</Catch>

View File

@ -97,3 +97,72 @@ TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[match
{
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
}
TEST_CASE( "Vector matchers", "[matchers][vector]" ) {
std::vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
v.push_back( 3 );
std::vector<int> v2;
v2.push_back( 1 );
v2.push_back( 2 );
std::vector<int> empty;
SECTION( "Contains (element)" ) {
CHECK_THAT( v, VectorContains( 1 ) );
CHECK_THAT( v, VectorContains( 2 ) );
}
SECTION( "Contains (vector)" ) {
CHECK_THAT( v, Contains( v2 ) );
v2.push_back( 3 ); // now exactly matches
CHECK_THAT( v, Contains( v2 ) );
CHECK_THAT( v, Contains( empty) );
CHECK_THAT( empty, Contains( empty) );
}
SECTION( "Equals" ) {
// Same vector
CHECK_THAT( v, Equals( v ) );
CHECK_THAT( empty, Equals( empty ) );
// Different vector with same elements
v2.push_back( 3 );
CHECK_THAT( v, Equals( v2 ) );
}
}
TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) {
std::vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
v.push_back( 3 );
std::vector<int> v2;
v2.push_back( 1 );
v2.push_back( 2 );
std::vector<int> empty;
SECTION( "Contains (element)" ) {
CHECK_THAT( v, VectorContains( -1 ) );
CHECK_THAT( empty, VectorContains( 1 ) );
}
SECTION( "Contains (vector)" ) {
CHECK_THAT( empty, Contains( v) );
v2.push_back( 4 );
CHECK_THAT( v, Contains( v2 ) );
}
SECTION( "Equals" ) {
CHECK_THAT( v, Equals( v2 ) );
CHECK_THAT( v2, Equals( v ) );
CHECK_THAT( empty, Equals( v ) );
CHECK_THAT( v, Equals( empty ) );
}
}