mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Add and use new singleton class
Use a very basic implementation and explicit inst() calls for access
This commit is contained in:
parent
e92f52821d
commit
9f1690b5da
10 changed files with 78 additions and 45 deletions
|
|
@ -12,36 +12,35 @@
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
#include "function.hpp"
|
#include "function.hpp"
|
||||||
#include "mutex.hpp"
|
#include "mutex.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
class functor_mutex_t :
|
class functor_mutex_t :
|
||||||
public boost::unit_test::singleton< functor_mutex_t >,
|
public singleton< functor_mutex_t >,
|
||||||
public mutex
|
public mutex
|
||||||
{
|
{
|
||||||
private:
|
MOCK_SINGLETON_CONS( functor_mutex_t );
|
||||||
BOOST_TEST_SINGLETON_CONS( functor_mutex_t );
|
|
||||||
};
|
};
|
||||||
BOOST_TEST_SINGLETON_INST( functor_mutex )
|
|
||||||
|
|
||||||
template< typename Signature >
|
template< typename Signature >
|
||||||
struct functor : function< Signature >
|
struct functor : function< Signature >
|
||||||
{
|
{
|
||||||
functor()
|
functor()
|
||||||
{
|
{
|
||||||
scoped_lock _( functor_mutex );
|
scoped_lock _( functor_mutex::inst() );
|
||||||
static functor* f = 0;
|
static functor* f = 0;
|
||||||
if( f )
|
if( f )
|
||||||
{
|
{
|
||||||
*this = *f;
|
*this = *f;
|
||||||
f = 0;
|
f = 0;
|
||||||
functor_mutex.unlock();
|
functor_mutex::inst().unlock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
functor_mutex.lock();
|
functor_mutex::inst().lock();
|
||||||
f = this;
|
f = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#define MOCK_MUTEX_HPP_INCLUDED
|
#define MOCK_MUTEX_HPP_INCLUDED
|
||||||
|
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
#include <boost/test/utils/trivial_singleton.hpp>
|
#include "singleton.hpp"
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#ifdef MOCK_THREAD_SAFE
|
#ifdef MOCK_THREAD_SAFE
|
||||||
|
|
@ -93,13 +93,11 @@ namespace mock
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
class error_mutex_t : public boost::unit_test::singleton< error_mutex_t >,
|
class error_mutex_t : public singleton< error_mutex_t >,
|
||||||
public mutex
|
public mutex
|
||||||
{
|
{
|
||||||
private:
|
MOCK_SINGLETON_CONS( error_mutex_t );
|
||||||
BOOST_TEST_SINGLETON_CONS( error_mutex_t );
|
|
||||||
};
|
};
|
||||||
BOOST_TEST_SINGLETON_INST( error_mutex )
|
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
# pragma warning( push )
|
# pragma warning( push )
|
||||||
|
|
@ -110,25 +108,25 @@ namespace detail
|
||||||
{
|
{
|
||||||
static Result abort()
|
static Result abort()
|
||||||
{
|
{
|
||||||
scoped_lock _( error_mutex );
|
scoped_lock _( error_mutex::inst() );
|
||||||
return Error::abort();
|
return Error::abort();
|
||||||
}
|
}
|
||||||
template< typename Context >
|
template< typename Context >
|
||||||
static void fail( const char* message, const Context& context,
|
static void fail( const char* message, const Context& context,
|
||||||
const char* file = "unknown location", int line = 0 )
|
const char* file = "unknown location", int line = 0 )
|
||||||
{
|
{
|
||||||
scoped_lock _( error_mutex );
|
scoped_lock _( error_mutex::inst() );
|
||||||
Error::fail( message, context, file, line );
|
Error::fail( message, context, file, line );
|
||||||
}
|
}
|
||||||
template< typename Context >
|
template< typename Context >
|
||||||
static void call( const Context& context, const char* file, int line )
|
static void call( const Context& context, const char* file, int line )
|
||||||
{
|
{
|
||||||
scoped_lock _( error_mutex );
|
scoped_lock _( error_mutex::inst() );
|
||||||
Error::call( context, file, line );
|
Error::call( context, file, line );
|
||||||
}
|
}
|
||||||
static void pass( const char* file, int line )
|
static void pass( const char* file, int line )
|
||||||
{
|
{
|
||||||
scoped_lock _( error_mutex );
|
scoped_lock _( error_mutex::inst() );
|
||||||
Error::pass( file, line );
|
Error::pass( file, line );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace detail
|
||||||
{
|
{
|
||||||
lock _( mutex_ );
|
lock _( mutex_ );
|
||||||
if( children_.empty() )
|
if( children_.empty() )
|
||||||
detail::root.add( *this );
|
detail::root::inst().add( *this );
|
||||||
children_[ &v ].update( parent_, instance, type, name );
|
children_[ &v ].update( parent_, instance, type, name );
|
||||||
}
|
}
|
||||||
virtual void add( verifiable& v )
|
virtual void add( verifiable& v )
|
||||||
|
|
@ -54,7 +54,7 @@ namespace detail
|
||||||
group_.remove( v );
|
group_.remove( v );
|
||||||
children_.erase( &v );
|
children_.erase( &v );
|
||||||
if( children_.empty() )
|
if( children_.empty() )
|
||||||
detail::root.remove( *this );
|
detail::root::inst().remove( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void serialize( std::ostream& s, const verifiable& v ) const
|
virtual void serialize( std::ostream& s, const verifiable& v ) const
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "child.hpp"
|
#include "child.hpp"
|
||||||
#include "mutex.hpp"
|
#include "mutex.hpp"
|
||||||
#include <boost/test/utils/trivial_singleton.hpp>
|
#include "singleton.hpp"
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
@ -24,7 +24,7 @@ namespace mock
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
class root_t : public boost::unit_test::singleton< root_t >, public context
|
class root_t : public singleton< root_t >, public context
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void add( const void* p, verifiable& v,
|
virtual void add( const void* p, verifiable& v,
|
||||||
|
|
@ -128,10 +128,8 @@ namespace detail
|
||||||
group group_;
|
group group_;
|
||||||
mutable mutex mutex_;
|
mutable mutex mutex_;
|
||||||
|
|
||||||
private:
|
MOCK_SINGLETON_CONS( root_t );
|
||||||
BOOST_TEST_SINGLETON_CONS( root_t );
|
|
||||||
};
|
};
|
||||||
BOOST_TEST_SINGLETON_INST( root )
|
|
||||||
}
|
}
|
||||||
} // mock
|
} // mock
|
||||||
|
|
||||||
|
|
|
||||||
39
include/turtle/detail/singleton.hpp
Normal file
39
include/turtle/detail/singleton.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
// http://turtle.sourceforge.net
|
||||||
|
//
|
||||||
|
// Copyright Mathieu Champlon 2014
|
||||||
|
//
|
||||||
|
// 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_SINGLETON_HPP
|
||||||
|
#define MOCK_SINGLETON_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
namespace mock {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
class singleton {
|
||||||
|
public:
|
||||||
|
static Derived& inst() { static Derived the_inst; return the_inst; }
|
||||||
|
|
||||||
|
BOOST_DELETED_FUNCTION(singleton(singleton const&))
|
||||||
|
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOST_DEFAULTED_FUNCTION(singleton(), {})
|
||||||
|
BOOST_DEFAULTED_FUNCTION(~singleton(), {})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add a private ctor to the type to prevent misuse
|
||||||
|
#define MOCK_SINGLETON_CONS( type ) \
|
||||||
|
private: \
|
||||||
|
friend class ::mock::detail::singleton<type>; \
|
||||||
|
type() {}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
} // mock
|
||||||
|
|
||||||
|
#endif // MOCK_SINGLETON_HPP
|
||||||
|
|
@ -55,9 +55,9 @@
|
||||||
#endif // MOCK_VARIADIC_MACROS
|
#endif // MOCK_VARIADIC_MACROS
|
||||||
|
|
||||||
#define MOCK_HELPER(t) \
|
#define MOCK_HELPER(t) \
|
||||||
t##_mock( mock::detail::root, BOOST_PP_STRINGIZE(t) )
|
t##_mock( mock::detail::root::inst(), BOOST_PP_STRINGIZE(t) )
|
||||||
#define MOCK_ANONYMOUS_HELPER(t) \
|
#define MOCK_ANONYMOUS_HELPER(t) \
|
||||||
t##_mock( mock::detail::root, "?." )
|
t##_mock( mock::detail::root::inst(), "?." )
|
||||||
|
|
||||||
#define MOCK_METHOD_HELPER(S, t, tpn) \
|
#define MOCK_METHOD_HELPER(S, t, tpn) \
|
||||||
mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \
|
mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace detail
|
||||||
typename boost::is_base_of< object, T >
|
typename boost::is_base_of< object, T >
|
||||||
>::type* = 0 )
|
>::type* = 0 )
|
||||||
{
|
{
|
||||||
e.configure( detail::root, &t, instance, type, name );
|
e.configure( detail::root::inst(), &t, instance, type, name );
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace mock
|
||||||
{
|
{
|
||||||
inline void reset()
|
inline void reset()
|
||||||
{
|
{
|
||||||
detail::root.reset();
|
detail::root::inst().reset();
|
||||||
}
|
}
|
||||||
inline void reset( const object& o )
|
inline void reset( const object& o )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace mock
|
||||||
{
|
{
|
||||||
inline bool verify()
|
inline bool verify()
|
||||||
{
|
{
|
||||||
return detail::root.verify();
|
return detail::root::inst().verify();
|
||||||
}
|
}
|
||||||
inline bool verify( const object& o )
|
inline bool verify( const object& o )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
#define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED
|
#define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED
|
||||||
|
|
||||||
#define MOCK_ERROR_POLICY mock_error
|
#define MOCK_ERROR_POLICY mock_error
|
||||||
|
#include <turtle/detail/singleton.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <boost/test/utils/trivial_singleton.hpp>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
struct mock_error_data_t : boost::unit_test::singleton< mock_error_data_t >
|
struct mock_error_data_t : turtle::detail::singleton< mock_error_data_t >
|
||||||
{
|
{
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
|
|
@ -52,10 +52,9 @@ struct mock_error_data_t : boost::unit_test::singleton< mock_error_data_t >
|
||||||
std::string last_context;
|
std::string last_context;
|
||||||
std::string last_file;
|
std::string last_file;
|
||||||
int last_line;
|
int last_line;
|
||||||
private:
|
|
||||||
BOOST_TEST_SINGLETON_CONS( mock_error_data_t );
|
MOCK_SINGLETON_CONS( mock_error_data_t );
|
||||||
};
|
};
|
||||||
BOOST_TEST_SINGLETON_INST( mock_error_data )
|
|
||||||
|
|
||||||
template< typename Result >
|
template< typename Result >
|
||||||
struct mock_error
|
struct mock_error
|
||||||
|
|
@ -72,14 +71,14 @@ struct mock_error
|
||||||
static void call( const Context& /*context*/,
|
static void call( const Context& /*context*/,
|
||||||
const char* /*file*/, int /*line*/ )
|
const char* /*file*/, int /*line*/ )
|
||||||
{
|
{
|
||||||
mock_error_data.call();
|
mock_error_data::inst().call();
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Context >
|
template< typename Context >
|
||||||
static void fail( const std::string& message, const Context& context,
|
static void fail( const std::string& message, const Context& context,
|
||||||
const char* file = "", int line = 0 )
|
const char* file = "", int line = 0 )
|
||||||
{
|
{
|
||||||
mock_error_data.fail( message,
|
mock_error_data::inst().fail( message,
|
||||||
boost::lexical_cast< std::string >( context ), file, line );
|
boost::lexical_cast< std::string >( context ), file, line );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -88,25 +87,25 @@ struct mock_error_fixture
|
||||||
{
|
{
|
||||||
mock_error_fixture()
|
mock_error_fixture()
|
||||||
{
|
{
|
||||||
mock_error_data.reset();
|
mock_error_data::inst().reset();
|
||||||
}
|
}
|
||||||
~mock_error_fixture()
|
~mock_error_fixture()
|
||||||
{
|
{
|
||||||
BOOST_CHECK( mock_error_data.verify() );
|
BOOST_CHECK( mock_error_data::inst().verify() );
|
||||||
BOOST_CHECK_EQUAL( 0, mock_error_data.call_count );
|
BOOST_CHECK_EQUAL( 0, mock_error_data::inst().call_count );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHECK_CALLS( calls ) \
|
#define CHECK_CALLS( calls ) \
|
||||||
BOOST_CHECK_EQUAL( calls, mock_error_data.call_count ); \
|
BOOST_CHECK_EQUAL( calls, mock_error_data::inst().call_count ); \
|
||||||
mock_error_data.call_count = 0;
|
mock_error_data::inst().call_count = 0;
|
||||||
#define CHECK_ERROR( expr, error, calls, context ) \
|
#define CHECK_ERROR( expr, error, calls, context ) \
|
||||||
BOOST_CHECK( mock_error_data.verify() ); \
|
BOOST_CHECK( mock_error_data::inst().verify() ); \
|
||||||
try { expr; } catch( ... ) {} \
|
try { expr; } catch( ... ) {} \
|
||||||
BOOST_CHECK_EQUAL( 1, mock_error_data.error_count ); \
|
BOOST_CHECK_EQUAL( 1, mock_error_data::inst().error_count ); \
|
||||||
BOOST_CHECK_EQUAL( error, mock_error_data.last_message ); \
|
BOOST_CHECK_EQUAL( error, mock_error_data::inst().last_message ); \
|
||||||
BOOST_CHECK_EQUAL( context, mock_error_data.last_context ); \
|
BOOST_CHECK_EQUAL( context, mock_error_data::inst().last_context ); \
|
||||||
CHECK_CALLS( calls ); \
|
CHECK_CALLS( calls ); \
|
||||||
mock_error_data.reset();
|
mock_error_data::inst().reset();
|
||||||
|
|
||||||
#endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED
|
#endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue