Changed layout to match boost

This commit is contained in:
Mathieu Champlon 2015-03-04 06:23:30 +01:00
parent 7a8ba352c6
commit c950c24f52
122 changed files with 15469 additions and 15550 deletions

View file

@ -1,28 +0,0 @@
# Copyright Rene Rivera 2007.
#
# 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)
# Usage:
#
# bjam [options | properties | targets]
#
# Options:
#
# --boost=<BOOST> The directory of a Boost source tree.
# Default; BOOST env var (if found)
# Default; ../boost (if found)
#
# --boost-build=<BOOST_BUILD>
# The directory for the Boost.Build v2 files.
# Default; BOOST_BUILD_PATH env var (if found)
# Default; BOOST_BUILD env var (if found)
# Default; <BOOST>/tools/build/v2 (if found)
#~ If we have the Boost sources we can use the project...
if [ GLOB $(BOOST) : [ modules.peek project : JAMFILE ] ]
{
use-project /boost : $(BOOST) ;
}

View file

@ -1,9 +0,0 @@
import modules ;
local boost = [ modules.peek : BOOST ] ;
project mock : requirements <include>$(boost) <include>. ;
# This seems to prevent some Boost.Build errors that otherwise occur :-(
use-project /boost : $(boost) ;

View file

@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View file

@ -1,52 +0,0 @@
# Boost.Mock
#
# Copyright Mathieu Champlon 2012
#
# 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)
using boostbook ;
using quickbook ;
using doxygen ;
xml mock : mock.qbk ;
#doxygen reference
# :
# [ glob ../../../boost/mock/*.hpp ]
# :
# <doxygen:param>EXPAND_ONLY_PREDEF=YES
# <doxygen:param>HIDE_UNDOC_MEMBERS=NO
# <doxygen:param>QUIET=YES
# <doxygen:param>WARN_IF_UNDOCUMENTED=NO
# <doxygen:param>EXTRACT_PRIVATE=NO
# <doxygen:param>ENABLE_PREPROCESSING=YES
# <doxygen:param>MACRO_EXPANSION=YES
# <doxygen:param>SEARCH_INCLUDES=NO
#;
boostbook standalone
:
mock
:
# <dependency>reference
<xsl:param>boost.root=../../../..
<xsl:param>boost.image.src=images/boost.png
<xsl:param>chunk.first.sections=1
# <xsl:param>toc.max.depth=3
<xsl:param>toc.section.depth=4
<xsl:param>nav.layout=horizontal
;
project example
: requirements
<include>../include
;
rule compile-examples
{
for name in [ glob example/*.cpp ] { compile $(name) ; }
}
alias mock_examples : [ compile-examples ] ;

View file

@ -1,12 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Acknowledgements]
Many thanks to Adrien Gervaise, Silvin Lubecki and Takatoshi Kondo !
[endsect]

View file

@ -1,155 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Changelog]
[section trunk]
Not yet released
* Dropped support for obsolete Boost.Phoenix V2
* Added support for multiple parameters constraints
[section 1.2.6]
Released 24 May 2014
* Added MOCK_THREAD_SAFE to enable thread safety
[endsect]
[section 1.2.5]
Released 10 February 2014
* Added workaround for when msvc defines small and near macros
* Added support for using non default calling conventions
* Changed MOCK_DESTRUCTOR which now requires '~' to preceed the class name
* Changed MOCK_\*CONVERSION_OPERATOR\* which now require an extra first argument 'operator'
* Added version.hpp with the library version number
[endsect]
[section 1.2.4]
Released 14 August 2013
* Reworked MOCK_CONSTRAINT to be able to provide names to parameters
* Added MOCK_NO_VARIADIC_MACROS to deactivate variadic macros support
* Added support for movable only types as parameters
* Added logging support for std::unique_ptr, std::shared_ptr and std::weak_ptr
* Added move support in actions
[endsect]
[section 1.2.3]
Released 20 May 2013
* Added support for C++11 lambdas as constraints
* Return actions now accept by copy types derived from abstract base types
* Added MOCK_CONSTRAINT helper macro
* Added support for several sequences in 'in'
* Added support for nullptr as constraint
* Added mock::close, mock::close_fraction, mock::small and mock::near constraints
[endsect]
[section 1.2.2]
Released 9 March 2013
* Added variadic macro support for MOCK_BASE_CLASS
* Added variadic macro support for MOCK_FUNCTION, MOCK_FUNCTOR and the MOCK_METHOD family
* Added round parenthesis support for signatures for MOCK_FUNCTION, MOCK_FUNCTOR and the MOCK_METHOD family
* Added MOCK_CONVERSION_OPERATOR_TPL, MOCK_CONST_CONVERSION_OPERATOR_TPL and MOCK_NON_CONST_CONVERSION_OPERATOR_TPL
* Added MOCK_FUNCTOR_TPL
[endsect]
[section 1.2.1]
Released 24 January 2013
* Fixed boost::lambda_functor forward declaration
* Added test for whether BOOST_RESULT_OF_NUM_ARGS is large enough
* Removed default error policy keeping only Boost.Test integration
* Refactored error policy to simplify test frameworks integration
* Changed C-string constraint short-cut behaviour to compare strings instead of pointers
* Fixed potential conflict with macro max
* Fixed missing file name and line number in logs
* Moved mock::exception in its own header so that it can be included without the error policy
* Fixed type name extraction involving template classes
[endsect]
[section 1.2.0]
Released 25 May 2012
* Changed MOCK_FUNCTOR syntax to MOCK_FUNCTOR( functor, signature )
* Changed MOCK_EXPECT syntax to MOCK_EXPECT( object.tag ) and MOCK_EXPECT( functor )
* Changed MOCK_RESET syntax to MOCK_RESET( object.tag ) and MOCK_RESET( functor )
* Changed MOCK_VERIFY syntax to MOCK_VERIFY( object.tag ) and MOCK_VERIFY( functor )
* Replaced object.verify() with mock::verify( object )
* Replaced object.reset() with mock::reset( object )
* Added MOCK_FUNCTION, MOCK_STATIC_METHOD and MOCK_STATIC_METHOD_TPL
* Removed all std::string to spare unnecessary memory allocations
* Wrapped constraints parameters with boost::addressof where needed in order to support types with overloaded operator &
* Fixed limitation on operator() of a custom constraint which is no longer required to be const
* Added support for mock::reset( functor ) and mock::verify( functor )
* Renamed basic_error_policy to default_error_policy
* Added checkpoint notification to error policy
* Added specialization to log unsigned chars as integers
* Fixed a bug that caused an object to remain invalid forever after being invalid and verified once
* Added support for mocking constructors
* Fixed phoenix and lambda functors logging in the presence of their operators & and <<
* Fixed a crash when resetting self-referenced object
[endsect]
[section 1.1.1]
Released 10 July 2011
* Added support for boost::cref and boost::ref in built-in constraints and mock::format
* Removed MOCK_METHOD_TPL for using non compliant code
* Added a mock::affirm constraint as evaluating ''actual'' as a boolean
* Fixed a bug preventing non-const pointers to be logged properly
* Added support for logging std::auto_ptr, boost::shared_ptr and boost::weak_ptr
* Added missing check for BOOST_FT_MAX_ARITY when MOCK_MAX_ARGS was set to 21 or higher
* Fixed a bug with const smart pointers as first argument to MOCK_EXPECT being invalid
* Fixed a crash with Boost.Test when destroying failed static mock objects
[endsect]
[section 1.1.0 ]
Released 23 March 2011
* Added Boost.Test log info when an expectation is fulfilled
* Fixed a bug preventing to increase the maximum number of arguments of a mocked method using MOCK_MAX_ARGS
* Changed the default value for MOCK_MAX_ARGS to 9 instead of 10
* Renamed mock::constraint to mock::call
* Added custom constraints logging customization in the same way as parameters
* Changed the way the default logging of constraints and parameters can be overridden to use a serialization operator to a mock::stream
* Enhanced logging by lazily serializing constraints and parameters
* Added the possibility to perform conversions when logging constraints and parameters by defining MOCK_USE_CONVERSIONS
[endsect]
[section 1.0.1]
Released 16 June 2010
* Destroying a sequence does not remove the associated order call enforcement any more
* Added detection for a pointer in mock::assign to dereference it before performing the assignment
* Renamed error policies no_match method to unexpected_call
* Made boost_test_error_policy throw a mock::exception extending boost::execution_aborted (helpful in order to filter on exceptions)
* Fully qualified function calls to prevent unwanted [@http://en.wikipedia.org/wiki/Argument_dependent_name_lookup ADL]
* Added extra namespace level to protect from unwanted [@http://en.wikipedia.org/wiki/Argument_dependent_name_lookup ADL] with operator<<
* Fixed a crash due to [@http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 static initialization order fiasco] on some platforms
* Added support for mocking conversion operators
* Added [@http://www.boost.org/doc/libs/release/libs/concept_check/concept_check.htm concept checks] for better diagnostic upon compilation error
* Made template parameter names more user friendly for better diagnostic upon compilation error
* Fixed expectation argument types to match signature
* Shared parent names among their expectations when a mock::object is used as a base class
* Fixed maximum number of mocked methods arguments
* Prevented a crash when mocking a destructor and throwing out of the object scope
[endsect]
[endsect]

View file

@ -1,163 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Customization]
[import example/customization.cpp]
This section explains how to customize different aspects of the library.
[section Logging]
The library will perform logging lazily, e.g. only when actually needed, which is usually because an error happens but it depends on the [link turtle.customization.test_framework_integration test framework integration] used.
Parameters and [link turtle.customization.constraints constraints] are serialized to report meaningful diagnostics of the failures.
By default the library attempts to serialize to an std::ostream and if this is not possible will use a '?'.
[note Any incomplete type is gracefully handled and yields a '?'.]
[warning Serializing a type inconsistently (including across several translation units) violates the [@http://en.wikipedia.org/wiki/One_Definition_Rule One Definition Rule].]
If for some reason the serialization to an std::ostream shouldn't be used, it can be overridden by a serialization operator to a mock::stream, for instance to log user_type declared in user_namespace :
[mock_stream_user_type]
The operator is found using [@http://en.wikipedia.org/wiki/Argument-dependent_name_lookup argument-dependent name lookup] which means it needs to be in the namespace of either one of its arguments.
The easiest is to define it in the same namespace as the type being serialized. If this is not possible (for instance when serializing a type in namespace std because the C++ standard explicitly forbids adding definitions into the std namespace) a serialization operator to mock::stream can be in the mock namespace instead.
The serialization operators detection doesn't attempt to do conversions when looking for a match (because this can sometimes yield an ambiguous resolution error).
As conversions can prove convenient, for instance when dealing with a base class which is derived to a lot of sub-classes, they can be activated by defining MOCK_USE_CONVERSIONS prior to including the library :
[mock_use_conversions]
Be aware though that in this case the compiler can produce a compilation error when attempting to detect whether serialization operators exist or not.
It is always possible however to define a serialization operator to a mock::stream in order to bypass the detection.
In all custom operator implementations it is probably a good thing to rely on the same mechanism the library uses in order to log everything, for instance here is how std::pair is handled :
namespace mock
{
template< typename T1, typename T2 >
mock::stream& operator<<( mock::stream& s, const std::pair< T1, T2 >& p )
{
return s << '(' << mock::format( p.first ) << ',' << mock::format( p.second ) << ')';
}
}
The interesting part is the call to mock::format which enables the whole can-be-serialized-or-? logics.
[endsect]
[section Constraints]
Constraint provide a means to validate the parameters received in a call to a mock object.
The library comes with a set of pre-defined [link turtle.reference.expectation.constraints constraints] matching the most widely used cases, however it is quite common to need to perform a custom validation.
Creating a constraint can be as simple as writing a function, for instance :
[custom_constraint_free_function]
Any functor will actually do as long as its signature matches the requirement : take a type convertible from the actual type and return a boolean.
Using the custom constraint is also pretty trivial, for instance :
[custom_constraint_free_function_test]
Simple enough, however this constraint isn't serializable and thus yields a rather uninformative '?' in the logs.
Just like a parameter, a constraint can be displayed in a readable form using its serialization operator, see [link turtle.customization.logging logging].
Thus a widely used constraint (for instance one shipped with the code of a library) is likely better defined like this :
[custom_constraint_functor]
And of course the constraint is to be used in a slightly different way :
[custom_constraint_functor_test]
Actually real world use cases sometimes need several other features as well :
* a state
* (template) parameters
* an operator with one or several (template) signatures
Therefore a more realistic and complete example would be :
[near_constraint]
And it would be used like this :
[near_constraint_test]
The purpose of the 'near' template function is to :
* remove the burden of specifying the template parameter when instantiating near_constraint
* wrap the constraint in a mock::constraint so that it plays nicely with !, && and ||.
The use of boost::unwrap_ref provides support for passing arguments as references with boost::ref and boost::cref and delaying their initialization, for instance :
[near_constraint_cref_test]
See [link turtle.reference.expectation.constraints constraints] for an explanation of how the library detects whether an argument is a functor or a value.
For more information about the serialization operator and the use of mock::format, refer to [link turtle.customization.logging logging].
[note The [link turtle.reference.constraint constraint helper macro] takes care of everything for simple cases.]
[endsect]
[section Number of arguments]
The maximum number of arguments a mocked method can have is defined by MOCK_MAX_ARGS.
By default this value is set to 9, but if needed it can be changed before including the library :
[max_args]
This means methods with up to 20 arguments will then be accepted.
The mock object library uses several boost libraries and will adjust some of their constants if they haven't already been defined :
* Boost.Function with BOOST_FUNCTION_MAX_ARGS required at MOCK_MAX_ARGS or higher
* Boost.FunctionTypes with BOOST_FT_MAX_ARITY required at MOCK_MAX_ARGS + 1 or higher
A compilation error will happen if one of those constants is already defined too low.
[endsect]
[section Test framework integration]
By default the library expects to be used in conjunction with Boost.Test e.g. :
* logs using the logger from Boost.Test
* throws mock::exception deriving from boost::execution_aborted via boost::enable_current_exception
* adds Boost.Test checkpoints whenever possible
* verifies and resets all remaining (static or leaked objects) with a global fixture
However integrating with any given unit test framework can be done by defining a custom error policy implementing the following concept :
[custom_policy]
The context, which stands for "something serializable to an std::ostream", is actually built only if an attempt to serialize it is made, thus enabling lazy serialization of all elements (e.g. constraints and parameters).
File and line show were the expectation has been configured.
The policy can then be activated by defining MOCK_ERROR_POLICY prior to including the library :
[define_custom_policy]
[endsect]
[section Thread safety]
Thread safety is not activated by default however defining MOCK_THREAD_SAFE before including the library will make creations and calls to mock objects thread-safe :
[thread_safe]
If available the library will rely on the C++11 standard mutexes and locks, otherwise Boost.Thread will be used.
[endsect]
[endsect]

View file

@ -1,24 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// 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 CALCULATOR
#define CALCULATOR
class view;
//[ calculator
class calculator
{
public:
calculator( view& v );
void add( int a, int b ); // the result will be sent to the view 'v'
};
//]
#endif // CALCULATOR

View file

@ -1,178 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// 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)
//[ mock_use_conversions
#define MOCK_USE_CONVERSIONS
#include <turtle/mock.hpp>
//]
#include "calculator.hpp"
#include "mock_view.hpp"
//[ mock_stream_user_type
namespace user_namespace
{
struct user_type
{};
inline mock::stream& operator<<( mock::stream& s, const user_type& )
{
return s << "user_type";
}
}
//]
namespace custom_constraint_free_function_test
{
//[ custom_constraint_free_function
bool custom_constraint( int actual )
{
return actual == 42;
}
//]
//[ custom_constraint_free_function_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).with( &custom_constraint );
c.add( 41, 1 );
}
//]
}
namespace custom_constraint_functor_test
{
//[ custom_constraint_functor
struct custom_constraint
{
friend bool operator==( int actual, const custom_constraint& )
{
return actual == 42;
}
friend std::ostream& operator<<( std::ostream& s, const custom_constraint& )
{
return s << "_ == 42";
}
};
//]
//[ custom_constraint_functor_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).with( custom_constraint() );
c.add( 41, 1 );
}
//]
}
//[ near_constraint
template< typename Expected >
struct near_constraint
{
near_constraint( Expected expected, Expected threshold )
: expected_( expected )
, threshold_( threshold )
{}
template< typename Actual >
bool operator()( Actual actual ) const
{
return std::abs( actual - boost::unwrap_ref( expected_ ) )
< boost::unwrap_ref( threshold_ );
}
friend std::ostream& operator<<( std::ostream& s, const near_constraint& c )
{
return s << "near( " << mock::format( c.expected_ )
<< ", " << mock::format( c.threshold_ ) << " )";
}
Expected expected_, threshold_;
};
template< typename Expected >
mock::constraint< near_constraint< Expected > > near( Expected expected, Expected threshold )
{
return near_constraint< Expected >( expected, threshold );
}
//]
namespace near_constraint_test
{
//[ near_constraint_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).with( near( 42, 1 ) );
c.add( 41, 1 );
}
//]
}
namespace near_constraint_cref_test
{
//[ near_constraint_cref_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
{
mock_view v;
calculator c( v );
int expected, threshold;
MOCK_EXPECT( v.display ).with( near( boost::cref( expected ), boost::cref( threshold ) ) );
expected = 42;
threshold = 1;
c.add( 41, 1 );
}
//]
}
#undef MOCK_MAX_ARGS
//[ max_args
#define MOCK_MAX_ARGS 20
#include <turtle/mock.hpp>
//]
//[ custom_policy
template< typename Result >
struct custom_policy
{
static Result abort()
{
// ...
}
template< typename Context >
static void fail( const char* message, const Context& context, const char* file = "unknown location", int line = 0 )
{
// ...
}
template< typename Context >
static void call( const Context& context, const char* file, int line )
{
// ...
}
static void pass( const char* file, int line )
{
// ...
}
};
//]
#undef MOCK_ERROR_POLICY
//[ define_custom_policy
#define MOCK_ERROR_POLICY custom_policy
#include <turtle/mock.hpp>
//]
//[ thread_safe
#define MOCK_THREAD_SAFE
#include <turtle/mock.hpp>
//]

View file

@ -1,96 +0,0 @@
// 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)
//[ prerequisite
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
//]
#include "calculator.hpp"
#include "mock_view.hpp"
namespace phases
{
//[ phases
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v; // create mock objects
calculator c( v ); // create object under test
MOCK_EXPECT( v.display ).once().with( 0 ); // configure mock objects
c.add( 0, 0 ); // exercise object under test
} // verify mock objects
//]
}
namespace verify_reset
{
//[ verify_reset
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).once().with( 0 );
c.add( 0, 0 );
MOCK_VERIFY( v.display ); // verify all expectations are fulfilled for the 'display' method
mock::verify( v ); // verify all expectations are fulfilled for all methods of 'v'
mock::verify(); // verify all expectations are fulfilled for all existing mock objects
MOCK_RESET( v.display ); // reset all expectations for the 'display' method
mock::reset( v ); // reset all expectations for all methods of 'v'
mock::reset(); // reset all expectations for all existing mock objects
} // automatically verify all expectations are fulfilled for all mock objects going out of scope
//]
}
namespace expectations
{
//[ expectations
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).once().with( 0 ); // this call must occur once (and only once)
MOCK_EXPECT( v.display ).with( 1 ); // this call can occur any number of times (including never)
c.add( 0, 0 );
}
//]
}
namespace sequence
{
//[ sequence
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v;
calculator c( v );
mock::sequence s;
MOCK_EXPECT( v.display ).once().with( 0 ).in( s ); // add this expectation to the sequence
MOCK_EXPECT( v.display ).with( 1 ).in( s ); // add this expectation to the sequence after the previous call
c.add( 0, 0 );
c.add( 1, 0 );
}
//]
}
namespace several_sequences
{
//[ several_sequences
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v;
calculator c( v );
mock::sequence s1, s2;
MOCK_EXPECT( v.display ).once().with( 0 ).in( s1 );
MOCK_EXPECT( v.display ).once().with( 1 ).in( s2 );
MOCK_EXPECT( v.display ).with( 2 ).in( s1, s2 ); // add this expectation to both sequences after the previous calls
c.add( 0, 0 );
c.add( 1, 0 );
c.add( 1, 1 );
c.add( 2, 0 );
}
//]
}

View file

@ -1,48 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_comma_in_macro_problem
template< typename T1, typename T2 >
struct my_base_class
{};
//]
}
namespace limitations_comma_in_macro_solution_1
{
//[ limitations_comma_in_macro_solution_1
typedef my_base_class< int, int > my_base_type;
MOCK_BASE_CLASS( my_mock, my_base_type )
{};
//]
}
namespace limitations_comma_in_macro_solution_2
{
//[ limitations_comma_in_macro_solution_2
template< typename T1, typename T2 >
MOCK_BASE_CLASS( my_mock, my_base_class< T1 BOOST_PP_COMMA() T2 > )
{};
//]
}
namespace limitations_comma_in_macro_solution_3
{
//[ limitations_comma_in_macro_solution_3
template< typename T1, typename T2 >
struct my_mock : my_base_class< T1, T2 >, mock::object
{};
//]
}

View file

@ -1,50 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_const_parameter_warning_problem
class base
{
public:
virtual void method( const int ) = 0;
};
//]
}
namespace limitations_const_parameter_warning_explanation
{
//[ limitations_const_parameter_warning_explanation
class derived : public base
{
public:
virtual void method( const int );
};
void derived::method( int )
{}
//]
}
namespace limitations_const_parameter_warning_solution
{
//[ limitations_const_parameter_warning_solution
MOCK_BASE_CLASS( mock_base, base )
{
void method( const int i )
{
method_stub( i );
}
MOCK_METHOD( method_stub, 1, void( int ), method )
};
//]
}

View file

@ -1,43 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_literal_zero_problem
class base
{
public:
virtual void method( int* i ) = 0;
};
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 1 )
};
//]
}
BOOST_AUTO_TEST_CASE( literal_zero )
{
mock_base m;
//[ limitations_literal_zero_solution_1
MOCK_EXPECT( m.method ).with( mock::equal< int* >( 0 ) ); // this compiles
//]
//[ limitations_literal_zero_solution_2
MOCK_EXPECT( m.method ).with( mock::negate );
//]
#ifdef MOCK_NULLPTR
//[ limitations_literal_zero_solution_3
MOCK_EXPECT( m.method ).with( nullptr );
//]
#endif
}

View file

@ -1,27 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
//[ limitations_non_virtual_method_problem
class base
{
public:
void method() // the method is not virtual
{}
};
//]
//[ limitations_non_virtual_method_problem_2
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 0 )
};
//]

View file

@ -1,29 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_private_method_problem
class base
{
private:
virtual void method() = 0;
};
//]
//[ limitations_private_method_solution
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 0, void() )
};
//]
}

View file

@ -1,83 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace limitations_template_method_problem
{
//[ limitations_template_method_problem
class concept
{
public:
template< typename T >
void method( T t )
{}
};
template< typename T >
void function_under_test( T t ) // T is supposed to model the previous concept
{
t.method( 42 );
t.method( "string" );
}
//]
//[ limitations_template_method_solution
MOCK_CLASS( mock_concept )
{
MOCK_METHOD( method, 1, void( int ), method_int )
MOCK_METHOD( method, 1, void( const char* ), method_string )
};
//]
}
namespace limitations_template_method_problem_2
{
//[ limitations_template_method_problem_2
class concept
{
public:
template< typename T >
T create()
{
return T();
}
};
template< typename T >
void function_under_test( T t ) // T is supposed to model the previous concept
{
t.create< int >();
t.create< std::string >();
}
//]
//[ limitations_template_method_solution_2
MOCK_CLASS( mock_concept )
{
template< typename T >
T create();
template<>
int create< int >()
{
return create_int();
}
template<>
std::string create< std::string >()
{
return create_string();
}
MOCK_METHOD( create_int, 0, int(), create_int )
MOCK_METHOD( create_string, 0, std::string(), create_string )
};
//]
}

View file

@ -1,35 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_throw_specifier_problem
struct base_class
{
virtual ~base_class()
{}
virtual void method() throw ();
};
//]
//[ limitations_throw_specifier_solution
MOCK_BASE_CLASS( mock_class, base_class )
{
void method() throw ()
{
method_proxy();
}
MOCK_METHOD( method_proxy, 0, void(), method )
};
//]
}

View file

@ -1,22 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// 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_VIEW
#define MOCK_VIEW
#include <turtle/mock.hpp>
#include "view.hpp"
//[ mock_view
MOCK_BASE_CLASS( mock_view, view ) // declare a 'mock_view' class implementing 'view'
{
MOCK_METHOD( display, 1 ) // implement the 'display' method from 'view' (taking 1 argument)
};
//]
#endif // MOCK_VIEW

View file

@ -1,76 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/mock/mock.hpp>
#include "calculator.hpp"
#include "mock_view.hpp"
namespace simple
{
//[ simple_calculator
class calculator
{
public:
int add( int a, int b );
};
//]
//[ simple_zero_plus_zero_is_zero
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
calculator c;
BOOST_CHECK_EQUAL( 0, c.add( 0, 0 ) );
}
//]
}
namespace without_mock_object
{
//[ my_view
class my_view : public view
{
public:
my_view()
: called( false )
{}
virtual void display( int result )
{
called = true;
value = result;
}
bool called;
int value;
};
//]
//[ zero_plus_zero_is_zero_without_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
my_view v;
calculator c( v );
c.add( 0, 0 );
BOOST_REQUIRE( v.called );
BOOST_CHECK_EQUAL( 0, v.value );
}
//]
}
namespace with_mock_object
{
//[ zero_plus_zero_is_zero_with_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).once().with( 0 ); // expect the 'display' method to be called once (and only once) with a parameter value equal to 0
c.add( 0, 0 );
}
//]
}

View file

@ -1,61 +0,0 @@
// 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)
//[ async_call_problem
namespace
{
class base_class
{
public:
virtual void method() = 0;
};
class my_class
{
public:
explicit my_class( base_class& );
void flush(); // repetitively calling this method will in turn call base_class::method at some point
};
}
//]
//[ async_call_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread.hpp>
#include <turtle/mock.hpp>
namespace
{
template< typename F >
void wait( bool& condition, F flush, int timeout = 100, int sleep = 100 )
{
while( !condition && timeout > 0 )
{
--timeout;
boost::this_thread::sleep( boost::posix_time::milliseconds( sleep ) );
flush();
}
}
MOCK_BASE_CLASS( mock_base_class, base_class )
{
MOCK_METHOD( method, 0 )
};
}
BOOST_AUTO_TEST_CASE( method_is_called )
{
mock_base_class mock;
my_class c( mock );
bool done = false;
MOCK_EXPECT( mock.method ).once().calls( boost::lambda::var( done ) = true ); // when method is called it will set done to true
wait( done, boost::bind( &my_class::flush, &c ) ); // just wait on done, flushing from time to time
}
//]

View file

@ -1,44 +0,0 @@
// 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)
//[ invoke_functor_problem
#include <boost/function.hpp>
namespace
{
class base_class
{
public:
virtual void method( boost::function< void( int ) > functor ) = 0;
};
void function( base_class& ); // the function will call 'method' with a functor to be applied
}
//]
//[ invoke_functor_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/bind/apply.hpp>
#include <turtle/mock.hpp>
namespace
{
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 1 )
};
}
BOOST_AUTO_TEST_CASE( how_to_invoke_a_functor_passed_as_parameter_of_a_mock_method )
{
mock_class mock;
MOCK_EXPECT( mock.method ).calls( boost::bind( boost::apply< void >(), _1, 42 ) ); // whenever 'method' is called, invoke the functor with 42
function( mock );
}
//]

View file

@ -1,54 +0,0 @@
// 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)
//[ quick_constraint_problem
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
#include <iostream>
namespace
{
class my_class
{
public:
explicit my_class( int data )
: data_( data )
{}
int data_;
};
std::ostream& operator<<( std::ostream& os, const my_class& c ) // my_class is serializable to an std::ostream
{
return os << "my_class( " << c.data_ << " )";
}
MOCK_CLASS( my_mock )
{
MOCK_METHOD( method, 1, void( const my_class& ) ) // how to simply write a custom constraint ?
};
}
//]
//[ quick_constraint_solution
#include <boost/lexical_cast.hpp>
namespace mock // it could also be in the namespace of 'my_class'
{
bool operator==( const my_class& actual, const std::string& expected ) // the first part of the trick is to compare to a string
{
return boost::lexical_cast< std::string >( actual ) == expected;
}
} // mock
BOOST_AUTO_TEST_CASE( method_is_called )
{
my_mock mock;
MOCK_EXPECT( mock.method ).once().with( "my_class( 42 )" ); // the second part of the trick is to express the constraint as a string
mock.method( my_class( 42 ) );
}
//]

View file

@ -1,50 +0,0 @@
// 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)
//[ retrieve_cref_problem
namespace
{
class base_class
{
public:
virtual void method( int value ) = 0;
};
class my_class
{
public:
explicit my_class( base_class& );
void process(); // the processing will call 'method' two times with the same value, but we don't know what value beforehand
};
}
//]
//[ retrieve_cref_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
MOCK_BASE_CLASS( mock_base_class, base_class )
{
MOCK_METHOD( method, 1 )
};
}
BOOST_AUTO_TEST_CASE( method_is_called_two_times_with_the_same_value )
{
mock_base_class mock;
my_class c( mock );
int value;
MOCK_EXPECT( mock.method ).once().with( mock::retrieve( value ) ); // on first call retrieve the value, this expectation takes precedence because it can never fail
MOCK_EXPECT( mock.method ).once().with( boost::cref( value ) ); // on second call compare the previously retrieved value with the newly received one
c.process();
}
//]

View file

@ -1,20 +0,0 @@
// 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)
#include <turtle/mock.hpp>
#include "calculator.hpp"
#include "mock_view.hpp"
//[ overflow_throws
BOOST_AUTO_TEST_CASE( overflow_throws )
{
mock_view v;
calculator c( v );
BOOST_CHECK_THROW( c.add( (std::numeric_limits< int >::max)(), 1 ), std::exception );
}
//]

View file

@ -1,984 +0,0 @@
// 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)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace class_example_1
{
//[ class_example_1
MOCK_CLASS( mock_class )
{};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_class )
{
mock_class c;
}
//]
}
namespace class_example_2
{
//[ class_example_2
template< typename T >
MOCK_CLASS( mock_class )
{};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_template_mock_class )
{
mock_class< int > c;
}
//]
}
namespace class_example_3
{
//[ class_example_3
struct base_class
{};
MOCK_BASE_CLASS( mock_class, base_class )
{};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_derived_mock_class )
{
mock_class c;
}
//]
}
namespace class_example_4
{
//[ class_example_4
template< typename T >
struct base_class
{};
template< typename T >
MOCK_BASE_CLASS( mock_class, base_class< T > )
{};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_template_derived_mock_class )
{
mock_class< int > c;
}
//]
}
namespace class_example_5
{
//[ class_example_5
struct name : mock::object // equivalent to using MOCK_CLASS
{};
//]
}
namespace class_example_6
{
//[ class_example_6
template< typename T >
struct name : mock::object // equivalent to using MOCK_CLASS
{};
//]
}
namespace class_example_7
{
//[ class_example_7
class base
{};
struct name : base, mock::object // equivalent to using MOCK_BASE_CLASS
{
typedef base base_type; // this is required for the shortest form of MOCK_METHOD to work when not using MOCK_BASE_CLASS
};
//]
}
namespace class_example_8
{
//[ class_example_8
template< typename T >
struct base
{};
template< typename T >
struct mock : base< T >, mock::object
{
typedef typename base< T > base_type;
};
//]
}
namespace member_function_example_1
{
//[ member_function_example_1
struct base_class
{
virtual ~base_class()
{}
virtual void method( int ) = 0;
};
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 1 ) // only possible when referring unambiguously to a base class method
};
//]
}
namespace member_function_example_2
{
//[ member_function_example_2
struct base_class
{
virtual ~base_class()
{}
virtual void method( int, const std::string& ) = 0;
virtual void method( float ) = 0;
};
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ), identifier_1 ) // both the signature and identifier must be specified because of ambiguity due to overloading
MOCK_METHOD( method, 1, void( float ), identifier_2 ) // the identifier must differ from the previous one in order to fully disambiguate methods
};
//]
}
namespace member_function_example_3
{
//[ member_function_example_3
struct base_class
{
virtual ~base_class()
{}
virtual void method( float ) = 0;
virtual void method( float ) const = 0;
};
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 1, void( float ) ) // this generates both const and non-const versions
};
//]
}
namespace member_function_example_4
{
//[ member_function_example_4
struct base_class
{
virtual ~base_class()
{}
virtual void method( float ) = 0;
virtual void method( float ) const = 0;
};
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_CONST_METHOD( method, 1, void( float ), identifier_1 ) // this generates only the const version
MOCK_NON_CONST_METHOD( method, 1, void( float ), identifier_2 ) // this generates only the non-const version, with a different identifier
};
//]
}
namespace member_function_example_5
{
//[ member_function_example_5
struct base_class
{
virtual ~base_class()
{}
virtual void method( float ) = 0;
};
struct mock_class : base_class
{
typedef base_class base_type; // this is required for MOCK_METHOD to work when not using MOCK_BASE_CLASS
MOCK_METHOD( method, 1 )
};
//]
}
namespace member_function_example_6
{
//[ member_function_example_6
MOCK_CLASS( mock_class )
{
MOCK_NON_CONST_METHOD( operator=, 1, mock_class&( const mock_class& ), assignment ) // operators require a custom identifier
};
//]
}
namespace member_function_example_7
{
//[ member_function_example_7
template< typename T >
MOCK_CLASS( mock_class )
{
MOCK_METHOD_TPL( method, 1, void( const T& ) ) // the _TPL variants must be used if the signature includes a template parameter of the class
};
//]
}
namespace member_function_example_8
{
//[ member_function_example_8
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 0, (std::map< int, int >()) ) // the signature must be surrounded with round parenthesis if the return type contains a comma
};
//]
}
#ifdef BOOST_MSVC
namespace member_function_example_9
{
//[ member_function_example_9
MOCK_CLASS( mock_class )
{
MOCK_METHOD( __stdcall method, 0, void(), method ) // all parameters must be provided when specifying a different calling convention
};
//]
}
#elif defined( BOOST_GCC )
namespace member_function_example_10
{
//[ member_function_example_10
MOCK_CLASS( mock_class )
{
MOCK_METHOD( __attribute((stdcall)) method, 0, void(), method ) // all parameters must be provided when specifying a different calling convention
};
//]
}
#endif
namespace static_member_function_example_1
{
//[ static_member_function_example_1
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, float( int ) )
};
//]
}
namespace static_member_function_example_2
{
//[ static_member_function_example_2
template< typename T >
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD_TPL( method, 1, void( T ) )
};
//]
}
#ifdef BOOST_MSVC
namespace static_member_function_example_3
{
//[ static_member_function_example_3
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( __stdcall method, 0, void(), method ) // all parameters must be provided when specifying a different calling convention
};
//]
}
#elif defined( BOOST_GCC )
namespace static_member_function_example_4
{
//[ static_member_function_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( __attribute((stdcall)) method, 0, void(), method ) // all parameters must be provided when specifying a different calling convention
};
//]
}
#endif
namespace constructor_example_1
{
//[ constructor_example_1
MOCK_CLASS( mock_class )
{
MOCK_CONSTRUCTOR( mock_class, 2, ( int, const std::string& ), identifier )
};
//]
}
namespace constructor_example_2
{
//[ constructor_example_2
template< typename T >
MOCK_CLASS( mock_class )
{
MOCK_CONSTRUCTOR( mock_class, 2, ( int, const std::string& ), identifier )
MOCK_CONSTRUCTOR_TPL( mock_class, 2, ( T, const std::string& ), identifier )
};
//]
}
#ifdef BOOST_MSVC
namespace constructor_example_3
{
//[ constructor_example_3
MOCK_CLASS( mock_class )
{
MOCK_CONSTRUCTOR( __stdcall mock_class, 0, (), constructor )
};
//]
}
#elif defined( BOOST_GCC )
namespace constructor_example_4
{
//[ constructor_example_4
MOCK_CLASS( mock_class )
{
MOCK_CONSTRUCTOR( __attribute((stdcall)) mock_class, 0, (), constructor )
};
//]
}
#endif
namespace destructor_example_1
{
//[ destructor_example_1
MOCK_CLASS( mock_class )
{
MOCK_DESTRUCTOR( ~mock_class, destructor )
};
//]
}
#ifdef BOOST_MSVC
namespace destructor_example_2
{
//[ destructor_example_2
MOCK_CLASS( mock_class )
{
MOCK_DESTRUCTOR( __stdcall ~mock_class, destructor )
};
//]
}
#elif defined( BOOST_GCC )
namespace destructor_example_3
{
//[ destructor_example_3
MOCK_CLASS( mock_class )
{
MOCK_DESTRUCTOR( __attribute((stdcall)) ~mock_class, destructor )
};
//]
}
#endif
namespace conversion_operator_example_1
{
//[ conversion_operator_example_1
MOCK_CLASS( mock_class )
{
MOCK_CONVERSION_OPERATOR( operator, int, conversion_to_int )
MOCK_CONST_CONVERSION_OPERATOR( operator, const std::string&, conversion_to_string )
};
//]
}
namespace conversion_operator_example_2
{
//[ conversion_operator_example_2
template< typename T >
MOCK_CLASS( mock_class )
{
MOCK_CONVERSION_OPERATOR_TPL( operator, T, conversion_to_T ) // the _TPL variants must be used if the signature includes a template parameter of the class
MOCK_CONST_CONVERSION_OPERATOR( operator, const std::string&, const_conversion_to_string )
MOCK_NON_CONST_CONVERSION_OPERATOR( operator, const std::string&, non_const_conversion_to_string )
};
//]
}
#ifdef BOOST_MSVC
namespace conversion_operator_example_3
{
//[ conversion_operator_example_3
MOCK_CLASS( mock_class )
{
MOCK_CONVERSION_OPERATOR( __stdcall operator, int, conversion_to_int )
};
//]
}
#elif defined( BOOST_GCC )
namespace conversion_operator_example_4
{
//[ conversion_operator_example_4
MOCK_CLASS( mock_class )
{
MOCK_CONVERSION_OPERATOR( __attribute((stdcall)) operator, int, conversion_to_int )
};
//]
}
#endif
namespace function_example_1
{
//[ function_example_1
MOCK_FUNCTION( f, 1, float( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_function )
{
f( 3 );
}
//]
}
#ifdef BOOST_MSVC
namespace function_example_2
{
//[ function_example_2
MOCK_FUNCTION( __stdcall f, 0, void(), f ) // all parameters must be provided when specifying a different calling convention
//]
}
#elif defined( BOOST_GCC )
namespace function_example_3
{
//[ function_example_3
MOCK_FUNCTION( __attribute((stdcall)) f, 0, void(), f ) // all parameters must be provided when specifying a different calling convention
//]
}
#endif
namespace functor_example_1
{
//[ functor_example_1
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int ) );
f( 3 );
}
//]
}
namespace functor_example_2
{
//[ functor_example_2
template< typename T >
struct mock_class
{
MOCK_FUNCTOR_TPL( f, void( T ) );
};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
{
mock_class< int > c;
c.f( 3 );
}
//]
}
namespace expectation_example_1
{
//[ expectation_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, int( int ), method )
MOCK_METHOD( method, 2, void( const std::string&, float ), method2 )
};
BOOST_AUTO_TEST_CASE( demonstrates_configuring_mock_objects )
{
mock_class c;
mock::sequence s;
MOCK_EXPECT( c.method ).once().with( 0 ).in( s ).returns( 42 );
MOCK_EXPECT( c.method2 ).never().with( "ok", mock::any );
MOCK_EXPECT( c.method2 ).at_least( 2 ).in( s ).throws( std::runtime_error( "error !" ) );
}
//]
}
namespace invocation_example_1
{
//[ invocation_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_invocations_on_a_mock_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once(); // can only be called once
MOCK_EXPECT( c.method ); // can be called an unlimited number of times
}
//]
}
namespace invocation_example_2
{
//[ invocation_example_2
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int, const std::string& ) );
MOCK_EXPECT( f ).once();
}
//]
}
namespace invocation_example_3
{
//[ invocation_example_3
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_function )
{
MOCK_EXPECT( f ).once();
}
//]
}
namespace invocation_example_4
{
//[ invocation_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_static_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once();
MOCK_EXPECT( mock_class::method ).once(); // does the same
}
//]
}
namespace constraints_example_1
{
//[ constraints_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_builtin_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::equal( 3 ), mock::equal( "some string" ) );
MOCK_EXPECT( c.method ).with( 3, "some string" ); // equivalent to the previous one using short-cuts
}
//]
}
namespace constraints_example_2
{
//[ constraints_example_2
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
bool custom_constraint( int actual )
{
return actual == 42;
}
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_free_function )
{
mock_class c;
MOCK_EXPECT( c.method ).with( &custom_constraint );
}
//]
}
namespace constraints_example_3
{
//[ constraints_example_3
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
bool custom_constraint( int expected, int actual )
{
return expected == actual;
}
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_standard_library_functor )
{
mock_class c;
MOCK_EXPECT( c.method ).with( std::bind1st( std::ptr_fun( &custom_constraint ), 42 ) ); // std::ptr_fun creates an std::unary_function
}
//]
}
namespace constraints_example_4
{
//[ constraints_example_4
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
bool custom_constraint( int expected, int actual )
{
return expected == actual;
}
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_bind )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::bind( &custom_constraint, 42, _1 ) );
}
//]
}
#ifndef BOOST_MSVC // this produces an ICE with all versions of MSVC
#include <boost/lambda/lambda.hpp>
namespace constraints_example_5
{
//[ constraints_example_5
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_lambda )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::lambda::_1 == 42 );
}
//]
}
#endif // BOOST_MSVC
#include <boost/phoenix/phoenix.hpp>
namespace constraints_example_6
{
//[ constraints_example_6
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_phoenix )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::arg1 == 42 );
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::_1 == 42 );
}
//]
}
#ifdef MOCK_LAMBDAS
namespace constraints_example_7
{
//[ constraints_example_7
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_constraint_with_cxx11_lambda )
{
mock_class c;
MOCK_EXPECT( c.method ).with( []( int actual ) { return 42 == actual; } );
}
//]
}
#endif
namespace constraints_example_8
{
//[ constraints_example_8
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_combining_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::less( 4 ) && mock::greater( 2 ), ! mock::equal( "" ) );
}
//]
}
namespace sequence_example_1
{
//[ sequence_example_1
MOCK_CLASS( mock_class_1 )
{
MOCK_METHOD( method_1, 0, void() )
};
MOCK_CLASS( mock_class_2 )
{
MOCK_METHOD( method_2, 0, void() )
};
MOCK_CLASS( mock_class_3 )
{
MOCK_METHOD( method_3, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_enforcing_several_expectation_orders )
{
mock_class_1 c_1;
mock_class_2 c_2;
mock_class_3 c_3;
mock::sequence s_1, s_2;
MOCK_EXPECT( c_1.method_1 ).in( s_1 );
MOCK_EXPECT( c_2.method_2 ).in( s_2 ); // c_1.method_1 and c_2.method_2 are in different sequences and can be called in any order
MOCK_EXPECT( c_3.method_3 ).in( s_1, s_2 ); // c_3.method_3 must be called after both c_1.method_1 and c_2.method_2
}
//]
}
namespace action_example_1
{
//[ action_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, int( int ) )
};
int function( int i )
{
return i;
}
BOOST_AUTO_TEST_CASE( demonstrates_configuring_actions )
{
mock_class c;
MOCK_EXPECT( c.method ).returns( 42 );
MOCK_EXPECT( c.method ).moves( 42 ); // returns by moving the value
MOCK_EXPECT( c.method ).throws( std::runtime_error( "error !" ) );
MOCK_EXPECT( c.method ).calls( &function ); // forwards 'method' parameter to 'function'
MOCK_EXPECT( c.method ).calls( boost::bind( &function, 42 ) ); // drops 'method' parameter and binds 42 as parameter to 'function'
MOCK_EXPECT( c.method ).calls( []( int i ) { return i; } ); // uses a C++11 lambda
}
//]
}
namespace verification_example_1
{
//[ verification_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_mock_method )
{
mock_class c;
MOCK_VERIFY( c.method ); // logs an error and returns false if not all expectations are met
mock::verify( c ); // verifies all expectations set for all methods of 'c'
mock::verify(); // verifies all existing mock objects, functions and functors
}
//]
}
namespace verification_example_2
{
//[ verification_example_2
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_VERIFY( f ); // logs an error and returns false if not all expectations are met
mock::verify( f ); // behaves the same as MOCK_VERIFY
mock::verify(); // verifies all existing mock objects, functions and functors
}
//]
}
namespace verification_example_3
{
//[ verification_example_3
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_mock_function )
{
MOCK_VERIFY( f ); // logs an error and returns false if not all expectations are met
mock::verify(); // verifies all existing mock objects, functions and functors
}
//]
}
namespace verification_example_4
{
//[ verification_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_static_mock_method )
{
mock_class c;
MOCK_VERIFY( c.method ); // logs an error and returns false if not all expectations are met
MOCK_VERIFY( mock_class::method ); // does the same
mock::verify(); // verifies all existing mock objects, functions and functors
}
//]
}
namespace reset_example_1
{
//[ reset_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_mock_method )
{
mock_class c;
MOCK_RESET( c.method ); // resets all expectations set for 'c.method'
mock::reset( c ); // resets all expectations set on 'c'
mock::reset(); // resets all existing mock objects, functions and functors
}
//]
}
namespace reset_example_2
{
//[ reset_example_2
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_RESET( f ); // resets all expectations set for 'f'
mock::reset( f ); // behaves the same as MOCK_RESET
mock::reset(); // resets all existing mock objects, functions and functors
}
//]
}
namespace reset_example_3
{
//[ reset_example_3
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_mock_function )
{
MOCK_RESET( f ); // resets all expectations set for 'f'
mock::reset(); // resets all existing mock objects, functions and functors
}
//]
}
namespace reset_example_4
{
//[ reset_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_static_mock_method )
{
mock_class c;
MOCK_RESET( c.method ); // resets all expectations set for 'c::method'
MOCK_RESET( mock_class::method ); // resets all expectations set for 'c::method'
mock::reset(); // resets all existing mock objects, functions and functors
}
//]
}
namespace helpers_example_1
{
//[ helpers_example_1
MOCK_CONSTRAINT( any, true ) // this is how mock::any could be defined
MOCK_CONSTRAINT( forty_two, actual == 42 ) // this defines a 'forty_two' constraint
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( forty_two );
MOCK_EXPECT( f ).with( any );
}
//]
}
namespace helpers_example_2
{
//[ helpers_example_2
MOCK_CONSTRAINT( equal, expected, actual == expected ) // this is how mock::equal could be defined
MOCK_CONSTRAINT( near, expected, std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42 ) );
MOCK_EXPECT( f ).with( equal( 42 ) );
}
//]
}
namespace helpers_example_3
{
//[ helpers_example_3
MOCK_CONSTRAINT( near, expected, tolerance, std::abs( actual - expected ) < tolerance ) // this is how mock::near could be defined
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
}
//]
}
namespace helpers_example_4
{
//[ helpers_example_4
MOCK_CONSTRAINT_EXT( any, 0,, true ) // this is (almost) how mock::any is defined
MOCK_CONSTRAINT_EXT( forty_two, 0,, actual == 42 ) // this defines a 'forty_two' constraint
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( forty_two );
MOCK_EXPECT( f ).with( any );
}
//]
}
namespace helpers_example_5
{
//[ helpers_example_5
MOCK_CONSTRAINT_EXT( equal, 1, ( expected ), actual == expected ) // this is how mock::equal is defined
MOCK_CONSTRAINT_EXT( near, 1, ( expected ), std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42 ) );
MOCK_EXPECT( f ).with( equal( 42 ) );
}
//]
}
namespace helpers_example_6
{
//[ helpers_example_6
MOCK_CONSTRAINT_EXT( near, 2, ( expected, tolerance ), std::abs( actual - expected ) < tolerance ) // this is how mock::near is defined
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
}
//]
}

View file

@ -1,20 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// 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 VIEW
#define VIEW
//[ view
class view
{
public:
virtual void display( int result ) = 0;
};
//]
#endif // VIEW

View file

@ -1,100 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Getting Started]
[import example/getting_started.cpp]
This section introduces most of the library features in a series of use cases built on the example from the [link turtle.motivation motivation] section.
For all the code examples the following is assumed :
[prerequisite]
[section Create, expect, trigger, verify]
A simple unit test with mock objects usually splits into several phases as illustrated by :
[phases]
Triggering the object under test in turn calls methods on the mock objects, and any unexpected call raises an error.
Mock objects are automatically verified during their destruction and an error is signalled if any unfulfilled expectation remains.
More sophisticated tests sometimes require more complex use cases and in particular might need to verify or reset mock objects.
Here is an example highlighting the different possibilities :
[verify_reset]
Note that all verifications upon destruction will be disabled if the mock objects are destroyed in the context of an exception being raised.
[endsect]
[section Expectation selection algorithm]
A method can be configured with several expectations, for instance :
[expectations]
Each method call is then handled by processing the expectations in the order they have been defined :
# looking for a match with valid parameter constraints evaluated from left to right
# checking that the invocation count for this match is not exhausted
An error is raised if none can be found.
By default the relative order of the calls does not matter. It can however be enforced :
[sequence]
Therefore an error will be issued if the second expectation is matched before the first one has been exhausted.
An expectation can be part of several sequences :
[several_sequences]
[endsect]
[section Error diagnostic]
During the execution of a test case, an error can happen for one of the following reasons :
* unexpected call when no match can be found for the given arguments (typically logs an error and throws an exception)
* sequence failure when an enforced call sequence has not been followed (typically logs an error and throws an exception)
* verification failure if a remaining match has not been fulfilled upon manual verification (typically logs an error)
* untriggered expectation if a remaining match has not been fulfilled when destroying the mock object (typically logs an error)
* missing action if a method supposed to return something else than void has not been configured properly (typically logs an error and throws an exception)
The exact type of the exception thrown depends on the [link turtle.customization.test_framework_integration test framework integration] used.
An error log typically looks like :
unknown location(0): error in "zero_plus_zero_is_zero": unexpected call: v.mock_view::display( 0 )
v once().with( 1 )
v once().with( 2 )
. once().with( 3 )
On the first line is the description of what happened : here the display method of object v of class mock_view has been called with an actual value of 0.
The following lines list the set expectations with the check (the v character) meaning the expectation has been exhausted.
It therefore means that the two first expectations have been fulfilled by two calls, and then instead of 3 in the third call 0 has been erroneously passed on to the mock object.
Another common error looks like :
src/tests/turtle_test/Tutorial.cpp(73): error in "zero_plus_zero_is_zero": untriggered expectation: v.mock_view::display
v once().with( 1 )
v once().with( 2 )
. once().with( 3 )
The first line tells that a set expectation has not been fulfilled. The file and line number give the location where the corresponding expectation has been configured.
The following lines once again list the set expectations.
It means the two first calls correctly passed the expected values to the mock object, but then no third call happened.
[endsect]
[endsect]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,237 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Limitations]
[import example/limitations_literal_zero.cpp]
[import example/limitations_throw_specifier.cpp]
[import example/limitations_non_virtual_method.cpp]
[import example/limitations_template_method.cpp]
[import example/limitations_private_method.cpp]
[import example/limitations_comma_in_macro.cpp]
[import example/limitations_const_parameter_warning.cpp]
This section lists the library known limitations.
[section No support for unicode logging]
There is no support for unicode logging mainly because Boost.Test does not support it either.
[endsect]
[section Literal 0 cannot be used as null pointer in constraints]
Given :
[limitations_literal_zero_problem]
The following code does not compile :
BOOST_AUTO_TEST_CASE( literal_zero )
{
mock_base m;
MOCK_EXPECT( m.method ).with( mock::equal( 0 ) ); // this fails
MOCK_EXPECT( m.method ).with( 0 ); // this fails too !
}
This is due to the fact that the library uses templates pretty heavily, and literal 0 is considered as an int when instantiating a template function.
A workaround is :
[limitations_literal_zero_solution_1]
However a somewhat better solution would be :
[limitations_literal_zero_solution_2]
or with C++11 nullptr support :
[limitations_literal_zero_solution_3]
[endsect]
[section Template methods cannot be mocked]
Given :
[limitations_template_method_problem]
writing a mock object modeling 'concept' requires to list all the possible versions of 'method' :
[limitations_template_method_solution]
However if one or more template parameters must be explicitly specified as in :
[limitations_template_method_problem_2]
delegate methods must be manually added :
[limitations_template_method_solution_2]
While still somewhat possible, mocking a template method can indeed prove a bit cumbersome.
[endsect]
[section Non-virtual methods cannot be mocked]
Given :
[limitations_non_virtual_method_problem]
the following code compiles but will not work as expected :
[limitations_non_virtual_method_problem_2]
The mock object will never be exercised because the library relies on polymorphism to hook the calls.
There is no other solution than to refactor the production code, the most simple being to change the method to virtual.
[endsect]
[section Private virtual methods cannot be mocked without spelling out the signature]
Given :
[limitations_private_method_problem]
the following code does not compile :
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 0 ) // this fails because 'method' is not visible
};
A workaround would be to add the signature to MOCK_METHOD :
[limitations_private_method_solution]
[endsect]
[section Methods with a throw specifier cannot be mocked]
Given :
[limitations_throw_specifier_problem]
the following code does not compile :
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 0 ) // this fails because of the throw specifier
};
A workaround would be to write a proxy member function :
[limitations_throw_specifier_solution]
[endsect]
[section Compilers without support for variadic macros fail on commas in MOCK_BASE_CLASS]
For compilers without support for variadic macros given :
[limitations_comma_in_macro_problem]
the following code does not compile :
MOCK_BASE_CLASS( my_mock, my_base_class< int, int > ) // this fails because the pre-processor believes the macro to be called with 3 arguments
{};
One workaround is :
[limitations_comma_in_macro_solution_1]
Of course this is not always possible, as in :
template< typename T1, typename T2 >
MOCK_BASE_CLASS( my_mock, my_base_type< T1, T2 > )
{};
Another workaround would make use of [@http://www.boost.org/libs/preprocessor Boost.Preprocessor] :
[limitations_comma_in_macro_solution_2]
Actually BOOST_PP_COMMA implementation is quite trivial, being only :
#define BOOST_PP_COMMA() ,
Finally another workaround would be to not use the macro at all :
[limitations_comma_in_macro_solution_3]
Note that [@http://www.boost.org/libs/utility/identity_type/doc/html/index.html Boost.IdentityType] is of little help here because the type is by essence very often abstract, which doesn't work well for some compilers (e.g. gcc).
[endsect]
[section Warning C4505: '...' : unreferenced local function has been removed]
Example :
[teletype]
warning C4505: 'base::[thunk]: __thiscall base::`vcall'{0,{flat}}' }'' : unreferenced local function has been removed
[c++]
This seems to be [@https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324427 a random bug] with some versions of the Microsoft Visual Studio compiler.
The only known workaround is to disable the warning with a pragma :
#pragma warning( disable: 4505 )
[endsect]
[section Warning C4301: '...': overriding virtual function only differs from '...' by const/volatile qualifier]
Example :
[teletype]
warning C4301: '`anonymous-namespace'::base::method': overriding virtual function only differs from '`anonymous-namespace'::base::method' by const/volatile qualifier
[c++]
Given :
[limitations_const_parameter_warning_problem]
the following code produces this warning with some versions of the Microsoft Visual Studio compiler :
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 1 ) // this produces the warning
MOCK_METHOD( method, 1, void( const int ) ) // forcing the signature will not help, this produces the warning too !
};
The problem is that the 'const' is actually not part of the function signature and therefore cannot be introspected.
The first workaround would be to remove the 'const' all together.
This is more sensible than it first sounds, after all the 'const' is useless in this situation, indeed the following compiles, links and is valid C++ :
[limitations_const_parameter_warning_explanation]
Otherwise another workaround would be to provide a proxy method :
[limitations_const_parameter_warning_solution]
[endsect]
[section Warning C4267: 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data]
Compiling under Microsoft Visual Studio with the /Wp64 flag produces this warning at various locations in the library code.
This is actually a bug in the compiler, for more information see [@http://connect.microsoft.com/VisualStudio/feedback/details/253172/incorrect-warning-c4267 incorrect-warning-c4267].
[endsect]
[section Using C++11 lambda as constraints requires decltype compiler support]
The technique used in order to detect whether a constraint is a C++11 lambda or not is based on decltype, which means the library can fail to detect a lambda in case the compiler does not support it.
[endsect]
[endsect]

View file

@ -1,37 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[article Turtle
[quickbook 1.5]
[/ [authors [Champlon, Mathieu]] ]
[authors [,A C++ mock object library for Boost]]
[copyright 2008-2014 Mathieu Champlon]
[license
Distributed under the [@http://www.boost.org/LICENSE_1_0.txt Boost Software License, Version 1.0].
]
[/ [purpose A C++ mock object library for Boost] ]
]
[note Turtle is not an official Boost library.]
[/
[section:introduction Introduction]
[endsect]
]
[include motivation.qbk]
[include getting_started.qbk]
[include customization.qbk]
[/ [xinclude reference.xml] ]
[include reference.qbk]
[include patterns.qbk]
[include limitations.qbk]
[include rationale.qbk]
[include changelog.qbk]
[/ [include future_work.qbk] ]
[include acknowledgements.qbk]

View file

@ -1,41 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Motivation]
[import example/motivation.cpp]
[import example/calculator.hpp]
[import example/mock_view.hpp]
[import example/view.hpp]
Consider a (very) simple calculator class :
[simple_calculator]
Obviously writing unit tests for such a class is trivial, one of them could be :
[simple_zero_plus_zero_is_zero]
What now if the calculator class looks more like this :
[view]
[calculator]
Writing unit tests becomes a bit more tedious and requires some boiler-plate code, for instance :
[my_view]
[zero_plus_zero_is_zero_without_mock_object]
Mock objects main purpose is to alleviate the user from the burden of writing all this boiler-plate code.
Here is how the last test can be rewritten using a mock object :
[mock_view]
[zero_plus_zero_is_zero_with_mock_object]
and all the checks are automatically handled by the library.
[endsect]

View file

@ -1,64 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Patterns]
[import example/patterns_async_call.cpp]
[import example/patterns_retrieve_cref.cpp]
[import example/patterns_invoke_functor.cpp]
[import example/patterns_quick_constraint.cpp]
This section highlights not-so-obvious features of the library gathered from real use cases.
[section Waiting for an asynchronous call]
Problem :
[async_call_problem]
Solution :
[async_call_solution]
[endsect]
[section Retrieving an argument to use in a later constraint]
Problem :
[retrieve_cref_problem]
Solution :
[retrieve_cref_solution]
[endsect]
[section Invoking a functor received as parameter]
Problem :
[invoke_functor_problem]
Solution :
[invoke_functor_solution]
[endsect]
[section Quickly writing a custom constraint for a serializable type]
Problem :
[quick_constraint_problem]
Solution :
[quick_constraint_solution]
[endsect]
[endsect]

View file

@ -1,61 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section:rationale Rationale]
[import example/rationale.cpp]
This section explains some of the design and implementation choices.
[section General design forces]
The general idea behind the library design is to be able to write tests quickly and easily as well as to get the best possible diagnostic upon error (both compile and runtime errors).
The chainable syntax has been chosen in order to be as intuitive as possible, with the most simple form covering the most general use cases.
Several design choices follow the same motivation :
* expectations are automatically verified upon destruction
* both const and non-const versions of a method are mocked by default
* the short-cuts for adding constraints cover 95% of the use cases
* non-serializable types do not yield compilation errors but are logged as '?' by default
At the same time customizing any aspect of the library should require minimum effort, for instance :
* custom constraints can be any functors, including free functions
* customizing the logging of a type is done by defining a serialization operator
* integrating into a test framework is made possible by writing a simple custom policy
[endsect]
[section Exceptions thrown should not extend std::exception]
By design the exceptions thrown upon error should not inherit from std::exception, for instance consider the following test case based on the example from the [link turtle.motivation motivation] section :
[overflow_throws]
Any call to 'v' will be unexpected and yield an exception, which if it were an std::exception would erroneously make the test succeed whereas it is supposed to pass only if the operation overflows (thus not triggering 'v').
[endsect]
[section The library interface is based on many macros]
Despite being often considered harmful they also provide a number of advantages :
* they pack a lot of code and hide implementation details (MOCK_BASE_CLASS, MOCK_METHOD)
* they make the interface homogeneous (MOCK_FUNCTOR, MOCK_CLASS)
* line number and file name can be added for logging purposes (MOCK_EXPECT)
Variadic macros are available for fairly recent compilers and provide a smoother user interface :
* they help seemlessly support arguments containing commas (MOCK_BASE_CLASS)
* they make some of the parameters optional (MOCK_METHOD)
An alternate more portable set of macros is provided for maximum portability if needed.
[endsect]
[endsect]

View file

@ -1,604 +0,0 @@
[/
/ Copyright (c) 2014 Mathieu Champlon
/
/ 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)
/]
[section Reference]
[import example/reference.cpp]
This section describes the library syntax exhaustively.
All source code snippets assume the following prerequisite :
[prerequisite]
[section Creation]
Mock objects can be assigned and copied around freely, unless they derive from a type which disables it.
Copies of a mock object share the same internal state, meaning setting an expectation on one of them will impact all of them. Thus it is possible to let an object under test copy a mock object and still be able to set, verify or reset expectations.
The library defines a set of convenient macros for creating mock objects of different kinds :
* classes
* functors
* functions
Creating a mock object involves two parts under the hood :
* defining an object
* declaring an identifier for manipulating the object
Most of the time the identifier will be identical to the object name, but in case of ambiguity (for instance overloaded methods) a different identifier will have to be specified.
[warning Creating a mock object creates a new object and does not magically replace existing ones, for instance creating a mock function will not replace an already existing function with the same name and signature.]
[section Class]
Synopsis :
MOCK_CLASS( name ) // defines a class
MOCK_BASE_CLASS( name, base ) // defines a class deriving from a base class
The preferred form for defining a mock class is with using MOCK_CLASS and MOCK_BASE_CLASS, however using a regular struct or class is also perfectly fine.
Example :
[class_example_1]
Example :
[class_example_2]
Example :
[class_example_3]
Example :
[class_example_4]
Example :
[class_example_5]
Example :
[class_example_6]
Example :
[class_example_7]
Example :
[class_example_8]
Deriving from mock::object is optional but provides the additional following benefits :
* the object acts as a composite to [link turtle.reference.verification verify] and [link turtle.reference.reset reset] all the expectations for all its methods at once
* logs involving the object are enhanced because configuring an expectation for a method will set the class name for all the other methods as well
[endsect]
[section Member function]
Synopsis :
MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates both const and non-const methods
MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the const version of the method
MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the non-const version of the method
MOCK_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates both const and non-const methods
MOCK_CONST_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates only the const version of the method
MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates only the non-const version of the method
[note If the identifier is omitted it will default to the method name.]
[note If the method name is not ambiguous both the signature and the identifier can be omitted in the context of a derived MOCK_BASE_CLASS or base_type typedef.]
[note The signature must be surrounded with round parenthesis if the return type contains a comma.]
[note [link turtle.reference.creation.constructor Constructors], [link turtle.reference.creation.destructor destructors] and [link turtle.reference.creation.conversion_operator conversion operators] require special care.]
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the MOCK_METHOD_EXT familly set of macros must be used.]
Synopsis :
MOCK_METHOD_EXT( [calling convention] name, arity, signature, identifier ) // generates both const and non-const methods
MOCK_CONST_METHOD_EXT( [calling convention] name, arity, signature, identifier ) // generates only the const version of the method
MOCK_NON_CONST_METHOD_EXT( [calling convention] name, arity, signature, identifier ) // generates only the non-const version of the method
MOCK_METHOD_EXT_TPL( [calling convention] name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, generates both const and non-const methods
MOCK_CONST_METHOD_EXT_TPL( [calling convention] name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, generates only the const version of the method
MOCK_NON_CONST_METHOD_EXT_TPL( [calling convention] name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, generates only the non-const version of the method
Example :
[member_function_example_1]
Example :
[member_function_example_2]
Example :
[member_function_example_3]
Example :
[member_function_example_4]
Example :
[member_function_example_6]
Example :
[member_function_example_7]
Example :
[member_function_example_8]
Example for msvc :
[member_function_example_9]
Example for gcc :
[member_function_example_10]
[endsect]
[section Static member function]
Synopsis :
MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] ) // if 'identifier' is omitted it will default to 'name'
MOCK_STATIC_METHOD_TPL( [calling convention] name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, if 'identifier' is omitted it will default to 'name'
[note A static object is used behind the scene in order to keep track of the expectations of a mock static method, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the static method at the end of each test.]
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the identifier cannot be omitted and must be given explicitly.]
Example :
[static_member_function_example_1]
Example :
[static_member_function_example_2]
Example for msvc :
[static_member_function_example_3]
Example for gcc :
[static_member_function_example_4]
[endsect]
[section Constructor]
Synopsis :
MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
MOCK_CONSTRUCTOR_TPL( [calling convention] name, arity, parameters, identifier ) // must be used if the signature uses a template parameter of the class
[note As constructors do not have a return type, the usual signature gets restricted here to just the parameters.]
Example :
[constructor_example_1]
Example :
[constructor_example_2]
Example for msvc :
[constructor_example_3]
Example for gcc :
[constructor_example_4]
[endsect]
[section Destructor]
Synopsis :
MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
[note When mocking a destructor it is strongly suggested to manually [link turtle.reference.verification verify] the expectation at the end of the test, because the automatic verification will not be triggered if the mock object is not destroyed.]
Example :
[destructor_example_1]
Example for msvc :
[destructor_example_2]
Example for gcc :
[destructor_example_3]
[endsect]
[section Conversion operator]
Synopsis :
MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier ) // generates both const and non-const operators
MOCK_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier ) // generates only a const operator
MOCK_NON_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier ) // generates only a non-const operator
MOCK_CONVERSION_OPERATOR_TPL( [calling convention] name, type, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_CONST_CONVERSION_OPERATOR_TPL( [calling convention] name, type, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_NON_CONST_CONVERSION_OPERATOR_TPL( [calling convention] name, type, identifier ) // must be used if the signature uses a template parameter of the class
Example :
[conversion_operator_example_1]
Example :
[conversion_operator_example_2]
Example for msvc :
[conversion_operator_example_3]
Example for gcc :
[conversion_operator_example_4]
[endsect]
[section Function]
Synopsis :
MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] ) // if 'identifier' is omitted it will default to 'name'
[note A static object is used behind the scene in order to keep track of the expectations of a mock function, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the mock function at the end of each test.]
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the identifier cannot be omitted and must be given explicitly.]
Example :
[function_example_1]
Example for msvc :
[function_example_2]
Example for gcc :
[function_example_3]
[endsect]
[section Functor]
Synopsis :
MOCK_FUNCTOR( [calling convention] name, signature );
MOCK_FUNCTOR_TPL( [calling convention] name, signature ); // must be used if the signature uses a template parameter
Example :
[functor_example_1]
Example :
[functor_example_2]
[endsect]
[endsect]
[section Expectation]
An expectation is a statement of configuration for a mock object.
Synopsis :
MOCK_EXPECT( identifier ).``[link turtle.reference.expectation.invocation invocation]``( arguments ).with( ``[link turtle.reference.expectation.constraints constraints]`` ).in( ``[link turtle.reference.expectation.sequence sequences]`` ).``[link turtle.reference.expectation.actions action]``( value );
[note The identifier refers to the one specified when [link turtle.reference.creation creating] a mock object.]
Example :
[expectation_example_1]
[section Invocation]
An invocation defines how many times a mock object is to be exercised.
Synopsis :
MOCK_EXPECT( identifier ); // any number of times including never
MOCK_EXPECT( identifier ).once();
MOCK_EXPECT( identifier ).never();
MOCK_EXPECT( identifier ).exactly( count );
MOCK_EXPECT( identifier ).at_least( min );
MOCK_EXPECT( identifier ).at_most( max );
MOCK_EXPECT( identifier ).between( min, max ); // throws std::invalid_argument if 'min' > 'max'
Example :
[invocation_example_1]
Example :
[invocation_example_2]
Example :
[invocation_example_3]
Example :
[invocation_example_4]
[endsect]
[section Constraints]
Constraints validate the actual parameter values of a call to a mock object.
Synopsis :
MOCK_EXPECT( identifier ).with( constraint ); // one constraint for all parameters
MOCK_EXPECT( identifier ).with( constraint_1, constraint_2, ... ); // one constraint for each parameter
In the following table 'expected' denotes a user supplied data whereas 'actual' stands for the one or several parameter values received in a call to a mock function.
Constraints :
[table
[[Constraint] [Effect] [Description]]
[[mock::any] [true] [does not perform any verification]]
[[['expected]] [['expected]( ['actual] )
['expected]( ['actual_1], ['actual_2], ... )
['actual] == ['expected]] [calls ['expected] as a functor returning a ['bool], throws std::invalid_argument if ! ['expected]
calls ['expected] as a functor returning a ['bool], throws std::invalid_argument if ! ['expected]
compares ['actual] to ['expected] using operator ==]]
[[mock::equal( ['expected] )] [['actual] == ['expected]] [compares ['actual] to ['expected] using operator ==]]
[[mock::less( ['expected] )] [['actual] < ['expected]] [compares ['actual] to ['expected] using operator <]]
[[mock::greater( ['expected] )] [['actual] > ['expected]] [compares ['actual] to ['expected] using operator >]]
[[mock::less_equal( ['expected] )] [['actual] <= ['expected]] [compares ['actual] to ['expected] using operator <=]]
[[mock::greater_equal( ['expected] )] [['actual] >= ['expected]] [compares ['actual] to ['expected] using operator >=]]
[[mock::near( ['expected], ['tolerance] )] [std::abs( ['actual] - ['expected] ) < ['tolerance]] [checks whether ['actual] is near ['expected] within ['tolerance]]]
[[mock::close( ['expected], ['tolerance] )] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::percent_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
[[mock::close_fraction( ['expected], ['tolerance] )] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::fraction_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
[[mock::small( ['tolerance] )] [boost::test_tools::check_is_small( ['actual], ['expected] ) )] [checks whether ['actual] is small within ['tolerance], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
[[mock::call( ['expected] )] [['expected]( ['actual] )] [calls ['expected] as a functor returning a ['bool] and accepting ['actual] as parameter]]
[[mock::same( ['expected] )] [&['actual] == &['expected]] [compares ['actual] to ['expected] by comparing their pointers]]
[[mock::assign( ['expected] )] [['actual] = ['expected], true
*['actual] = ['expected], true] [assigns ['expected] to ['actual] using operator =
assigns ['expected] to ['actual] content using operator =]]
[[mock::retrieve( ['expected] )] [['expected] = ['actual], true
['expected] = &['actual], true] [retrieves ['actual] into ['expected] using operator =
retrieves ['actual] address into ['expected] using operator =]]
[[mock::contain( ['expected] )] [['actual].find( ['expected] ) != std::string::npos] [checks whether ['expected] is contained in the std::string ['actual]]]
[[mock::affirm] [['actual]] [uses ['actual] as a boolean]]
[[mock::negate] [! ['actual]] [negates ['actual] using operator !]]
[[mock::evaluate] [['actual]()] [evaluates ['actual] as a functor returning a bool and taking no argument]]
]
[important When passing ['expected] directly as a shortcut mock::call is implied for a function, a function pointer, an instance of a type with a result_type member typedef (support for standard library, [@http://www.boost.org/libs/bind/bind.html Boost.Bind], [@http://www.boost.org/libs/function Boost.Function] functors), an instance of a type with a sig member (support for [@http://www.boost.org/libs/lambda Boost.Lambda] functors), an instance of a type with a result member (support for [@http://www.boost.org/libs/phoenix Boost.Phoenix] functors); mock::equal is implied for anything else.]
[warning Because mock::assign and mock::retrieve have side effects they may modify ['expected] in unexpected ways. For instance they may be called again after their expectations have already been exhausted because of the way the [link turtle.getting_started.expectation_selection_algorithm expectation selection algorithm] works. Therefore it is probably a good idea to use an [link turtle.reference.expectation.actions action] instead.]
[note For mock::assign and mock::retrieve the switch to one form or another is made depending on whichever is the most relevant based on types involved.]
[note All constraints accepting a parameter support the use of boost::ref and boost::cref in order to delay initialization.]
[note All constraints can be combined using the && and || operators, as well as negated with the ! operator.]
Example :
[constraints_example_1]
Example using a function pointer :
[constraints_example_2]
Example using a standard library functor :
[constraints_example_3]
Example using [@http://www.boost.org/libs/bind Boost.Bind] :
[constraints_example_4]
Example using [@http://www.boost.org/libs/lambda Boost.Lambda] :
[constraints_example_5]
Example using [@http://www.boost.org/libs/phoenix Boost.Phoenix] :
[constraints_example_6]
Example using C++11 lambdas :
[constraints_example_7]
Example using &&, || and ! :
[constraints_example_8]
[endsect]
[section Sequence]
A sequence enforces a given order between two or more expectations.
Synopsis :
MOCK_EXPECT( identifier_1 ).in( sequence_1, sequence_2, ... );
Each sequence is an instance of mock::sequence.
The maximum number of sequences that can be set is MOCK_MAX_SEQUENCES which defaults to 10. If needed the value can be increased before including the library :
#define MOCK_MAX_SEQUENCES 12
#include <turtle/mock.hpp>
Example :
[sequence_example_1]
[endsect]
[section Actions]
An action performs additional treatments after an expectation has been deemed valid.
Synopsis :
MOCK_EXPECT( identifier ).returns( value );
MOCK_EXPECT( identifier ).moves( value );
MOCK_EXPECT( identifier ).throws( exception );
MOCK_EXPECT( identifier ).calls( functor ); // gets assigned to a boost::function and throws std::invalid_argument if empty
[note The returns and moves actions are not available for mock methods returning void, including constructors and destructors.]
Example :
[action_example_1]
[endsect]
[endsect]
[section Verification]
Synopsis :
MOCK_VERIFY( identifier );
mock::verify( object ); // verifies all expectations for all methods of 'object' which must be an instance of a class created using MOCK_CLASS or MOCK_BASE_CLASS, or inherit mock::object
mock::verify( functor ); // verifies all expectations for 'functor' which must be an instance of a functor created using MOCK_FUNCTOR
mock::verify(); // verifies all expectations for all mock objects, functions and functors
[note These calls all return a boolean indicating whether the verification was successful or not, however usually simply calling them is enough because a failing verification will be logged to the test framework.]
[note Each mock object verifies itself automatically upon destruction, which is usually sufficient for the most common use cases.]
[warning Using [link turtle.reference.creation.function mock functions] or [link turtle.reference.creation.static_member_function mock static member functions] means the associated underlying objects will not be destroyed before exiting the test application, thus it is strongly suggested to verify (and possibly [link turtle.reference.reset reset]) them at the end of each test case (for instance using a fixture) to ensure that each test runs in isolation.]
Example :
[verification_example_1]
Example :
[verification_example_2]
Example :
[verification_example_3]
Example :
[verification_example_4]
[endsect]
[section Reset]
Synopsis :
MOCK_RESET( identifier );
mock::reset( object ); // resets all expectations for all methods of 'object' which must be an instance of a class created using MOCK_CLASS or MOCK_BASE_CLASS, or inherit mock::object
mock::reset( functor ); // resets all expectations for 'functor' which must be an instance of a functor created using MOCK_FUNCTOR
mock::reset(); // resets all expectations for all mock objects, functions and functors
Example :
[reset_example_1]
Example :
[reset_example_2]
Example :
[reset_example_3]
Example :
[reset_example_4]
[endsect]
[section Constraint]
This section presents a simple means of creating a new constraint.
Synopsis :
MOCK_CONSTRAINT( name, expected_1, expected_2, ..., expression ) // defines a constraint 'name' based on the given 'expression'
The expression manipulates a received parameter ['actual] in order to implement the constraint, as well as extra optional arguments named ['expected_1], ['expected_2], ...
For compilers without support for variadic macros the alternate following macro must be used.
Synopsis :
MOCK_CONSTRAINT_EXT( name, arity, ( expected_1, expected_2, ... ), expression ) // defines a constraint 'name' based on the given 'expression'
Of course this macro is also available for compilers which support variadic macros.
Example without any extra argument :
[helpers_example_1]
or with the alternate more portable macro :
[helpers_example_4]
Example with one extra argument :
[helpers_example_2]
or with the alternate more portable macro :
[helpers_example_5]
Example with two extra arguments :
[helpers_example_3]
or with the alternate more portable macro :
[helpers_example_6]
[endsect]
[endsect]

View file

@ -1,20 +0,0 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/html/index.html">doc/html/index.html</a>
<hr>
<tt>
Boost.Mock<br>
<br>
Copyright Mathieu Champlon 2012<br>
<br>
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at
<a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>)<br>
<br>
</tt>
</body>
</html>

View file

@ -1,50 +0,0 @@
# Boost.Mock
#
# Copyright Mathieu Champlon 2012
#
# 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)
import testing ;
project
: requirements
<define>BOOST_AUTO_TEST_MAIN
<define>BOOST_ALL_NO_LIB
<include>../include
;
path-constant parent : .. ;
alias mock_inspect :
[ run /boost/tools/inspect//inspect/<variant>release
: $(parent) -text -brief : : : inspect
]
;
rule run-test ( name )
{
run $(name) undefined.cpp /boost//unit_test_framework : : : : $(name)_ ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_MAX_ARGS=21 : $(name)_max_args ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_USE_CONVERSIONS : $(name)_use_conversions ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_NO_DECLTYPE : $(name)_no_decltype ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_NO_VARIADIC_MACROS : $(name)_no_variadic_macros ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_THREAD_SAFE : $(name)_thread_safe ;
}
rule run-tests
{
for name in [ glob test_*.cpp detail/test_*.cpp ] { run-test $(name) ; }
}
alias mock_tests : [ run-tests ] ;
rule run-failures
{
for name in [ glob fail_*.cpp ] { compile-fail $(name) ; }
}
alias mock_failures : [ run-failures ] ;
# How to time bench_*.cpp compilation ?

View file

@ -1,5 +1 @@
extensions = svn,headers,check
src.dir = ${root.dir}
tests.dir = ${root.dir}
libraries.dir = ${root.dir}
boost.dir = ${out.dir}/../boost
extensions = headers,check

View file

@ -1,135 +1,26 @@
<!--
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)
-->
<project name="turtle" default="all">
<property environment="env"/>
<import file="${env.PONEY_HOME}/poney.xml"/>
<property name="boost.root" value="${env.BOOST_ROOT}"/>
<property name="boost.dir" value="${out.dir}/../boost"/>
<fail unless="env.BOOST_ROOT" message="missing BOOST_ROOT environment variable"/>
<property name="boost.dir" value="${env.BOOST_ROOT}"/>
<property name="include.dir" value="${env.BOOST_ROOT}"/>
<property name="src.dir" value="${root.dir}"/>
<property name="doc.dir" value="${src.dir}/doc"/>
<property name="tests.dir" value="${src.dir}/test"/>
<property name="libraries.dir" value="${src.dir}/include"/>
<property name="boostbook.dir" value="${out.dir}/boostbook"/>
<property name="boost-mock.dir" value="${boost.dir}/libs/mock"/>
<target name="clean" description="clean intermediate build artifacts">
<delete dir="${out.dir}"/>
</target>
<target name="configure" description="update external libraries">
<update name="boost"/>
</target>
<presetdef name="build-turtle-test">
<build-test input="test" depends="boost" mode="all" excludes="bench_*,fail_*">
<compilerarg value="-Wno-uninitialized" location="mid" if="is-cygwin"/>
<compilerarg value="-Wno-strict-aliasing" location="mid" if="is-gcc"/>
<compilerarg value="/wd4505" if="is-msvc"/>
</build-test>
</presetdef>
<target name="test" description="run unit tests">
<delete dir="${tests.dir}/test/bin"/>
<build-turtle-test name="turtle"/>
<build-turtle-test name="turtle_max_args">
<defineset>
<define name="MOCK_MAX_ARGS" value="21"/>
</defineset>
</build-turtle-test>
<build-turtle-test name="turtle_use_conversions">
<defineset define="MOCK_USE_CONVERSIONS"/>
</build-turtle-test>
<build-turtle-test name="turtle_no_decltype">
<defineset define="MOCK_NO_DECLTYPE"/>
</build-turtle-test>
<build-turtle-test name="turtle_no_variadic_macros">
<defineset define="MOCK_NO_VARIADIC_MACROS"/>
</build-turtle-test>
<build-turtle-test name="turtle_thread_safe">
<defineset define="MOCK_THREAD_SAFE"/>
</build-turtle-test>
</target>
<target name="analyse" description="run errors analyser">
<quiet>
<mkdir dir="${reports.dir}"/>
<delete file="${reports.dir}/errors-${platform}.log"/>
<touch file="${reports.dir}/errors-${platform}.log"/>
</quiet>
<for param="file">
<fileset dir="${tests.dir}/test" includes="fail*.cpp"/>
<sequential>
<record name="${reports.dir}/errors-${platform}.log" action="start" append="true"/>
<ant target="-analyse">
<property name="file" value="@{file}"/>
</ant>
<record name="${reports.dir}/errors-${platform}.log" action="stop"/>
</sequential>
</for>
</target>
<target name="-analyse">
<trycatch>
<try>
<echo>${file}</echo>
<compile name="errors" input="${tests.dir}/errors_test" outdir="${out.dir}/errors_test" excludes="**">
<includepath path="${libraries.dir}"/>
<fileset file="${file}"/>
</compile>
</try>
</trycatch>
</target>
<target name="bench" description="run compilation benchmark">
<mkdir dir="${reports.dir}"/>
<quiet>
<delete file="${reports.dir}/benchmark-${platform}.log"/>
<touch file="${reports.dir}/benchmark-${platform}.log"/>
<delete dir="${out.dir}/bench_test"/>
<delete dir="${tests.dir}/test/bin"/>
</quiet>
<for param="file">
<fileset dir="${tests.dir}/test" includes="bench_*.cpp"/>
<sequential>
<record name="${reports.dir}/benchmark-${platform}.log" action="start" append="true"/>
<ant target="-bench">
<property name="file" value="@{file}"/>
</ant>
<record name="${reports.dir}/benchmark-${platform}.log" action="stop"/>
</sequential>
</for>
</target>
<target name="-bench">
<echo>${file}</echo>
<stopwatch name="bench"/>
<quiet>
<compile name="bench" input="${tests.dir}/test" outdir="${out.dir}/bench_test" excludes="**">
<includepath path="${libraries.dir}"/>
<fileset file="${file}"/>
</compile>
</quiet>
<stopwatch name="bench" action="total"/>
</target>
<target name="reports" description="generate code analysis reports">
<headers name="turtle" excludes="**/*_iterate.hpp,**/*_template.hpp"/>
<check name="turtle"/>
</target>
<target name="export" description="export distribution">
<sync todir="${dist.dir}/include">
<fileset dir="${libraries.dir}" includes="turtle/**"/>
</sync>
<info version="svn rev ${svn.revision}" todir="${dist.dir}"/>
</target>
<target name="package" depends="export" description="package distribution">
<mkdir dir="${dist.dir}"/>
<zip destfile="${dist.dir}/${ant.project.name}.zip">
<fileset dir="${dist.dir}" includes="include/**"/>
</zip>
<tar destfile="${dist.dir}/${ant.project.name}.tar.bz2" compression="bzip2">
<fileset dir="${dist.dir}" includes="include/**"/>
</tar>
</target>
<property name="boost-mock.dir" value="${out.dir}/boost-mock"/>
<property name="version" value="unreleased"/>
<import file="${env.PONEY_HOME}/poney.xml"/>
<condition property="b2.toolset" value="--toolset=${boost.toolset}" else="">
<isset property="boost.toolset"/>
</condition>
@ -137,37 +28,65 @@
<os family="windows"/>
</condition>
<presetdef name="b2">
<exec taskname="b2" failonerror="true" executable="${boost.root}/${b2}">
<exec taskname="b2" failonerror="true" executable="${boost.dir}/${b2}">
<arg value="-q"/>
<arg value="${b2.toolset}"/>
</exec>
</presetdef>
<target name="boost.generate" description="generate boost.mock into ${boost.dir}">
<target name="reports" description="generate code analysis reports">
<headers name="turtle" excludes="**/*_iterate.hpp,**/*_template.hpp"/>
<check name="turtle"/>
</target>
<target name="test" description="run tests">
<b2 dir="${tests.dir}"/>
</target>
<target name="documentation" depends="boost.generate" description="generate documentation">
<b2 dir="${boost-mock.dir}/doc">
<env key="BOOSTBOOK_DIR" value="${boostbook.dir}"/>
</b2>
</target>
<target name="release" depends="documentation" description="produce release packages">
<fail unless="version" message="missing version property"/>
<copy file="version.hpp" tofile="${out.dir}/version.hpp">
<filterset>
<filter token="MOCK_VERSION" value="${version}"/>
</filterset>
</copy>
<zip destfile="${dist.dir}/${ant.project.name}-${version}.zip">
<fileset dir="${dist.dir}" includes="include/**"/>
<zipfileset dir="${doc.dir}/html" prefix="doc"/>
<zipfileset dir="${out.dir}" includes="version.hpp" prefix="include/turtle"/>
</zip>
<tar destfile="${dist.dir}/${ant.project.name}-${version}.tar.bz2" compression="bzip2">
<fileset dir="${dist.dir}" includes="include/**"/>
<zipfileset dir="${doc.dir}/html" prefix="doc"/>
<zipfileset dir="${out.dir}" includes="version.hpp" prefix="include/turtle"/>
</tar>
</target>
<target name="all" depends="test,reports,release" description="build and run tests then package distribution"/>
<target name="boost.generate" description="generate Boost.Mock">
<delete dir="${boost-mock.dir}"/>
<copy todir="${boost-mock.dir}/include/turtle">
<fileset dir="${libraries.dir}/turtle"/>
<copy todir="${boost-mock.dir}" overwrite="true" preservelastmodified="true">
<fileset dir="${src.dir}" includes="LICENSE_1_0.txt,index.html,include/**,doc/**,test/**" excludes="**/bin/**"/>
</copy>
<copy todir="${boostbook.dir}">
<fileset dir="${boost.root}/tools/boostbook" includes="xsl/**,dtd/**"/>
<fileset dir="${boost.dir}/tools/boostbook" includes="xsl/**,dtd/**"/>
</copy>
<copy todir="${boostbook.dir}" overwrite="true">
<fileset dir="boostbook"/>
</copy>
<copy todir="${boost-mock.dir}/doc/html">
<fileset dir="${boost.root}/doc/src" includes="**/boostbook.css,**/**.png"/>
<fileset dir="boost/doc" includes="images/*.png"/>
</copy>
<copy todir="${boost-mock.dir}" overwrite="true">
<fileset dir="${tests.dir}" includes="test/**"/>
<fileset dir="boost" includes="test/**,doc/**,index.html"/>
</copy>
<copy todir="${boost.dir}">
<fileset dir="boost" includes="LICENSE_1_0.txt,Jamroot.jam,Jamfile.v2"/>
<fileset dir="${boost.dir}/doc/src" includes="**/boostbook.css,**/**.png"/>
</copy>
</target>
<target name="boost.convert" description="convert boost.mock in ${boost.dir}">
<target name="boost.convert" depends="boost.generate" description="convert Boost.Mock">
<move file="${boost-mock.dir}/include/turtle" tofile="${boost-mock.dir}/include/boost/mock"/>
<replaceregexp match="MOCK" replace="BOOST_MOCK" flags="g">
<fileset dir="${boost-mock.dir}" includes="**/*.cpp,**/*.hpp,**/*.qbk"/>
@ -214,55 +133,29 @@
<replaceregexp match="\[include changelog.qbk\]" replace="" flags="g">
<fileset dir="${boost-mock.dir}" includes="**/mock.qbk"/>
</replaceregexp>
<copy todir="${boostbook.dir}" overwrite="true">
<fileset dir="${boost.root}/tools/boostbook" includes="xsl/**,dtd/**"/>
</copy>
</target>
<target name="boost.test" description="run boost.mock tests in ${boost.dir}">
<target name="boost.test" description="run Boost.Mock tests">
<b2 dir="${boost-mock.dir}/test"/>
</target>
<target name="boost.doc" description="generate boost.mock documentation in ${boost.dir}">
<target name="boost.documentation" depends="boost.generate" description="generate Boost.Mock documentation">
<b2 dir="${boost-mock.dir}/doc">
<env key="BOOSTBOOK_DIR" value="${boostbook.dir}"/>
</b2>
</target>
<target name="boost.package" description="package boost.mock">
<target name="boost.package" description="package Boost.Mock">
<zip destfile="${out.dir}/boost-mock.zip">
<fileset dir="${boost.dir}" includes="libs/mock/**" excludes="**/bin/**"/>
<fileset dir="${boost.dir}" includes="LICENSE_1_0.txt"/>
<fileset dir="${boost-mock.dir}" includes="libs/mock/**" excludes="**/bin/**"/>
<fileset dir="${boost-mock.dir}" includes="LICENSE_1_0.txt"/>
</zip>
<tar destfile="${out.dir}/boost-mock.tar.bz2" compression="bzip2">
<fileset dir="${boost.dir}" includes="libs/mock/**" excludes="**/bin/**"/>
<fileset dir="${boost.dir}" includes="LICENSE_1_0.txt"/>
<fileset dir="${boost-mock.dir}" includes="libs/mock/**" excludes="**/bin/**"/>
<fileset dir="${boost-mock.dir}" includes="LICENSE_1_0.txt"/>
</tar>
</target>
<target name="documentation" depends="boost.generate,boost.doc" description="generate documentation"/>
<target name="boost" depends="boost.generate,boost.convert,boost.doc,boost.test,boost.package" description="convert to boost with documentation and tests"/>
<target name="release" depends="documentation,package" description="produce release packages">
<fail unless="version" message="missing version property"/>
<copy file="version.hpp" tofile="${out.dir}/version.hpp">
<filterset>
<filter token="MOCK_VERSION" value="${version}"/>
</filterset>
</copy>
<zip destfile="${dist.dir}/${ant.project.name}-${version}.zip">
<fileset dir="${dist.dir}" includes="include/**"/>
<zipfileset dir="${boost-mock.dir}/doc/html" prefix="doc"/>
<zipfileset dir="${out.dir}" includes="version.hpp" prefix="include/turtle"/>
</zip>
<tar destfile="${dist.dir}/${ant.project.name}-${version}.tar.bz2" compression="bzip2">
<fileset dir="${dist.dir}" includes="include/**"/>
<zipfileset dir="${boost-mock.dir}/doc/html" prefix="doc"/>
<zipfileset dir="${out.dir}" includes="version.hpp" prefix="include/turtle"/>
</tar>
</target>
<target name="all" depends="configure,test,bench,reports,export,package" description="configure, build and run tests and benchmark, export and package distribution"/>
<target name="boost" depends="boost.convert,boost.test,boost.documentation,boost.package" description="convert to boost with documentation and tests"/>
</project>

3
build/vc100/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/*.opensdf
/*.sdf
/*.suo

View file

@ -19,45 +19,45 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\turtle\config.hpp" />
<ClInclude Include="..\..\turtle\constraint.hpp" />
<ClInclude Include="..\..\turtle\constraints.hpp" />
<ClInclude Include="..\..\turtle\detail\action.hpp" />
<ClInclude Include="..\..\turtle\detail\addressof.hpp" />
<ClInclude Include="..\..\turtle\detail\child.hpp" />
<ClInclude Include="..\..\turtle\detail\cleanup.hpp" />
<ClInclude Include="..\..\turtle\detail\context.hpp" />
<ClInclude Include="..\..\turtle\detail\expectation_template.hpp" />
<ClInclude Include="..\..\turtle\detail\formatter.hpp" />
<ClInclude Include="..\..\turtle\detail\function.hpp" />
<ClInclude Include="..\..\turtle\detail\function_impl_template.hpp" />
<ClInclude Include="..\..\turtle\detail\function_iterate.hpp" />
<ClInclude Include="..\..\turtle\detail\function_template.hpp" />
<ClInclude Include="..\..\turtle\detail\functor.hpp" />
<ClInclude Include="..\..\turtle\detail\group.hpp" />
<ClInclude Include="..\..\turtle\detail\invocation.hpp" />
<ClInclude Include="..\..\turtle\detail\is_functor.hpp" />
<ClInclude Include="..\..\turtle\detail\matcher_base_template.hpp" />
<ClInclude Include="..\..\turtle\detail\mutex.hpp" />
<ClInclude Include="..\..\turtle\detail\object_impl.hpp" />
<ClInclude Include="..\..\turtle\detail\parameter.hpp" />
<ClInclude Include="..\..\turtle\detail\parent.hpp" />
<ClInclude Include="..\..\turtle\detail\root.hpp" />
<ClInclude Include="..\..\turtle\detail\sequence_impl.hpp" />
<ClInclude Include="..\..\turtle\detail\signature.hpp" />
<ClInclude Include="..\..\turtle\detail\type_name.hpp" />
<ClInclude Include="..\..\turtle\detail\verifiable.hpp" />
<ClInclude Include="..\..\turtle\error.hpp" />
<ClInclude Include="..\..\turtle\exception.hpp" />
<ClInclude Include="..\..\turtle\format.hpp" />
<ClInclude Include="..\..\turtle\log.hpp" />
<ClInclude Include="..\..\turtle\matcher.hpp" />
<ClInclude Include="..\..\turtle\mock.hpp" />
<ClInclude Include="..\..\turtle\object.hpp" />
<ClInclude Include="..\..\turtle\reset.hpp" />
<ClInclude Include="..\..\turtle\sequence.hpp" />
<ClInclude Include="..\..\turtle\stream.hpp" />
<ClInclude Include="..\..\turtle\verify.hpp" />
<ClInclude Include="..\..\include\turtle\config.hpp" />
<ClInclude Include="..\..\include\turtle\constraint.hpp" />
<ClInclude Include="..\..\include\turtle\constraints.hpp" />
<ClInclude Include="..\..\include\turtle\detail\action.hpp" />
<ClInclude Include="..\..\include\turtle\detail\addressof.hpp" />
<ClInclude Include="..\..\include\turtle\detail\child.hpp" />
<ClInclude Include="..\..\include\turtle\detail\cleanup.hpp" />
<ClInclude Include="..\..\include\turtle\detail\context.hpp" />
<ClInclude Include="..\..\include\turtle\detail\expectation_template.hpp" />
<ClInclude Include="..\..\include\turtle\detail\formatter.hpp" />
<ClInclude Include="..\..\include\turtle\detail\function.hpp" />
<ClInclude Include="..\..\include\turtle\detail\function_impl_template.hpp" />
<ClInclude Include="..\..\include\turtle\detail\function_iterate.hpp" />
<ClInclude Include="..\..\include\turtle\detail\function_template.hpp" />
<ClInclude Include="..\..\include\turtle\detail\functor.hpp" />
<ClInclude Include="..\..\include\turtle\detail\group.hpp" />
<ClInclude Include="..\..\include\turtle\detail\invocation.hpp" />
<ClInclude Include="..\..\include\turtle\detail\is_functor.hpp" />
<ClInclude Include="..\..\include\turtle\detail\matcher_base_template.hpp" />
<ClInclude Include="..\..\include\turtle\detail\mutex.hpp" />
<ClInclude Include="..\..\include\turtle\detail\object_impl.hpp" />
<ClInclude Include="..\..\include\turtle\detail\parameter.hpp" />
<ClInclude Include="..\..\include\turtle\detail\parent.hpp" />
<ClInclude Include="..\..\include\turtle\detail\root.hpp" />
<ClInclude Include="..\..\include\turtle\detail\sequence_impl.hpp" />
<ClInclude Include="..\..\include\turtle\detail\signature.hpp" />
<ClInclude Include="..\..\include\turtle\detail\type_name.hpp" />
<ClInclude Include="..\..\include\turtle\detail\verifiable.hpp" />
<ClInclude Include="..\..\include\turtle\error.hpp" />
<ClInclude Include="..\..\include\turtle\exception.hpp" />
<ClInclude Include="..\..\include\turtle\format.hpp" />
<ClInclude Include="..\..\include\turtle\log.hpp" />
<ClInclude Include="..\..\include\turtle\matcher.hpp" />
<ClInclude Include="..\..\include\turtle\mock.hpp" />
<ClInclude Include="..\..\include\turtle\object.hpp" />
<ClInclude Include="..\..\include\turtle\reset.hpp" />
<ClInclude Include="..\..\include\turtle\sequence.hpp" />
<ClInclude Include="..\..\include\turtle\stream.hpp" />
<ClInclude Include="..\..\include\turtle\verify.hpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}</ProjectGuid>

View file

@ -10,121 +10,121 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\turtle\config.hpp">
<ClInclude Include="..\..\include\turtle\config.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\constraint.hpp">
<ClInclude Include="..\..\include\turtle\constraint.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\constraints.hpp">
<ClInclude Include="..\..\include\turtle\constraints.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\error.hpp">
<ClInclude Include="..\..\include\turtle\error.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\log.hpp">
<ClInclude Include="..\..\include\turtle\exception.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\mock.hpp">
<ClInclude Include="..\..\include\turtle\format.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\object.hpp">
<ClInclude Include="..\..\include\turtle\log.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\sequence.hpp">
<ClInclude Include="..\..\include\turtle\matcher.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\signature.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\child.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\group.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\context.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\parent.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\root.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\type_name.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\verifiable.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\action.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\expectation_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\function.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\function_iterate.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\function_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\invocation.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\object_impl.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\function_impl_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\is_functor.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\stream.hpp">
<ClInclude Include="..\..\include\turtle\mock.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\format.hpp">
<ClInclude Include="..\..\include\turtle\object.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\verify.hpp">
<ClInclude Include="..\..\include\turtle\reset.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\reset.hpp">
<ClInclude Include="..\..\include\turtle\sequence.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\functor.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\parameter.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\sequence_impl.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\formatter.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\cleanup.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\matcher.hpp">
<ClInclude Include="..\..\include\turtle\stream.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\exception.hpp">
<ClInclude Include="..\..\include\turtle\verify.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\addressof.hpp">
<ClInclude Include="..\..\include\turtle\detail\function.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\mutex.hpp">
<ClInclude Include="..\..\include\turtle\detail\function_impl_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\turtle\detail\matcher_base_template.hpp">
<ClInclude Include="..\..\include\turtle\detail\function_iterate.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\function_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\functor.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\group.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\invocation.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\is_functor.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\matcher_base_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\mutex.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\object_impl.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\parameter.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\parent.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\root.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\sequence_impl.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\signature.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\type_name.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\verifiable.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\action.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\addressof.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\child.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\cleanup.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\context.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\expectation_template.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\turtle\detail\formatter.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
</ItemGroup>