Reworked logging (again)

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@262 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-03-18 21:33:50 +00:00
parent 1f0b12e990
commit fc53abcea0
19 changed files with 1255 additions and 660 deletions

View file

@ -12,7 +12,7 @@
#include "is_functor.hpp"
#include "constraints.hpp"
#include "operators.hpp"
#include "format.hpp"
#include "log.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/concept_check.hpp>

View file

@ -10,7 +10,7 @@
#define MOCK_CONSTRAINTS_HPP_INCLUDED
#include "constraint.hpp"
#include "format.hpp"
#include "log.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/preprocessor/stringize.hpp>

View file

@ -1,155 +0,0 @@
//
// Copyright Mathieu Champlon 2008
//
// 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_FORMAT_HPP_INCLUDED
#define MOCK_FORMAT_HPP_INCLUDED
#include "is_serializable.hpp"
#include "is_formattable.hpp"
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <utility>
#include <ostream>
#include <string>
namespace mock
{
namespace detail
{
template< typename T >
void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >
>::type* = 0 )
{
format( s, t );
}
template< typename T >
void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::mpl::and_<
boost::mpl::not_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >
>,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
>
>::type* = 0 )
{
s << t;
}
template< typename T >
void serialize( std::ostream& s, const T&,
BOOST_DEDUCED_TYPENAME boost::disable_if<
boost::mpl::or_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
>
>::type* = 0 )
{
s << '?';
}
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(is_container, const_iterator, false)
}
template< typename T >
class protect
{
public:
explicit protect( const T& t )
: t_( &t )
{}
const T& operator*() const
{
return *t_;
}
const T* operator->() const
{
return t_;
}
private:
const T* t_;
};
template< typename T >
std::ostream& operator<<( std::ostream& s, protect< T > t )
{
format( s, t );
return s;
}
template< typename T >
protect< T > format( const T& t )
{
return protect< T >( t );
}
template< typename T >
void format( std::ostream& s, protect< T > t,
BOOST_DEDUCED_TYPENAME boost::disable_if<
detail::is_container< T >
>::type* = 0 )
{
detail::serialize( s, *t );
}
inline void format( std::ostream& s, protect< bool > b )
{
s << std::boolalpha << *b;
}
inline void format( std::ostream& s, protect< std::string > str )
{
s << '"' << *str << '"';
}
inline void format( std::ostream& s, protect< const char* > str )
{
s << '"' << *str << '"';
}
template< typename T1, typename T2 >
void format( std::ostream& s, protect< std::pair< T1, T2 > > p )
{
s << '(' << mock::format( p->first )
<< ',' << mock::format( p->second ) << ')';
}
template< typename T >
void format( std::ostream& s, protect< T* >,
BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::function_types::is_callable_builtin< T* >
>::type* = 0 )
{
s << '?';
}
template< typename T >
void format( std::ostream& s, protect< T > c,
BOOST_DEDUCED_TYPENAME boost::enable_if<
detail::is_container< T >
>::type* = 0 )
{
s << '(';
// if an error is generated by the line below it means T is
// being mistaken for a container because it has a typedef
// const_iterator : the solution would be to add a format override
// for mock::protect< T >.
for( BOOST_DEDUCED_TYPENAME T::const_iterator it = c->begin();
it != c->end(); ++it )
{
if( it != c->begin() )
s << ',';
s << mock::format( *it );
}
s << ')';
}
}
#endif // #ifndef MOCK_FORMAT_HPP_INCLUDED

View file

@ -13,7 +13,7 @@
#include "error.hpp"
#include "expectation.hpp"
#include "root.hpp"
#include "format.hpp"
#include "log.hpp"
#include "args.hpp"
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/function_arity.hpp>

View file

@ -0,0 +1,26 @@
//
// 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_IS_CONTAINER_HPP_INCLUDED
#define MOCK_IS_CONTAINER_HPP_INCLUDED
#include <boost/mpl/has_xxx.hpp>
namespace mock
{
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF( const_iterator )
template< typename T >
struct is_container : has_const_iterator< T >
{};
}
}
#endif // #ifndef MOCK_IS_CONTAINER_HPP_INCLUDED

View file

@ -1,52 +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_IS_FORMATABLE_HPP_INCLUDED
#define MOCK_IS_FORMATABLE_HPP_INCLUDED
#include "yes_no_type.hpp"
#include "sink.hpp"
#include <boost/mpl/bool.hpp>
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable: 4913 )
#endif
namespace mock
{
namespace detail
{
namespace formattable
{
template< typename S >
detail::yes_type format( S&, detail::sink );
template< typename S, typename T >
struct impl
{
static S* s;
static T* t;
// 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
// solution would be to add a format function for T as well.
enum { value = sizeof( yes_type(), format( *s, *t ), yes_type() ) == sizeof( yes_type ) };
};
}
template< typename S, typename T >
struct is_formattable
: boost::mpl::bool_< formattable::impl< S, T >::value >
{};
}
}
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#endif // #ifndef MOCK_IS_FORMATABLE_HPP_INCLUDED

View file

@ -1,47 +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_IS_SERIALIZABLE_HPP_INCLUDED
#define MOCK_IS_SERIALIZABLE_HPP_INCLUDED
#include "yes_no_type.hpp"
#include <boost/mpl/bool.hpp>
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable: 4913 )
#endif
namespace mock
{
namespace detail
{
namespace serializable
{
template< typename S, typename T >
yes_type operator<<( S&, const T& );
template< typename S, typename T >
struct impl
{
static S* s;
static T* t;
enum { value = sizeof( yes_type(), (*s << *t), yes_type() ) == sizeof( yes_type ) };
};
}
template< typename S, typename T >
struct is_serializable : boost::mpl::bool_< serializable::impl< S, T >::value >
{};
}
}
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#endif // #ifndef MOCK_IS_SERIALIZABLE_HPP_INCLUDED

View file

@ -0,0 +1,245 @@
//
// 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_LOG_HPP_INCLUDED
#define MOCK_LOG_HPP_INCLUDED
#include "is_container.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#include <iostream>
#include <string>
namespace mock
{
struct stream
{
explicit stream( std::ostream& s )
: s_( &s )
{}
std::ostream* s_;
};
namespace detail3
{
template< typename T >
struct serializer
{
explicit serializer( const T& t )
: t_( &t )
{}
void serialize( stream& s ) const
{
// if it fails here because ambiguous stuff
// -> add operator<< to mock::stream for T
s << *t_;
}
const T* t_;
};
template<>
struct serializer< bool >
{
explicit serializer( bool b )
: b_( b )
{}
void serialize( stream& s ) const
{
*s.s_ << std::boolalpha << b_;
}
bool b_;
};
template<>
struct serializer< const char* >
{
explicit serializer( const char* s )
: s_( s )
{}
void serialize( stream& s ) const
{
*s.s_ << '"' << s_ << '"';
}
const char* s_;
};
template<>
struct serializer< std::string >
{
explicit serializer( const std::string& s )
: s_( &s )
{}
void serialize( stream& s ) const
{
*s.s_ << '"' << *s_ << '"';
}
const std::string* s_;
};
template< typename T >
stream& operator<<( stream& s, const serializer< T >& ser )
{
ser.serialize( s );
return s;
}
template< typename T >
std::ostream& operator<<( std::ostream& s, const serializer< T >& ser )
{
stream ss( s );
ser.serialize( ss );
return s;
}
}
template< typename T >
detail3::serializer< T > format( const T& t )
{
return detail3::serializer< T >( t );
}
inline detail3::serializer< const char* > format( const char* s )
{
return detail3::serializer< const char* >( s );
}
#ifdef MOCK_LOG_CONVERSIONS
namespace detail
{
struct sink
{
template< typename T >
sink( const T&, BOOST_DEDUCED_TYPENAME boost::disable_if<
boost::is_fundamental< T > >::type* = 0 )
{}
};
std::ostream& operator<<( std::ostream& s, const detail::sink& )
{
return s << "?";
}
struct holder
{
virtual ~holder()
{}
virtual void serialize( std::ostream& s ) const = 0;
};
template< typename T >
struct holder_imp : holder
{
explicit holder_imp( const T& t )
: t_( &t )
{}
virtual void serialize( std::ostream& s ) const
{
// if it fails here because ambiguous stuff
// -> add operator<< to mock::stream for T
s << *t_;
}
const T* t_;
};
struct any
{
template< typename T >
any( const T& t )
: h_( new holder_imp< T >( t ) )
{}
~any()
{
delete h_;
}
holder* h_;
};
}
stream& operator<<( stream& s, const detail::any& d )
{
d.h_->serialize( *s.s_ );
return s;
}
#else // MOCK_LOG_CONVERSIONS
namespace detail
{
template< typename S, typename T >
S& operator<<( S &s, const T& )
{
return s << "?";
}
}
template< typename T >
void serialize( std::ostream& s, const T& t )
{
using namespace detail;
s << t;
}
namespace detail2
{
template< typename S, typename T >
S& operator<<( S& s, const T& t )
{
serialize( s, t );
return s;
}
}
template< typename T >
BOOST_DEDUCED_TYPENAME boost::disable_if<
detail::is_container< T >, stream&
>::type
operator<<( stream& s, const T& t )
{
using namespace detail2;
*s.s_ << t;
return s;
}
#endif // MOCK_LOG_CONVERSIONS
template< typename T1, typename T2 >
stream& operator<<( stream& s, const std::pair< T1, T2 >& p )
{
return s << '(' << mock::format( p.first )
<< ',' << mock::format( p.second ) << ')';
}
template< typename Container >
BOOST_DEDUCED_TYPENAME boost::enable_if<
detail::is_container< Container >, stream&
>::type
operator<<( stream& s, const Container& c )
{
s << '(';
// if an error is generated by the line below it means Container is
// being mismatched for a container because it has a typedef
// const_iterator : the easiest solution would be to add a format
// function for Container as well.
for( BOOST_DEDUCED_TYPENAME Container::const_iterator it = c.begin();
it != c.end(); ++it )
{
if( it != c.begin() )
s << ',';
s << mock::format( *it );
}
return s << ')';
}
template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::function_types::is_callable_builtin< T >, stream&
>::type
operator<<( stream& s, const T* )
{
return s << '?';
}
}
#endif // #ifndef MOCK_LOG_HPP_INCLUDED

View file

@ -10,7 +10,7 @@
#define MOCK_OPERATORS_HPP_INCLUDED
#include "constraint.hpp"
#include "format.hpp"
#include "log.hpp"
namespace mock
{

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

@ -10,13 +10,13 @@
namespace
{
MOCK_CLASS( mocked )
MOCK_CLASS( cl )
{
MOCK_METHOD_EXT( method, 0, int(), method ) // add another test with void() and another with std::string()
MOCK_METHOD_EXT( m, 0, int(), m ) // add another test with void() and another with std::string()
};
void test_case()
{
mocked m;
MOCK_EXPECT( m, method ).returns( "42" );
cl c;
MOCK_EXPECT( c, m ).returns( "42" );
}
}

View file

@ -1,217 +0,0 @@
//
// Copyright Mathieu Champlon 2008
//
// 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/format.hpp>
#include <boost/assign.hpp>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <boost/test/auto_unit_test.hpp>
#define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp>
namespace
{
template< typename T >
std::string to_string( T t )
{
std::stringstream s;
s << mock::format( t );
return s.str();
}
}
namespace
{
struct non_serializable
{};
}
BOOST_AUTO_TEST_CASE( non_serializable_type_yields_an_interrogation_mark_when_serialized )
{
BOOST_CHECK_EQUAL( "?", to_string( non_serializable() ) );
}
namespace
{
struct serializable
{};
std::ostream& operator<<( std::ostream& s, const serializable& )
{
return s << "serializable";
}
}
BOOST_AUTO_TEST_CASE( serializable_type_yields_its_value_when_serialized )
{
BOOST_CHECK_EQUAL( "serializable", to_string( serializable() ) );
}
namespace
{
struct formattable {};
std::ostream& operator<<( std::ostream& s, const formattable& )
{
BOOST_FAIL( "should not be called" );
return s;
}
}
BOOST_AUTO_TEST_CASE( format_overrides_standard_stream_serialization_even_if_defined_after_being_used )
{
BOOST_CHECK_EQUAL( "formattable", to_string( formattable() ) );
}
namespace
{
void format( std::ostream& s, const formattable& )
{
s << "formattable";
}
}
namespace
{
struct protected_formattable {};
std::ostream& operator<<( std::ostream& s, const protected_formattable& )
{
BOOST_FAIL( "should not be called" );
return s;
}
void format( std::ostream&, const protected_formattable& )
{
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_CHECK_EQUAL( "protected_formattable", to_string( protected_formattable() ) );
}
namespace
{
void format( std::ostream& s, mock::protect< protected_formattable > )
{
s << "protected_formattable";
}
}
BOOST_AUTO_TEST_CASE( base_type_yields_its_value_when_serialized )
{
BOOST_CHECK_EQUAL( "42", to_string( 42 ) );
}
BOOST_AUTO_TEST_CASE( booleans_are_serialized_as_bool_alpha )
{
BOOST_CHECK_EQUAL( "true", to_string( true ) );
BOOST_CHECK_EQUAL( "false", to_string( false ) );
}
BOOST_AUTO_TEST_CASE( strings_are_serialized_with_double_quotes )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( "string" ) );
BOOST_CHECK_EQUAL( "\"string\"", to_string( std::string( "string" ) ) );
}
BOOST_AUTO_TEST_CASE( std_pairs_are_serialized )
{
BOOST_CHECK_EQUAL( "(3,42)", to_string( std::make_pair( 3, 42.f ) ) );
}
BOOST_AUTO_TEST_CASE( std_deques_are_serialized )
{
std::deque< int > d;
d.push_back( 12 );
d.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( d ) );
}
BOOST_AUTO_TEST_CASE( std_lists_are_serialized )
{
std::list< int > l;
l.push_back( 12 );
l.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( l ) );
}
BOOST_AUTO_TEST_CASE( std_vectors_are_serialized )
{
std::vector< int > v;
v.push_back( 12 );
v.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( v ) );
}
BOOST_AUTO_TEST_CASE( std_maps_are_serialized )
{
std::map< int, std::string > m;
m[ 12 ] = "12";
m[ 42 ] = "42";
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_multimaps_are_serialized )
{
std::multimap< int, std::string > m;
m.insert( std::make_pair( 12, "12" ));
m.insert( std::make_pair( 42, "42" ));
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_sets_are_serialized )
{
std::set< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( std_multisets_are_serialized )
{
std::multiset< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( boost_assign_list_of_are_serialized )
{
BOOST_CHECK_EQUAL( "(12,42)", to_string( boost::assign::list_of( 12 )( 42 ) ) );
}
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" ) ) );
}
namespace
{
struct false_positive_container
{
typedef int const_iterator;
};
BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > ));
void format( std::ostream& s, mock::protect< false_positive_container > )
{
s << "false_positive_container";
}
}
BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden )
{
BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) );
}

View file

@ -0,0 +1,27 @@
//
// Copyright Mathieu Champlon 2009
//
// 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_container.hpp>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <set>
#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_container< int > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::vector< int > > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::deque< int > > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::list< int > > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::map< int, float > > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::multimap< int, float > > ));
BOOST_MPL_ASSERT(( mock::detail::is_container< std::multiset< int > > ));

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

@ -1,91 +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_serializable.hpp>
#include <boost/static_assert.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(( mock::detail::is_serializable< std::ostream, int > ));
BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, std::string > ));
namespace
{
struct declared_but_not_defined;
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, declared_but_not_defined > ));
namespace
{
struct non_serializable
{};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, non_serializable > ));
namespace
{
struct serializable
{};
std::ostream& operator<<( std::ostream& s, const serializable& );
}
BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, serializable > ));
namespace
{
template< typename T >
struct template_serializable {};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_serializable< T >& );
}
BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, template_serializable< int > > ));
namespace
{
struct convertible_to_base
{
operator int() const;
};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, convertible_to_base > ));
namespace
{
struct convertible_to_string
{
operator std::string() const;
};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, convertible_to_string > ));
namespace
{
struct convertible_to_serializable
{
operator serializable() const;
};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, convertible_to_serializable > ));
namespace
{
struct derived_from_serializable : serializable
{};
}
BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, derived_from_serializable > ));

View file

@ -0,0 +1,472 @@
//
// Copyright Mathieu Champlon 2008
//
// 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)
//
#define MOCK_LOG_CONVERSIONS
#include <turtle/log.hpp>
#include <boost/assign.hpp>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <boost/test/auto_unit_test.hpp>
#define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp>
namespace
{
template< typename T >
std::string to_string( T t )
{
std::stringstream s;
s << mock::format( t );
return s.str();
}
}
BOOST_AUTO_TEST_CASE( base_type_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "42", to_string( 42 ) );
}
BOOST_AUTO_TEST_CASE( booleans_are_serialized_as_bool_alpha_with_conversions )
{
BOOST_CHECK_EQUAL( "true", to_string( true ) );
BOOST_CHECK_EQUAL( "false", to_string( false ) );
}
BOOST_AUTO_TEST_CASE( strings_are_serialized_with_double_quotes_with_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( "string" ) );
BOOST_CHECK_EQUAL( "\"string\"", to_string( std::string( "string" ) ) );
}
namespace
{
struct non_serializable
{};
}
BOOST_AUTO_TEST_CASE( non_serializable_type_yields_an_interrogation_mark_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( non_serializable() ) );
}
namespace
{
struct serializable
{};
std::ostream& operator<<( std::ostream& s, const serializable& )
{
return s << "serializable";
}
}
BOOST_AUTO_TEST_CASE( serializable_type_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "serializable", to_string( serializable() ) );
}
namespace
{
struct streamable
{};
std::ostream& operator<<( std::ostream& s, const streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
mock::stream& operator<<( mock::stream& s, const streamable& )
{
return s << "streamable";
}
}
BOOST_AUTO_TEST_CASE( streamable_type_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "streamable", to_string( streamable() ) );
}
namespace
{
struct mock_streamable
{};
std::ostream& operator<<( std::ostream& s, const mock_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
stream& operator<<( stream& s, const mock_streamable& )
{
return s << "mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( mock_streamable_type_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "mock_streamable", to_string( mock_streamable() ) );
}
namespace
{
struct derived_from_serializable : serializable
{};
}
BOOST_AUTO_TEST_CASE( type_derived_from_serializable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "serializable", to_string( derived_from_serializable() ) );
}
namespace
{
struct derived_from_streamable : streamable
{};
}
BOOST_AUTO_TEST_CASE( type_derived_from_streamable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "streamable", to_string( derived_from_streamable() ) );
}
//namespace
//{
// struct convertible_to_base
// {
// operator int() const
// {
// return 3;
// }
// };
//}
//
//BOOST_AUTO_TEST_CASE( type_convertible_to_base_yields_its_value_when_serialized_with_conversions )
//{
// BOOST_CHECK_EQUAL( "3", to_string( convertible_to_base() ) );
//}
//namespace
//{
// struct convertible_to_serializable
// {
// operator serializable() const;
// };
//}
//
//BOOST_AUTO_TEST_CASE( type_convertible_to_serializable_yields_its_value_when_serialized_with_conversions )
//{
// BOOST_CHECK_EQUAL( "serializable", to_string( convertible_to_serializable() ) );
//}
//namespace
//{
// struct convertible_to_streamable
// {
// operator streamable() const;
// };
//}
//
//BOOST_AUTO_TEST_CASE( type_convertible_to_streamable_yields_its_value_when_serialized_with_conversions )
//{
// BOOST_CHECK_EQUAL( "streamable", to_string( convertible_to_streamable() ) );
//}
//namespace
//{
// struct ambiguous_convertible
// {
// operator float() const;
// operator int() const;
// operator serializable() const;
// operator streamable() const;
// template< typename T > operator T() const;
// };
//}
//
//BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_yields_an_interrogation_mark_when_serialized_with_conversions )
//{
// BOOST_CHECK_EQUAL( "?", to_string( ambiguous_convertible() ) );
//}
//namespace
//{
// struct ambiguous_convertible_serializable
// {
// operator float() const;
// operator int() const;
// operator serializable() const;
// operator streamable() const;
// template< typename T > operator T() const;
// };
// std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_serializable& )
// {
// return s << "ambiguous_convertible_serializable";
// }
//}
//
//BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_serializable_yields_its_value_when_serialized_with_conversions )
//{
// BOOST_CHECK_EQUAL( "ambiguous_convertible_serializable", to_string( ambiguous_convertible_serializable() ) );
//}
namespace
{
struct ambiguous_convertible_streamable
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
mock::stream& operator<<( mock::stream& s, const ambiguous_convertible_streamable& )
{
return s << "ambiguous_convertible_streamable";
}
}
BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_streamable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "ambiguous_convertible_streamable", to_string( ambiguous_convertible_streamable() ) );
}
namespace
{
struct ambiguous_convertible_mock_streamable
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_mock_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
stream& operator<<( stream& s, const ambiguous_convertible_mock_streamable& )
{
return s << "ambiguous_convertible_mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_mock_streamable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "ambiguous_convertible_mock_streamable", to_string( ambiguous_convertible_mock_streamable() ) );
}
namespace
{
template< typename T >
struct template_serializable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_serializable< T >& )
{
return s << "template_serializable";
}
}
BOOST_AUTO_TEST_CASE( template_type_serializable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "template_serializable", to_string( template_serializable< int >() ) );
}
namespace
{
template< typename T >
struct template_streamable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_streamable< T >& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
template< typename T >
mock::stream& operator<<( mock::stream& s, const template_streamable< T >& )
{
return s << "template_streamable";
}
}
BOOST_AUTO_TEST_CASE( template_streamable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "template_streamable", to_string( template_streamable< int >() ) );
}
namespace
{
template< typename T >
struct template_mock_streamable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_mock_streamable< T >& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
template< typename T >
stream& operator<<( stream& s, const template_mock_streamable< T >& )
{
return s << "template_mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( template_mock_streamable_yields_its_value_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "template_mock_streamable", to_string( template_mock_streamable< int >() ) );
}
BOOST_AUTO_TEST_CASE( std_pairs_are_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "(3,42)", to_string( std::make_pair( 3, 42.f ) ) );
}
BOOST_AUTO_TEST_CASE( std_deques_are_serialized_with_conversions )
{
std::deque< int > d;
d.push_back( 12 );
d.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( d ) );
}
BOOST_AUTO_TEST_CASE( std_lists_are_serialized_with_conversions )
{
std::list< int > l;
l.push_back( 12 );
l.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( l ) );
}
BOOST_AUTO_TEST_CASE( std_vectors_are_serialized_with_conversions )
{
std::vector< int > v;
v.push_back( 12 );
v.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( v ) );
}
BOOST_AUTO_TEST_CASE( std_maps_are_serialized_with_conversions )
{
std::map< int, std::string > m;
m[ 12 ] = "12";
m[ 42 ] = "42";
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_multimaps_are_serialized_with_conversions )
{
std::multimap< int, std::string > m;
m.insert( std::make_pair( 12, "12" ));
m.insert( std::make_pair( 42, "42" ));
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_sets_are_serialized_with_conversions )
{
std::set< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( std_multisets_are_serialized_with_conversions )
{
std::multiset< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( boost_assign_list_of_are_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "(12,42)", to_string( boost::assign::list_of( 12 )( 42 ) ) );
}
BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( boost::assign::map_list_of( 12, "12" )( 42, "42" ) ) );
}
namespace
{
struct false_positive_container
{
typedef int const_iterator;
};
BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > ));
mock::stream& operator<<( mock::stream& s, false_positive_container )
{
return s << "false_positive_container";
}
}
BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden_with_conversions )
{
BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) );
}
namespace
{
void callable_builtin()
{}
}
BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) );
BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) );
}
namespace
{
struct serialized_using_format
{};
std::ostream& operator<<( std::ostream& s, const serialized_using_format& )
{
return s << mock::format( "string" );
}
}
BOOST_AUTO_TEST_CASE( type_can_use_format_when_serialized_with_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( serialized_using_format() ) );
}
namespace
{
struct streamed_using_format
{};
mock::stream& operator<<( mock::stream& s, const streamed_using_format& )
{
return s << mock::format( "string" );
}
}
BOOST_AUTO_TEST_CASE( type_can_use_format_when_streamed_with_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( streamed_using_format() ) );
}

View file

@ -0,0 +1,468 @@
//
// Copyright Mathieu Champlon 2008
//
// 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/log.hpp>
#include <boost/assign.hpp>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <boost/test/auto_unit_test.hpp>
#define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp>
namespace
{
template< typename T >
std::string to_string( T t )
{
std::stringstream s;
s << mock::format( t );
return s.str();
}
}
BOOST_AUTO_TEST_CASE( base_type_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "42", to_string( 42 ) );
}
BOOST_AUTO_TEST_CASE( booleans_are_serialized_as_bool_alpha_without_conversions )
{
BOOST_CHECK_EQUAL( "true", to_string( true ) );
BOOST_CHECK_EQUAL( "false", to_string( false ) );
}
BOOST_AUTO_TEST_CASE( strings_are_serialized_with_double_quotes_without_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( "string" ) );
BOOST_CHECK_EQUAL( "\"string\"", to_string( std::string( "string" ) ) );
}
namespace
{
struct non_serializable
{};
}
BOOST_AUTO_TEST_CASE( non_serializable_type_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( non_serializable() ) );
}
namespace
{
struct serializable
{};
std::ostream& operator<<( std::ostream& s, const serializable& )
{
return s << "serializable";
}
}
BOOST_AUTO_TEST_CASE( serializable_type_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "serializable", to_string( serializable() ) );
}
namespace
{
struct streamable
{};
std::ostream& operator<<( std::ostream& s, const streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
mock::stream& operator<<( mock::stream& s, const streamable& )
{
return s << "streamable";
}
}
BOOST_AUTO_TEST_CASE( streamable_type_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "streamable", to_string( streamable() ) );
}
namespace
{
struct mock_streamable
{};
std::ostream& operator<<( std::ostream& s, const mock_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
stream& operator<<( stream& s, const mock_streamable& )
{
return s << "mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( mock_streamable_type_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "mock_streamable", to_string( mock_streamable() ) );
}
namespace
{
struct derived_from_serializable : serializable
{};
}
BOOST_AUTO_TEST_CASE( type_derived_from_serializable_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( derived_from_serializable() ) );
}
namespace
{
struct derived_from_streamable : streamable
{};
}
BOOST_AUTO_TEST_CASE( type_derived_from_streamable_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( derived_from_streamable() ) );
}
namespace
{
struct convertible_to_base
{
operator int() const;
};
}
BOOST_AUTO_TEST_CASE( type_convertible_to_base_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( convertible_to_base() ) );
}
namespace
{
struct convertible_to_serializable
{
operator serializable() const;
};
}
BOOST_AUTO_TEST_CASE( type_convertible_to_serializable_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( convertible_to_serializable() ) );
}
namespace
{
struct convertible_to_streamable
{
operator streamable() const;
};
}
BOOST_AUTO_TEST_CASE( type_convertible_to_streamable_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( convertible_to_streamable() ) );
}
namespace
{
struct ambiguous_convertible
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
}
BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( ambiguous_convertible() ) );
}
namespace
{
struct ambiguous_convertible_serializable
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_serializable& )
{
return s << "ambiguous_convertible_serializable";
}
}
BOOST_AUTO_TEST_CASE( type_convertible_serializable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "ambiguous_convertible_serializable", to_string( ambiguous_convertible_serializable() ) );
}
namespace
{
struct ambiguous_convertible_streamable
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
mock::stream& operator<<( mock::stream& s, const ambiguous_convertible_streamable& )
{
return s << "ambiguous_convertible_streamable";
}
}
BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_streamable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "ambiguous_convertible_streamable", to_string( ambiguous_convertible_streamable() ) );
}
namespace
{
struct ambiguous_convertible_mock_streamable
{
operator float() const;
operator int() const;
operator serializable() const;
operator streamable() const;
template< typename T > operator T() const;
};
std::ostream& operator<<( std::ostream& s, const ambiguous_convertible_mock_streamable& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
stream& operator<<( stream& s, const ambiguous_convertible_mock_streamable& )
{
return s << "ambiguous_convertible_mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( type_ambiguous_convertible_mock_streamable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "ambiguous_convertible_mock_streamable", to_string( ambiguous_convertible_mock_streamable() ) );
}
namespace
{
template< typename T >
struct template_serializable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_serializable< T >& )
{
return s << "template_serializable";
}
}
BOOST_AUTO_TEST_CASE( template_type_serializable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "template_serializable", to_string( template_serializable< int >() ) );
}
namespace
{
template< typename T >
struct template_streamable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_streamable< T >& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
template< typename T >
mock::stream& operator<<( mock::stream& s, const template_streamable< T >& )
{
return s << "template_streamable";
}
}
BOOST_AUTO_TEST_CASE( template_template_streamable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "template_streamable", to_string( template_streamable< int >() ) );
}
namespace
{
template< typename T >
struct template_mock_streamable
{};
template< typename T >
std::ostream& operator<<( std::ostream& s, const template_mock_streamable< T >& )
{
BOOST_FAIL( "should not have been called" );
return s;
}
}
namespace mock
{
template< typename T >
stream& operator<<( stream& s, const template_mock_streamable< T >& )
{
return s << "template_mock_streamable";
}
}
BOOST_AUTO_TEST_CASE( template_mock_streamable_yields_its_value_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "template_mock_streamable", to_string( template_mock_streamable< int >() ) );
}
BOOST_AUTO_TEST_CASE( std_pairs_are_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "(3,42)", to_string( std::make_pair( 3, 42.f ) ) );
}
BOOST_AUTO_TEST_CASE( std_deques_are_serialized_without_conversions )
{
std::deque< int > d;
d.push_back( 12 );
d.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( d ) );
}
BOOST_AUTO_TEST_CASE( std_lists_are_serialized_without_conversions )
{
std::list< int > l;
l.push_back( 12 );
l.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( l ) );
}
BOOST_AUTO_TEST_CASE( std_vectors_are_serialized_without_conversions )
{
std::vector< int > v;
v.push_back( 12 );
v.push_back( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( v ) );
}
BOOST_AUTO_TEST_CASE( std_maps_are_serialized_without_conversions )
{
std::map< int, std::string > m;
m[ 12 ] = "12";
m[ 42 ] = "42";
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_multimaps_are_serialized_without_conversions )
{
std::multimap< int, std::string > m;
m.insert( std::make_pair( 12, "12" ));
m.insert( std::make_pair( 42, "42" ));
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( m ) );
}
BOOST_AUTO_TEST_CASE( std_sets_are_serialized_without_conversions )
{
std::set< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( std_multisets_are_serialized_without_conversions )
{
std::multiset< int > s;
s.insert( 12 );
s.insert( 42 );
BOOST_CHECK_EQUAL( "(12,42)", to_string( s ) );
}
BOOST_AUTO_TEST_CASE( boost_assign_list_of_are_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "(12,42)", to_string( boost::assign::list_of( 12 )( 42 ) ) );
}
BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( boost::assign::map_list_of( 12, "12" )( 42, "42" ) ) );
}
namespace
{
struct false_positive_container
{
typedef int const_iterator;
};
BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > ));
mock::stream& operator<<( mock::stream& s, false_positive_container )
{
return s << "false_positive_container";
}
}
BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden_without_conversions )
{
BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) );
}
namespace
{
void callable_builtin()
{}
}
BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) );
BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) );
}
namespace
{
struct serialized_using_format
{};
std::ostream& operator<<( std::ostream& s, const serialized_using_format& )
{
return s << mock::format( "string" );
}
}
BOOST_AUTO_TEST_CASE( type_can_use_format_when_serialized_without_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( serialized_using_format() ) );
}
namespace
{
struct streamed_using_format
{};
mock::stream& operator<<( mock::stream& s, const streamed_using_format& )
{
return s << mock::format( "string" );
}
}
BOOST_AUTO_TEST_CASE( type_can_use_format_when_streamed_without_conversions )
{
BOOST_CHECK_EQUAL( "\"string\"", to_string( streamed_using_format() ) );
}