Reworked logging

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@254 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-03-12 09:45:45 +00:00
parent 7cd9cfc4e3
commit bc0da4c319
14 changed files with 237 additions and 170 deletions

View file

@ -184,10 +184,6 @@
RelativePath="..\..\src\libraries\turtle\expectation.hpp" RelativePath="..\..\src\libraries\turtle\expectation.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\format.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\function.hpp" RelativePath="..\..\src\libraries\turtle\function.hpp"
> >
@ -197,11 +193,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\libraries\turtle\is_formattable.hpp" RelativePath="..\..\src\libraries\turtle\is_functor.hpp"
> >
</File> </File>
<File <File
RelativePath="..\..\src\libraries\turtle\is_functor.hpp" RelativePath="..\..\src\libraries\turtle\is_loggable.hpp"
> >
</File> </File>
<File <File
@ -212,6 +208,10 @@
RelativePath="..\..\src\libraries\turtle\lambda.hpp" RelativePath="..\..\src\libraries\turtle\lambda.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\log.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\mock.hpp" RelativePath="..\..\src\libraries\turtle\mock.hpp"
> >
@ -236,10 +236,6 @@
RelativePath="..\..\src\libraries\turtle\sequence.hpp" RelativePath="..\..\src\libraries\turtle\sequence.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\sink.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\type_name.hpp" RelativePath="..\..\src\libraries\turtle\type_name.hpp"
> >

View file

@ -198,10 +198,6 @@
RelativePath="..\..\src\tests\turtle_test\error_test.cpp" RelativePath="..\..\src\tests\turtle_test\error_test.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\tests\turtle_test\format_test.cpp"
>
</File>
<File <File
RelativePath="..\..\src\tests\turtle_test\function_test.cpp" RelativePath="..\..\src\tests\turtle_test\function_test.cpp"
> >
@ -214,18 +210,22 @@
RelativePath="..\..\src\tests\turtle_test\invocation_test.cpp" RelativePath="..\..\src\tests\turtle_test\invocation_test.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\tests\turtle_test\is_formattable_test.cpp"
>
</File>
<File <File
RelativePath="..\..\src\tests\turtle_test\is_functor_test.cpp" RelativePath="..\..\src\tests\turtle_test\is_functor_test.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\tests\turtle_test\is_loggable_test.cpp"
>
</File>
<File <File
RelativePath="..\..\src\tests\turtle_test\is_serializable_test.cpp" RelativePath="..\..\src\tests\turtle_test\is_serializable_test.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\tests\turtle_test\log_test.cpp"
>
</File>
<File <File
RelativePath="..\..\src\tests\turtle_test\max_args_test.cpp" RelativePath="..\..\src\tests\turtle_test\max_args_test.cpp"
> >

View file

@ -12,7 +12,7 @@
#include "is_functor.hpp" #include "is_functor.hpp"
#include "constraints.hpp" #include "constraints.hpp"
#include "operators.hpp" #include "operators.hpp"
#include "format.hpp" #include "log.hpp"
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
@ -66,11 +66,11 @@ namespace detail
friend std::ostream& operator<<( std::ostream& s, const check_base& c ) friend std::ostream& operator<<( std::ostream& s, const check_base& c )
{ {
c.format( s ); c.log( s );
return s; return s;
} }
private: private:
virtual void format( std::ostream& ) const = 0; virtual void log( std::ostream& ) const = 0;
}; };
template< typename Actual, typename Expected, typename Enable = void > template< typename Actual, typename Expected, typename Enable = void >
@ -87,9 +87,9 @@ namespace detail
{ {
return actual == expected_; return actual == expected_;
} }
virtual void format( std::ostream& s ) const virtual void log( std::ostream& s ) const
{ {
s << mock::format( expected_ ); s << ::mock::format( expected_ );
} }
private: private:
Expected expected_; Expected expected_;
@ -110,9 +110,9 @@ namespace detail
{ {
return c_( actual ); return c_( actual );
} }
virtual void format( std::ostream& s ) const virtual void log( std::ostream& s ) const
{ {
s << mock::format( c_ ); s << ::mock::format( c_ );
} }
private: private:
Constraint c_; Constraint c_;
@ -136,9 +136,9 @@ namespace detail
{ {
return f_( actual ); return f_( actual );
} }
virtual void format( std::ostream& s ) const virtual void log( std::ostream& s ) const
{ {
s << mock::format( f_ ); s << ::mock::format( f_ );
} }
private: private:
Functor f_; Functor f_;

View file

@ -10,7 +10,7 @@
#define MOCK_CONSTRAINTS_HPP_INCLUDED #define MOCK_CONSTRAINTS_HPP_INCLUDED
#include "constraint.hpp" #include "constraint.hpp"
#include "format.hpp" #include "log.hpp"
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
@ -64,7 +64,7 @@ namespace mock
} \ } \
friend std::ostream& operator<<( std::ostream& s, const N& n ) \ friend std::ostream& operator<<( std::ostream& s, const N& n ) \
{ \ { \
return s << BOOST_STRINGIZE(N) << "( " << mock::format( n.expected_ ) << " )"; \ return s << BOOST_STRINGIZE(N) << "( " << ::mock::format( n.expected_ ) << " )"; \
} \ } \
Expected expected_; \ Expected expected_; \
}; \ }; \
@ -98,7 +98,7 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& os, const same& s ) friend std::ostream& operator<<( std::ostream& os, const same& s )
{ {
return os << "same( " << mock::format( *s.expected_ ) << " )"; return os << "same( " << ::mock::format( *s.expected_ ) << " )";
} }
const Expected* expected_; const Expected* expected_;
}; };
@ -127,7 +127,7 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const assign& a ) friend std::ostream& operator<<( std::ostream& s, const assign& a )
{ {
return s << "assign( " << mock::format( a.expected_ ) << " )"; return s << "assign( " << ::mock::format( a.expected_ ) << " )";
} }
Expected expected_; Expected expected_;
}; };
@ -156,7 +156,7 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) friend std::ostream& operator<<( std::ostream& s, const retrieve& r )
{ {
return s << "retrieve( " << mock::format( *r.expected_ ) << " )"; return s << "retrieve( " << ::mock::format( *r.expected_ ) << " )";
} }
Expected* expected_; Expected* expected_;
}; };
@ -173,7 +173,7 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const contain& n ) friend std::ostream& operator<<( std::ostream& s, const contain& n )
{ {
return s << "contain ( " << mock::format( n.expected_ ) << " )"; return s << "contain ( " << ::mock::format( n.expected_ ) << " )";
} }
Expected expected_; Expected expected_;
}; };

View file

@ -13,7 +13,7 @@
#include "error.hpp" #include "error.hpp"
#include "expectation.hpp" #include "expectation.hpp"
#include "root.hpp" #include "root.hpp"
#include "format.hpp" #include "log.hpp"
#include "args.hpp" #include "args.hpp"
#include <boost/function_types/result_type.hpp> #include <boost/function_types/result_type.hpp>
#include <boost/function_types/function_arity.hpp> #include <boost/function_types/function_arity.hpp>
@ -205,7 +205,7 @@ namespace mock
} }
#define MOCK_EXPECTATION_FORMAT(z, n, N) \ #define MOCK_EXPECTATION_FORMAT(z, n, N) \
<< " " << mock::format( p##n ) << BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",") << " " << ::mock::format( p##n ) << BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",")
#define MOCK_EXPECTATION_CALL_CONTEXT(n) \ #define MOCK_EXPECTATION_CALL_CONTEXT(n) \
boost::unit_test::lazy_ostream::instance() \ boost::unit_test::lazy_ostream::instance() \
<< lazy_context( this ) \ << lazy_context( this ) \

View file

@ -10,7 +10,6 @@
#define MOCK_IS_FORMATABLE_HPP_INCLUDED #define MOCK_IS_FORMATABLE_HPP_INCLUDED
#include "yes_no_type.hpp" #include "yes_no_type.hpp"
#include "sink.hpp"
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -22,25 +21,34 @@ namespace mock
{ {
namespace detail namespace detail
{ {
namespace formattable struct sink
{ {
template< typename S > template< typename T >
detail::yes_type format( S&, detail::sink ); sink( const T& );
};
}
template< typename S >
detail::no_type log( S&, detail::sink );
namespace detail
{
namespace loggable
{
template< typename S, typename T > template< typename S, typename T >
struct impl struct impl
{ {
static S* s; static S* s;
static T* t; static T* t;
// if an error is generated by the line below it means T has more than // if an error is generated by the line below it means T has more than
// one conversion to other types which are formattable : the easiest // one conversion to other types which are loggable : the easiest
// solution would be to add a format function for T as well. // solution would be to add a mock::log function for T as well.
enum { value = sizeof( yes_type(), format( *s, *t ), yes_type() ) == sizeof( yes_type ) }; enum { value = sizeof( yes_type(), ::mock::log( *s, *t ), yes_type() ) == sizeof( yes_type ) };
}; };
} }
template< typename S, typename T > template< typename S, typename T >
struct is_formattable struct is_loggable
: boost::mpl::bool_< formattable::impl< S, T >::value > : boost::mpl::bool_< loggable::impl< S, T >::value >
{}; {};
} }
} }

View file

@ -24,7 +24,7 @@ namespace detail
namespace serializable namespace serializable
{ {
template< typename S, typename T > template< typename S, typename T >
yes_type operator<<( S&, const T& ); no_type operator<<( S&, const T& );
template< typename S, typename T > template< typename S, typename T >
struct impl struct impl

View file

@ -10,7 +10,7 @@
#define MOCK_FORMAT_HPP_INCLUDED #define MOCK_FORMAT_HPP_INCLUDED
#include "is_serializable.hpp" #include "is_serializable.hpp"
#include "is_formattable.hpp" #include "is_loggable.hpp"
#include <boost/function_types/is_callable_builtin.hpp> #include <boost/function_types/is_callable_builtin.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
@ -28,17 +28,17 @@ namespace detail
template< typename T > template< typename T >
void serialize( std::ostream& s, const T& t, void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if< BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T > BOOST_DEDUCED_TYPENAME detail::is_loggable< std::ostream, T >
>::type* = 0 ) >::type* = 0 )
{ {
format( s, t ); ::mock::log( s, t );
} }
template< typename T > template< typename T >
void serialize( std::ostream& s, const T& t, void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if< BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::mpl::and_< boost::mpl::and_<
boost::mpl::not_< boost::mpl::not_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T > BOOST_DEDUCED_TYPENAME detail::is_loggable< std::ostream, T >
>, >,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T > BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
> >
@ -50,7 +50,7 @@ namespace detail
void serialize( std::ostream& s, const T&, void serialize( std::ostream& s, const T&,
BOOST_DEDUCED_TYPENAME boost::disable_if< BOOST_DEDUCED_TYPENAME boost::disable_if<
boost::mpl::or_< boost::mpl::or_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >, BOOST_DEDUCED_TYPENAME detail::is_loggable< std::ostream, T >,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T > BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
> >
>::type* = 0 ) >::type* = 0 )
@ -82,7 +82,7 @@ namespace detail
template< typename T > template< typename T >
std::ostream& operator<<( std::ostream& s, protect< T > t ) std::ostream& operator<<( std::ostream& s, protect< T > t )
{ {
format( s, t ); ::mock::log( s, t );
return s; return s;
} }
@ -93,36 +93,33 @@ namespace detail
} }
template< typename T > template< typename T >
void format( std::ostream& s, protect< T > t, void log( std::ostream& s, protect< T > t )
BOOST_DEDUCED_TYPENAME boost::disable_if<
detail::is_container< T >
>::type* = 0 )
{ {
detail::serialize( s, *t ); detail::serialize( s, *t );
} }
inline void format( std::ostream& s, protect< bool > b ) inline void log( std::ostream& s, protect< bool > b )
{ {
s << std::boolalpha << *b; s << std::boolalpha << *b;
} }
inline void format( std::ostream& s, protect< std::string > str ) inline void log( std::ostream& s, protect< std::string > str )
{ {
s << '"' << *str << '"'; s << '"' << *str << '"';
} }
inline void format( std::ostream& s, protect< const char* > str ) inline void log( std::ostream& s, protect< const char* > str )
{ {
s << '"' << *str << '"'; s << '"' << *str << '"';
} }
template< typename T1, typename T2 > template< typename T1, typename T2 >
void format( std::ostream& s, protect< std::pair< T1, T2 > > p ) void log( std::ostream& s, const std::pair< T1, T2 >& p )
{ {
s << '(' << mock::format( p->first ) s << '(' << ::mock::format( p.first )
<< ',' << mock::format( p->second ) << ')'; << ',' << ::mock::format( p.second ) << ')';
} }
template< typename T > template< typename T >
void format( std::ostream& s, protect< T* >, void log( std::ostream& s, protect< T* >,
BOOST_DEDUCED_TYPENAME boost::enable_if< BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::function_types::is_callable_builtin< T* > boost::function_types::is_callable_builtin< T* >
>::type* = 0 ) >::type* = 0 )
@ -131,22 +128,22 @@ namespace detail
} }
template< typename T > template< typename T >
void format( std::ostream& s, protect< T > c, void log( std::ostream& s, T t,
BOOST_DEDUCED_TYPENAME boost::enable_if< BOOST_DEDUCED_TYPENAME boost::enable_if<
detail::is_container< T > detail::is_container< T >
>::type* = 0 ) >::type* = 0 )
{ {
s << '('; s << '(';
// if an error is generated by the line below it means T is // if an error is generated by the line below it means T is
// being mistaken for a container because it has a typedef // being mistaken for a container because it has an inner type
// const_iterator : the solution would be to add a format override // const_iterator : the solution would be to add a mock::log
// for mock::protect< T >. // override for T.
for( BOOST_DEDUCED_TYPENAME T::const_iterator it = c->begin(); for( BOOST_DEDUCED_TYPENAME T::const_iterator it = t.begin();
it != c->end(); ++it ) it != t.end(); ++it )
{ {
if( it != c->begin() ) if( it != t.begin() )
s << ','; s << ',';
s << mock::format( *it ); s << ::mock::format( *it );
} }
s << ')'; s << ')';
} }

View file

@ -10,7 +10,7 @@
#define MOCK_OPERATORS_HPP_INCLUDED #define MOCK_OPERATORS_HPP_INCLUDED
#include "constraint.hpp" #include "constraint.hpp"
#include "format.hpp" #include "log.hpp"
namespace mock namespace mock
{ {
@ -31,8 +31,8 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const and_& a ) friend std::ostream& operator<<( std::ostream& s, const and_& a )
{ {
return s << "( " << mock::format( a.c1_ ) return s << "( " << ::mock::format( a.c1_ )
<< " && " << mock::format( a.c2_ ) << " )"; << " && " << ::mock::format( a.c2_ ) << " )";
} }
private: private:
Constraint1 c1_; Constraint1 c1_;
@ -54,8 +54,8 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const or_& o ) friend std::ostream& operator<<( std::ostream& s, const or_& o )
{ {
return s << "( " << mock::format( o.c1_ ) return s << "( " << ::mock::format( o.c1_ )
<< " || " << mock::format( o.c2_ )<< " )"; << " || " << ::mock::format( o.c2_ )<< " )";
} }
private: private:
Constraint1 c1_; Constraint1 c1_;
@ -76,7 +76,7 @@ namespace detail
} }
friend std::ostream& operator<<( std::ostream& s, const not_& n ) friend std::ostream& operator<<( std::ostream& s, const not_& n )
{ {
return s << "! " << mock::format( n.f_ ); return s << "! " << ::mock::format( n.f_ );
} }
private: private:
Constraint f_; Constraint f_;

View file

@ -1,24 +0,0 @@
//
// Copyright Mathieu Champlon 2011
//
// 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 MOCK_ANY_HPP_INCLUDED
#define MOCK_ANY_HPP_INCLUDED
namespace mock
{
namespace detail
{
struct sink
{
template< typename T >
sink( const T& );
};
}
}
#endif // #ifndef MOCK_ANY_HPP_INCLUDED

View file

@ -23,7 +23,7 @@ namespace detail
BOOST_STATIC_ASSERT( sizeof( yes_type ) != sizeof( no_type ) ); BOOST_STATIC_ASSERT( sizeof( yes_type ) != sizeof( no_type ) );
template< typename T > void operator,( yes_type, const T& ); template< typename T > void operator,( yes_type, const T& );
no_type operator,( yes_type, yes_type ); no_type operator,( yes_type, no_type );
no_type operator,( no_type, yes_type ); no_type operator,( no_type, yes_type );
} }
} }

View file

@ -1,49 +0,0 @@
//
// Copyright Mathieu Champlon 2011
//
// 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)
//
#include <turtle/is_formattable.hpp>
#include <boost/test/auto_unit_test.hpp>
#define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp>
BOOST_MPL_ASSERT_NOT(( mock::detail::is_formattable< std::ostream, int > ));
namespace
{
struct non_formattable {};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_formattable< std::ostream, non_formattable > ));
namespace
{
struct formattable {};
void format( std::ostream&, const formattable& );
}
BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, formattable > ));
namespace
{
struct derived_from_formattable : formattable
{};
}
BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, derived_from_formattable > ));
namespace
{
struct convertible_to_formattable
{
operator formattable() const;
};
}
BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, convertible_to_formattable > ));

View file

@ -0,0 +1,54 @@
//
// Copyright Mathieu Champlon 2011
//
// 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)
//
#include <turtle/is_loggable.hpp>
#include <boost/test/auto_unit_test.hpp>
#define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp>
BOOST_MPL_ASSERT_NOT(( mock::detail::is_loggable< std::ostream, int > ));
namespace
{
struct non_loggable {};
void log( std::ostream&, const non_loggable& );
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_loggable< std::ostream, non_loggable > ));
namespace
{
struct loggable {};
}
namespace mock
{
void log( std::ostream&, const loggable& );
}
BOOST_MPL_ASSERT(( mock::detail::is_loggable< std::ostream, loggable > ));
namespace
{
struct derived_from_loggable : loggable
{};
}
BOOST_MPL_ASSERT(( mock::detail::is_loggable< std::ostream, derived_from_loggable > ));
namespace
{
struct convertible_to_loggable
{
operator loggable() const;
};
}
BOOST_MPL_ASSERT(( mock::detail::is_loggable< std::ostream, convertible_to_loggable > ));

View file

@ -6,7 +6,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
#include <turtle/format.hpp> #include <turtle/log.hpp>
#include <boost/assign.hpp> #include <boost/assign.hpp>
#include <vector> #include <vector>
#include <deque> #include <deque>
@ -24,7 +24,7 @@ namespace
std::string to_string( T t ) std::string to_string( T t )
{ {
std::stringstream s; std::stringstream s;
s << mock::format( t ); s << ::mock::format( t );
return s.str(); return s.str();
} }
} }
@ -33,6 +33,15 @@ namespace
{ {
struct non_serializable struct non_serializable
{}; {};
void log( std::ostream&, const non_serializable& )
{
BOOST_FAIL( "should not be called" );
}
void log( std::ostream&, mock::protect< non_serializable > )
{
BOOST_FAIL( "should not be called" );
}
} }
BOOST_AUTO_TEST_CASE( non_serializable_type_yields_an_interrogation_mark_when_serialized ) BOOST_AUTO_TEST_CASE( non_serializable_type_yields_an_interrogation_mark_when_serialized )
@ -58,54 +67,57 @@ BOOST_AUTO_TEST_CASE( serializable_type_yields_its_value_when_serialized )
namespace namespace
{ {
struct formattable {}; struct loggable {};
std::ostream& operator<<( std::ostream& s, const formattable& ) std::ostream& operator<<( std::ostream& s, const loggable& )
{ {
BOOST_FAIL( "should not be called" ); BOOST_FAIL( "should not be called" );
return s; return s;
} }
} }
BOOST_AUTO_TEST_CASE( format_overrides_standard_stream_serialization_even_if_defined_after_being_used ) BOOST_AUTO_TEST_CASE( mock_log_overrides_standard_stream_serialization_even_if_defined_after_being_used )
{ {
BOOST_CHECK_EQUAL( "formattable", to_string( formattable() ) ); BOOST_CHECK_EQUAL( "loggable", to_string( loggable() ) );
} }
namespace namespace mock
{ {
void format( std::ostream& s, const formattable& ) void log( std::ostream& s, const loggable& )
{ {
s << "formattable"; s << "loggable";
} }
} }
namespace namespace
{ {
struct protected_formattable {}; struct protected_loggable {};
std::ostream& operator<<( std::ostream& s, const protected_formattable& ) std::ostream& operator<<( std::ostream& s, const protected_loggable& )
{ {
BOOST_FAIL( "should not be called" ); BOOST_FAIL( "should not be called" );
return s; return s;
} }
}
void format( std::ostream&, const protected_formattable& ) namespace mock
{
void log( std::ostream&, const protected_loggable& )
{ {
BOOST_FAIL( "should not be called" ); BOOST_FAIL( "should not be called" );
} }
} }
BOOST_AUTO_TEST_CASE( protected_format_overrides_standard_stream_serialization_and_format_even_if_defined_after_being_used ) BOOST_AUTO_TEST_CASE( protected_mock_log_overrides_standard_stream_serialization_and_mock_log_even_if_defined_after_being_used )
{ {
BOOST_CHECK_EQUAL( "protected_formattable", to_string( protected_formattable() ) ); BOOST_CHECK_EQUAL( "protected_loggable", to_string( protected_loggable() ) );
} }
namespace namespace mock
{ {
void format( std::ostream& s, mock::protect< protected_formattable > ) void log( std::ostream& s, mock::protect< protected_loggable > )
{ {
s << "protected_formattable"; s << "protected_loggable";
} }
} }
@ -197,6 +209,18 @@ BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized )
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( boost::assign::map_list_of( 12, "12" )( 42, "42" ) ) ); BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( boost::assign::map_list_of( 12, "12" )( 42, "42" ) ) );
} }
namespace
{
void callable_builtin()
{}
}
BOOST_AUTO_TEST_CASE( callable_builtin_cannot_be_serialized )
{
BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) );
BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) );
}
namespace namespace
{ {
struct false_positive_container struct false_positive_container
@ -204,14 +228,75 @@ namespace
typedef int const_iterator; typedef int const_iterator;
}; };
BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > )); BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > ));
}
void format( std::ostream& s, mock::protect< false_positive_container > ) namespace mock
{
void log( std::ostream& s, false_positive_container )
{ {
s << "false_positive_container"; s << "false_positive_container";
} }
} }
BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden ) BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_be_overriden )
{ {
BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) ); BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) );
} }
namespace
{
template< typename T >
struct template_type
{};
}
namespace mock
{
template< typename T >
void log( std::ostream& s, template_type< T > )
{
s << "template_type";
}
}
BOOST_AUTO_TEST_CASE( template_type_serialization_can_be_overriden )
{
BOOST_CHECK_EQUAL( "template_type", to_string( template_type< int >() ) );
}
namespace mock
{
void log( std::ostream& s, const std::vector< float >& )
{
s << "vector< float >";
}
}
BOOST_AUTO_TEST_CASE( vector_of_floats_serialization_can_be_overriden )
{
BOOST_CHECK_EQUAL( "vector< float >", to_string( std::vector< float >() ) );
}
namespace
{
struct convertible_to_many
{
operator bool() const;
operator std::string() const;
operator const char*() const;
operator std::pair< int, int >() const;
template< typename T1, typename T2 > operator std::pair< T1, T2 >() const;
typedef void (*pf)();
operator pf() const;
operator std::set< int >() const;
template< typename T > operator std::set< T >() const;
};
}
BOOST_AUTO_TEST_CASE( build_in_log_customizations_do_not_yield_ambiguous_errors )
{
BOOST_CHECK_EQUAL( "?", to_string( convertible_to_many() ) );
}