Skip to content

Commit

Permalink
update r708
Browse files Browse the repository at this point in the history
  • Loading branch information
srz-zumix committed Sep 30, 2014
1 parent 4a8466b commit ccf9df6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 34 deletions.
2 changes: 1 addition & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Changes for 1.11.0:
* Matcher に StrEq,StrNe,StrCaseEq,StrCaseNe,HasSubstr を追加
* Matcher に FloatEq,DoubleEq,NanSensitiveFloatEq,NanSensitiveDoubleEq を追加
* コンテナMatcher に Each,ElementsAre,ElementsAreArray を追加
* メンバーMatcher に Pair を追加
* メンバーMatcher に Pair,Field を追加

** 修正
* IUTEST_*_FLOAT_EQ,DOUBLE_EQ で NAN の比較が真を返す不具合を修正
Expand Down
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PROJECT_NAME = iutest
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = 1.10.99.12
PROJECT_NUMBER = 1.10.99.13

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
104 changes: 75 additions & 29 deletions include/iutest_matcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ inline ::std::string MatcherAssertionFailureMessage(const char* actual, const ch
*/
class IMatcher
{
protected:
public:
template<typename T>
struct is_matcher : public iutest_type_traits::is_base_of<IMatcher, T> {};
public:
Expand Down Expand Up @@ -449,6 +449,24 @@ class EqMatcher : public IMatcher
const T& m_expected;
};

/**
* @brief Cast to matcher
*/
template<typename T>
const T& CastToMatcher(const T& matcher
, typename detail::enable_if_t< IMatcher::is_matcher<T> >::type*& = detail::enabler::value)
{
return matcher;
}
/** @overload */
template<typename T>
EqMatcher<T> CastToMatcher(const T& value
, typename detail::disable_if_t< IMatcher::is_matcher<T> >::type*& = detail::enabler::value)
{
return EqMatcher<T>(value);
}


/**
* @brief Contains matcher
*/
Expand Down Expand Up @@ -573,26 +591,18 @@ class EachMatcher : public IMatcher
#endif

template<typename TT, typename Ite>
static bool EachContainer(Ite begin, Ite end, const TT& expected
, typename detail::enable_if_t< is_matcher<TT> >::type*& = detail::enabler::value)
static bool EachContainer(Ite begin, Ite end, const TT& expected)
{
for( Ite it = begin; it != end; ++it )
{
if( !expected(*it) )
if( !CastToMatcher(expected)(*it) )
{
return false;
}
}
return true;
}

template<typename TT, typename Ite>
static bool EachContainer(Ite begin, Ite end, const TT& expected
, typename detail::disable_if_t< is_matcher<TT> >::type*& = detail::enabler::value)
{
return EachContainer(begin, end, EqMatcher<TT>(expected));
}

private:
IUTEST_PP_DISALLOW_ASSIGN(EachMatcher);

Expand Down Expand Up @@ -692,16 +702,9 @@ class ElementsAreMatcherBase : public IMatcher
}
private:
template<typename T, typename U>
static AssertionResult CallMatcher(const T& actual, const U& expected
, typename detail::enable_if_t< is_matcher<U> >::type*& = detail::enabler::value)
{
return expected(actual);
}
template<typename T, typename U>
static AssertionResult CallMatcher(const T& actual, const U& expected
, typename detail::disable_if_t< is_matcher<U> >::type*& = detail::enabler::value)
static AssertionResult CallMatcher(const T& actual, const U& expected)
{
return EqMatcher<T>(expected)(actual);
return CastToMatcher(expected)(actual);
}

template<typename T, typename U, int N, int LAST>
Expand Down Expand Up @@ -828,6 +831,50 @@ IIUT_DECL_ELEMENTSARE_MATCHER(10);

#endif

/**
* @brief Field matcher
*/
template<typename F, typename T>
class FieldMatcher : public IMatcher
{
public:
FieldMatcher(const F& field, const T& expected) : m_field(field), m_expected(expected) {}

public:
template<typename U>
AssertionResult operator ()(const U& actual) const
{
if( Check(actual) ) return AssertionSuccess();
return AssertionFailure() << WitchIs();
}

public:
::std::string WitchIs(void) const IUTEST_CXX_OVERRIDE
{
iu_global_format_stringstream strm;
strm << "Field: " << m_expected;
//strm << "Field: (" << detail::GetTypeName<F>() << ") " << m_expected;
return strm.str();
}
private:
template<typename U>
bool Check(const U& actual
, typename detail::disable_if_t< detail::is_pointer<U> >::type*& = detail::enabler::value) const
{
return static_cast<bool>(CastToMatcher(m_expected)(actual.*m_field));
}
template<typename U>
bool Check(const U& actual
, typename detail::enable_if_t< detail::is_pointer<U> >::type*& = detail::enabler::value) const
{
return static_cast<bool>(CastToMatcher(m_expected)(actual->*m_field));
}
private:
IUTEST_PP_DISALLOW_ASSIGN(FieldMatcher);

const F& m_field;
const T& m_expected;
};

/**
* @brief Pair matcher
Expand Down Expand Up @@ -862,16 +909,9 @@ class PairMatcher : public IMatcher
}
private:
template<typename T, typename U>
static bool CheckElem(const T& actual, const U& matcher
, typename detail::enable_if_t< is_matcher<U> >::type*& = detail::enabler::value)
{
return static_cast<bool>(matcher(actual));
}
template<typename T, typename U>
static bool CheckElem(const T& actual, const U& matcher
, typename detail::disable_if_t< is_matcher<U> >::type*& = detail::enabler::value)
static bool CheckElem(const T& actual, const U& matcher)
{
return CheckElem(actual, EqMatcher<U>(matcher));
return static_cast<bool>(CastToMatcher(matcher)(actual));
}

private:
Expand Down Expand Up @@ -1330,6 +1370,12 @@ IIUT_DECL_ELEMENTSARE(10)
template<typename T1, typename T2>
detail::PairMatcher<T1, T2> Pair(const T1& m1, const T2& m2) { return detail::PairMatcher<T1, T2>(m1, m2); }

/**
* @brief Make Field matcher
*/
template<typename F, typename T>
detail::FieldMatcher<F, T> Field(const F& field, const T& expected) { return detail::FieldMatcher<F, T>(field, expected); }


#if IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF

Expand Down
6 changes: 3 additions & 3 deletions include/iutest_ver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@

//======================================================================
// define
#define IUTEST_VER 0x01109912u //!< iutest version 1.10.99.12
#define IUTEST_VER 0x01109913u //!< iutest version 1.10.99.13
#define IUTEST_MAJORVER 0x01u //!< Major Version
#define IUTEST_MINORVER 0x10u //!< Minor Version
#define IUTEST_BUILD 0x99u //!< Build
#define IUTEST_REVISION 0x12u //!< Revision
#define IUTEST_REVISION 0x13u //!< Revision

/**
* @mainpage
Expand Down Expand Up @@ -122,7 +122,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<li>Matcher に FloatEq,DoubleEq,NanSensitiveFloatEq,NanSensitiveDoubleEq を追加</li>
<li>コンテナMatcher に Each,ElementsAre,ElementsAreArray を追加</li>
<li>コンテナMatcher の条件に Matcher を使えるように修正</li>
<li>メンバーMatcher に Pair を追加</li>
<li>メンバーMatcher に Pair,Field を追加</li>
<li>IUTEST_*_FLOAT_EQ,DOUBLE_EQ で NAN の比較が真を返す不具合を修正</li>
</ul>
</li>
Expand Down
18 changes: 18 additions & 0 deletions test/iutest_matcher_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ void* p1 = NULL;
void* p2 = &p1;
float f0 = 0.0f;
double d0 = 0.0;
struct X { int a, b; X(int _a, int _b) : a(_a), b(_b) {} int GetA() { return a; } };
X x(1,1);
::std::map<int, X> mx;

}

Expand Down Expand Up @@ -196,6 +199,14 @@ IUTEST(Matcher, Pair)
IUTEST_EXPECT_THAT( m, ::iutest::Each(::iutest::Pair(::iutest::Le(10), 100)));
}

IUTEST(Matcher, Field)
{
IUTEST_EXPECT_THAT( x, ::iutest::Field(&X::a, 1));
IUTEST_EXPECT_THAT(&x, ::iutest::Field(&X::a, 1));
IUTEST_EXPECT_THAT(mx, ::iutest::Each(
::iutest::Pair(::iutest::Le(10), ::iutest::Field(&X::b, ::iutest::Ge(0))) ));
}

IUTEST(Matcher, ElementsAreArray)
{
IUTEST_EXPECT_THAT( a, ::iutest::ElementsAreArray(va));
Expand Down Expand Up @@ -341,6 +352,12 @@ IUTEST(MatcherFailure, Pair)
IUTEST_EXPECT_FATAL_FAILURE( IUTEST_ASSERT_THAT( m, ::iutest::Each(::iutest::Pair(::iutest::Gt(5), 100))), "Each: Pair: (Gt: 5, 100)" );
}

IUTEST(MatcherFailure, Field)
{
IUTEST_EXPECT_FATAL_FAILURE( IUTEST_ASSERT_THAT( x, ::iutest::Field(&X::a, 100)), "Field: 100" );
IUTEST_EXPECT_FATAL_FAILURE( IUTEST_ASSERT_THAT( x, ::iutest::Field(&X::a, ::iutest::Ne(1))), "Field: Ne: 1" );
}

IUTEST(MatcherFailure, ElementsAreArray)
{
IUTEST_EXPECT_FATAL_FAILURE( IUTEST_ASSERT_THAT(b, ::iutest::ElementsAreArray(c)), "ElementsAreArray: " );
Expand Down Expand Up @@ -436,6 +453,7 @@ int main(int argc, char* argv[])
for( int i=0; i < 10; ++i ) va.push_back(i);
for( int i=0; i < 10; ++i ) vv.push_back(va);
for( int i=0; i < 10; ++i ) m.insert( ::std::pair<int,int>(i, 100) );
for( int i=0; i < 10; ++i ) mx.insert( ::std::pair<int,X>(i, X(i, i)) );
#endif

IUTEST_INIT(&argc, argv);
Expand Down

0 comments on commit ccf9df6

Please sign in to comment.