Preview of clang-format changes and CI

This commit is contained in:
Alexander Grund 2020-09-05 14:37:48 +02:00
parent bfd1701fcb
commit 805e3b02bf
No known key found for this signature in database
GPG key ID: E92C451FC21EF13F
98 changed files with 6339 additions and 11357 deletions

139
.clang-format Normal file
View file

@ -0,0 +1,139 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '<turtle/'
Priority: 10
SortPriority: 0
- Regex: '<boost/'
Priority: 20
SortPriority: 0
- Regex: '^<'
Priority: 30
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Impl|_Win32|_Other)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 10000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: c++14
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
...

17
.github/workflows/static-analysis.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: Static analysis
on:
push:
pull_request:
jobs:
Formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: git submodule update --init
- name: Formatting
uses: DoozyX/clang-format-lint-action@v0.9
with:
source: 'include test doc'
clangFormatVersion: 10

View file

@ -15,9 +15,9 @@ class view;
class calculator class calculator
{ {
public: public:
calculator( view& v ); calculator(view& v);
void add( int a, int b ); // the result will be sent to the view 'v' void add(int a, int b); // the result will be sent to the view 'v'
}; };
//] //]

View file

@ -14,126 +14,110 @@
#include "mock_view.hpp" #include "mock_view.hpp"
//[ mock_stream_user_type //[ mock_stream_user_type
namespace user_namespace namespace user_namespace {
{ struct user_type
struct user_type {};
{};
inline mock::stream& operator<<( mock::stream& s, const user_type& ) inline mock::stream& operator<<(mock::stream& s, const user_type&)
{ {
return s << "user_type"; return s << "user_type";
}
} }
} // namespace user_namespace
//] //]
namespace custom_constraint_free_function_test namespace custom_constraint_free_function_test {
{
//[ custom_constraint_free_function //[ custom_constraint_free_function
bool custom_constraint( int actual ) bool custom_constraint(int actual)
{ {
return actual == 42; return actual == 42;
} }
//] //]
//[ custom_constraint_free_function_test //[ custom_constraint_free_function_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two ) BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).with( &custom_constraint ); MOCK_EXPECT(v.display).with(&custom_constraint);
c.add( 41, 1 ); c.add(41, 1);
}
//]
} }
//]
} // namespace custom_constraint_free_function_test
namespace custom_constraint_functor_test namespace custom_constraint_functor_test {
{
//[ custom_constraint_functor //[ custom_constraint_functor
struct custom_constraint struct custom_constraint
{ {
friend bool operator==( int actual, const custom_constraint& ) friend bool operator==(int actual, const custom_constraint&) { return actual == 42; }
{
return actual == 42;
}
friend std::ostream& operator<<( std::ostream& s, const custom_constraint& ) friend std::ostream& operator<<(std::ostream& s, const custom_constraint&) { return s << "_ == 42"; }
{
return s << "_ == 42";
}
}; };
//] //]
//[ custom_constraint_functor_test //[ custom_constraint_functor_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two ) BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).with( custom_constraint() ); MOCK_EXPECT(v.display).with(custom_constraint());
c.add( 41, 1 ); c.add(41, 1);
} }
//] //]
} } // namespace custom_constraint_functor_test
//[ near_constraint //[ near_constraint
template< typename Expected > template<typename Expected>
struct near_constraint struct near_constraint
{ {
near_constraint( Expected expected, Expected threshold ) near_constraint(Expected expected, Expected threshold) : expected_(expected), threshold_(threshold) {}
: expected_( expected )
, threshold_( threshold )
{}
template< typename Actual > template<typename Actual>
bool operator()( Actual actual ) const bool operator()(Actual actual) const
{ {
return std::abs( actual - boost::unwrap_ref( expected_ ) ) return std::abs(actual - boost::unwrap_ref(expected_)) < boost::unwrap_ref(threshold_);
< boost::unwrap_ref( threshold_ );
} }
friend std::ostream& operator<<( std::ostream& s, const near_constraint& c ) friend std::ostream& operator<<(std::ostream& s, const near_constraint& c)
{ {
return s << "near( " << mock::format( c.expected_ ) return s << "near( " << mock::format(c.expected_) << ", " << mock::format(c.threshold_) << " )";
<< ", " << mock::format( c.threshold_ ) << " )";
} }
Expected expected_, threshold_; Expected expected_, threshold_;
}; };
template< typename Expected > template<typename Expected>
mock::constraint< near_constraint< Expected > > near( Expected expected, Expected threshold ) mock::constraint<near_constraint<Expected>> near(Expected expected, Expected threshold)
{ {
return near_constraint< Expected >( expected, threshold ); return near_constraint<Expected>(expected, threshold);
} }
//] //]
namespace near_constraint_test namespace near_constraint_test {
{
//[ near_constraint_test //[ near_constraint_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one ) BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_plus_or_minus_one)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).with( near( 42, 1 ) ); MOCK_EXPECT(v.display).with(near(42, 1));
c.add( 41, 1 ); c.add(41, 1);
} }
//] //]
} } // namespace near_constraint_test
namespace near_constraint_cref_test namespace near_constraint_cref_test {
{
//[ near_constraint_cref_test //[ near_constraint_cref_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one ) BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_plus_or_minus_one)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
int expected, threshold; int expected, threshold;
MOCK_EXPECT( v.display ).with( near( boost::cref( expected ), boost::cref( threshold ) ) ); MOCK_EXPECT(v.display).with(near(boost::cref(expected), boost::cref(threshold)));
expected = 42; expected = 42;
threshold = 1; threshold = 1;
c.add( 41, 1 ); c.add(41, 1);
} }
//] //]
} } // namespace near_constraint_cref_test
#undef MOCK_MAX_ARGS #undef MOCK_MAX_ARGS
//[ max_args //[ max_args
@ -142,7 +126,7 @@ BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
//] //]
//[ custom_policy //[ custom_policy
template< typename Result > template<typename Result>
struct custom_policy struct custom_policy
{ {
static Result abort() static Result abort()
@ -150,17 +134,17 @@ struct custom_policy
// Notify the test framework that an error occurs which makes it impossible to continue the test. // Notify the test framework that an error occurs which makes it impossible to continue the test.
// This should most likely throw an exception of some kind. // This should most likely throw an exception of some kind.
} }
template< typename Context > template<typename Context>
static void fail( const char* message, const Context& context, const char* file = "unknown location", int line = 0 ) static void fail(const char* message, const Context& context, const char* file = "unknown location", int line = 0)
{ {
// Notify the test framework that an unexpected call has occurred. // Notify the test framework that an unexpected call has occurred.
} }
template< typename Context > template<typename Context>
static void call( const Context& context, const char* file, int line ) static void call(const Context& context, const char* file, int line)
{ {
// Notify the test framework that an expectation has been fulfilled. // Notify the test framework that an expectation has been fulfilled.
} }
static void pass( const char* file, int line ) static void pass(const char* file, int line)
{ {
// Notify the test framework that the test execution merely passed the given code location. // Notify the test framework that the test execution merely passed the given code location.
} }

View file

@ -8,122 +8,113 @@
//[ prerequisite //[ prerequisite
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
//] //]
#include "calculator.hpp" #include "calculator.hpp"
#include "mock_view.hpp" #include "mock_view.hpp"
namespace phases namespace phases {
{
//[ phases //[ phases
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; // create mock objects mock_view v; // create mock objects
calculator c( v ); // create object under test calculator c(v); // create object under test
MOCK_EXPECT( v.display ).once().with( 0 ); // configure mock objects MOCK_EXPECT(v.display).once().with(0); // configure mock objects
c.add( 0, 0 ); // exercise object under test c.add(0, 0); // exercise object under test
} // verify mock objects } // verify mock objects
//] //]
} } // namespace phases
namespace verify_reset namespace verify_reset {
{
//[ verify_reset //[ verify_reset
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).once().with( 0 ); MOCK_EXPECT(v.display).once().with(0);
c.add( 0, 0 ); c.add(0, 0);
MOCK_VERIFY( v.display ); // verify all expectations are fulfilled for the 'display' method 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(v); // verify all expectations are fulfilled for all methods of 'v'
mock::verify(); // verify all expectations are fulfilled for all existing mock objects 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.display); // reset all expectations for the 'display' method
mock::reset( v ); // reset all expectations for all methods of 'v' mock::reset(v); // reset all expectations for all methods of 'v'
mock::reset(); // reset all expectations for all existing mock objects mock::reset(); // reset all expectations for all existing mock objects
} // automatically verify all expectations are fulfilled for all mock objects going out of scope } // automatically verify all expectations are fulfilled for all mock objects going out of scope
//] //]
} } // namespace verify_reset
namespace expectations namespace expectations {
{
//[ expectations //[ expectations
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).once().with( 0 ); // this call must occur once (and only once) 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) MOCK_EXPECT(v.display).with(1); // this call can occur any number of times (including never)
c.add( 0, 0 ); c.add(0, 0);
} }
//] //]
} } // namespace expectations
namespace sequence namespace sequence {
{
//[ sequence //[ sequence
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
mock::sequence s; mock::sequence s;
MOCK_EXPECT( v.display ).once().with( 0 ).in( s ); // add this expectation to the sequence 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 MOCK_EXPECT(v.display).with(1).in(s); // add this expectation to the sequence after the previous call
c.add( 0, 0 ); c.add(0, 0);
c.add( 1, 0 ); c.add(1, 0);
} }
//] //]
} } // namespace sequence
namespace several_sequences namespace several_sequences {
{
//[ several_sequences //[ several_sequences
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
mock::sequence s1, s2; mock::sequence s1, s2;
MOCK_EXPECT( v.display ).once().with( 0 ).in( s1 ); MOCK_EXPECT(v.display).once().with(0).in(s1);
MOCK_EXPECT( v.display ).once().with( 1 ).in( s2 ); 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 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(0, 0);
c.add( 1, 0 ); c.add(1, 0);
c.add( 1, 1 ); c.add(1, 1);
c.add( 2, 0 ); c.add(2, 0);
} }
//] //]
} } // namespace several_sequences
namespace action namespace action {
{
//[ action_view //[ action_view
class view class view
{ {
public: public:
virtual bool display( int result ) = 0; // returns a boolean virtual bool display(int result) = 0; // returns a boolean
}; };
//] //]
MOCK_BASE_CLASS( mock_view, view ) MOCK_BASE_CLASS(mock_view, view){MOCK_METHOD(display, 1)};
{
MOCK_METHOD( display, 1 )
};
class calculator class calculator
{ {
public: public:
calculator( view& v ); calculator(view& v);
void add( int a, int b ); void add(int a, int b);
}; };
//[ action_test //[ action_test
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
MOCK_EXPECT( v.display ).once().with( 0 ); // missing returns( true ) MOCK_EXPECT(v.display).once().with(0); // missing returns( true )
c.add( 0, 0 ); c.add(0, 0);
} }
//] //]
} } // namespace action

View file

@ -7,42 +7,36 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
{
//[ limitations_comma_in_macro_problem //[ limitations_comma_in_macro_problem
template< typename T1, typename T2 > template<typename T1, typename T2>
struct my_base_class struct my_base_class
{}; {};
//] //]
} } // namespace
namespace limitations_comma_in_macro_solution_1 namespace limitations_comma_in_macro_solution_1 {
{
//[ limitations_comma_in_macro_solution_1 //[ limitations_comma_in_macro_solution_1
typedef my_base_class< int, int > my_base_type; typedef my_base_class<int, int> my_base_type;
MOCK_BASE_CLASS( my_mock, my_base_type ) MOCK_BASE_CLASS(my_mock, my_base_type){};
{};
//] //]
} } // namespace limitations_comma_in_macro_solution_1
namespace limitations_comma_in_macro_solution_2 namespace limitations_comma_in_macro_solution_2 {
{
//[ limitations_comma_in_macro_solution_2 //[ limitations_comma_in_macro_solution_2
template< typename T1, typename T2 > template<typename T1, typename T2>
MOCK_BASE_CLASS( my_mock, my_base_class< T1 BOOST_PP_COMMA() T2 > ) MOCK_BASE_CLASS(my_mock, my_base_class<T1 BOOST_PP_COMMA() T2>){};
{};
//] //]
} } // namespace limitations_comma_in_macro_solution_2
namespace limitations_comma_in_macro_solution_3 namespace limitations_comma_in_macro_solution_3 {
{
//[ limitations_comma_in_macro_solution_3 //[ limitations_comma_in_macro_solution_3
template< typename T1, typename T2 > template<typename T1, typename T2>
struct my_mock : my_base_class< T1, T2 >, mock::object struct my_mock : my_base_class<T1, T2>, mock::object
{}; {};
//] //]
} } // namespace limitations_comma_in_macro_solution_3

View file

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

View file

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

View file

@ -7,8 +7,8 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
//[ limitations_non_virtual_method_problem //[ limitations_non_virtual_method_problem
class base class base
@ -20,8 +20,5 @@ public:
//] //]
//[ limitations_non_virtual_method_problem_2 //[ limitations_non_virtual_method_problem_2
MOCK_BASE_CLASS( mock_base, base ) MOCK_BASE_CLASS(mock_base, base){MOCK_METHOD(method, 0)};
{
MOCK_METHOD( method, 0 )
};
//] //]

View file

@ -7,26 +7,22 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
{
//[ limitations_protected_private_method_problem //[ limitations_protected_private_method_problem
class base class base
{ {
protected: protected:
virtual void method_1() = 0; virtual void method_1() = 0;
private:
virtual void method_2() = 0; private:
}; virtual void method_2() = 0;
};
//] //]
//[ limitations_protected_private_method_solution //[ limitations_protected_private_method_solution
MOCK_BASE_CLASS( mock_base, base ) MOCK_BASE_CLASS(mock_base, base){MOCK_METHOD(method_1, 0, void()) MOCK_METHOD(method_2, 0, void())};
{
MOCK_METHOD( method_1, 0, void() )
MOCK_METHOD( method_2, 0, void() )
};
//] //]
} } // namespace

View file

@ -7,28 +7,23 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
{
//[ limitations_template_base_class_method_problem //[ limitations_template_base_class_method_problem
template< typename T > template<typename T>
class base class base
{ {
public: public:
virtual ~base() virtual ~base() {}
{}
virtual void method() = 0; virtual void method() = 0;
}; };
//] //]
//[ limitations_template_base_class_method_solution //[ limitations_template_base_class_method_solution
template< typename T > template<typename T>
MOCK_BASE_CLASS( mock_base, base< T > ) MOCK_BASE_CLASS(mock_base, base<T>){MOCK_METHOD(method, 1, void())};
{
MOCK_METHOD( method, 1, void() )
};
//] //]
} } // namespace

View file

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

View file

@ -7,29 +7,24 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
{
//[ limitations_throw_specifier_problem //[ limitations_throw_specifier_problem
struct base_class struct base_class
{ {
virtual ~base_class() virtual ~base_class() {}
{}
virtual void method() throw (); virtual void method() throw();
}; };
//] //]
//[ limitations_throw_specifier_solution //[ limitations_throw_specifier_solution
MOCK_BASE_CLASS( mock_class, base_class ) MOCK_BASE_CLASS(mock_class, base_class){void method() throw(){method_proxy();
{ } // namespace
void method() throw () MOCK_METHOD(method_proxy, 0, void(), method)
{ }
method_proxy(); ;
}
MOCK_METHOD( method_proxy, 0, void(), method )
};
//] //]
} }

View file

@ -9,13 +9,13 @@
#ifndef MOCK_VIEW #ifndef MOCK_VIEW
#define MOCK_VIEW #define MOCK_VIEW
#include <turtle/mock.hpp>
#include "view.hpp" #include "view.hpp"
#include <turtle/mock.hpp>
//[ mock_view //[ mock_view
MOCK_BASE_CLASS( mock_view, view ) // declare a 'mock_view' class implementing '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) MOCK_METHOD(display, 1) // implement the 'display' method from 'view' (taking 1 argument)
}; };
//] //]

View file

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

View file

@ -7,67 +7,62 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
//[ async_call_problem //[ async_call_problem
namespace namespace {
class base_class
{ {
class base_class public:
{ virtual void method() = 0;
public: };
virtual void method() = 0;
};
class my_class class my_class
{ {
public: public:
explicit my_class( base_class& ); explicit my_class(base_class&);
void flush(); // repetitively calling this method will in turn call base_class::method at some point void flush(); // repetitively calling this method will in turn call base_class::method at some point
}; };
} } // namespace
//] //]
//[ async_call_solution //[ async_call_solution
#define BOOST_AUTO_TEST_MAIN #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> #include <turtle/mock.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/thread.hpp>
namespace namespace {
template<typename F>
void check(bool& condition, F flush, int attempts = 100, int sleep = 100)
{ {
template< typename F > while(!condition && attempts > 0)
void check( bool& condition, F flush, int attempts = 100, int sleep = 100 )
{ {
while( !condition && attempts > 0 ) --attempts;
{ boost::this_thread::sleep(boost::posix_time::milliseconds(sleep));
--attempts; flush();
boost::this_thread::sleep( boost::posix_time::milliseconds( sleep ) );
flush();
}
}
MOCK_BASE_CLASS( mock_base_class, base_class )
{
MOCK_METHOD( method, 0 )
};
void set_bool(bool& b)
{
b = true;
} }
} }
BOOST_AUTO_TEST_CASE( method_is_called ) MOCK_BASE_CLASS(mock_base_class, base_class){MOCK_METHOD(method, 0)};
void set_bool(bool& b)
{
b = true;
}
} // namespace
BOOST_AUTO_TEST_CASE(method_is_called)
{ {
mock_base_class m; mock_base_class m;
my_class c( m ); my_class c(m);
bool done = false; bool done = false;
// when method is called it will set done to true // when method is called it will set done to true
// Note: Boost 1.57 introduced a bug preventing usage of the lambda with clang in C++98 // Note: Boost 1.57 introduced a bug preventing usage of the lambda with clang in C++98
// See: https://svn.boost.org/trac10/ticket/10785 // See: https://svn.boost.org/trac10/ticket/10785
#if defined(BOOST_CLANG) && (BOOST_VERSION >= 105700) #if defined(BOOST_CLANG) && (BOOST_VERSION >= 105700)
MOCK_EXPECT( m.method ).once().calls( boost::bind(&set_bool, done) ); MOCK_EXPECT(m.method).once().calls(boost::bind(&set_bool, done));
#else #else
MOCK_EXPECT( m.method ).once().calls( boost::lambda::var( done ) = true ); MOCK_EXPECT(m.method).once().calls(boost::lambda::var(done) = true);
#endif #endif
check( done, boost::bind( &my_class::flush, &c ) ); // just wait on done, flushing from time to time check(done, boost::bind(&my_class::flush, &c)); // just wait on done, flushing from time to time
} }
//] //]

View file

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

View file

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

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

View file

@ -8,33 +8,31 @@
//[ static_objects_problem //[ static_objects_problem
#define BOOST_AUTO_TEST_MAIN #define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <ostream> #include <ostream>
namespace namespace {
struct my_class
{ {
struct my_class my_class(int i) : i_(i) {}
{
my_class( int i )
: i_( i )
{}
int i_; int i_;
}; };
std::ostream& operator<<( std::ostream& os, const my_class* c ) std::ostream& operator<<(std::ostream& os, const my_class* c)
{ {
return os << "my_class " << c->i_; // the 'c' pointer must be valid when logging return os << "my_class " << c->i_; // the 'c' pointer must be valid when logging
}
MOCK_FUNCTION( f, 1, void( my_class* ) ) // being static 'f' outlive the test case
} }
BOOST_AUTO_TEST_CASE( static_objects_problem ) MOCK_FUNCTION(f, 1, void(my_class*)) // being static 'f' outlive the test case
} // namespace
BOOST_AUTO_TEST_CASE(static_objects_problem)
{ {
my_class c( 42 ); my_class c(42);
MOCK_EXPECT( f ).once().with( &c ); // the set expectation will also outlive the test case and leak into other test cases using 'f' MOCK_EXPECT(f).once().with(
&c); // the set expectation will also outlive the test case and leak into other test cases using 'f'
} // the 'c' instance goes out of scope and the '&c' pointer becomes dangling } // the 'c' instance goes out of scope and the '&c' pointer becomes dangling
//] //]
@ -43,25 +41,28 @@ struct fixture
{ {
~fixture() ~fixture()
{ {
mock::reset(); // the use of a fixture ensures the reset will prevent the expectations from leaking into other test cases mock::reset(); // the use of a fixture ensures the reset will prevent the expectations from leaking into other
// test cases
} }
}; };
BOOST_FIXTURE_TEST_CASE( static_object_partial_solution, fixture ) BOOST_FIXTURE_TEST_CASE(static_object_partial_solution, fixture)
{ {
my_class c( 42 ); my_class c(42);
MOCK_EXPECT( f ).once().with( &c ); MOCK_EXPECT(f).once().with(&c);
f( &c ); f(&c);
mock::verify(); // verify the expectations before local objects are destroyed and before the fixture resets them mock::verify(); // verify the expectations before local objects are destroyed and before the fixture resets them
} }
//] //]
//[ static_objects_solution //[ static_objects_solution
BOOST_FIXTURE_TEST_CASE( static_objects_solution, mock::cleanup ) // actually the library includes a ready to use fixture just like the one described BOOST_FIXTURE_TEST_CASE(
static_objects_solution,
mock::cleanup) // actually the library includes a ready to use fixture just like the one described
{ {
my_class c( 42 ); my_class c(42);
MOCK_EXPECT( f ).once().with( &c ); MOCK_EXPECT(f).once().with(&c);
f( &c ); f(&c);
mock::verify(); mock::verify();
} }
//] //]

View file

@ -6,15 +6,15 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/mock.hpp>
#include "calculator.hpp" #include "calculator.hpp"
#include "mock_view.hpp" #include "mock_view.hpp"
#include <turtle/mock.hpp>
//[ overflow_throws //[ overflow_throws
BOOST_AUTO_TEST_CASE( overflow_throws ) BOOST_AUTO_TEST_CASE(overflow_throws)
{ {
mock_view v; mock_view v;
calculator c( v ); calculator c(v);
BOOST_CHECK_THROW( c.add( (std::numeric_limits< int >::max)(), 1 ), std::exception ); BOOST_CHECK_THROW(c.add((std::numeric_limits<int>::max)(), 1), std::exception);
} }
//] //]

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
class view class view
{ {
public: public:
virtual void display( int result ) = 0; virtual void display(int result) = 0;
}; };
//] //]

View file

@ -11,34 +11,31 @@
#include <catch.hpp> #include <catch.hpp>
template< typename Result > template<typename Result>
struct catch_mock_error_policy struct catch_mock_error_policy
{ {
static Result abort() static Result abort()
{ {
FAIL( "Aborted" ); FAIL("Aborted");
throw std::runtime_error( "unreachable" ); throw std::runtime_error("unreachable");
} }
template< typename Context > template<typename Context>
static void fail( const char* message, const Context& context, static void fail(const char* message, const Context& context, const char* file = "file://unknown-location",
const char* file = "file://unknown-location", int line = 0 ) int line = 0)
{ {
CAPTURE( context ); CAPTURE(context);
FAIL_CHECK( message << " in: " << file << ":" << line ); FAIL_CHECK(message << " in: " << file << ":" << line);
} }
template< typename Context > template<typename Context>
static void call( const Context& context, const char* file, int line ) static void call(const Context& context, const char* file, int line)
{ {
CAPTURE( context ); CAPTURE(context);
INFO( file << ":" << line ); INFO(file << ":" << line);
} }
static void pass( const char* file, int line ) static void pass(const char* file, int line) { INFO(file << ":" << line); }
{
INFO( file << ":" << line );
}
}; };
#define MOCK_ERROR_POLICY catch_mock_error_policy #define MOCK_ERROR_POLICY catch_mock_error_policy

View file

@ -10,30 +10,25 @@
#define MOCK_CLEANUP_HPP_INCLUDED #define MOCK_CLEANUP_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "verify.hpp"
#include "reset.hpp" #include "reset.hpp"
#include "verify.hpp"
#ifdef MOCK_USE_BOOST_TEST #ifdef MOCK_USE_BOOST_TEST
#include <boost/test/unit_test_suite.hpp> # include <boost/test/unit_test_suite.hpp>
#endif #endif
namespace mock namespace mock {
struct cleanup
{ {
struct cleanup ~cleanup() { mock::reset(); }
{ };
~cleanup()
{
mock::reset();
}
};
#ifdef MOCK_USE_BOOST_TEST #ifdef MOCK_USE_BOOST_TEST
BOOST_GLOBAL_FIXTURE( cleanup ) BOOST_GLOBAL_FIXTURE(cleanup)
#if BOOST_VERSION >= 105900 # if BOOST_VERSION >= 105900
; ;
#endif # endif
#endif #endif
} // mock } // namespace mock
#endif // MOCK_CLEANUP_HPP_INCLUDED #endif // MOCK_CLEANUP_HPP_INCLUDED

View file

@ -16,89 +16,88 @@
#include <boost/preprocessor/comparison/less.hpp> #include <boost/preprocessor/comparison/less.hpp>
#ifndef MOCK_ERROR_POLICY #ifndef MOCK_ERROR_POLICY
# define MOCK_ERROR_POLICY mock::error # define MOCK_ERROR_POLICY mock::error
# define MOCK_USE_BOOST_TEST # define MOCK_USE_BOOST_TEST
#endif #endif
#ifndef MOCK_MAX_ARGS #ifndef MOCK_MAX_ARGS
# define MOCK_MAX_ARGS 9 # define MOCK_MAX_ARGS 9
#endif #endif
#ifndef MOCK_MAX_SEQUENCES #ifndef MOCK_MAX_SEQUENCES
# define MOCK_MAX_SEQUENCES 10 # define MOCK_MAX_SEQUENCES 10
#endif #endif
#ifndef BOOST_FUNCTION_MAX_ARGS #ifndef BOOST_FUNCTION_MAX_ARGS
# define BOOST_FUNCTION_MAX_ARGS MOCK_MAX_ARGS # define BOOST_FUNCTION_MAX_ARGS MOCK_MAX_ARGS
#elif BOOST_PP_LESS(BOOST_FUNCTION_MAX_ARGS, MOCK_MAX_ARGS) #elif BOOST_PP_LESS(BOOST_FUNCTION_MAX_ARGS, MOCK_MAX_ARGS)
# error BOOST_FUNCTION_MAX_ARGS must be set to MOCK_MAX_ARGS or higher # error BOOST_FUNCTION_MAX_ARGS must be set to MOCK_MAX_ARGS or higher
#endif #endif
#ifndef BOOST_FT_MAX_ARITY #ifndef BOOST_FT_MAX_ARITY
# define BOOST_FT_MAX_ARITY BOOST_PP_INC(MOCK_MAX_ARGS) # define BOOST_FT_MAX_ARITY BOOST_PP_INC(MOCK_MAX_ARGS)
#elif BOOST_PP_LESS_EQUAL(BOOST_FT_MAX_ARITY, MOCK_MAX_ARGS) #elif BOOST_PP_LESS_EQUAL(BOOST_FT_MAX_ARITY, MOCK_MAX_ARGS)
# error BOOST_FT_MAX_ARITY must be set to MOCK_MAX_ARGS + 1 or higher # error BOOST_FT_MAX_ARITY must be set to MOCK_MAX_ARGS + 1 or higher
#endif #endif
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) #if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
# ifndef MOCK_NO_NULLPTR # ifndef MOCK_NO_NULLPTR
# define MOCK_NULLPTR # define MOCK_NULLPTR
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) #if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE)
# ifndef MOCK_NO_DECLTYPE # ifndef MOCK_NO_DECLTYPE
# define MOCK_DECLTYPE # define MOCK_DECLTYPE
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) #if !defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS)
# ifndef MOCK_NO_VARIADIC_MACROS # ifndef MOCK_NO_VARIADIC_MACROS
# define MOCK_VARIADIC_MACROS # define MOCK_VARIADIC_MACROS
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_SMART_PTR) && !defined(BOOST_NO_SMART_PTR) #if !defined(BOOST_NO_CXX11_SMART_PTR) && !defined(BOOST_NO_SMART_PTR)
# ifndef MOCK_NO_SMART_PTR # ifndef MOCK_NO_SMART_PTR
# define MOCK_SMART_PTR # define MOCK_SMART_PTR
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES)
# ifndef MOCK_NO_RVALUE_REFERENCES # ifndef MOCK_NO_RVALUE_REFERENCES
# define MOCK_RVALUE_REFERENCES # define MOCK_RVALUE_REFERENCES
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
# ifndef MOCK_NO_HDR_FUNCTIONAL # ifndef MOCK_NO_HDR_FUNCTIONAL
# define MOCK_HDR_FUNCTIONAL # define MOCK_HDR_FUNCTIONAL
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) #if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
# ifndef MOCK_NO_HDR_MUTEX # ifndef MOCK_NO_HDR_MUTEX
# define MOCK_HDR_MUTEX # define MOCK_HDR_MUTEX
# endif # endif
#endif #endif
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) #if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS)
# ifndef MOCK_NO_LAMBDAS # ifndef MOCK_NO_LAMBDAS
# define MOCK_LAMBDAS # define MOCK_LAMBDAS
# endif # endif
#endif #endif
#if !defined(BOOST_NO_AUTO_PTR) #if !defined(BOOST_NO_AUTO_PTR)
# ifndef MOCK_NO_AUTO_PTR # ifndef MOCK_NO_AUTO_PTR
# define MOCK_AUTO_PTR # define MOCK_AUTO_PTR
# endif # endif
#endif #endif
#if defined(__cpp_lib_uncaught_exceptions) || \ #if defined(__cpp_lib_uncaught_exceptions) || defined(_MSC_VER) && (_MSC_VER >= 1900)
defined(_MSC_VER) && (_MSC_VER >= 1900) # ifndef MOCK_NO_UNCAUGHT_EXCEPTIONS
# ifndef MOCK_NO_UNCAUGHT_EXCEPTIONS # define MOCK_UNCAUGHT_EXCEPTIONS
# define MOCK_UNCAUGHT_EXCEPTIONS # endif
# endif
#endif #endif
#endif // MOCK_CONFIG_HPP_INCLUDED #endif // MOCK_CONFIG_HPP_INCLUDED

View file

@ -11,248 +11,194 @@
#include "config.hpp" #include "config.hpp"
#include "log.hpp" #include "log.hpp"
#include <boost/ref.hpp> #include <boost/move/move.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/array.hpp>
#include <boost/preprocessor/control/if.hpp> #include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/variadic/to_array.hpp> #include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp> #include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/array.hpp> #include <boost/preprocessor/variadic/to_array.hpp>
#include <boost/move/move.hpp> #include <boost/ref.hpp>
#include <boost/type_traits/decay.hpp> #include <boost/type_traits/decay.hpp>
namespace mock namespace mock {
template<typename Constraint>
struct constraint
{ {
template< typename Constraint > constraint() {}
struct constraint constraint(const Constraint& c) : c_(c) {}
{ Constraint c_;
constraint() };
{}
constraint( const Constraint& c )
: c_( c )
{}
Constraint c_;
};
namespace detail namespace detail {
{ template<typename Lhs, typename Rhs>
template< typename Lhs, typename Rhs >
class and_ class and_
{ {
public: public:
and_( const Lhs& lhs, const Rhs& rhs ) and_(const Lhs& lhs, const Rhs& rhs) : lhs_(lhs), rhs_(rhs) {}
: lhs_( lhs ) template<typename Actual>
, rhs_( rhs ) bool operator()(const Actual& actual) const
{}
template< typename Actual >
bool operator()( const Actual& actual ) const
{ {
return lhs_( actual ) && rhs_( actual ); return lhs_(actual) && rhs_(actual);
} }
friend std::ostream& operator<<( std::ostream& s, const and_& a ) friend std::ostream& operator<<(std::ostream& s, const and_& a)
{ {
return s << "( " << mock::format( a.lhs_ ) return s << "( " << mock::format(a.lhs_) << " && " << mock::format(a.rhs_) << " )";
<< " && " << mock::format( a.rhs_ ) << " )";
} }
private: private:
Lhs lhs_; Lhs lhs_;
Rhs rhs_; Rhs rhs_;
}; };
template< typename Lhs, typename Rhs > template<typename Lhs, typename Rhs>
class or_ class or_
{ {
public: public:
or_( const Lhs& lhs, const Rhs& rhs ) or_(const Lhs& lhs, const Rhs& rhs) : lhs_(lhs), rhs_(rhs) {}
: lhs_( lhs ) template<typename Actual>
, rhs_( rhs ) bool operator()(const Actual& actual) const
{}
template< typename Actual >
bool operator()( const Actual& actual ) const
{ {
return lhs_( actual ) || rhs_( actual ); return lhs_(actual) || rhs_(actual);
} }
friend std::ostream& operator<<( std::ostream& s, const or_& o ) friend std::ostream& operator<<(std::ostream& s, const or_& o)
{ {
return s << "( " << mock::format( o.lhs_ ) return s << "( " << mock::format(o.lhs_) << " || " << mock::format(o.rhs_) << " )";
<< " || " << mock::format( o.rhs_ )<< " )";
} }
private: private:
Lhs lhs_; Lhs lhs_;
Rhs rhs_; Rhs rhs_;
}; };
template< typename Constraint > template<typename Constraint>
class not_ class not_
{ {
public: public:
explicit not_( const Constraint& c ) explicit not_(const Constraint& c) : c_(c) {}
: c_( c ) template<typename Actual>
{} bool operator()(const Actual& actual) const
template< typename Actual >
bool operator()( const Actual& actual ) const
{ {
return ! c_( actual ); return !c_(actual);
}
friend std::ostream& operator<<( std::ostream& s, const not_& n )
{
return s << "! " << mock::format( n.c_ );
} }
friend std::ostream& operator<<(std::ostream& s, const not_& n) { return s << "! " << mock::format(n.c_); }
private: private:
Constraint c_; Constraint c_;
}; };
} // namespace detail
template<typename Lhs, typename Rhs>
const constraint<detail::or_<Lhs, Rhs>> operator||(const constraint<Lhs>& lhs, const constraint<Rhs>& rhs)
{
return detail::or_<Lhs, Rhs>(lhs.c_, rhs.c_);
} }
template< typename Lhs, typename Rhs > template<typename Lhs, typename Rhs>
const constraint< detail::or_< Lhs, Rhs > > const constraint<detail::and_<Lhs, Rhs>> operator&&(const constraint<Lhs>& lhs, const constraint<Rhs>& rhs)
operator||( const constraint< Lhs >& lhs, {
const constraint< Rhs >& rhs ) return detail::and_<Lhs, Rhs>(lhs.c_, rhs.c_);
{ }
return detail::or_< Lhs, Rhs >( lhs.c_, rhs.c_ );
}
template< typename Lhs, typename Rhs > template<typename Constraint>
const constraint< detail::and_< Lhs, Rhs > > const constraint<detail::not_<Constraint>> operator!(const constraint<Constraint>& c)
operator&&( const constraint< Lhs >& lhs, {
const constraint< Rhs >& rhs ) return detail::not_<Constraint>(c.c_);
{ }
return detail::and_< Lhs, Rhs >( lhs.c_, rhs.c_ ); } // namespace mock
}
template< typename Constraint > #define MOCK_UNARY_CONSTRAINT(Name, n, Args, Expr) \
const constraint< detail::not_< Constraint > > namespace detail { \
operator!( const constraint< Constraint >& c ) struct Name \
{ { \
return detail::not_< Constraint >( c.c_ ); template<typename Actual> \
} bool operator()(const Actual& actual) const \
} // mock { \
return Expr; \
} \
friend std::ostream& operator<<(std::ostream& s, const Name&) { return s << BOOST_STRINGIZE(Name); } \
}; \
} \
const mock::constraint<detail::Name> Name;
#define MOCK_UNARY_CONSTRAINT(Name, n, Args, Expr) \ #define MOCK_CONSTRAINT_ASSIGN(z, n, d) expected##n(boost::forward<T##n>(e##n))
namespace detail \
{ \
struct Name \
{ \
template< typename Actual > \
bool operator()( const Actual& actual ) const \
{ \
return Expr; \
} \
friend std::ostream& operator<<( std::ostream& s, const Name& ) \
{ \
return s << BOOST_STRINGIZE(Name); \
} \
}; \
} \
const mock::constraint< detail::Name > Name;
#define MOCK_CONSTRAINT_ASSIGN(z, n, d) \ #define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) boost::unwrap_ref(expected##n)
expected##n( boost::forward< T##n >(e##n) )
#define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) \ #define MOCK_CONSTRAINT_FORMAT(z, n, d) BOOST_PP_IF(n, << ", " <<, ) mock::format(c.expected##n)
boost::unwrap_ref( expected##n )
#define MOCK_CONSTRAINT_FORMAT(z, n, d) \ #define MOCK_CONSTRAINT_MEMBER(z, n, d) Expected_##n expected##n;
BOOST_PP_IF(n, << ", " <<,) mock::format( c.expected##n )
#define MOCK_CONSTRAINT_MEMBER(z, n, d) \ #define MOCK_CONSTRAINT_TPL_TYPE(z, n, d) typename boost::decay<const T##n>::type
Expected_##n expected##n;
#define MOCK_CONSTRAINT_TPL_TYPE(z, n, d) \
typename boost::decay< const T##n >::type
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \ #define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
const typename boost::unwrap_reference< Expected_##n >::type& \ const typename boost::unwrap_reference<Expected_##n>::type& BOOST_PP_ARRAY_ELEM(n, Args)
BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARG(z, n, Args) \ #define MOCK_CONSTRAINT_ARG(z, n, Args) BOOST_FWD_REF(T##n) BOOST_PP_ARRAY_ELEM(n, Args)
BOOST_FWD_REF(T##n) BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARGS(z, n, Args) \ #define MOCK_CONSTRAINT_ARGS(z, n, Args) BOOST_FWD_REF(T##n) e##n
BOOST_FWD_REF(T##n) e##n
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \ #define MOCK_CONSTRAINT_PARAM(z, n, Args) boost::forward<T##n>(BOOST_PP_ARRAY_ELEM(n, Args))
boost::forward< T##n >( BOOST_PP_ARRAY_ELEM(n, Args) )
#define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \ #define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \
namespace detail \ namespace detail { \
{ \ template<BOOST_PP_ENUM_PARAMS(n, typename Expected_)> \
template< BOOST_PP_ENUM_PARAMS(n, typename Expected_) > \ struct Name \
struct Name \ { \
{ \ template<BOOST_PP_ENUM_PARAMS(n, typename T)> \
template< BOOST_PP_ENUM_PARAMS(n, typename T) > \ explicit Name(BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARGS, _)) : BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \
explicit Name( \ {} \
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARGS, _) ) \ template<typename Actual> \
: BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \ bool operator()(const Actual& actual) const \
{} \ { \
template< typename Actual > \ return test(actual, BOOST_PP_ENUM(n, MOCK_CONSTRAINT_UNWRAP_REF, _)); \
bool operator()( const Actual& actual ) const \ } \
{ \ template<typename Actual> \
return test( actual, \ bool test(const Actual& actual, BOOST_PP_ENUM(n, MOCK_CONSTRAINT_CREF_PARAM, (n, Args))) const \
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_UNWRAP_REF, _) ); \ { \
} \ return Expr; \
template< typename Actual > \ } \
bool test( const Actual& actual, \ friend std::ostream& operator<<(std::ostream& s, const Name& c) \
BOOST_PP_ENUM(n, \ { \
MOCK_CONSTRAINT_CREF_PARAM, (n, Args)) ) const \ return s << BOOST_STRINGIZE(Name) << "( " << BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_FORMAT, _) << " )"; \
{ \ } \
return Expr; \ BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_MEMBER, _) \
} \ }; \
friend std::ostream& operator<<( std::ostream& s, const Name& c ) \ } \
{ \ template<BOOST_PP_ENUM_PARAMS(n, typename T)> \
return s << BOOST_STRINGIZE(Name) << "( " \ mock::constraint<detail::Name<BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _)>> Name( \
<< BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_FORMAT, _) \ BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARG, (n, Args))) \
<< " )"; \ { \
} \ return detail::Name<BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _)>( \
BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_MEMBER, _) \ BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args))); \
}; \
} \
template< BOOST_PP_ENUM_PARAMS(n, typename T) > \
mock::constraint< \
detail::Name< BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _) > \
> Name( BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARG, (n, Args)) ) \
{ \
return detail::Name< BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _) >( \
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args)) ); \
} }
#define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \ #define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \
BOOST_PP_IF(n, \ BOOST_PP_IF(n, MOCK_NARY_CONSTRAINT, MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
MOCK_NARY_CONSTRAINT, \
MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
#ifdef BOOST_MSVC # ifdef BOOST_MSVC
# define MOCK_VARIADIC_SIZE(...) \ # define MOCK_VARIADIC_SIZE(...) \
BOOST_PP_CAT(MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \ BOOST_PP_CAT(MOCK_VARIADIC_SIZE_I(__VA_ARGS__, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \ 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ), )
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \ # else // BOOST_MSVC
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),) # define MOCK_VARIADIC_SIZE(...) \
#else // BOOST_MSVC MOCK_VARIADIC_SIZE_I(__VA_ARGS__, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, \
# define MOCK_VARIADIC_SIZE(...) \ 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, )
MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \ # endif // BOOST_MSVC
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \ # define MOCK_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, \
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \ e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, size, ...) \
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) size
#endif // BOOST_MSVC
#define MOCK_VARIADIC_SIZE_I( \
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, \
e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, \
e25, e26, e27, e28, e29, e30, e31, size, ...) size
#define MOCK_CONSTRAINT_AUX_AUX(Name, n, Array) \ # define MOCK_CONSTRAINT_AUX_AUX(Name, n, Array) \
MOCK_CONSTRAINT_EXT( \ MOCK_CONSTRAINT_EXT(Name, n, BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_POP_BACK(Array)), \
Name, n, \ BOOST_PP_ARRAY_ELEM(n, Array))
BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_POP_BACK(Array)), \
BOOST_PP_ARRAY_ELEM(n, Array))
#define MOCK_CONSTRAINT_AUX(Name, Size, Tuple) \ # define MOCK_CONSTRAINT_AUX(Name, Size, Tuple) MOCK_CONSTRAINT_AUX_AUX(Name, BOOST_PP_DEC(Size), (Size, Tuple))
MOCK_CONSTRAINT_AUX_AUX(Name, BOOST_PP_DEC(Size), (Size,Tuple))
#define MOCK_CONSTRAINT(Name, ...) \ # define MOCK_CONSTRAINT(Name, ...) MOCK_CONSTRAINT_AUX(Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
MOCK_CONSTRAINT_AUX( \
Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS

View file

@ -14,299 +14,244 @@
#include "detail/addressof.hpp" #include "detail/addressof.hpp"
#include "detail/move_helper.hpp" #include "detail/move_helper.hpp"
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/version.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/common_type.hpp> #include <boost/type_traits/common_type.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/has_equal_to.hpp> #include <boost/type_traits/has_equal_to.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 107000 #if BOOST_VERSION >= 107000
#include <boost/test/tools/floating_point_comparison.hpp> # include <boost/test/tools/floating_point_comparison.hpp>
#else #else
#include <boost/test/floating_point_comparison.hpp> # include <boost/test/floating_point_comparison.hpp>
#endif #endif
namespace mock namespace mock {
{ MOCK_UNARY_CONSTRAINT(any, 0, , ((void)actual, true))
MOCK_UNARY_CONSTRAINT( any, 0,, ((void)actual, true) ) MOCK_UNARY_CONSTRAINT(affirm, 0, , !!actual)
MOCK_UNARY_CONSTRAINT( affirm, 0,, !! actual ) MOCK_UNARY_CONSTRAINT(negate, 0, , !actual)
MOCK_UNARY_CONSTRAINT( negate, 0,, ! actual ) MOCK_UNARY_CONSTRAINT(evaluate, 0, , actual())
MOCK_UNARY_CONSTRAINT( evaluate, 0,, actual() )
MOCK_NARY_CONSTRAINT( less, 1, ( expected ), actual < expected ) MOCK_NARY_CONSTRAINT(less, 1, (expected), actual < expected)
MOCK_NARY_CONSTRAINT( greater, 1, ( expected ), actual > expected ) MOCK_NARY_CONSTRAINT(greater, 1, (expected), actual > expected)
MOCK_NARY_CONSTRAINT( less_equal, 1, ( expected ), actual <= expected ) MOCK_NARY_CONSTRAINT(less_equal, 1, (expected), actual <= expected)
MOCK_NARY_CONSTRAINT( greater_equal, 1, ( expected ), actual >= expected ) MOCK_NARY_CONSTRAINT(greater_equal, 1, (expected), actual >= expected)
#if BOOST_VERSION < 105900 #if BOOST_VERSION < 105900
# define MOCK_SMALL() \ # define MOCK_SMALL() boost::test_tools::check_is_small(actual, tolerance)
boost::test_tools::check_is_small( actual, tolerance ) # define MOCK_PERCENT_TOLERANCE() \
# define MOCK_PERCENT_TOLERANCE() \ boost::test_tools::check_is_close(actual, expected, boost::test_tools::percent_tolerance(tolerance))
boost::test_tools::check_is_close( \ # define MOCK_FRACTION_TOLERANCE() \
actual, \ boost::test_tools::check_is_close(actual, expected, boost::test_tools::fraction_tolerance(tolerance))
expected, \
boost::test_tools::percent_tolerance( tolerance ) )
# define MOCK_FRACTION_TOLERANCE() \
boost::test_tools::check_is_close( \
actual, \
expected, \
boost::test_tools::fraction_tolerance( tolerance ) )
#else // BOOST_VERSION < 105900 #else // BOOST_VERSION < 105900
namespace detail namespace detail {
{ template<typename T, typename Tolerance>
template< typename T, typename Tolerance > bool is_small(const T& t, const Tolerance& tolerance)
bool is_small( const T& t, const Tolerance& tolerance )
{ {
return boost::math::fpc::small_with_tolerance< T >( tolerance )( t ); return boost::math::fpc::small_with_tolerance<T>(tolerance)(t);
} }
template< typename T1, typename T2, typename Tolerance > template<typename T1, typename T2, typename Tolerance>
bool is_close( const T1& t1, const T2& t2, const Tolerance& tolerance ) bool is_close(const T1& t1, const T2& t2, const Tolerance& tolerance)
{ {
typedef typename boost::common_type< T1, T2 >::type common_type; typedef typename boost::common_type<T1, T2>::type common_type;
return boost::math::fpc::close_at_tolerance< common_type >( return boost::math::fpc::close_at_tolerance<common_type>(tolerance, boost::math::fpc::FPC_STRONG)(t1, t2);
tolerance, boost::math::fpc::FPC_STRONG )( t1, t2 );
} }
} } // namespace detail
# define MOCK_SMALL() \ # define MOCK_SMALL() detail::is_small(actual, tolerance)
detail::is_small( actual, tolerance ) # define MOCK_PERCENT_TOLERANCE() detail::is_close(actual, expected, boost::math::fpc::percent_tolerance(tolerance))
# define MOCK_PERCENT_TOLERANCE() \ # define MOCK_FRACTION_TOLERANCE() detail::is_close(actual, expected, tolerance)
detail::is_close( actual, expected, \
boost::math::fpc::percent_tolerance( tolerance ) )
# define MOCK_FRACTION_TOLERANCE() \
detail::is_close( actual, expected, tolerance )
#endif // BOOST_VERSION < 105900 #endif // BOOST_VERSION < 105900
#ifdef small #ifdef small
# pragma push_macro( "small" ) # pragma push_macro("small")
# undef small # undef small
# define MOCK_SMALL_DEFINED # define MOCK_SMALL_DEFINED
#endif #endif
MOCK_NARY_CONSTRAINT( small, 1, ( tolerance ), MOCK_NARY_CONSTRAINT(small, 1, (tolerance), (MOCK_SMALL()))
( MOCK_SMALL() ) )
#ifdef MOCK_SMALL_DEFINED #ifdef MOCK_SMALL_DEFINED
# pragma pop_macro( "small" ) # pragma pop_macro("small")
#endif #endif
MOCK_NARY_CONSTRAINT( close, 2, ( expected, tolerance ), MOCK_NARY_CONSTRAINT(close, 2, (expected, tolerance), (MOCK_PERCENT_TOLERANCE()))
( MOCK_PERCENT_TOLERANCE() ) )
MOCK_NARY_CONSTRAINT( close_fraction, 2, ( expected, tolerance ), MOCK_NARY_CONSTRAINT(close_fraction, 2, (expected, tolerance), (MOCK_FRACTION_TOLERANCE()))
( MOCK_FRACTION_TOLERANCE() ) )
#undef MOCK_PERCENT_TOLERANCE #undef MOCK_PERCENT_TOLERANCE
#undef MOCK_FRACTION_TOLERANCE #undef MOCK_FRACTION_TOLERANCE
#ifdef near #ifdef near
# pragma push_macro( "near" ) # pragma push_macro("near")
# undef near # undef near
# define MOCK_NEAR_DEFINED # define MOCK_NEAR_DEFINED
#endif #endif
MOCK_NARY_CONSTRAINT( near, 2, ( expected, tolerance ), MOCK_NARY_CONSTRAINT(near, 2, (expected, tolerance), std::abs(actual - expected) < tolerance)
std::abs( actual - expected ) < tolerance )
#ifdef MOCK_NEAR_DEFINED #ifdef MOCK_NEAR_DEFINED
# pragma pop_macro( "near" ) # pragma pop_macro("near")
#endif #endif
namespace detail namespace detail {
{ template<typename Expected>
template< typename Expected >
struct equal struct equal
{ {
explicit equal( Expected expected ) explicit equal(Expected expected) : expected_(expected) {}
: expected_( expected ) template<typename Actual>
{} bool
template< typename Actual > operator()(const Actual& actual,
bool operator()( const Actual& actual, typename boost::enable_if<
typename boost::enable_if< boost::has_equal_to<Actual, typename boost::unwrap_reference<Expected>::type>>::type* = 0) const
boost::has_equal_to<
Actual,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{ {
return actual == boost::unwrap_ref( expected_ ); return actual == boost::unwrap_ref(expected_);
} }
template< typename Actual > template<typename Actual>
bool operator()( const Actual& actual, bool
typename boost::disable_if< operator()(const Actual& actual,
boost::has_equal_to< typename boost::disable_if<
Actual, boost::has_equal_to<Actual, typename boost::unwrap_reference<Expected>::type>>::type* = 0) const
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{ {
return actual && *actual == boost::unwrap_ref( expected_ ); return actual && *actual == boost::unwrap_ref(expected_);
} }
friend std::ostream& operator<<( std::ostream& s, const equal& e ) friend std::ostream& operator<<(std::ostream& s, const equal& e)
{ {
return s << "equal( " << mock::format( e.expected_ ) << " )"; return s << "equal( " << mock::format(e.expected_) << " )";
} }
Expected expected_; Expected expected_;
}; };
template< typename Expected > template<typename Expected>
struct same struct same
{ {
explicit same( const Expected& expected ) explicit same(const Expected& expected) : expected_(detail::addressof(boost::unwrap_ref(expected))) {}
: expected_( detail::addressof( boost::unwrap_ref( expected ) ) ) template<typename Actual>
{} bool operator()(const Actual& actual) const
template< typename Actual >
bool operator()( const Actual& actual ) const
{ {
return detail::addressof( actual ) == expected_; return detail::addressof(actual) == expected_;
} }
friend std::ostream& operator<<( std::ostream& os, const same& s ) friend std::ostream& operator<<(std::ostream& os, const same& s)
{ {
return os << "same( " << mock::format( *s.expected_ ) << " )"; return os << "same( " << mock::format(*s.expected_) << " )";
} }
const typename const typename boost::unwrap_reference<Expected>::type* expected_;
boost::unwrap_reference< Expected >::type* expected_;
}; };
template< typename Expected > template<typename Expected>
struct retrieve struct retrieve
{ {
explicit retrieve( Expected& expected ) explicit retrieve(Expected& expected) : expected_(detail::addressof(boost::unwrap_ref(expected))) {}
: expected_( detail::addressof( boost::unwrap_ref( expected ) ) ) template<typename Actual>
{} bool operator()(
template< typename Actual > const Actual& actual,
bool operator()( const Actual& actual, typename boost::disable_if<
typename boost::disable_if< boost::is_convertible<const Actual*, typename boost::unwrap_reference<Expected>::type>>::type* = 0) const
boost::is_convertible<
const Actual*,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{ {
*expected_ = actual; *expected_ = actual;
return true; return true;
} }
template< typename Actual > template<typename Actual>
bool operator()( BOOST_RV_REF(Actual) actual, bool operator()(
typename boost::disable_if< BOOST_RV_REF(Actual) actual,
boost::is_convertible< typename boost::disable_if<
const Actual*, boost::is_convertible<const Actual*, typename boost::unwrap_reference<Expected>::type>>::type* = 0) const
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{ {
*expected_ = boost::move( actual ); *expected_ = boost::move(actual);
return true; return true;
} }
template< typename Actual > template<typename Actual>
bool operator()( Actual& actual, bool
typename boost::enable_if< operator()(Actual& actual,
boost::is_convertible< Actual*, typename boost::enable_if<
typename boost::is_convertible<Actual*, typename boost::unwrap_reference<Expected>::type>>::type* = 0) const
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{ {
*expected_ = detail::addressof( actual ); *expected_ = detail::addressof(actual);
return true; return true;
} }
friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) friend std::ostream& operator<<(std::ostream& s, const retrieve& r)
{ {
return s << "retrieve( " << mock::format( *r.expected_ ) << " )"; return s << "retrieve( " << mock::format(*r.expected_) << " )";
} }
typename typename boost::unwrap_reference<Expected>::type* expected_;
boost::unwrap_reference< Expected >::type* expected_;
}; };
template< typename Expected > template<typename Expected>
struct assign struct assign
{ {
explicit assign( const Expected& expected ) explicit assign(const Expected& expected) : expected_(expected) {}
: expected_( expected ) template<typename Actual>
{} bool operator()(Actual& actual) const
template< typename Actual >
bool operator()( Actual& actual ) const
{ {
actual = boost::unwrap_ref( expected_ ); actual = boost::unwrap_ref(expected_);
return true; return true;
} }
template< typename Actual > template<typename Actual>
bool operator()( Actual* actual, bool
typename boost::enable_if< operator()(Actual* actual,
boost::is_convertible< typename boost::enable_if<
typename boost::is_convertible<typename boost::unwrap_reference<Expected>::type, Actual>>::type* = 0) const
boost::unwrap_reference< Expected >::type,
Actual
>
>::type* = 0 ) const
{ {
if( ! actual ) if(!actual)
return false; return false;
*actual = boost::unwrap_ref( expected_ ); *actual = boost::unwrap_ref(expected_);
return true; return true;
} }
friend std::ostream& operator<<( std::ostream& s, const assign& a ) friend std::ostream& operator<<(std::ostream& s, const assign& a)
{ {
return s << "assign( " << mock::format( a.expected_ ) << " )"; return s << "assign( " << mock::format(a.expected_) << " )";
} }
Expected expected_; Expected expected_;
}; };
template< typename Expected > template<typename Expected>
struct contain struct contain
{ {
explicit contain( const Expected& expected ) explicit contain(const Expected& expected) : expected_(expected) {}
: expected_( expected ) bool operator()(const std::string& actual) const
{}
bool operator()( const std::string& actual ) const
{ {
return actual.find( boost::unwrap_ref( expected_ ) ) return actual.find(boost::unwrap_ref(expected_)) != std::string::npos;
!= std::string::npos;
} }
friend std::ostream& operator<<( std::ostream& s, const contain& n ) friend std::ostream& operator<<(std::ostream& s, const contain& n)
{ {
return s << "contain( " << mock::format( n.expected_ ) << " )"; return s << "contain( " << mock::format(n.expected_) << " )";
} }
Expected expected_; Expected expected_;
}; };
} // namespace detail
template<typename T>
constraint<detail::equal<typename detail::forward_type<T>::type>> equal(BOOST_FWD_REF(T) t)
{
return detail::equal<typename detail::forward_type<T>::type>(boost::forward<T>(t));
} }
template< typename T > template<typename T>
constraint< detail::equal< typename detail::forward_type< T >::type > > equal( BOOST_FWD_REF(T) t ) constraint<detail::same<T>> same(T& t)
{ {
return detail::equal< typename detail::forward_type< T >::type >( boost::forward< T >( t ) ); return detail::same<T>(t);
} }
template<typename T>
constraint<detail::retrieve<T>> retrieve(T& t)
{
return detail::retrieve<T>(t);
}
template<typename T>
constraint<detail::assign<T>> assign(T t)
{
return detail::assign<T>(t);
}
template<typename T>
constraint<detail::contain<T>> contain(T t)
{
return detail::contain<T>(t);
}
template< typename T > template<typename T>
constraint< detail::same< T > > same( T& t ) constraint<T> call(T t)
{ {
return detail::same< T >( t ); return constraint<T>(t);
} }
template< typename T > } // namespace mock
constraint< detail::retrieve< T > > retrieve( T& t )
{
return detail::retrieve< T >( t );
}
template< typename T >
constraint< detail::assign< T > > assign( T t )
{
return detail::assign< T >( t );
}
template< typename T >
constraint< detail::contain< T > > contain( T t )
{
return detail::contain< T >( t );
}
template< typename T >
constraint< T > call( T t )
{
return constraint< T >( t );
}
} // mock
#endif // MOCK_CONSTRAINTS_HPP_INCLUDED #endif // MOCK_CONSTRAINTS_HPP_INCLUDED

View file

@ -10,77 +10,62 @@
#define MOCK_ACTION_HPP_INCLUDED #define MOCK_ACTION_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/move/move.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace mock namespace mock { namespace detail {
{ template<typename Result, typename Signature>
namespace detail
{
template< typename Result, typename Signature >
class action_base class action_base
{ {
private: private:
#ifdef MOCK_HDR_FUNCTIONAL #ifdef MOCK_HDR_FUNCTIONAL
typedef std::function< Signature > functor_type; typedef std::function<Signature> functor_type;
typedef std::function< Result() > action_type; typedef std::function<Result()> action_type;
#else #else
typedef boost::function< Signature > functor_type; typedef boost::function<Signature> functor_type;
typedef boost::function< Result() > action_type; typedef boost::function<Result()> action_type;
#endif #endif
public: public:
const functor_type& functor() const const functor_type& functor() const { return f_; }
{ bool valid() const { return f_ || a_; }
return f_; Result trigger() const { return a_(); }
}
bool valid() const
{
return f_ || a_;
}
Result trigger() const
{
return a_();
}
void calls( const functor_type& f ) void calls(const functor_type& f)
{ {
if( ! f ) if(!f)
throw std::invalid_argument( "null functor" ); throw std::invalid_argument("null functor");
f_ = f; f_ = f;
} }
template< typename Exception > template<typename Exception>
void throws( Exception e ) void throws(Exception e)
{ {
a_ = boost::bind( &do_throw< Exception >, e ); a_ = boost::bind(&do_throw<Exception>, e);
} }
protected: protected:
void set( const action_type& a ) void set(const action_type& a) { a_ = a; }
template<typename Y>
void set(const boost::reference_wrapper<Y>& r)
{ {
a_ = a; a_ = boost::bind(&do_ref<Y>, r.get_pointer());
}
template< typename Y >
void set( const boost::reference_wrapper< Y >& r )
{
a_ = boost::bind( &do_ref< Y >, r.get_pointer() );
} }
private: private:
template< typename T > template<typename T>
static T& do_ref( T* t ) static T& do_ref(T* t)
{ {
return *t; return *t;
} }
template< typename T > template<typename T>
static Result do_throw( T t ) static Result do_throw(T t)
{ {
throw t; throw t;
} }
@ -89,138 +74,117 @@ namespace detail
action_type a_; action_type a_;
}; };
template< typename Result, typename Signature > template<typename Result, typename Signature>
class action : public action_base< Result, Signature > class action : public action_base<Result, Signature>
{ {
public: public:
template< typename Value > template<typename Value>
void returns( const Value& v ) void returns(const Value& v)
{ {
this->set( boost::ref( store( v ) ) ); this->set(boost::ref(store(v)));
} }
template< typename Y > template<typename Y>
void returns( const boost::reference_wrapper< Y >& r ) void returns(const boost::reference_wrapper<Y>& r)
{ {
this->set( r ); this->set(r);
} }
template< typename Value > template<typename Value>
void moves( BOOST_RV_REF(Value) v ) void moves(BOOST_RV_REF(Value) v)
{ {
this->set( this->set(
boost::bind( boost::bind(&move<typename boost::remove_reference<Value>::type>, boost::ref(store(boost::move(v)))));
&move< typename boost::remove_reference< Value >::type >,
boost::ref( store( boost::move( v ) ) ) ) );
} }
private: private:
template< typename Value > template<typename Value>
static BOOST_RV_REF(Value) move( Value& t ) static BOOST_RV_REF(Value) move(Value& t)
{ {
return boost::move( t ); return boost::move(t);
} }
struct value : boost::noncopyable struct value : boost::noncopyable
{ {
virtual ~value() virtual ~value() {}
{}
}; };
template< typename T > template<typename T>
struct value_imp : value struct value_imp : value
{ {
typedef typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type value_type;
typename boost::remove_const<
typename boost::remove_reference<
T
>::type
>::type value_type;
value_imp( BOOST_RV_REF(value_type) t ) value_imp(BOOST_RV_REF(value_type) t) : t_(boost::move(t)) {}
: t_( boost::move( t ) ) value_imp(const value_type& t) : t_(t) {}
{} template<typename Y>
value_imp( const value_type& t ) value_imp(Y* y) : t_(y)
: t_( t )
{}
template< typename Y >
value_imp( Y* y )
: t_( y )
{} {}
value_type t_; value_type t_;
}; };
template< typename T > template<typename T>
T& store( BOOST_RV_REF(T) t ) T& store(BOOST_RV_REF(T) t)
{ {
v_.reset( new value_imp< T >( boost::move( t ) ) ); v_.reset(new value_imp<T>(boost::move(t)));
return static_cast< value_imp< T >& >( *v_ ).t_; return static_cast<value_imp<T>&>(*v_).t_;
} }
template< typename T > template<typename T>
T& store( const T& t ) T& store(const T& t)
{ {
v_.reset( new value_imp< T >( t ) ); v_.reset(new value_imp<T>(t));
return static_cast< value_imp< T >& >( *v_ ).t_; return static_cast<value_imp<T>&>(*v_).t_;
} }
template< typename T > template<typename T>
typename boost::remove_reference< Result >::type& store( T* t ) typename boost::remove_reference<Result>::type& store(T* t)
{ {
v_.reset( new value_imp< Result >( t ) ); v_.reset(new value_imp<Result>(t));
return static_cast< value_imp< Result >& >( *v_ ).t_; return static_cast<value_imp<Result>&>(*v_).t_;
} }
boost::shared_ptr< value > v_; boost::shared_ptr<value> v_;
}; };
template< typename Signature > template<typename Signature>
class action< void, Signature > : public action_base< void, Signature > class action<void, Signature> : public action_base<void, Signature>
{ {
public: public:
action() action() { this->set(boost::bind(&do_nothing)); }
{
this->set( boost::bind( &do_nothing ) );
}
private: private:
static void do_nothing() static void do_nothing() {}
{}
}; };
#ifdef MOCK_AUTO_PTR #ifdef MOCK_AUTO_PTR
template< typename Result, typename Signature > template<typename Result, typename Signature>
class action< std::auto_ptr< Result >, Signature > class action<std::auto_ptr<Result>, Signature> : public action_base<std::auto_ptr<Result>, Signature>
: public action_base< std::auto_ptr< Result >, Signature >
{ {
public: public:
action() action() {}
{} action(const action& rhs) : v_(rhs.v_.release())
action( const action& rhs )
: v_( rhs.v_.release() )
{ {
if( v_.get() ) if(v_.get())
returns( boost::ref( v_ ) ); returns(boost::ref(v_));
} }
template< typename Y > template<typename Y>
void returns( Y* r ) void returns(Y* r)
{ {
v_.reset( r ); v_.reset(r);
this->set( boost::ref( v_ ) ); this->set(boost::ref(v_));
} }
template< typename Y > template<typename Y>
void returns( std::auto_ptr< Y > r ) void returns(std::auto_ptr<Y> r)
{ {
v_ = r; v_ = r;
this->set( boost::ref( v_ ) ); this->set(boost::ref(v_));
} }
template< typename Y > template<typename Y>
void returns( const boost::reference_wrapper< Y >& r ) void returns(const boost::reference_wrapper<Y>& r)
{ {
this->set( r ); this->set(r);
} }
private: private:
mutable std::auto_ptr< Result > v_; mutable std::auto_ptr<Result> v_;
}; };
#endif // MOCK_AUTO_PTR #endif // MOCK_AUTO_PTR
} }} // namespace mock::detail
} // mock
#endif // MOCK_ACTION_HPP_INCLUDED #endif // MOCK_ACTION_HPP_INCLUDED

View file

@ -12,25 +12,15 @@
#include "../config.hpp" #include "../config.hpp"
#include <boost/utility/addressof.hpp> #include <boost/utility/addressof.hpp>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
using boost::addressof; using boost::addressof;
#ifdef MOCK_NULLPTR #ifdef MOCK_NULLPTR
inline const std::nullptr_t* addressof( const std::nullptr_t& p ) inline const std::nullptr_t* addressof(const std::nullptr_t& p) { return &p; }
{ inline std::nullptr_t* addressof(std::nullptr_t& p) { return &p; }
return &p;
}
inline std::nullptr_t* addressof( std::nullptr_t& p )
{
return &p;
}
#endif #endif
} }} // namespace mock::detail
} // mock
#endif // MOCK_ADDRESSOF_HPP_INCLUDED #endif // MOCK_ADDRESSOF_HPP_INCLUDED

View file

@ -10,43 +10,36 @@
#define MOCK_CHILD_HPP_INCLUDED #define MOCK_CHILD_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include "type_name.hpp"
#include "parent.hpp" #include "parent.hpp"
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include "type_name.hpp"
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream> #include <ostream>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class child class child
{ {
public: public:
child() child() : parent_(0) {}
: parent_( 0 ) void update(parent& p, boost::unit_test::const_string instance, boost::optional<type_name> type,
{} boost::unit_test::const_string name)
void update( parent& p,
boost::unit_test::const_string instance,
boost::optional< type_name > type,
boost::unit_test::const_string name )
{ {
if( instance != "?." || name_.empty() ) if(instance != "?." || name_.empty())
p = parent( instance, type ); p = parent(instance, type);
parent_ = &p; parent_ = &p;
name_ = name; name_ = name;
} }
friend std::ostream& operator<<( std::ostream& s, const child& c ) friend std::ostream& operator<<(std::ostream& s, const child& c)
{ {
if( c.parent_ ) if(c.parent_)
s << *c.parent_; s << *c.parent_;
return s << c.name_; return s << c.name_;
} }
private: private:
const parent* parent_; const parent* parent_;
boost::unit_test::const_string name_; boost::unit_test::const_string name_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_CHILD_HPP_INCLUDED #endif // MOCK_CHILD_HPP_INCLUDED

View file

@ -16,10 +16,7 @@
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream> #include <ostream>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class verifiable; class verifiable;
class context : boost::noncopyable class context : boost::noncopyable
@ -28,17 +25,13 @@ namespace detail
context() {} context() {}
virtual ~context() {} virtual ~context() {}
virtual void add( const void* p, verifiable& v, virtual void add(const void* p, verifiable& v, boost::unit_test::const_string instance,
boost::unit_test::const_string instance, boost::optional<type_name> type, boost::unit_test::const_string name) = 0;
boost::optional< type_name > type, virtual void add(verifiable& v) = 0;
boost::unit_test::const_string name ) = 0; virtual void remove(verifiable& v) = 0;
virtual void add( verifiable& v ) = 0;
virtual void remove( verifiable& v ) = 0;
virtual void serialize( std::ostream& s, virtual void serialize(std::ostream& s, const verifiable& v) const = 0;
const verifiable& v ) const = 0;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_CONTEXT_HPP_INCLUDED #endif // MOCK_CONTEXT_HPP_INCLUDED

View file

@ -8,115 +8,84 @@
#include "matcher_base_template.hpp" #include "matcher_base_template.hpp"
#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \ #define MOCK_EXPECTATION_INITIALIZE(z, n, d) BOOST_PP_COMMA_IF(n) c##n##_(c##n)
BOOST_PP_COMMA_IF(n) c##n##_( c##n )
#define MOCK_EXPECTATION_MEMBER(z, n, d) \ #define MOCK_EXPECTATION_MEMBER(z, n, d) matcher<T##n, Constraint_##n> c##n##_;
matcher< T##n, Constraint_##n > c##n##_;
#define MOCK_EXPECTATION_IS_VALID(z, n, d) \ #define MOCK_EXPECTATION_IS_VALID(z, n, d) \
BOOST_PP_IF(n, &&,) c##n##_( mock::detail::move_if_not_lvalue_reference< T##n >( a##n ) ) BOOST_PP_IF(n, &&, ) c##n##_(mock::detail::move_if_not_lvalue_reference<T##n>(a##n))
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \ #define MOCK_EXPECTATION_SERIALIZE(z, n, d) BOOST_PP_IF(n, << ", " <<, ) c##n##_
BOOST_PP_IF(n, << ", " <<,) c##n##_
#define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) \ #define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) BOOST_PP_IF(n, << ", " <<, ) "any"
BOOST_PP_IF(n, << ", " <<,) "any"
#define MOCK_EXPECTATION_PARAM(z, n, Args) \ #define MOCK_EXPECTATION_PARAM(z, n, Args) mock::detail::move_if_not_lvalue_reference<T##n>(a##n)
mock::detail::move_if_not_lvalue_reference< T##n >( a##n )
#define MOCK_REF_ARG(z, n, d) \ #define MOCK_REF_ARG(z, n, d) typename ref_arg<T##n>::type a##n
typename ref_arg< T##n >::type a##n
#define MOCK_REF_ARG_T(z, n, d) \ #define MOCK_REF_ARG_T(z, n, d) typename ref_arg<T##n>::type
typename ref_arg< T##n >::type
namespace mock namespace mock { namespace detail {
{ template<typename Signature>
namespace detail class default_matcher;
{
template< typename Signature > class default_matcher;
template< template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) > class default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> :
class default_matcher< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > public matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{ {
private: private:
virtual bool operator()( virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG_T, _)) { return true; }
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG_T, _) ) virtual void serialize(std::ostream& s) const
{ {
return true; s << "" BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_SERIALIZE_ANY, _);
}
virtual void serialize( std::ostream& s ) const
{
s << "" BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_SERIALIZE_ANY, _);
} }
}; };
#ifndef MOCK_NUM_ARGS_0 #ifndef MOCK_NUM_ARGS_0
template< typename Constraint, typename Signature > class single_matcher; template<typename Constraint, typename Signature>
class single_matcher;
template< template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_), BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_), class single_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_)),
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> :
> public matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
class single_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ),
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{ {
public: public:
single_matcher( single_matcher(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c))
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) ) : BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_INITIALIZE, _)
: BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_INITIALIZE, _)
{} {}
private: private:
virtual bool operator()( virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _))
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) )
{ {
return BOOST_PP_REPEAT(MOCK_NUM_ARGS, return BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_IS_VALID, _);
MOCK_EXPECTATION_IS_VALID, _);
} }
virtual void serialize( std::ostream& s ) const virtual void serialize(std::ostream& s) const
{ {
s << BOOST_PP_REPEAT(MOCK_NUM_ARGS, s << BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_SERIALIZE, _);
MOCK_EXPECTATION_SERIALIZE, _);
} }
private: private:
BOOST_PP_REPEAT( BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, _)
MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, _) };
};
template< typename F, typename Signature > class multi_matcher; template<typename F, typename Signature>
class multi_matcher;
template< typename F, template<typename F, BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) > class multi_matcher<F, void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> :
class multi_matcher< F, void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > public matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{ {
public: public:
multi_matcher( const F& f ) multi_matcher(const F& f) : f_(f) {}
: f_( f )
{}
private: private:
virtual bool operator()( virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _))
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) )
{ {
return f_( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) ); return f_(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _));
}
virtual void serialize( std::ostream& s ) const
{
s << mock::format( f_ );
} }
virtual void serialize(std::ostream& s) const { s << mock::format(f_); }
private: private:
F f_; F f_;
@ -124,146 +93,99 @@ namespace detail
#endif #endif
template< typename Signature > class expectation; template<typename Signature>
class expectation;
template< typename R template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) > class expectation<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> :
class expectation< R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) > public action<R, R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
: public action< R, R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
{ {
public: public:
expectation() expectation()
: invocation_( boost::make_shared< unlimited >() ) : invocation_(boost::make_shared<unlimited>()),
, matcher_( matcher_(boost::make_shared<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()),
boost::make_shared< file_("unknown location"), line_(0)
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> () )
, file_( "unknown location" )
, line_( 0 )
{} {}
expectation( const char* file, int line ) expectation(const char* file, int line)
: invocation_( boost::make_shared< unlimited >() ) : invocation_(boost::make_shared<unlimited>()),
, matcher_( matcher_(boost::make_shared<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()),
boost::make_shared< file_(file), line_(line)
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> () )
, file_( file )
, line_( line )
{} {}
~expectation() ~expectation()
{ {
for( sequences_cit it = sequences_.begin(); for(sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it)
it != sequences_.end(); ++it ) (*it)->remove(this);
(*it)->remove( this );
} }
void invoke( const boost::shared_ptr< invocation >& i ) void invoke(const boost::shared_ptr<invocation>& i) { invocation_ = i; }
{
invocation_ = i;
}
#ifndef MOCK_NUM_ARGS_0 #ifndef MOCK_NUM_ARGS_0
template< template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_) expectation& with(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c))
>
expectation& with(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
{ {
matcher_.reset( matcher_.reset(
new single_matcher< new single_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_)),
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ), void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c)));
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) ) );
return *this; return *this;
} }
#if MOCK_NUM_ARGS > 1 # if MOCK_NUM_ARGS > 1
template< typename Constraint > template<typename Constraint>
expectation& with( const Constraint& c ) expectation& with(const Constraint& c)
{ {
matcher_.reset( matcher_.reset(new multi_matcher<Constraint, void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>(c));
new multi_matcher<
Constraint,
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( c ) );
return *this; return *this;
} }
#endif # endif
#endif #endif
void add( sequence& s ) void add(sequence& s)
{ {
s.impl_->add( this ); s.impl_->add(this);
sequences_.push_back( s.impl_ ); sequences_.push_back(s.impl_);
} }
bool verify() const bool verify() const { return invocation_->verify(); }
{
return invocation_->verify();
}
bool is_valid( bool is_valid(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _)) const
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) const
{ {
return !invocation_->exhausted() return !invocation_->exhausted() && (*matcher_)(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _));
&& (*matcher_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) );
} }
bool invoke() const bool invoke() const
{ {
for( sequences_cit it = sequences_.begin(); for(sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it)
it != sequences_.end(); ++it ) if(!(*it)->is_valid(this))
if( ! (*it)->is_valid( this ) )
return false; return false;
bool result = invocation_->invoke(); bool result = invocation_->invoke();
for( sequences_cit it = sequences_.begin(); for(sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it)
it != sequences_.end(); ++it ) (*it)->invalidate(this);
(*it)->invalidate( this );
return result; return result;
} }
const char* file() const const char* file() const { return file_; }
{ int line() const { return line_; }
return file_;
}
int line() const
{
return line_;
}
friend std::ostream& operator<<( friend std::ostream& operator<<(std::ostream& s, const expectation& e)
std::ostream& s, const expectation& e )
{ {
return s << ( e.invocation_->exhausted() ? 'v' : '.' ) return s << (e.invocation_->exhausted() ? 'v' : '.') << ' ' << *e.invocation_
<< ' ' << *e.invocation_
#ifndef MOCK_NUM_ARGS_0 #ifndef MOCK_NUM_ARGS_0
<< ".with( " << *e.matcher_ << " )" << ".with( " << *e.matcher_ << " )"
#endif #endif
; ;
} }
private: private:
typedef std::vector< typedef std::vector<boost::shared_ptr<sequence_impl>> sequences_type;
boost::shared_ptr< sequence_impl >
> sequences_type;
typedef sequences_type::const_iterator sequences_cit; typedef sequences_type::const_iterator sequences_cit;
boost::shared_ptr< invocation > invocation_; boost::shared_ptr<invocation> invocation_;
boost::shared_ptr< boost::shared_ptr<matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>> matcher_;
matcher_base<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> matcher_;
sequences_type sequences_; sequences_type sequences_;
const char* file_; const char* file_;
int line_; int line_;
}; };
} }} // namespace mock::detail
} // mock
#undef MOCK_EXPECTATION_INITIALIZE #undef MOCK_EXPECTATION_INITIALIZE
#undef MOCK_EXPECTATION_MEMBER #undef MOCK_EXPECTATION_MEMBER

View file

@ -13,38 +13,29 @@
#include "../stream.hpp" #include "../stream.hpp"
#include "addressof.hpp" #include "addressof.hpp"
namespace mock namespace mock { namespace detail {
{ template<typename T>
namespace detail
{
template< typename T >
struct formatter struct formatter
{ {
explicit formatter( const T& t ) explicit formatter(const T& t) : t_(detail::addressof(t)) {}
: t_( detail::addressof( t ) ) void serialize(stream& s) const { detail::serialize(s, *t_); }
{}
void serialize( stream& s ) const
{
detail::serialize( s, *t_ );
}
const T* t_; const T* t_;
}; };
template< typename T > template<typename T>
stream& operator<<( stream& s, const formatter< T >& f ) stream& operator<<(stream& s, const formatter<T>& f)
{ {
f.serialize( s ); f.serialize(s);
return s; return s;
} }
template< typename T > template<typename T>
std::ostream& operator<<( std::ostream& s, const formatter< T >& f ) std::ostream& operator<<(std::ostream& s, const formatter<T>& f)
{ {
stream ss( s ); stream ss(s);
f.serialize( ss ); f.serialize(ss);
return s; return s;
} }
} }} // namespace mock::detail
} // mock
#endif // MOCK_FORMATTER_HPP_INCLUDED #endif // MOCK_FORMATTER_HPP_INCLUDED

View file

@ -10,79 +10,67 @@
#define MOCK_FUNCTION_HPP_INCLUDED #define MOCK_FUNCTION_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include "../constraints.hpp"
#include "../error.hpp" #include "../error.hpp"
#include "../log.hpp" #include "../log.hpp"
#include "../constraints.hpp"
#include "../sequence.hpp"
#include "../matcher.hpp" #include "../matcher.hpp"
#include "../sequence.hpp"
#include "action.hpp" #include "action.hpp"
#include "verifiable.hpp"
#include "invocation.hpp"
#include "type_name.hpp"
#include "context.hpp" #include "context.hpp"
#include "mutex.hpp" #include "invocation.hpp"
#include "move_helper.hpp" #include "move_helper.hpp"
#include <boost/preprocessor/iteration/iterate.hpp> #include "mutex.hpp"
#include <boost/preprocessor/repetition/repeat_from_to.hpp> #include "type_name.hpp"
#include <boost/preprocessor/repetition/enum_params.hpp> #include "verifiable.hpp"
#include <boost/preprocessor/repetition/enum_binary_params.hpp> #include <boost/call_traits.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <boost/move/move.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/preprocessor/comparison/equal.hpp> #include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/comparison/greater.hpp> #include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/lazy_ostream.hpp> #include <boost/test/utils/lazy_ostream.hpp>
#include <boost/enable_shared_from_this.hpp> #include <list>
#include <boost/call_traits.hpp>
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
#include <boost/move/move.hpp>
#include <boost/optional.hpp>
#include <ostream> #include <ostream>
#include <vector> #include <vector>
#include <list>
namespace mock namespace mock { namespace detail {
{ template<typename R, typename E>
namespace detail
{
template< typename R, typename E >
struct wrapper_base struct wrapper_base
{ {
wrapper_base( E& e ) wrapper_base(E& e) : e_(&e) {}
: e_( &e )
{}
template< typename T > template<typename T>
void returns( T t ) void returns(T t)
{ {
e_->returns( t ); e_->returns(t);
} }
E* e_; E* e_;
}; };
template< typename E > template<typename E>
struct wrapper_base< void, E > struct wrapper_base<void, E>
{ {
wrapper_base( E& e ) wrapper_base(E& e) : e_(&e) {}
: e_( &e )
{}
E* e_; E* e_;
}; };
template< typename R, typename E > template<typename R, typename E>
struct wrapper_base< R*, E > struct wrapper_base<R*, E>
{ {
wrapper_base( E& e ) wrapper_base(E& e) : e_(&e) {}
: e_( &e )
{}
void returns( R* r ) void returns(R* r) { e_->returns(r); }
template<typename Y>
void returns(const boost::reference_wrapper<Y>& r)
{ {
e_->returns( r ); e_->returns(r);
}
template< typename Y >
void returns( const boost::reference_wrapper< Y >& r )
{
e_->returns( r );
} }
E* e_; E* e_;
@ -97,8 +85,7 @@ namespace detail
return std::uncaught_exception() ? 1 : 0; return std::uncaught_exception() ? 1 : 0;
#endif #endif
} }
} }} // namespace mock::detail
} // mock
#define MOCK_NUM_ARGS 0 #define MOCK_NUM_ARGS 0
#define MOCK_NUM_ARGS_0 #define MOCK_NUM_ARGS_0

View file

@ -9,200 +9,163 @@
#include "expectation_template.hpp" #include "expectation_template.hpp"
#ifndef MOCK_ERROR_POLICY #ifndef MOCK_ERROR_POLICY
# error no error policy has been set # error no error policy has been set
#endif #endif
#define MOCK_FUNCTION_FORMAT(z, n, N) \ #define MOCK_FUNCTION_FORMAT(z, n, N) << ' ' << mock::format(t##n) << BOOST_PP_IF(BOOST_PP_EQUAL(N, n), ' ', ',')
<< ' ' << mock::format( t##n ) \
<< BOOST_PP_IF(BOOST_PP_EQUAL(N,n), ' ', ',')
#define MOCK_FUNCTION_CONTEXT \ #define MOCK_FUNCTION_CONTEXT \
boost::unit_test::lazy_ostream::instance() \ boost::unit_test::lazy_ostream::instance() \
<< lazy_context( this ) \ << lazy_context(this) << '(' BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_FORMAT, BOOST_PP_DEC(MOCK_NUM_ARGS)) \
<< '(' BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_FORMAT, \ << ')' << lazy_expectations(this)
BOOST_PP_DEC(MOCK_NUM_ARGS)) \
<< ')' \
<< lazy_expectations( this )
#define MOCK_MOVE(z, n, d) \ #define MOCK_MOVE(z, n, d) mock::detail::move_if_not_lvalue_reference<T##n>(t##n)
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
namespace mock namespace mock { namespace detail {
{ template<typename Signature>
namespace detail class function_impl;
{
template< typename Signature > class function_impl;
template< typename R template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) > class function_impl<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> :
class function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > public verifiable,
: public verifiable, public boost::enable_shared_from_this< public boost::enable_shared_from_this<function_impl<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>
function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )> >
{ {
public: public:
typedef safe_error< R, MOCK_ERROR_POLICY< R > > error_type; typedef safe_error<R, MOCK_ERROR_POLICY<R>> error_type;
public: public:
function_impl() function_impl() : context_(0), valid_(true), exceptions_(exceptions()), mutex_(boost::make_shared<mutex>()) {}
: context_( 0 )
, valid_( true )
, exceptions_( exceptions() )
, mutex_( boost::make_shared< mutex >() )
{}
virtual ~function_impl() virtual ~function_impl()
{ {
if( valid_ && exceptions_ >= exceptions() ) if(valid_ && exceptions_ >= exceptions())
for( expectations_cit it = expectations_.begin(); for(expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it)
it != expectations_.end(); ++it ) if(!it->verify())
if( ! it->verify() ) error_type::fail("untriggered expectation",
error_type::fail( "untriggered expectation", boost::unit_test::lazy_ostream::instance()
boost::unit_test::lazy_ostream::instance() << lazy_context(this) << lazy_expectations(this),
<< lazy_context( this ) it->file(), it->line());
<< lazy_expectations( this ), if(context_)
it->file(), it->line() ); context_->remove(*this);
if( context_ )
context_->remove( *this );
} }
virtual bool verify() const virtual bool verify() const
{ {
lock _( mutex_ ); lock _(mutex_);
for( expectations_cit it = expectations_.begin(); for(expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it)
it != expectations_.end(); ++it ) if(!it->verify())
if( ! it->verify() )
{ {
valid_ = false; valid_ = false;
error_type::fail( "verification failed", error_type::fail("verification failed",
boost::unit_test::lazy_ostream::instance() boost::unit_test::lazy_ostream::instance()
<< lazy_context( this ) << lazy_context(this) << lazy_expectations(this),
<< lazy_expectations( this ), it->file(), it->line());
it->file(), it->line() );
} }
return valid_; return valid_;
} }
virtual void reset() virtual void reset()
{ {
lock _( mutex_ ); lock _(mutex_);
valid_ = true; valid_ = true;
boost::shared_ptr< function_impl > guard = boost::shared_ptr<function_impl> guard = this->shared_from_this();
this->shared_from_this();
expectations_.clear(); expectations_.clear();
} }
private: private:
typedef expectation< typedef expectation<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> expectation_type;
R( BOOST_PP_ENUM_PARAMS( MOCK_NUM_ARGS, T ) )
> expectation_type;
class wrapper : public wrapper_base< R, expectation_type > class wrapper : public wrapper_base<R, expectation_type>
{ {
private: private:
typedef wrapper_base< R, expectation_type > base_type; typedef wrapper_base<R, expectation_type> base_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(wrapper) BOOST_MOVABLE_BUT_NOT_COPYABLE(wrapper)
public: public:
wrapper( const boost::shared_ptr< mutex >& m, expectation_type& e ) wrapper(const boost::shared_ptr<mutex>& m, expectation_type& e) : base_type(e), lock_(m) {}
: base_type( e ) wrapper(BOOST_RV_REF(wrapper) x) : base_type(x), lock_(boost::move(x.lock_)) {}
, lock_( m ) wrapper& operator=(BOOST_RV_REF(wrapper) x)
{}
wrapper( BOOST_RV_REF( wrapper ) x )
: base_type( x )
, lock_( boost::move( x.lock_) )
{}
wrapper& operator=( BOOST_RV_REF( wrapper ) x )
{ {
static_cast< base_type& >( *this ) = x; static_cast<base_type&>(*this) = x;
lock_ = boost::move( x.lock_ ); lock_ = boost::move(x.lock_);
return *this; return *this;
} }
wrapper& once() wrapper& once()
{ {
this->e_->invoke( boost::make_shared< detail::once >() ); this->e_->invoke(boost::make_shared<detail::once>());
return *this; return *this;
} }
wrapper& never() wrapper& never()
{ {
this->e_->invoke( boost::make_shared< detail::never >() ); this->e_->invoke(boost::make_shared<detail::never>());
return *this; return *this;
} }
wrapper& exactly( std::size_t count ) wrapper& exactly(std::size_t count)
{ {
this->e_->invoke( this->e_->invoke(boost::make_shared<detail::exactly>(count));
boost::make_shared< detail::exactly >( count ) );
return *this; return *this;
} }
wrapper& at_least( std::size_t min ) wrapper& at_least(std::size_t min)
{ {
this->e_->invoke( this->e_->invoke(boost::make_shared<detail::at_least>(min));
boost::make_shared< detail::at_least >( min ) );
return *this; return *this;
} }
wrapper& at_most( std::size_t max ) wrapper& at_most(std::size_t max)
{ {
this->e_->invoke( this->e_->invoke(boost::make_shared<detail::at_most>(max));
boost::make_shared< detail::at_most >( max ) );
return *this; return *this;
} }
wrapper& between( std::size_t min, std::size_t max ) wrapper& between(std::size_t min, std::size_t max)
{ {
this->e_->invoke( this->e_->invoke(boost::make_shared<detail::between>(min, max));
boost::make_shared< detail::between >( min, max ) );
return *this; return *this;
} }
#ifndef MOCK_NUM_ARGS_0 #ifndef MOCK_NUM_ARGS_0
template< template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_) wrapper& with(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c))
>
wrapper& with(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
{ {
this->e_->with( this->e_->with(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c));
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) );
return *this; return *this;
} }
#if MOCK_NUM_ARGS > 1 # if MOCK_NUM_ARGS > 1
template< typename Constraint > template<typename Constraint>
wrapper& with( const Constraint& c ) wrapper& with(const Constraint& c)
{ {
this->e_->with( c ); this->e_->with(c);
return *this; return *this;
} }
#endif # endif
#endif #endif
#define MOCK_FUNCTION_IN_ADD(z, n, d) \ #define MOCK_FUNCTION_IN_ADD(z, n, d) this->e_->add(s##n);
this->e_->add( s##n );
#define MOCK_FUNCTION_IN(z, n, d) \ #define MOCK_FUNCTION_IN(z, n, d) \
wrapper& in( BOOST_PP_ENUM_PARAMS(n, sequence& s) ) \ wrapper& in(BOOST_PP_ENUM_PARAMS(n, sequence& s)) \
{ \ { \
BOOST_PP_REPEAT(n, MOCK_FUNCTION_IN_ADD, _) \ BOOST_PP_REPEAT(n, MOCK_FUNCTION_IN_ADD, _) \
return *this; \ return *this; \
} }
BOOST_PP_REPEAT(MOCK_MAX_SEQUENCES, BOOST_PP_REPEAT(MOCK_MAX_SEQUENCES, MOCK_FUNCTION_IN, _)
MOCK_FUNCTION_IN, _)
#undef MOCK_FUNCTION_IN #undef MOCK_FUNCTION_IN
#undef MOCK_FUNCTION_IN_ADD #undef MOCK_FUNCTION_IN_ADD
template< typename TT > template<typename TT>
void calls( TT t ) void calls(TT t)
{ {
this->e_->calls( t ); this->e_->calls(t);
} }
template< typename TT > template<typename TT>
void throws( TT t ) void throws(TT t)
{ {
this->e_->throws( t ); this->e_->throws(t);
} }
template< typename TT > template<typename TT>
void moves( BOOST_RV_REF(TT) t ) void moves(BOOST_RV_REF(TT) t)
{ {
this->e_->moves( boost::move( t ) ); this->e_->moves(boost::move(t));
} }
lock lock_; lock lock_;
@ -211,84 +174,71 @@ namespace detail
public: public:
typedef wrapper wrapper_type; typedef wrapper wrapper_type;
wrapper expect( const char* file, int line ) wrapper expect(const char* file, int line)
{ {
lock _( mutex_ ); lock _(mutex_);
expectations_.push_back( expectation_type( file, line ) ); expectations_.push_back(expectation_type(file, line));
valid_ = true; valid_ = true;
return wrapper( mutex_, expectations_.back() ); return wrapper(mutex_, expectations_.back());
} }
wrapper expect() wrapper expect()
{ {
lock _( mutex_ ); lock _(mutex_);
expectations_.push_back( expectation_type() ); expectations_.push_back(expectation_type());
valid_ = true; valid_ = true;
return wrapper( mutex_, expectations_.back() ); return wrapper(mutex_, expectations_.back());
} }
R operator()( R operator()(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t)) const
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{ {
lock _( mutex_ ); lock _(mutex_);
valid_ = false; valid_ = false;
for( expectations_cit it = expectations_.begin(); for(expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it)
it != expectations_.end(); ++it ) if(it->is_valid(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _)))
if( it->is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) ) )
{ {
if( ! it->invoke() ) if(!it->invoke())
{ {
error_type::fail( "sequence failed", error_type::fail("sequence failed", MOCK_FUNCTION_CONTEXT, it->file(), it->line());
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
return error_type::abort(); return error_type::abort();
} }
if( ! it->valid() ) if(!it->valid())
{ {
error_type::fail( "missing action", error_type::fail("missing action", MOCK_FUNCTION_CONTEXT, it->file(), it->line());
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
return error_type::abort(); return error_type::abort();
} }
valid_ = true; valid_ = true;
error_type::call( error_type::call(MOCK_FUNCTION_CONTEXT, it->file(), it->line());
MOCK_FUNCTION_CONTEXT, it->file(), it->line() ); if(it->functor())
if( it->functor() ) return it->functor()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _));
return it->functor()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
return it->trigger(); return it->trigger();
} }
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT ); error_type::fail("unexpected call", MOCK_FUNCTION_CONTEXT);
return error_type::abort(); return error_type::abort();
} }
void add( context& c, const void* p, void add(context& c, const void* p, boost::unit_test::const_string instance, boost::optional<type_name> type,
boost::unit_test::const_string instance, boost::unit_test::const_string name)
boost::optional< type_name > type,
boost::unit_test::const_string name )
{ {
lock _( mutex_ ); lock _(mutex_);
if( ! context_ ) if(!context_)
c.add( *this ); c.add(*this);
c.add( p, *this, instance, type, name ); c.add(p, *this, instance, type, name);
context_ = &c; context_ = &c;
} }
friend std::ostream& operator<<( friend std::ostream& operator<<(std::ostream& s, const function_impl& impl)
std::ostream& s, const function_impl& impl )
{ {
lock _( impl.mutex_ ); lock _(impl.mutex_);
return s << lazy_context( &impl ) << lazy_expectations( &impl ); return s << lazy_context(&impl) << lazy_expectations(&impl);
} }
struct lazy_context struct lazy_context
{ {
lazy_context( const function_impl* impl ) lazy_context(const function_impl* impl) : impl_(impl) {}
: impl_( impl ) friend std::ostream& operator<<(std::ostream& s, const lazy_context& c)
{}
friend std::ostream& operator<<(
std::ostream& s, const lazy_context& c )
{ {
if( c.impl_->context_ ) if(c.impl_->context_)
c.impl_->context_->serialize( s, *c.impl_ ); c.impl_->context_->serialize(s, *c.impl_);
else else
s << '?'; s << '?';
return s; return s;
@ -298,31 +248,26 @@ namespace detail
struct lazy_expectations struct lazy_expectations
{ {
lazy_expectations( const function_impl* impl ) lazy_expectations(const function_impl* impl) : impl_(impl) {}
: impl_( impl ) friend std::ostream& operator<<(std::ostream& s, const lazy_expectations& e)
{}
friend std::ostream& operator<<(
std::ostream& s, const lazy_expectations& e )
{ {
for( expectations_cit it = e.impl_->expectations_.begin(); for(expectations_cit it = e.impl_->expectations_.begin(); it != e.impl_->expectations_.end(); ++it)
it != e.impl_->expectations_.end(); ++it )
s << std::endl << *it; s << std::endl << *it;
return s; return s;
} }
const function_impl* impl_; const function_impl* impl_;
}; };
typedef std::list< expectation_type > expectations_type; typedef std::list<expectation_type> expectations_type;
typedef typename expectations_type::const_iterator expectations_cit; typedef typename expectations_type::const_iterator expectations_cit;
expectations_type expectations_; expectations_type expectations_;
context* context_; context* context_;
mutable bool valid_; mutable bool valid_;
const int exceptions_; const int exceptions_;
const boost::shared_ptr< mutex > mutex_; const boost::shared_ptr<mutex> mutex_;
}; };
} }} // namespace mock::detail
} // mock
#undef MOCK_FUNCTION_FORMAT #undef MOCK_FUNCTION_FORMAT
#undef MOCK_FUNCTION_CONTEXT #undef MOCK_FUNCTION_CONTEXT

View file

@ -8,99 +8,74 @@
#include "function_impl_template.hpp" #include "function_impl_template.hpp"
#define MOCK_MOVE(z, n, d) \ #define MOCK_MOVE(z, n, d) mock::detail::move_if_not_lvalue_reference<T##n>(t##n)
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
namespace mock namespace mock { namespace detail {
{ template<typename Signature>
namespace detail class function;
{
template< typename Signature > class function;
template< typename R template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) > class function<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
class function< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{ {
public: public:
typedef R result_type; typedef R result_type;
template< typename Args > template<typename Args>
struct sig struct sig
{ {
typedef R type; typedef R type;
}; };
private: private:
typedef function_impl< typedef function_impl<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> impl_type;
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
> impl_type;
typedef typename impl_type::wrapper_type expectation_type; typedef typename impl_type::wrapper_type expectation_type;
typedef typename impl_type::error_type error_type; typedef typename impl_type::error_type error_type;
public: public:
function() function() : impl_(boost::make_shared<impl_type>()) {}
: impl_( boost::make_shared< impl_type >() )
{}
bool verify() const bool verify() const { return impl_->verify(); }
bool verify(const char* file, int line) const
{ {
error_type::pass(file, line);
return impl_->verify(); return impl_->verify();
} }
bool verify( const char* file, int line ) const void reset() { impl_->reset(); }
void reset(const char* file, int line)
{ {
error_type::pass( file, line ); error_type::pass(file, line);
return impl_->verify();
}
void reset()
{
impl_->reset();
}
void reset( const char* file, int line )
{
error_type::pass( file, line );
impl_->reset(); impl_->reset();
} }
expectation_type expect( const char* file, int line ) expectation_type expect(const char* file, int line)
{ {
error_type::pass( file, line ); error_type::pass(file, line);
return impl_->expect( file, line ); return impl_->expect(file, line);
} }
expectation_type expect() expectation_type expect() { return impl_->expect(); }
R operator()(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t)) const
{ {
return impl_->expect(); return (*impl_)(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _));
} }
R operator()( friend std::ostream& operator<<(std::ostream& s, const function& f) { return s << *f.impl_; }
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
}
friend std::ostream& operator<<( std::ostream& s, const function& f ) function& operator()(context& c, boost::unit_test::const_string instance)
{ {
return s << *f.impl_; impl_->add(c, impl_.get(), instance, boost::none, "");
}
function& operator()( context& c,
boost::unit_test::const_string instance )
{
impl_->add( c, impl_.get(), instance, boost::none, "" );
return *this; return *this;
} }
void configure( context& c, const void* p, void configure(context& c, const void* p, boost::unit_test::const_string instance,
boost::unit_test::const_string instance, boost::optional<type_name> type, boost::unit_test::const_string name) const
boost::optional< type_name > type,
boost::unit_test::const_string name ) const
{ {
impl_->add( c, p, instance, type, name ); impl_->add(c, p, instance, type, name);
} }
private: private:
boost::shared_ptr< impl_type > impl_; boost::shared_ptr<impl_type> impl_;
}; };
} }} // namespace mock::detail
} // mock
#undef MOCK_MOVE #undef MOCK_MOVE

View file

@ -14,39 +14,32 @@
#include "mutex.hpp" #include "mutex.hpp"
#include "singleton.hpp" #include "singleton.hpp"
namespace mock namespace mock { namespace detail {
{ class functor_mutex_t : public singleton<functor_mutex_t>, public mutex
namespace detail
{
class functor_mutex_t :
public singleton< functor_mutex_t >,
public mutex
{ {
MOCK_SINGLETON_CONS( functor_mutex_t ); MOCK_SINGLETON_CONS(functor_mutex_t);
}; };
MOCK_SINGLETON_INST( functor_mutex ) MOCK_SINGLETON_INST(functor_mutex)
template< typename Signature > template<typename Signature>
struct functor : function< Signature > struct functor : function<Signature>
{ {
functor() functor()
{ {
scoped_lock _( functor_mutex ); scoped_lock _(functor_mutex);
static functor* f = 0; static functor* f = 0;
if( f ) if(f)
{ {
*this = *f; *this = *f;
f = 0; f = 0;
functor_mutex.unlock(); functor_mutex.unlock();
} } else
else
{ {
functor_mutex.lock(); functor_mutex.lock();
f = this; f = this;
} }
} }
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_FUNCTOR_HPP_INCLUDED #endif // MOCK_FUNCTOR_HPP_INCLUDED

View file

@ -11,54 +11,42 @@
#include "../config.hpp" #include "../config.hpp"
#include "verifiable.hpp" #include "verifiable.hpp"
#include <functional>
#include <algorithm> #include <algorithm>
#include <functional>
#include <vector> #include <vector>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class group class group
{ {
public: public:
void add( verifiable& v ) void add(verifiable& v) { verifiables_.push_back(&v); }
void remove(verifiable& v)
{ {
verifiables_.push_back( &v ); verifiables_.erase(std::remove(verifiables_.begin(), verifiables_.end(), &v), verifiables_.end());
}
void remove( verifiable& v )
{
verifiables_.erase(
std::remove( verifiables_.begin(), verifiables_.end(), &v ),
verifiables_.end() );
} }
bool verify() const bool verify() const
{ {
bool valid = true; bool valid = true;
for( verifiables_cit it = verifiables_.begin(); for(verifiables_cit it = verifiables_.begin(); it != verifiables_.end(); ++it)
it != verifiables_.end(); ++it ) if(!(*it)->verify())
if( ! (*it)->verify() )
valid = false; valid = false;
return valid; return valid;
} }
void reset() void reset()
{ {
const verifiables_t verifiables = verifiables_; const verifiables_t verifiables = verifiables_;
for( verifiables_cit it = verifiables.begin(); for(verifiables_cit it = verifiables.begin(); it != verifiables.end(); ++it)
it != verifiables.end(); ++it ) if(std::find(verifiables_.begin(), verifiables_.end(), *it) != verifiables_.end())
if( std::find( verifiables_.begin(), verifiables_.end(), *it )
!= verifiables_.end() )
(*it)->reset(); (*it)->reset();
} }
private: private:
typedef std::vector< verifiable* > verifiables_t; typedef std::vector<verifiable*> verifiables_t;
typedef verifiables_t::const_iterator verifiables_cit; typedef verifiables_t::const_iterator verifiables_cit;
verifiables_t verifiables_; verifiables_t verifiables_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_GROUP_HPP_INCLUDED #endif // MOCK_GROUP_HPP_INCLUDED

View file

@ -11,14 +11,11 @@
#include "../config.hpp" #include "../config.hpp"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <stdexcept>
#include <ostream>
#include <limits> #include <limits>
#include <ostream>
#include <stdexcept>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class invocation : private boost::noncopyable class invocation : private boost::noncopyable
{ {
public: public:
@ -30,66 +27,51 @@ namespace detail
virtual bool exhausted() const = 0; virtual bool exhausted() const = 0;
friend std::ostream& operator<<( std::ostream& s, const invocation& i ) friend std::ostream& operator<<(std::ostream& s, const invocation& i) { return i.serialize(s); }
{
return i.serialize( s );
}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const = 0; virtual std::ostream& serialize(std::ostream& s) const = 0;
}; };
class between : public invocation class between : public invocation
{ {
public: public:
between( std::size_t min, std::size_t max ) between(std::size_t min, std::size_t max) : min_(min), max_(max), count_(0)
: min_( min )
, max_( max )
, count_( 0 )
{ {
if( min > max ) if(min > max)
throw std::invalid_argument( "'min' > 'max'" ); throw std::invalid_argument("'min' > 'max'");
} }
virtual bool invoke() virtual bool invoke()
{ {
if( count_ == max_ ) if(count_ == max_)
return false; return false;
++count_; ++count_;
return true; return true;
} }
virtual bool exhausted() const virtual bool exhausted() const { return count_ >= max_; }
{
return count_ >= max_;
}
virtual bool verify() const virtual bool verify() const { return min_ <= count_ && count_ <= max_; }
{
return min_ <= count_ && count_ <= max_;
}
protected: protected:
const std::size_t min_, max_; const std::size_t min_, max_;
std::size_t count_; std::size_t count_;
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const
{ {
return s << "between( " << count_ return s << "between( " << count_ << "/[" << min_ << ',' << max_ << "] )";
<< "/[" << min_ << ',' << max_ << "] )";
} }
}; };
class exactly : public between class exactly : public between
{ {
public: public:
explicit exactly( std::size_t count ) explicit exactly(std::size_t count) : between(count, count) {}
: between( count, count )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const
{ {
return s << "exactly( " << count_ << '/' << max_ << " )"; return s << "exactly( " << count_ << '/' << max_ << " )";
} }
@ -98,40 +80,28 @@ namespace detail
class never : public exactly class never : public exactly
{ {
public: public:
never() never() : exactly(0) {}
: exactly( 0 )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const { return s << "never()"; }
{
return s << "never()";
}
}; };
class once : public exactly class once : public exactly
{ {
public: public:
once() once() : exactly(1) {}
: exactly( 1 )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const { return s << "once()"; }
{
return s << "once()";
}
}; };
class at_least : public between class at_least : public between
{ {
public: public:
explicit at_least( std::size_t min ) explicit at_least(std::size_t min) : between(min, (std::numeric_limits<std::size_t>::max)()) {}
: between( min, (std::numeric_limits< std::size_t >::max)() )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const
{ {
return s << "at_least( " << count_ << '/' << min_ << " )"; return s << "at_least( " << count_ << '/' << min_ << " )";
} }
@ -140,12 +110,10 @@ namespace detail
class at_most : public between class at_most : public between
{ {
public: public:
explicit at_most( std::size_t max ) explicit at_most(std::size_t max) : between(0, max) {}
: between( 0, max )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const
{ {
return s << "at_most( " << count_ << '/' << max_ << " )"; return s << "at_most( " << count_ << '/' << max_ << " )";
} }
@ -154,17 +122,11 @@ namespace detail
class unlimited : public at_least class unlimited : public at_least
{ {
public: public:
unlimited() unlimited() : at_least(0) {}
: at_least( 0 )
{}
private: private:
virtual std::ostream& serialize( std::ostream& s ) const virtual std::ostream& serialize(std::ostream& s) const { return s << "unlimited()"; }
{
return s << "unlimited()";
}
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_INVOCATION_HPP_INCLUDED #endif // MOCK_INVOCATION_HPP_INCLUDED

View file

@ -11,52 +11,42 @@
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/is_callable_builtin.hpp> #include <boost/function_types/is_callable_builtin.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/utility/declval.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/or.hpp> #include <boost/mpl/or.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/utility/declval.hpp>
namespace mock namespace mock { namespace detail {
{ BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
namespace detail BOOST_MPL_HAS_XXX_TEMPLATE_DEF(sig)
{ BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
BOOST_MPL_HAS_XXX_TRAIT_DEF( result_type )
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( sig )
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( result )
#ifdef MOCK_DECLTYPE #ifdef MOCK_DECLTYPE
template< typename F, typename P > template<typename F, typename P>
struct is_callable struct is_callable
{ {
typedef boost::type_traits::yes_type yes_type; typedef boost::type_traits::yes_type yes_type;
typedef boost::type_traits::no_type no_type; typedef boost::type_traits::no_type no_type;
template< typename T > template<typename T>
static yes_type check( static yes_type check(decltype(boost::declval<T>()(boost::declval<P>()))*);
decltype( boost::declval< T >()( boost::declval< P >() ) )* ); template<typename T>
template< typename T > static no_type check(...);
static no_type check( ... );
typedef boost::mpl::bool_< typedef boost::mpl::bool_<sizeof(check<F>(0)) == sizeof(yes_type)> type;
sizeof( check< F >( 0 ) ) == sizeof( yes_type ) > type;
}; };
#endif // MOCK_DECLTYPE #endif // MOCK_DECLTYPE
template< typename T, typename P > template<typename T, typename P>
struct is_functor struct is_functor :
: boost::mpl::or_< boost::mpl::or_<boost::function_types::is_callable_builtin<T>,
boost::function_types::is_callable_builtin< T >,
#ifdef MOCK_DECLTYPE #ifdef MOCK_DECLTYPE
is_callable< T, P >, is_callable<T, P>,
#endif #endif
has_result_type< T >, has_result_type<T>, has_result<T>, has_sig<T>>
has_result< T >,
has_sig< T >
>
{}; {};
} }} // namespace mock::detail
} // mock
#endif // MOCK_IS_FUNCTOR_HPP_INCLUDED #endif // MOCK_IS_FUNCTOR_HPP_INCLUDED

View file

@ -6,37 +6,29 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define MOCK_REF_ARG(z, n, d) \ #define MOCK_REF_ARG(z, n, d) typename ref_arg<T##n>::type
typename ref_arg< T##n >::type
namespace mock namespace mock { namespace detail {
{ template<typename Signature>
namespace detail class matcher_base;
{
template< typename Signature > class matcher_base;
template< template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)>
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) > class matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> : boost::noncopyable
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: boost::noncopyable
{ {
public: public:
virtual ~matcher_base() {} virtual ~matcher_base() {}
virtual bool operator()( virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _)) = 0;
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) = 0;
friend std::ostream& operator<<( friend std::ostream& operator<<(std::ostream& s, const matcher_base& m)
std::ostream& s, const matcher_base& m )
{ {
m.serialize( s ); m.serialize(s);
return s; return s;
} }
private: private:
virtual void serialize( std::ostream& ) const = 0; virtual void serialize(std::ostream&) const = 0;
}; };
} }} // namespace mock::detail
} // mock
#undef MOCK_REF_ARG #undef MOCK_REF_ARG

View file

@ -10,69 +10,62 @@
#define MOCK_MOVE_HELPER_HPP_INCLUDED #define MOCK_MOVE_HELPER_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/add_reference.hpp> #include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_rvalue_reference.hpp> #include <boost/type_traits/add_rvalue_reference.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/decay.hpp> #include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
#ifdef MOCK_RVALUE_REFERENCES #ifdef MOCK_RVALUE_REFERENCES
template< typename T > template<typename T>
struct forward_type struct forward_type
{ {
typedef T type; typedef T type;
}; };
template< typename T > template<typename T>
struct ref_arg struct ref_arg
{ {
typedef typename boost::conditional< typedef typename boost::conditional<boost::is_reference<T>::value, T,
boost::is_reference< T >::value, typename boost::add_rvalue_reference<T>::type>::type type;
T,
typename boost::add_rvalue_reference< T >::type >::type type;
}; };
template< typename T > template<typename T>
inline T&& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type& t) inline T&& move_if_not_lvalue_reference(typename boost::remove_reference<T>::type& t)
{ {
return static_cast< T&& >(t); return static_cast<T&&>(t);
} }
template< typename T > template<typename T>
inline T&& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type&& t) inline T&& move_if_not_lvalue_reference(typename boost::remove_reference<T>::type&& t)
{ {
return static_cast< T&& >(t); return static_cast<T&&>(t);
} }
#else #else
template< typename T > template<typename T>
struct forward_type struct forward_type
{ {
typedef typename boost::decay< const T >::type type; typedef typename boost::decay<const T>::type type;
}; };
template< class T> template<class T>
struct forward_type< boost::rv< T > > struct forward_type<boost::rv<T>>
{ {
typedef T type; typedef T type;
}; };
template< typename T > template<typename T>
struct ref_arg struct ref_arg
{ {
typedef typename boost::conditional< typedef typename boost::conditional<boost::is_reference<T>::value, T,
boost::is_reference< T >::value, const typename boost::add_reference<T>::type>::type type;
T,
const typename boost::add_reference< T >::type >::type type;
}; };
template< typename T > template<typename T>
inline typename boost::remove_reference< T >::type& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type& t) inline typename boost::remove_reference<T>::type&
move_if_not_lvalue_reference(typename boost::remove_reference<T>::type& t)
{ {
return t; return t;
} }
#endif #endif
} }} // namespace mock::detail
}
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED #endif // MOCK_MOVE_HELPER_HPP_INCLUDED

View file

@ -17,24 +17,21 @@
#ifdef MOCK_THREAD_SAFE #ifdef MOCK_THREAD_SAFE
#ifdef MOCK_HDR_MUTEX # ifdef MOCK_HDR_MUTEX
#include <mutex> # include <mutex>
#else # else
#include <boost/thread/recursive_mutex.hpp> # include <boost/thread/lock_guard.hpp>
#include <boost/thread/lock_guard.hpp> # include <boost/thread/recursive_mutex.hpp>
#endif # endif
namespace mock namespace mock { namespace detail {
{ # ifdef MOCK_HDR_MUTEX
namespace detail
{
#ifdef MOCK_HDR_MUTEX
typedef std::recursive_mutex mutex; typedef std::recursive_mutex mutex;
typedef std::lock_guard< mutex > scoped_lock; typedef std::lock_guard<mutex> scoped_lock;
#else # else
typedef boost::recursive_mutex mutex; typedef boost::recursive_mutex mutex;
typedef boost::lock_guard< mutex > scoped_lock; typedef boost::lock_guard<mutex> scoped_lock;
#endif # endif
struct lock struct lock
{ {
@ -42,23 +39,18 @@ namespace detail
BOOST_MOVABLE_BUT_NOT_COPYABLE(lock) BOOST_MOVABLE_BUT_NOT_COPYABLE(lock)
public: public:
lock( const boost::shared_ptr< mutex >& m ) lock(const boost::shared_ptr<mutex>& m) : m_(m) { m_->lock(); }
: m_( m )
{
m_->lock();
}
~lock() ~lock()
{ {
if( m_ ) if(m_)
m_->unlock(); m_->unlock();
} }
lock( BOOST_RV_REF( lock ) x ) lock(BOOST_RV_REF(lock) x) : m_(x.m_)
: m_( x.m_ )
{ {
// Explicit reset to avoid unlock in destructor // Explicit reset to avoid unlock in destructor
x.m_.reset(); x.m_.reset();
} }
lock& operator=( BOOST_RV_REF( lock ) x ) lock& operator=(BOOST_RV_REF(lock) x)
{ {
m_ = x.m_; m_ = x.m_;
x.m_.reset(); x.m_.reset();
@ -66,32 +58,24 @@ namespace detail
} }
private: private:
boost::shared_ptr< mutex > m_; boost::shared_ptr<mutex> m_;
}; };
} }} // namespace mock::detail
} // mock
#else // MOCK_THREAD_SAFE #else // MOCK_THREAD_SAFE
namespace mock namespace mock { namespace detail {
{
namespace detail
{
struct mutex : boost::noncopyable struct mutex : boost::noncopyable
{ {
void lock() void lock() {}
{} void unlock() {}
void unlock()
{}
}; };
// Dummy lock classes. // Dummy lock classes.
// Constructor + Destructor make it RAII classes for compilers and avoid unused variable warnings // Constructor + Destructor make it RAII classes for compilers and avoid unused variable warnings
struct scoped_lock : boost::noncopyable struct scoped_lock : boost::noncopyable
{ {
scoped_lock( mutex& ) scoped_lock(mutex&) {}
{} ~scoped_lock() {}
~scoped_lock()
{}
}; };
class lock : boost::noncopyable class lock : boost::noncopyable
{ {
@ -99,68 +83,56 @@ namespace detail
BOOST_MOVABLE_BUT_NOT_COPYABLE(lock) BOOST_MOVABLE_BUT_NOT_COPYABLE(lock)
public: public:
lock( const boost::shared_ptr< mutex >& ) lock(const boost::shared_ptr<mutex>&) {}
{} ~lock() {}
~lock() lock(BOOST_RV_REF(lock)) {}
{} lock& operator=(BOOST_RV_REF(lock)) { return *this; }
lock( BOOST_RV_REF( lock ) )
{}
lock& operator=( BOOST_RV_REF( lock ) )
{
return *this;
}
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_THREAD_SAFE #endif // MOCK_THREAD_SAFE
namespace mock namespace mock { namespace detail {
{ class error_mutex_t : public singleton<error_mutex_t>, public mutex
namespace detail
{
class error_mutex_t : public singleton< error_mutex_t >,
public mutex
{ {
MOCK_SINGLETON_CONS( error_mutex_t ); MOCK_SINGLETON_CONS(error_mutex_t);
}; };
MOCK_SINGLETON_INST( error_mutex ) MOCK_SINGLETON_INST(error_mutex)
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
# pragma warning( push ) # pragma warning(push)
# pragma warning( disable: 4702 ) # pragma warning(disable : 4702)
#endif #endif
template< typename Result, typename Error > template<typename Result, typename Error>
struct safe_error struct safe_error
{ {
static Result abort() static Result abort()
{ {
scoped_lock _( error_mutex ); scoped_lock _(error_mutex);
return Error::abort(); return Error::abort();
} }
template< typename Context > template<typename Context>
static void fail( const char* message, const Context& context, static void fail(const char* message, const Context& context, const char* file = "unknown location",
const char* file = "unknown location", int line = 0 ) int line = 0)
{ {
scoped_lock _( error_mutex ); scoped_lock _(error_mutex);
Error::fail( message, context, file, line ); Error::fail(message, context, file, line);
} }
template< typename Context > template<typename Context>
static void call( const Context& context, const char* file, int line ) static void call(const Context& context, const char* file, int line)
{ {
scoped_lock _( error_mutex ); scoped_lock _(error_mutex);
Error::call( context, file, line ); Error::call(context, file, line);
} }
static void pass( const char* file, int line ) static void pass(const char* file, int line)
{ {
scoped_lock _( error_mutex ); scoped_lock _(error_mutex);
Error::pass( file, line ); Error::pass(file, line);
} }
}; };
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
# pragma warning( pop ) # pragma warning(pop)
#endif #endif
} }} // namespace mock::detail
} // mock
#endif // MOCK_MUTEX_HPP_INCLUDED #endif // MOCK_MUTEX_HPP_INCLUDED

View file

@ -10,58 +10,50 @@
#define MOCK_OBJECT_IMPL_HPP_INCLUDED #define MOCK_OBJECT_IMPL_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include "root.hpp"
#include "parent.hpp"
#include "type_name.hpp"
#include "context.hpp"
#include "child.hpp" #include "child.hpp"
#include "context.hpp"
#include "mutex.hpp" #include "mutex.hpp"
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include "parent.hpp"
#include "root.hpp"
#include "type_name.hpp"
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
namespace mock namespace mock { namespace detail {
{ class object_impl : public context, public verifiable, public boost::enable_shared_from_this<object_impl>
namespace detail
{
class object_impl : public context, public verifiable,
public boost::enable_shared_from_this< object_impl >
{ {
public: public:
object_impl() object_impl() : mutex_(boost::make_shared<mutex>()) {}
: mutex_( boost::make_shared< mutex >() )
{}
virtual void add( const void* /*p*/, verifiable& v, virtual void add(const void* /*p*/, verifiable& v, boost::unit_test::const_string instance,
boost::unit_test::const_string instance, boost::optional<type_name> type, boost::unit_test::const_string name)
boost::optional< type_name > type,
boost::unit_test::const_string name )
{ {
lock _( mutex_ ); lock _(mutex_);
if( children_.empty() ) if(children_.empty())
detail::root.add( *this ); detail::root.add(*this);
children_[ &v ].update( parent_, instance, type, name ); children_[&v].update(parent_, instance, type, name);
} }
virtual void add( verifiable& v ) virtual void add(verifiable& v)
{ {
lock _( mutex_ ); lock _(mutex_);
group_.add( v ); group_.add(v);
} }
virtual void remove( verifiable& v ) virtual void remove(verifiable& v)
{ {
lock _( mutex_ ); lock _(mutex_);
group_.remove( v ); group_.remove(v);
children_.erase( &v ); children_.erase(&v);
if( children_.empty() ) if(children_.empty())
detail::root.remove( *this ); detail::root.remove(*this);
} }
virtual void serialize( std::ostream& s, const verifiable& v ) const virtual void serialize(std::ostream& s, const verifiable& v) const
{ {
lock _( mutex_ ); lock _(mutex_);
children_cit it = children_.find( &v ); children_cit it = children_.find(&v);
if( it != children_.end() ) if(it != children_.end())
s << it->second; s << it->second;
else else
s << "?"; s << "?";
@ -69,26 +61,25 @@ namespace detail
virtual bool verify() const virtual bool verify() const
{ {
lock _( mutex_ ); lock _(mutex_);
return group_.verify(); return group_.verify();
} }
virtual void reset() virtual void reset()
{ {
lock _( mutex_ ); lock _(mutex_);
boost::shared_ptr< object_impl > guard = shared_from_this(); boost::shared_ptr<object_impl> guard = shared_from_this();
group_.reset(); group_.reset();
} }
private: private:
typedef std::map< const verifiable*, child > children_t; typedef std::map<const verifiable*, child> children_t;
typedef children_t::const_iterator children_cit; typedef children_t::const_iterator children_cit;
group group_; group group_;
parent parent_; parent parent_;
children_t children_; children_t children_;
const boost::shared_ptr< mutex > mutex_; const boost::shared_ptr<mutex> mutex_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_OBJECT_IMPL_HPP_INCLUDED #endif // MOCK_OBJECT_IMPL_HPP_INCLUDED

View file

@ -10,25 +10,16 @@
#define MOCK_PARAMETER_HPP_INCLUDED #define MOCK_PARAMETER_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp> #include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/at.hpp> #include <boost/mpl/at.hpp>
namespace mock namespace mock { namespace detail {
{ template<typename Signature, int n>
namespace detail
{
template< typename Signature, int n >
struct parameter struct parameter
{ {
typedef typename typedef typename boost::mpl::at_c<typename boost::function_types::parameter_types<Signature>, n>::type type;
boost::mpl::at_c<
typename
boost::function_types::parameter_types< Signature >,
n
>::type type;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_PARAMETER_HPP_INCLUDED #endif // MOCK_PARAMETER_HPP_INCLUDED

View file

@ -11,36 +11,30 @@
#include "../config.hpp" #include "../config.hpp"
#include "type_name.hpp" #include "type_name.hpp"
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <ostream> #include <ostream>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class parent class parent
{ {
public: public:
parent() parent() {}
parent(boost::unit_test::const_string instance, boost::optional<type_name> type)
: instance_(instance), type_(type)
{} {}
parent( boost::unit_test::const_string instance, friend std::ostream& operator<<(std::ostream& s, const parent& p)
boost::optional< type_name > type )
: instance_( instance )
, type_( type )
{}
friend std::ostream& operator<<( std::ostream& s, const parent& p )
{ {
s << p.instance_; s << p.instance_;
if( p.type_ ) if(p.type_)
s << *p.type_ << "::"; s << *p.type_ << "::";
return s; return s;
} }
private: private:
boost::unit_test::const_string instance_; boost::unit_test::const_string instance_;
boost::optional< type_name > type_; boost::optional<type_name> type_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_PARENT_HPP_INCLUDED #endif // MOCK_PARENT_HPP_INCLUDED

View file

@ -10,117 +10,99 @@
#define MOCK_ROOT_HPP_INCLUDED #define MOCK_ROOT_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include "parent.hpp"
#include "group.hpp"
#include "context.hpp"
#include "child.hpp" #include "child.hpp"
#include "context.hpp"
#include "group.hpp"
#include "mutex.hpp" #include "mutex.hpp"
#include "parent.hpp"
#include "singleton.hpp" #include "singleton.hpp"
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <ostream>
#include <map> #include <map>
#include <ostream>
namespace mock namespace mock { namespace detail {
{ class root_t : public singleton<root_t>, public context
namespace detail
{
class root_t : public singleton< root_t >, public context
{ {
public: public:
virtual void add( const void* p, verifiable& v, virtual void add(const void* p, verifiable& v, boost::unit_test::const_string instance,
boost::unit_test::const_string instance, boost::optional<type_name> type, boost::unit_test::const_string name)
boost::optional< type_name > type,
boost::unit_test::const_string name )
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
children_t::iterator it = children_.lower_bound( &v ); children_t::iterator it = children_.lower_bound(&v);
if( it == children_.end() || if(it == children_.end() || children_.key_comp()(&v, it->first))
children_.key_comp()( &v, it->first ) ) it = children_.insert(it, std::make_pair(&v, counter_child(parents_, p)));
it = children_.insert( it, it->second.update(instance, type, name);
std::make_pair( &v, counter_child( parents_, p ) ) );
it->second.update( instance, type, name );
} }
virtual void add( verifiable& v ) virtual void add(verifiable& v)
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
group_.add( v ); group_.add(v);
} }
virtual void remove( verifiable& v ) virtual void remove(verifiable& v)
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
group_.remove( v ); group_.remove(v);
children_.erase( &v ); children_.erase(&v);
} }
bool verify() const bool verify() const
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
return group_.verify(); return group_.verify();
} }
void reset() void reset()
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
group_.reset(); group_.reset();
} }
virtual void serialize( std::ostream& s, const verifiable& v ) const virtual void serialize(std::ostream& s, const verifiable& v) const
{ {
scoped_lock _( mutex_ ); scoped_lock _(mutex_);
children_cit it = children_.find( &v ); children_cit it = children_.find(&v);
if( it != children_.end() ) if(it != children_.end())
s << it->second; s << it->second;
else else
s << "?"; s << "?";
} }
private: private:
typedef std::map< const void*, typedef std::map<const void*, std::pair<parent, std::size_t>> parents_t;
std::pair< parent, std::size_t > > parents_t;
class counter_child class counter_child
{ {
public: public:
counter_child( parents_t& parents, const void* p ) counter_child(parents_t& parents, const void* p)
: parents_( &parents ) : parents_(&parents), it_(parents.insert(std::make_pair(p, parents_t::mapped_type())).first)
, it_( parents.insert(
std::make_pair( p, parents_t::mapped_type() ) ).first )
{ {
++it_->second.second; ++it_->second.second;
} }
counter_child( const counter_child& rhs ) counter_child(const counter_child& rhs) : parents_(rhs.parents_), it_(rhs.it_), child_(rhs.child_)
: parents_( rhs.parents_ )
, it_( rhs.it_ )
, child_( rhs.child_ )
{ {
++it_->second.second; ++it_->second.second;
} }
~counter_child() ~counter_child()
{ {
if( --it_->second.second == 0 ) if(--it_->second.second == 0)
parents_->erase( it_ ); parents_->erase(it_);
} }
void update( boost::unit_test::const_string instance, void update(boost::unit_test::const_string instance, boost::optional<type_name> type,
boost::optional< type_name > type, boost::unit_test::const_string name)
boost::unit_test::const_string name )
{ {
child_.update( it_->second.first, instance, type, name ); child_.update(it_->second.first, instance, type, name);
}
friend std::ostream& operator<<( std::ostream& s,
const counter_child& c )
{
return s << c.child_;
} }
friend std::ostream& operator<<(std::ostream& s, const counter_child& c) { return s << c.child_; }
private: private:
counter_child& operator=( const counter_child& ); counter_child& operator=(const counter_child&);
parents_t* parents_; parents_t* parents_;
parents_t::iterator it_; parents_t::iterator it_;
child child_; child child_;
}; };
typedef std::map< const verifiable*, counter_child > children_t; typedef std::map<const verifiable*, counter_child> children_t;
typedef children_t::const_iterator children_cit; typedef children_t::const_iterator children_cit;
parents_t parents_; parents_t parents_;
@ -128,10 +110,9 @@ namespace detail
group group_; group group_;
mutable mutex mutex_; mutable mutex mutex_;
MOCK_SINGLETON_CONS( root_t ); MOCK_SINGLETON_CONS(root_t);
}; };
MOCK_SINGLETON_INST( root ) MOCK_SINGLETON_INST(root)
} }} // namespace mock::detail
} // mock
#endif // MOCK_ROOT_HPP_INCLUDED #endif // MOCK_ROOT_HPP_INCLUDED

View file

@ -11,57 +11,48 @@
#include "../config.hpp" #include "../config.hpp"
#include "mutex.hpp" #include "mutex.hpp"
#include <boost/noncopyable.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class sequence_impl : private boost::noncopyable class sequence_impl : private boost::noncopyable
{ {
public: public:
sequence_impl() sequence_impl() : mutex_(boost::make_shared<mutex>()) {}
: mutex_( boost::make_shared< mutex >() )
{}
void add( void* e ) void add(void* e)
{ {
lock _( mutex_ ); lock _(mutex_);
elements_.push_back( e ); elements_.push_back(e);
} }
void remove( void* e ) void remove(void* e)
{ {
lock _( mutex_ ); lock _(mutex_);
elements_.erase( std::remove( elements_.begin(), elements_.erase(std::remove(elements_.begin(), elements_.end(), e), elements_.end());
elements_.end(), e ), elements_.end() );
} }
bool is_valid( const void* e ) const bool is_valid(const void* e) const
{ {
lock _( mutex_ ); lock _(mutex_);
return std::find( elements_.begin(), elements_.end(), e ) return std::find(elements_.begin(), elements_.end(), e) != elements_.end();
!= elements_.end();
} }
void invalidate( const void* e ) void invalidate(const void* e)
{ {
lock _( mutex_ ); lock _(mutex_);
elements_type::iterator it = elements_type::iterator it = std::find(elements_.begin(), elements_.end(), e);
std::find( elements_.begin(), elements_.end(), e ); if(it != elements_.end())
if( it != elements_.end() ) elements_.erase(elements_.begin(), it);
elements_.erase( elements_.begin(), it );
} }
private: private:
typedef std::vector< void* > elements_type; typedef std::vector<void*> elements_type;
elements_type elements_; elements_type elements_;
const boost::shared_ptr< mutex > mutex_; const boost::shared_ptr<mutex> mutex_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED #endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED

View file

@ -10,36 +10,24 @@
#define MOCK_SIGNATURE_HPP_INCLUDED #define MOCK_SIGNATURE_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_type.hpp> #include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp> #include <boost/function_types/result_type.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/joint_view.hpp> #include <boost/mpl/joint_view.hpp>
#include <boost/mpl/pop_front.hpp> #include <boost/mpl/pop_front.hpp>
#include <boost/mpl/single_view.hpp>
#define BOOST_TYPEOF_SILENT #define BOOST_TYPEOF_SILENT
#include <boost/typeof/typeof.hpp> #include <boost/typeof/typeof.hpp>
namespace mock namespace mock { namespace detail {
{ template<typename M>
namespace detail
{
template< typename M >
struct signature : struct signature :
boost::function_types::function_type< boost::function_types::function_type<boost::mpl::joint_view<
boost::mpl::joint_view< boost::mpl::single_view<typename boost::function_types::result_type<M>::type>,
boost::mpl::single_view< typename boost::mpl::pop_front<typename boost::function_types::parameter_types<M>>::type>>
typename
boost::function_types::result_type< M >::type
>,
typename boost::mpl::pop_front<
typename
boost::function_types::parameter_types< M >
>::type
>
>
{}; {};
template< typename T > template<typename T>
struct base struct base
{ {
typedef T base_type; typedef T base_type;
@ -48,16 +36,12 @@ namespace detail
// if an error is generated by the line below it means // if an error is generated by the line below it means
// the method is ambiguous : specify its signature to // the method is ambiguous : specify its signature to
// disambiguate // disambiguate
template< typename T > template<typename T>
T& ambiguous_method_requires_to_specify_signature( const T& ); T& ambiguous_method_requires_to_specify_signature(const T&);
} }} // namespace mock::detail
} // mock
#define MOCK_SIGNATURE(M) \ #define MOCK_SIGNATURE(M) \
mock::detail::signature< \ mock::detail::signature<BOOST_TYPEOF( \
BOOST_TYPEOF( \ mock::detail::ambiguous_method_requires_to_specify_signature(&base_type::M))>::type
mock::detail::ambiguous_method_requires_to_specify_signature( \
&base_type::M ) ) \
>::type
#endif // MOCK_SIGNATURE_HPP_INCLUDED #endif // MOCK_SIGNATURE_HPP_INCLUDED

View file

@ -11,36 +11,34 @@
#include <boost/config.hpp> #include <boost/config.hpp>
namespace mock { namespace mock { namespace detail {
namespace detail {
template< typename Derived > template<typename Derived>
class singleton { class singleton
public:
static Derived& instance()
{ {
static Derived the_inst; public:
return the_inst; static Derived& instance()
} {
static Derived the_inst;
return the_inst;
}
BOOST_DELETED_FUNCTION(singleton(singleton const&)) BOOST_DELETED_FUNCTION(singleton(singleton const&))
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&)) BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
protected: protected:
BOOST_DEFAULTED_FUNCTION(singleton(), {}) BOOST_DEFAULTED_FUNCTION(singleton(), {})
BOOST_DEFAULTED_FUNCTION(~singleton(), {}) BOOST_DEFAULTED_FUNCTION(~singleton(), {})
}; };
} // detail }} // namespace mock::detail
} // mock
// Add a private ctor to the type to prevent misuse // Add a private ctor to the type to prevent misuse
#define MOCK_SINGLETON_CONS( type ) \ #define MOCK_SINGLETON_CONS(type) \
private: \ private: \
friend class mock::detail::singleton< type >; \ friend class mock::detail::singleton<type>; \
type() {} type() {}
#define MOCK_SINGLETON_INST( inst ) \ #define MOCK_SINGLETON_INST(inst) static BOOST_JOIN(inst, _t)& inst = BOOST_JOIN(inst, _t)::instance();
static BOOST_JOIN( inst, _t )& inst = BOOST_JOIN( inst, _t )::instance();
#endif // MOCK_SINGLETON_HPP #endif // MOCK_SINGLETON_HPP

View file

@ -10,108 +10,101 @@
#define MOCK_TYPE_NAME_HPP_INCLUDED #define MOCK_TYPE_NAME_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/erase.hpp> #include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/version.hpp> #include <boost/version.hpp>
#if BOOST_VERSION >= 107000 #if BOOST_VERSION >= 107000
# include <boost/core/typeinfo.hpp> # include <boost/core/typeinfo.hpp>
# define MOCK_TYPEID( t ) BOOST_CORE_TYPEID(t) # define MOCK_TYPEID(t) BOOST_CORE_TYPEID(t)
# define MOCK_TYPEINFO boost::core::typeinfo # define MOCK_TYPEINFO boost::core::typeinfo
#else #else
# include <boost/detail/sp_typeinfo.hpp> # include <boost/detail/sp_typeinfo.hpp>
# define MOCK_TYPEID( t ) BOOST_SP_TYPEID(t) # define MOCK_TYPEID(t) BOOST_SP_TYPEID(t)
# define MOCK_TYPEINFO boost::detail::sp_typeinfo # define MOCK_TYPEINFO boost::detail::sp_typeinfo
#endif #endif
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <ostream>
#include <stdexcept> #include <stdexcept>
#include <typeinfo> #include <typeinfo>
#include <ostream>
#ifdef __GNUC__ #ifdef __GNUC__
#include <cxxabi.h> # include <cstdlib>
#include <cstdlib> # include <cxxabi.h>
#endif #endif
#define MOCK_TYPE_NAME( t ) mock::detail::type_name( MOCK_TYPEID(t) ) #define MOCK_TYPE_NAME(t) mock::detail::type_name(MOCK_TYPEID(t))
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class type_name class type_name
{ {
public: public:
explicit type_name( const MOCK_TYPEINFO& info ) explicit type_name(const MOCK_TYPEINFO& info) : info_(&info) {}
: info_( &info ) friend std::ostream& operator<<(std::ostream& s, const type_name& t)
{}
friend std::ostream& operator<<( std::ostream& s, const type_name& t )
{ {
t.serialize( s, *t.info_ ); t.serialize(s, *t.info_);
return s; return s;
} }
private: private:
void serialize( std::ostream& s, void serialize(std::ostream& s, const MOCK_TYPEINFO& info) const
const MOCK_TYPEINFO& info ) const
{ {
const char* name = info.name(); const char* name = info.name();
#ifdef __GNUC__ #ifdef __GNUC__
int status = 0; int status = 0;
boost::shared_ptr< char > demangled( boost::shared_ptr<char> demangled(abi::__cxa_demangle(name, 0, 0, &status), &std::free);
abi::__cxa_demangle( name, 0, 0, &status ), if(!status && demangled)
&std::free ); serialize(s, demangled.get());
if( ! status && demangled )
serialize( s, demangled.get() );
else else
#endif #endif
serialize( s, name ); serialize(s, name);
} }
typedef std::string::size_type size_type; typedef std::string::size_type size_type;
void serialize( std::ostream& s, std::string name ) const void serialize(std::ostream& s, std::string name) const
{ {
const size_type nm = rfind( name, ':' ) + 1; const size_type nm = rfind(name, ':') + 1;
const size_type tpl = name.find( '<', nm ); const size_type tpl = name.find('<', nm);
s << clean( name.substr( nm, tpl - nm ) ); s << clean(name.substr(nm, tpl - nm));
if( tpl == std::string::npos ) if(tpl == std::string::npos)
return; return;
s << '<'; s << '<';
list( s, name.substr( tpl + 1, name.rfind( '>' ) - tpl - 1 ) ); list(s, name.substr(tpl + 1, name.rfind('>') - tpl - 1));
s << '>'; s << '>';
} }
void list( std::ostream& s, const std::string& name ) const void list(std::ostream& s, const std::string& name) const
{ {
const size_type comma = rfind( name, ',' ); const size_type comma = rfind(name, ',');
if( comma != std::string::npos ) if(comma != std::string::npos)
{ {
list( s, name.substr( 0, comma ) ); list(s, name.substr(0, comma));
s << ", "; s << ", ";
} }
serialize( s, name.substr( comma + 1 ) ); serialize(s, name.substr(comma + 1));
} }
std::string clean( std::string name ) const std::string clean(std::string name) const
{ {
boost::algorithm::trim( name ); boost::algorithm::trim(name);
boost::algorithm::erase_all( name, "class " ); boost::algorithm::erase_all(name, "class ");
boost::algorithm::erase_all( name, "struct " ); boost::algorithm::erase_all(name, "struct ");
boost::algorithm::erase_all( name, "__ptr64" ); boost::algorithm::erase_all(name, "__ptr64");
boost::algorithm::replace_all( name, " &", "&" ); boost::algorithm::replace_all(name, " &", "&");
boost::algorithm::replace_all( name, "& ", "&" ); boost::algorithm::replace_all(name, "& ", "&");
boost::algorithm::replace_all( name, " *", "*" ); boost::algorithm::replace_all(name, " *", "*");
boost::algorithm::replace_all( name, "* ", "*" ); boost::algorithm::replace_all(name, "* ", "*");
return name; return name;
} }
size_type rfind( const std::string& name, char c ) const size_type rfind(const std::string& name, char c) const
{ {
size_type count = 0; size_type count = 0;
for( size_type i = name.size() - 1; i > 0; --i ) for(size_type i = name.size() - 1; i > 0; --i)
{ {
if( name[ i ] == '>' ) if(name[i] == '>')
++count; ++count;
else if( name[ i ] == '<' ) else if(name[i] == '<')
--count; --count;
if( name[ i ] == c && count == 0 ) if(name[i] == c && count == 0)
return i; return i;
} }
return std::string::npos; return std::string::npos;
@ -119,7 +112,6 @@ namespace detail
const MOCK_TYPEINFO* info_; const MOCK_TYPEINFO* info_;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_TYPE_NAME_HPP_INCLUDED #endif // MOCK_TYPE_NAME_HPP_INCLUDED

View file

@ -12,10 +12,7 @@
#include "../config.hpp" #include "../config.hpp"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
namespace mock namespace mock { namespace detail {
{
namespace detail
{
class verifiable : private boost::noncopyable class verifiable : private boost::noncopyable
{ {
public: public:
@ -26,7 +23,6 @@ namespace detail
virtual void reset() = 0; virtual void reset() = 0;
}; };
} }} // namespace mock::detail
} // mock
#endif // MOCK_VERIFIABLE_HPP_INCLUDED #endif // MOCK_VERIFIABLE_HPP_INCLUDED

View file

@ -11,69 +11,59 @@
#include "config.hpp" #include "config.hpp"
#ifdef MOCK_USE_BOOST_TEST #ifdef MOCK_USE_BOOST_TEST
#include "exception.hpp" # include "exception.hpp"
#include <boost/version.hpp> # include <boost/exception/enable_current_exception.hpp>
#include <boost/test/framework.hpp> # include <boost/test/framework.hpp>
#include <boost/test/test_tools.hpp> # include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_suite.hpp> # include <boost/test/unit_test_suite.hpp>
#include <boost/exception/enable_current_exception.hpp> # include <boost/version.hpp>
namespace mock namespace mock {
template<typename Result>
struct error
{ {
template< typename Result > static Result abort()
struct error
{ {
static Result abort() boost::unit_test::framework::test_unit_aborted(boost::unit_test::framework::current_test_case());
{ throw boost::enable_current_exception(exception());
boost::unit_test::framework::test_unit_aborted( }
boost::unit_test::framework::current_test_case() );
throw boost::enable_current_exception( exception() );
}
static void pass( const char* file, int line ) static void pass(const char* file, int line)
{ {
boost::unit_test::unit_test_log.set_checkpoint( file, boost::unit_test::unit_test_log.set_checkpoint(file, static_cast<std::size_t>(line));
static_cast< std::size_t >( line ) ); }
}
template< typename Context > template<typename Context>
static void fail( const char* message, const Context& context, static void fail(const char* message, const Context& context, const char* file = "unknown location", int line = 0)
const char* file = "unknown location", int line = 0 ) {
{ boost::unit_test::framework::assertion_result(
boost::unit_test::framework::assertion_result( # if BOOST_VERSION < 105900
#if BOOST_VERSION < 105900 false
false # else
#else boost::unit_test::AR_FAILED
boost::unit_test::AR_FAILED # endif
#endif );
); boost::unit_test::unit_test_log << boost::unit_test::log::begin(file, static_cast<std::size_t>(line))
boost::unit_test::unit_test_log << boost::unit_test::log_all_errors << message << ": " << context
<< boost::unit_test::log::begin( file, << boost::unit_test::log::end();
static_cast< std::size_t >( line ) ) }
<< boost::unit_test::log_all_errors
<< message << ": " << context
<< boost::unit_test::log::end();
}
template< typename Context > template<typename Context>
static void call( const Context& context, const char* file, int line ) static void call(const Context& context, const char* file, int line)
{ {
boost::unit_test::framework::assertion_result( boost::unit_test::framework::assertion_result(
#if BOOST_VERSION < 105900 # if BOOST_VERSION < 105900
true true
#else # else
boost::unit_test::AR_PASSED boost::unit_test::AR_PASSED
#endif # endif
); );
boost::unit_test::unit_test_log boost::unit_test::unit_test_log << boost::unit_test::log::begin(file, static_cast<std::size_t>(line))
<< boost::unit_test::log::begin( file, << boost::unit_test::log_successful_tests
static_cast< std::size_t >( line ) ) << "mock expectation fulfilled: " << context << boost::unit_test::log::end();
<< boost::unit_test::log_successful_tests }
<< "mock expectation fulfilled: " << context };
<< boost::unit_test::log::end(); } // namespace mock
}
};
} // mock
#endif // MOCK_USE_BOOST_TEST #endif // MOCK_USE_BOOST_TEST

View file

@ -11,13 +11,12 @@
#include "config.hpp" #include "config.hpp"
#ifdef MOCK_USE_BOOST_TEST #ifdef MOCK_USE_BOOST_TEST
#include <boost/test/execution_monitor.hpp> # include <boost/test/execution_monitor.hpp>
namespace mock namespace mock {
{ struct exception : virtual boost::execution_aborted
struct exception : virtual boost::execution_aborted {};
{}; } // namespace mock
} // mock
#endif // MOCK_USE_BOOST_TEST #endif // MOCK_USE_BOOST_TEST

View file

@ -12,14 +12,13 @@
#include "config.hpp" #include "config.hpp"
#include "detail/formatter.hpp" #include "detail/formatter.hpp"
namespace mock namespace mock {
template<typename T>
detail::formatter<T> format(const T& t)
{ {
template< typename T > return detail::formatter<T>(t);
detail::formatter< T > format( const T& t ) }
{
return detail::formatter< T >( t );
}
} // mock } // namespace mock
#endif // MOCK_FORMAT_HPP_INCLUDED #endif // MOCK_FORMAT_HPP_INCLUDED

View file

@ -10,195 +10,186 @@
#define MOCK_LOG_HPP_INCLUDED #define MOCK_LOG_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "stream.hpp"
#include "format.hpp" #include "format.hpp"
#include <boost/utility/enable_if.hpp> #include "stream.hpp"
#include <boost/detail/container_fwd.hpp> #include <boost/detail/container_fwd.hpp>
#include <boost/function_types/is_callable_builtin.hpp> #include <boost/function_types/is_callable_builtin.hpp>
#include <boost/none.hpp> #include <boost/none.hpp>
#include <boost/utility/enable_if.hpp>
#include <memory> #include <memory>
namespace boost namespace boost {
{ template<typename T>
template< typename T > class shared_ptr; class shared_ptr;
template< typename T > class weak_ptr; template<typename T>
template< typename T > class reference_wrapper; class weak_ptr;
template< typename T > class optional; template<typename T>
class reference_wrapper;
template<typename T>
class optional;
namespace phoenix namespace phoenix {
{ template<typename T>
template< typename T > struct actor; struct actor;
} }
namespace lambda namespace lambda {
{ template<typename T>
template< typename T > class lambda_functor; class lambda_functor;
}
namespace assign_detail
{
template< typename T > class generic_list;
} }
namespace assign_detail {
template<typename T>
class generic_list;
} }
} // namespace boost
namespace mock namespace mock {
{ namespace detail {
namespace detail template<typename T>
{ void serialize(stream& s, const T& begin, const T& end)
template< typename T >
void serialize( stream& s, const T& begin, const T& end )
{ {
s << '('; s << '(';
for( T it = begin; it != end; ++it ) for(T it = begin; it != end; ++it)
s << (it == begin ? "" : ",") << mock::format( *it ); s << (it == begin ? "" : ",") << mock::format(*it);
s << ')'; s << ')';
} }
} } // namespace detail
#ifdef MOCK_AUTO_PTR #ifdef MOCK_AUTO_PTR
template< typename T > template<typename T>
stream& operator<<( stream& s, const std::auto_ptr< T >& t ) stream& operator<<(stream& s, const std::auto_ptr<T>& t)
{ {
return s << mock::format( t.get() ); return s << mock::format(t.get());
} }
#endif // MOCK_AUTO_PTR #endif // MOCK_AUTO_PTR
template< typename T1, typename T2 > template<typename T1, typename T2>
stream& operator<<( stream& s, const std::pair< T1, T2 >& p ) stream& operator<<(stream& s, const std::pair<T1, T2>& p)
{ {
return s << '(' << mock::format( p.first ) return s << '(' << mock::format(p.first) << ',' << mock::format(p.second) << ')';
<< ',' << mock::format( p.second ) << ')'; }
}
template< typename T, typename A > template<typename T, typename A>
stream& operator<<( stream& s, const std::deque< T, A >& t ) stream& operator<<(stream& s, const std::deque<T, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename T, typename A > template<typename T, typename A>
stream& operator<<( stream& s, const std::list< T, A >& t ) stream& operator<<(stream& s, const std::list<T, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename T, typename A > template<typename T, typename A>
stream& operator<<( stream& s, const std::vector< T, A >& t ) stream& operator<<(stream& s, const std::vector<T, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename K, typename T, typename C, typename A > template<typename K, typename T, typename C, typename A>
stream& operator<<( stream& s, const std::map< K, T, C, A >& t ) stream& operator<<(stream& s, const std::map<K, T, C, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename K, typename T, typename C, typename A > template<typename K, typename T, typename C, typename A>
stream& operator<<( stream& s, const std::multimap< K, T, C, A >& t ) stream& operator<<(stream& s, const std::multimap<K, T, C, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename T, typename C, typename A > template<typename T, typename C, typename A>
stream& operator<<( stream& s, const std::set< T, C, A >& t ) stream& operator<<(stream& s, const std::set<T, C, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename T, typename C, typename A > template<typename T, typename C, typename A>
stream& operator<<( stream& s, const std::multiset< T, C, A >& t ) stream& operator<<(stream& s, const std::multiset<T, C, A>& t)
{ {
detail::serialize( s, t.begin(), t.end() ); detail::serialize(s, t.begin(), t.end());
return s; return s;
} }
template< typename T > template<typename T>
stream& operator<<( stream& s, stream& operator<<(stream& s, const boost::assign_detail::generic_list<T>& t)
const boost::assign_detail::generic_list< T >& t ) {
{ detail::serialize(s, t.begin(), t.end());
detail::serialize( s, t.begin(), t.end() ); return s;
return s; }
} template<typename T>
template< typename T > stream& operator<<(stream& s, const boost::reference_wrapper<T>& t)
stream& operator<<( stream& s, const boost::reference_wrapper< T >& t ) {
{ return s << mock::format(t.get());
return s << mock::format( t.get() ); }
} template<typename T>
template< typename T > stream& operator<<(stream& s, const boost::shared_ptr<T>& t)
stream& operator<<( stream& s, const boost::shared_ptr< T >& t ) {
{ return s << mock::format(t.get());
return s << mock::format( t.get() ); }
} template<typename T>
template< typename T > stream& operator<<(stream& s, const boost::weak_ptr<T>& t)
stream& operator<<( stream& s, const boost::weak_ptr< T >& t ) {
{ return s << mock::format(t.lock());
return s << mock::format( t.lock() ); }
} inline stream& operator<<(stream& s, const boost::none_t&)
inline stream& operator<<( stream& s, const boost::none_t& ) {
{ return s << "none";
return s << "none"; }
} template<typename T>
template< typename T > stream& operator<<(stream& s, const boost::optional<T>& t)
stream& operator<<( stream& s, const boost::optional< T >& t ) {
{ if(t)
if( t ) return s << mock::format(t.get());
return s << mock::format( t.get() ); return s << boost::none;
return s << boost::none; }
}
#ifdef MOCK_SMART_PTR #ifdef MOCK_SMART_PTR
template< typename T > template<typename T>
stream& operator<<( stream& s, const std::shared_ptr< T >& t ) stream& operator<<(stream& s, const std::shared_ptr<T>& t)
{ {
return s << mock::format( t.get() ); return s << mock::format(t.get());
} }
template< typename T > template<typename T>
stream& operator<<( stream& s, const std::weak_ptr< T >& t ) stream& operator<<(stream& s, const std::weak_ptr<T>& t)
{ {
return s << mock::format( t.lock() ); return s << mock::format(t.lock());
} }
template< typename T, typename D > template<typename T, typename D>
stream& operator<<( stream& s, const std::unique_ptr< T, D >& p ) stream& operator<<(stream& s, const std::unique_ptr<T, D>& p)
{ {
return s << mock::format( p.get() ); return s << mock::format(p.get());
} }
#endif #endif
template< typename T > template<typename T>
stream& operator<<( stream& s, const boost::lambda::lambda_functor< T >& ) stream& operator<<(stream& s, const boost::lambda::lambda_functor<T>&)
{ {
return s << '?'; return s << '?';
} }
template< typename T > template<typename T>
stream& operator<<( stream& s, const boost::phoenix::actor< T >& ) stream& operator<<(stream& s, const boost::phoenix::actor<T>&)
{ {
return s << '?'; return s << '?';
} }
#ifdef MOCK_NULLPTR #ifdef MOCK_NULLPTR
inline stream& operator<<( stream& s, std::nullptr_t ) inline stream& operator<<(stream& s, std::nullptr_t)
{ {
return s << "nullptr"; return s << "nullptr";
} }
#endif #endif
template< typename T > template<typename T>
typename boost::enable_if< typename boost::enable_if<boost::function_types::is_callable_builtin<T>, stream&>::type operator<<(stream& s, T*)
boost::function_types::is_callable_builtin< T >, {
stream& return s << '?';
>::type }
operator<<( stream& s, T* ) template<typename T>
{ typename boost::disable_if<boost::function_types::is_callable_builtin<T>, stream&>::type operator<<(stream& s, T* t)
return s << '?'; {
} *s.s_ << t;
template< typename T > return s;
typename boost::disable_if< }
boost::function_types::is_callable_builtin< T >, } // namespace mock
stream&
>::type
operator<<( stream& s, T* t )
{
*s.s_ << t;
return s;
}
} // mock
#endif // MOCK_LOG_HPP_INCLUDED #endif // MOCK_LOG_HPP_INCLUDED

View file

@ -10,101 +10,72 @@
#define MOCK_MATCHER_HPP_INCLUDED #define MOCK_MATCHER_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "log.hpp"
#include "constraints.hpp" #include "constraints.hpp"
#include "detail/is_functor.hpp" #include "detail/is_functor.hpp"
#include "detail/move_helper.hpp" #include "detail/move_helper.hpp"
#include <boost/utility/enable_if.hpp> #include "log.hpp"
#include <boost/type_traits/add_reference.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <cstring> #include <cstring>
namespace mock namespace mock {
template<typename Actual, typename Expected, typename Enable = void>
class matcher
{ {
template< typename Actual, typename Expected, typename Enable = void > public:
class matcher explicit matcher(Expected expected) : expected_(expected) {}
bool operator()(typename boost::add_reference<const Actual>::type actual)
{ {
public: return mock::equal(boost::unwrap_ref(expected_)).c_(actual);
explicit matcher( Expected expected ) }
: expected_( expected ) friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); }
{}
bool operator()( typename boost::add_reference< const Actual >::type actual )
{
return mock::equal(
boost::unwrap_ref( expected_ ) ).c_( actual );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
{
return s << mock::format( m.expected_ );
}
private:
Expected expected_;
};
template<> private:
class matcher< const char*, const char* > Expected expected_;
{ };
public:
explicit matcher( const char* expected )
: expected_( expected )
{}
bool operator()( const char* actual )
{
return std::strcmp( actual, expected_ ) == 0;
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
{
return s << mock::format( m.expected_ );
}
private:
const char* expected_;
};
template< typename Actual, typename Constraint > template<>
class matcher< Actual, mock::constraint< Constraint > > class matcher<const char*, const char*>
{ {
public: public:
explicit matcher( const constraint< Constraint >& c ) explicit matcher(const char* expected) : expected_(expected) {}
: c_( c.c_ ) bool operator()(const char* actual) { return std::strcmp(actual, expected_) == 0; }
{} friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); }
bool operator()( typename detail::ref_arg< Actual >::type actual )
{
return c_( mock::detail::move_if_not_lvalue_reference< typename detail::ref_arg< Actual >::type >( actual ) );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
{
return s << mock::format( m.c_ );
}
private:
Constraint c_;
};
template< typename Actual, typename Functor > private:
class matcher< Actual, Functor, const char* expected_;
typename boost::enable_if< };
detail::is_functor< Functor, Actual >
>::type template<typename Actual, typename Constraint>
> class matcher<Actual, mock::constraint<Constraint>>
{
public:
explicit matcher(const constraint<Constraint>& c) : c_(c.c_) {}
bool operator()(typename detail::ref_arg<Actual>::type actual)
{ {
public: return c_(mock::detail::move_if_not_lvalue_reference<typename detail::ref_arg<Actual>::type>(actual));
explicit matcher( const Functor& f ) }
: c_( f ) friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.c_); }
{}
bool operator()( typename detail::ref_arg< Actual >::type actual ) private:
{ Constraint c_;
return c_( mock::detail::move_if_not_lvalue_reference< typename detail::ref_arg< Actual >::type >( actual ) ); };
}
friend std::ostream& operator<<( template<typename Actual, typename Functor>
std::ostream& s, const matcher& m ) class matcher<Actual, Functor, typename boost::enable_if<detail::is_functor<Functor, Actual>>::type>
{ {
return s << mock::format( m.c_ ); public:
} explicit matcher(const Functor& f) : c_(f) {}
private: bool operator()(typename detail::ref_arg<Actual>::type actual)
Functor c_; {
}; return c_(mock::detail::move_if_not_lvalue_reference<typename detail::ref_arg<Actual>::type>(actual));
} // mock }
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.c_); }
private:
Functor c_;
};
} // namespace mock
#endif // MOCK_MATCHER_HPP_INCLUDED #endif // MOCK_MATCHER_HPP_INCLUDED

View file

@ -9,245 +9,198 @@
#ifndef MOCK_MOCK_HPP_INCLUDED #ifndef MOCK_MOCK_HPP_INCLUDED
#define MOCK_MOCK_HPP_INCLUDED #define MOCK_MOCK_HPP_INCLUDED
#include "cleanup.hpp"
#include "config.hpp" #include "config.hpp"
#include "detail/function.hpp"
#include "detail/functor.hpp"
#include "detail/parameter.hpp"
#include "detail/signature.hpp"
#include "detail/type_name.hpp"
#include "object.hpp" #include "object.hpp"
#include "reset.hpp" #include "reset.hpp"
#include "verify.hpp" #include "verify.hpp"
#include "cleanup.hpp" #include <boost/mpl/assert.hpp>
#include "detail/functor.hpp"
#include "detail/function.hpp"
#include "detail/type_name.hpp"
#include "detail/signature.hpp"
#include "detail/parameter.hpp"
#include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
#include <boost/utility/identity_type.hpp> #include <boost/utility/identity_type.hpp>
#include <boost/mpl/assert.hpp>
#define MOCK_CLASS(T) \ #define MOCK_CLASS(T) struct T : mock::object
struct T : mock::object
#define MOCK_FUNCTION_TYPE(S, tpn) \ #define MOCK_FUNCTION_TYPE(S, tpn) tpn boost::remove_pointer<tpn BOOST_IDENTITY_TYPE(S)>::type
tpn boost::remove_pointer< tpn BOOST_IDENTITY_TYPE(S) >::type
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
#define MOCK_BASE_CLASS(T, ...) \ # define MOCK_BASE_CLASS(T, ...) struct T : __VA_ARGS__, mock::object, mock::detail::base<__VA_ARGS__>
struct T : __VA_ARGS__, mock::object, mock::detail::base< __VA_ARGS__ >
#define MOCK_FUNCTOR(f, ...) \ # define MOCK_FUNCTOR(f, ...) mock::detail::functor<MOCK_FUNCTION_TYPE((__VA_ARGS__), )> f, f##_mock
mock::detail::functor< MOCK_FUNCTION_TYPE((__VA_ARGS__),) > f, f##_mock # define MOCK_FUNCTOR_TPL(f, ...) mock::detail::functor<MOCK_FUNCTION_TYPE((__VA_ARGS__), typename)> f, f##_mock
#define MOCK_FUNCTOR_TPL(f, ...) \
mock::detail::functor< \
MOCK_FUNCTION_TYPE((__VA_ARGS__), typename) > f, f##_mock
#else // MOCK_VARIADIC_MACROS #else // MOCK_VARIADIC_MACROS
#define MOCK_BASE_CLASS(T, I) \ # define MOCK_BASE_CLASS(T, I) struct T : I, mock::object, mock::detail::base<I>
struct T : I, mock::object, mock::detail::base< I >
#define MOCK_FUNCTOR(f, S) \ # define MOCK_FUNCTOR(f, S) mock::detail::functor<MOCK_FUNCTION_TYPE((S), )> f, f##_mock
mock::detail::functor< MOCK_FUNCTION_TYPE((S),) > f, f##_mock # define MOCK_FUNCTOR_TPL(f, S) mock::detail::functor<MOCK_FUNCTION_TYPE((S), typename)> f, f##_mock
#define MOCK_FUNCTOR_TPL(f, S) \
mock::detail::functor< \
MOCK_FUNCTION_TYPE((S), typename) > f, f##_mock
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS
#define MOCK_HELPER(t) \ #define MOCK_HELPER(t) t##_mock(mock::detail::root, BOOST_PP_STRINGIZE(t))
t##_mock( mock::detail::root, BOOST_PP_STRINGIZE(t) ) #define MOCK_ANONYMOUS_HELPER(t) t##_mock(mock::detail::root, "?.")
#define MOCK_ANONYMOUS_HELPER(t) \
t##_mock( mock::detail::root, "?." )
#define MOCK_METHOD_HELPER(S, t, tpn) \ #define MOCK_METHOD_HELPER(S, t, tpn) \
mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \ mutable mock::detail::function<MOCK_FUNCTION_TYPE((S), tpn)> t##_mock_; \
mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) >& t##_mock( \ mock::detail::function<MOCK_FUNCTION_TYPE((S), tpn)>& t##_mock( \
const mock::detail::context&, \ const mock::detail::context&, const boost::unit_test::const_string& instance) const \
const boost::unit_test::const_string& instance ) const \ { \
{ \ mock::detail::configure(*this, t##_mock_, instance.substr(0, instance.rfind(BOOST_PP_STRINGIZE(t))), \
mock::detail::configure( *this, t##_mock_, \ MOCK_TYPE_NAME(*this), BOOST_PP_STRINGIZE(t)); \
instance.substr( 0, instance.rfind( BOOST_PP_STRINGIZE(t) ) ), \ return t##_mock_; \
MOCK_TYPE_NAME(*this), \
BOOST_PP_STRINGIZE(t) ); \
return t##_mock_; \
} }
#define MOCK_PARAM(S, tpn) \ #define MOCK_PARAM(S, tpn) tpn mock::detail::parameter < MOCK_FUNCTION_TYPE((S), tpn)
tpn mock::detail::parameter< MOCK_FUNCTION_TYPE((S), tpn) #define MOCK_DECL_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > ::type p##n
#define MOCK_DECL_PARAM(z, n, d) \ #define MOCK_DECL_PARAMS(n, S, tpn) BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
BOOST_PP_COMMA_IF(n) d, n >::type p##n
#define MOCK_DECL_PARAMS(n, S, tpn) \
BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
#define MOCK_DECL(M, n, S, c, tpn) \ #define MOCK_DECL(M, n, S, c, tpn) \
tpn boost::function_types::result_type< \ tpn boost::function_types::result_type<MOCK_FUNCTION_TYPE((S), tpn)>::type M(MOCK_DECL_PARAMS(n, S, tpn)) c
MOCK_FUNCTION_TYPE((S), tpn) >::type M( \
MOCK_DECL_PARAMS(n, S, tpn) ) c
#define MOCK_FORWARD_PARAM(z, n, d) \ #define MOCK_FORWARD_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > ::type > (p##n)
BOOST_PP_COMMA_IF(n) d, n >::type >( p##n )
#define MOCK_FORWARD_PARAMS(n, S, tpn) \ #define MOCK_FORWARD_PARAMS(n, S, tpn) \
BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, \ BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, mock::detail::move_if_not_lvalue_reference < MOCK_PARAM(S, tpn))
mock::detail::move_if_not_lvalue_reference< MOCK_PARAM(S, tpn)) #define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \
MOCK_DECL(M, n, S, c, tpn) \ { \
{ \ BOOST_MPL_ASSERT_RELATION(n, ==, boost::function_types::function_arity<MOCK_FUNCTION_TYPE((S), tpn)>::value); \
BOOST_MPL_ASSERT_RELATION( n, ==, \ return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
boost::function_types::function_arity< \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
return MOCK_ANONYMOUS_HELPER(t)( \
MOCK_FORWARD_PARAMS(n, S, tpn) ); \
} }
#define MOCK_METHOD_EXT(M, n, S, t) \ #define MOCK_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,,) \ MOCK_METHOD_AUX(M, n, S, t, , ) \
MOCK_METHOD_AUX(M, n, S, t, const,) \ MOCK_METHOD_AUX(M, n, S, t, const, ) \
MOCK_METHOD_HELPER(S, t,) MOCK_METHOD_HELPER(S, t, )
#define MOCK_CONST_METHOD_EXT(M, n, S, t) \ #define MOCK_CONST_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, const,) \ MOCK_METHOD_AUX(M, n, S, t, const, ) \
MOCK_METHOD_HELPER(S, t,) MOCK_METHOD_HELPER(S, t, )
#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) \ #define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,,) \ MOCK_METHOD_AUX(M, n, S, t, , ) \
MOCK_METHOD_HELPER(S, t,) MOCK_METHOD_HELPER(S, t, )
#define MOCK_METHOD_EXT_TPL(M, n, S, t) \ #define MOCK_METHOD_EXT_TPL(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,, typename) \ MOCK_METHOD_AUX(M, n, S, t, , typename) \
MOCK_METHOD_AUX(M, n, S, t, const, typename) \ MOCK_METHOD_AUX(M, n, S, t, const, typename) \
MOCK_METHOD_HELPER(S, t, typename) MOCK_METHOD_HELPER(S, t, typename)
#define MOCK_CONST_METHOD_EXT_TPL(M, n, S, t) \ #define MOCK_CONST_METHOD_EXT_TPL(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, const, typename) \ MOCK_METHOD_AUX(M, n, S, t, const, typename) \
MOCK_METHOD_HELPER(S, t, typename) MOCK_METHOD_HELPER(S, t, typename)
#define MOCK_NON_CONST_METHOD_EXT_TPL(M, n, S, t) \ #define MOCK_NON_CONST_METHOD_EXT_TPL(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,, typename) \ MOCK_METHOD_AUX(M, n, S, t, , typename) \
MOCK_METHOD_HELPER(S, t, typename) MOCK_METHOD_HELPER(S, t, typename)
#define MOCK_CONVERSION_OPERATOR(M, T, t) \ #define MOCK_CONVERSION_OPERATOR(M, T, t) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t,) MOCK_METHOD_HELPER(T(), t, )
#define MOCK_CONST_CONVERSION_OPERATOR(M, T, t) \ #define MOCK_CONST_CONVERSION_OPERATOR(M, T, t) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t,) MOCK_METHOD_HELPER(T(), t, )
#define MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t) \ #define MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t) \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t,) MOCK_METHOD_HELPER(T(), t, )
#define MOCK_CONVERSION_OPERATOR_TPL(M, T, t) \ #define MOCK_CONVERSION_OPERATOR_TPL(M, T, t) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename) MOCK_METHOD_HELPER(T(), t, typename)
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \ #define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename) MOCK_METHOD_HELPER(T(), t, typename)
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \ #define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \ M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename) MOCK_METHOD_HELPER(T(), t, typename)
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \ #define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
s mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) >& t##_mock( \ s mock::detail::function<MOCK_FUNCTION_TYPE((S), tpn)>& t##_mock(mock::detail::context& context, \
mock::detail::context& context, \ boost::unit_test::const_string instance) \
boost::unit_test::const_string instance ) \ { \
{ \ static mock::detail::function<MOCK_FUNCTION_TYPE((S), tpn)> f; \
static mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > f; \ return f(context, instance); \
return f( context, instance ); \
} }
#define MOCK_CONSTRUCTOR_AUX(T, n, A, t, tpn) \ #define MOCK_CONSTRUCTOR_AUX(T, n, A, t, tpn) \
T( MOCK_DECL_PARAMS(n, void A, tpn) ) \ T(MOCK_DECL_PARAMS(n, void A, tpn)) { MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, void A, tpn)); } \
{ \
MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, void A, tpn) ); \
} \
MOCK_FUNCTION_HELPER(void A, t, static, tpn) MOCK_FUNCTION_HELPER(void A, t, static, tpn)
#define MOCK_CONSTRUCTOR(T, n, A, t) \ #define MOCK_CONSTRUCTOR(T, n, A, t) MOCK_CONSTRUCTOR_AUX(T, n, A, t, )
MOCK_CONSTRUCTOR_AUX(T, n, A, t,) #define MOCK_CONSTRUCTOR_TPL(T, n, A, t) MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) \
MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
#define MOCK_DESTRUCTOR(T, t) \ #define MOCK_DESTRUCTOR(T, t) \
T() { try { MOCK_ANONYMOUS_HELPER(t)(); } catch( ... ) {} } \ T() \
MOCK_METHOD_HELPER(void(), t,) { \
try \
{ \
MOCK_ANONYMOUS_HELPER(t)(); \
} catch(...) \
{} \
} \
MOCK_METHOD_HELPER(void(), t, )
#define MOCK_FUNCTION_AUX(F, n, S, t, s, tpn) \ #define MOCK_FUNCTION_AUX(F, n, S, t, s, tpn) \
MOCK_FUNCTION_HELPER(S, t, s, tpn) \ MOCK_FUNCTION_HELPER(S, t, s, tpn) \
s MOCK_DECL(F, n, S,,tpn) \ s MOCK_DECL(F, n, S, , tpn) \
{ \ { \
BOOST_MPL_ASSERT_RELATION( n, ==, \ BOOST_MPL_ASSERT_RELATION(n, ==, boost::function_types::function_arity<MOCK_FUNCTION_TYPE((S), tpn)>::value); \
boost::function_types::function_arity< \ return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \
} }
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0 # define MOCK_VARIADIC_ELEM_0(e0, ...) e0
#define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1 # define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1
#define MOCK_VARIADIC_ELEM_2(e0, e1, e2, ...) e2 # define MOCK_VARIADIC_ELEM_2(e0, e1, e2, ...) e2
#define MOCK_METHOD(M, ...) \ # define MOCK_METHOD(M, ...) \
MOCK_METHOD_EXT(M, \ MOCK_METHOD_EXT(M, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \ MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, )) # define MOCK_CONST_METHOD(M, ...) \
#define MOCK_CONST_METHOD(M, ...) \ MOCK_CONST_METHOD_EXT(M, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_CONST_METHOD_EXT(M, \ MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \ # define MOCK_NON_CONST_METHOD(M, ...) \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, )) MOCK_NON_CONST_METHOD_EXT(M, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
#define MOCK_NON_CONST_METHOD(M, ...) \ MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_NON_CONST_METHOD_EXT(M, \ MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
#define MOCK_METHOD_TPL(M, n, ...) \ # define MOCK_METHOD_TPL(M, n, ...) \
MOCK_METHOD_EXT_TPL(M, n, \ MOCK_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ # define MOCK_CONST_METHOD_TPL(M, n, ...) \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, )) MOCK_CONST_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
#define MOCK_CONST_METHOD_TPL(M, n, ...) \ # define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
MOCK_CONST_METHOD_EXT_TPL(M, n, \ MOCK_NON_CONST_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
#define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
MOCK_NON_CONST_METHOD_EXT_TPL(M, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
#define MOCK_FUNCTION(F, n, ...) \ # define MOCK_FUNCTION(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \ MOCK_FUNCTION_AUX(F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), inline, )
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
inline,)
#define MOCK_STATIC_METHOD(F, n, ...) \ # define MOCK_STATIC_METHOD(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \ MOCK_FUNCTION_AUX(F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static, )
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
static,)
#define MOCK_STATIC_METHOD_TPL(F, n, ...) \ # define MOCK_STATIC_METHOD_TPL(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \ MOCK_FUNCTION_AUX(F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \ typename)
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
static, typename)
#else // MOCK_VARIADIC_MACROS #else // MOCK_VARIADIC_MACROS
#define MOCK_METHOD(M, n) \ # define MOCK_METHOD(M, n) MOCK_METHOD_EXT(M, n, MOCK_SIGNATURE(M), M)
MOCK_METHOD_EXT(M, n, MOCK_SIGNATURE(M), M)
#define MOCK_FUNCTION(F, n, S, t) \ # define MOCK_FUNCTION(F, n, S, t) MOCK_FUNCTION_AUX(F, n, S, t, inline, )
MOCK_FUNCTION_AUX(F, n, S, t, inline,)
#define MOCK_STATIC_METHOD(F, n, S, t) \ # define MOCK_STATIC_METHOD(F, n, S, t) MOCK_FUNCTION_AUX(F, n, S, t, static, )
MOCK_FUNCTION_AUX(F, n, S, t, static,)
#define MOCK_STATIC_METHOD_TPL(F, n, S, t) \ # define MOCK_STATIC_METHOD_TPL(F, n, S, t) MOCK_FUNCTION_AUX(F, n, S, t, static, typename)
MOCK_FUNCTION_AUX(F, n, S, t, static, typename)
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect( __FILE__, __LINE__ ) #define MOCK_EXPECT(t) MOCK_HELPER(t).expect(__FILE__, __LINE__)
#define MOCK_RESET(t) MOCK_HELPER(t).reset( __FILE__, __LINE__ ) #define MOCK_RESET(t) MOCK_HELPER(t).reset(__FILE__, __LINE__)
#define MOCK_VERIFY(t) MOCK_HELPER(t).verify( __FILE__, __LINE__ ) #define MOCK_VERIFY(t) MOCK_HELPER(t).verify(__FILE__, __LINE__)
#endif // MOCK_MOCK_HPP_INCLUDED #endif // MOCK_MOCK_HPP_INCLUDED

View file

@ -10,65 +10,53 @@
#define MOCK_OBJECT_HPP_INCLUDED #define MOCK_OBJECT_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "detail/object_impl.hpp"
#include "detail/root.hpp" #include "detail/root.hpp"
#include "detail/type_name.hpp" #include "detail/type_name.hpp"
#include "detail/object_impl.hpp" #include <boost/make_shared.hpp>
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
namespace mock namespace mock {
{ class object;
class object;
namespace detail namespace detail {
{ template<typename E>
template< typename E > E& configure(const object& o, E& e, boost::unit_test::const_string instance, boost::optional<type_name> type,
E& configure( const object& o, E& e, boost::unit_test::const_string name);
boost::unit_test::const_string instance,
boost::optional< type_name > type,
boost::unit_test::const_string name );
template< typename T, typename E > template<typename T, typename E>
E& configure( const T& t, E& e, E& configure(const T& t, E& e, boost::unit_test::const_string instance, boost::optional<type_name> type,
boost::unit_test::const_string instance, boost::unit_test::const_string name,
boost::optional< type_name > type, typename boost::disable_if<typename boost::is_base_of<object, T>>::type* = 0)
boost::unit_test::const_string name,
typename boost::disable_if<
typename boost::is_base_of< object, T >
>::type* = 0 )
{ {
e.configure( detail::root, &t, instance, type, name ); e.configure(detail::root, &t, instance, type, name);
return e; return e;
} }
} } // namespace detail
class object class object
{
public:
object()
: impl_( boost::make_shared< detail::object_impl >() )
{}
protected:
~object()
{}
public:
boost::shared_ptr< detail::object_impl > impl_;
};
namespace detail
{ {
template< typename E > public:
E& configure( const object& o, E& e, object() : impl_(boost::make_shared<detail::object_impl>()) {}
boost::unit_test::const_string instance,
boost::optional< type_name > type, protected:
boost::unit_test::const_string name ) ~object() {}
public:
boost::shared_ptr<detail::object_impl> impl_;
};
namespace detail {
template<typename E>
E& configure(const object& o, E& e, boost::unit_test::const_string instance, boost::optional<type_name> type,
boost::unit_test::const_string name)
{ {
e.configure( *o.impl_, o.impl_.get(), instance, type, name ); e.configure(*o.impl_, o.impl_.get(), instance, type, name);
return e; return e;
} }
} } // namespace detail
} // mock } // namespace mock
#endif // MOCK_OBJECT_HPP_INCLUDED #endif // MOCK_OBJECT_HPP_INCLUDED

View file

@ -10,25 +10,24 @@
#define MOCK_RESET_HPP_INCLUDED #define MOCK_RESET_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "object.hpp"
#include "detail/root.hpp"
#include "detail/functor.hpp" #include "detail/functor.hpp"
#include "detail/root.hpp"
#include "object.hpp"
namespace mock namespace mock {
inline void reset()
{ {
inline void reset() detail::root.reset();
{ }
detail::root.reset(); inline void reset(const object& o)
} {
inline void reset( const object& o ) o.impl_->reset();
{ }
o.impl_->reset(); template<typename Signature>
} void reset(detail::functor<Signature>& f)
template< typename Signature > {
void reset( detail::functor< Signature >& f ) f.reset();
{ }
f.reset(); } // namespace mock
}
} // mock
#endif // MOCK_RESET_HPP_INCLUDED #endif // MOCK_RESET_HPP_INCLUDED

View file

@ -12,17 +12,14 @@
#include "config.hpp" #include "config.hpp"
#include "detail/sequence_impl.hpp" #include "detail/sequence_impl.hpp"
namespace mock namespace mock {
class sequence
{ {
class sequence public:
{ sequence() : impl_(boost::make_shared<detail::sequence_impl>()) {}
public:
sequence()
: impl_( boost::make_shared< detail::sequence_impl >() )
{}
boost::shared_ptr< detail::sequence_impl > impl_; boost::shared_ptr<detail::sequence_impl> impl_;
}; };
} // mock } // namespace mock
#endif // MOCK_SEQUENCE_HPP_INCLUDED #endif // MOCK_SEQUENCE_HPP_INCLUDED

View file

@ -13,48 +13,36 @@
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <ostream> #include <ostream>
namespace mock namespace mock {
struct stream
{ {
struct stream explicit stream(std::ostream& s) : s_(&s) {}
{ std::ostream* s_;
explicit stream( std::ostream& s ) };
: s_( &s )
{}
std::ostream* s_;
};
#ifdef MOCK_USE_CONVERSIONS #ifdef MOCK_USE_CONVERSIONS
namespace detail namespace detail { namespace conversion {
{
namespace conversion
{
struct sink struct sink
{ {
template< typename T > template<typename T>
sink( const T& ) sink(const T&)
{} {}
}; };
inline std::ostream& operator<<( std::ostream& s, const sink& ) inline std::ostream& operator<<(std::ostream& s, const sink&) { return s << '?'; }
{
return s << '?';
}
struct holder : boost::noncopyable struct holder : boost::noncopyable
{ {
virtual ~holder() virtual ~holder() {}
{} virtual void serialize(std::ostream& s) const = 0;
virtual void serialize( std::ostream& s ) const = 0;
}; };
template< typename T > template<typename T>
struct holder_imp : holder struct holder_imp : holder
{ {
explicit holder_imp( const T& t ) explicit holder_imp(const T& t) : t_(t) {}
: t_( t ) virtual void serialize(std::ostream& s) const
{}
virtual void serialize( std::ostream& s ) const
{ {
// if an error about an ambiguous conversion is generated by the // if an error about an ambiguous conversion is generated by the
// line below the solution is to add a serialization operator to a // line below the solution is to add a serialization operator to a
@ -66,77 +54,58 @@ namespace conversion
struct any : boost::noncopyable struct any : boost::noncopyable
{ {
template< typename T > template<typename T>
any( const T& t ) any(const T& t) : h_(new holder_imp<T>(t))
: h_( new holder_imp< T >( t ) )
{} {}
~any() ~any() { delete h_; }
{
delete h_;
}
holder* h_; holder* h_;
}; };
} }} // namespace detail::conversion
}
inline stream& operator<<( stream& s, const detail::conversion::any& d ) inline stream& operator<<(stream& s, const detail::conversion::any& d)
{ {
d.h_->serialize( *s.s_ ); d.h_->serialize(*s.s_);
return s; return s;
} }
#else // MOCK_USE_CONVERSIONS #else // MOCK_USE_CONVERSIONS
namespace detail namespace detail { namespace conversion {
{ template<typename S, typename T>
namespace conversion S& operator<<(S& s, const T&)
{
template< typename S, typename T >
S& operator<<( S &s, const T& )
{ {
return s << '?'; return s << '?';
} }
} }} // namespace detail::conversion
}
template< typename T > template<typename T>
stream& operator<<( stream& s, const T& t ) stream& operator<<(stream& s, const T& t)
{ {
using namespace detail::conversion; using namespace detail::conversion;
*s.s_ << t; *s.s_ << t;
return s; return s;
} }
#endif // MOCK_USE_CONVERSIONS #endif // MOCK_USE_CONVERSIONS
namespace detail namespace detail {
{ template<typename T>
template< typename T > void serialize(stream& s, const T& t)
void serialize( stream& s, const T& t )
{ {
// if an error about an ambiguous conversion is generated by the // if an error about an ambiguous conversion is generated by the
// line below the solution is to add a serialization operator to a // line below the solution is to add a serialization operator to a
// mock::stream for T // mock::stream for T
s << t; s << t;
} }
inline void serialize( stream& s, bool b ) inline void serialize(stream& s, bool b) { s << (b ? "true" : "false"); }
{ template<typename C, typename T, typename A>
s << (b ? "true" : "false"); void serialize(stream& s, const std::basic_string<C, T, A>& str)
}
template< typename C, typename T, typename A >
void serialize( stream& s, const std::basic_string< C, T, A >& str )
{ {
s << '"' << str << '"'; s << '"' << str << '"';
} }
inline void serialize( stream& s, const char* const str ) inline void serialize(stream& s, const char* const str) { s << '"' << str << '"'; }
{ inline void serialize(stream& s, unsigned char c) { s << static_cast<int>(c); }
s << '"' << str << '"'; } // namespace detail
} } // namespace mock
inline void serialize( stream& s, unsigned char c )
{
s << static_cast< int >( c );
}
}
} // mock
#endif // MOCK_STREAM_HPP_INCLUDED #endif // MOCK_STREAM_HPP_INCLUDED

View file

@ -10,25 +10,24 @@
#define MOCK_VERIFY_HPP_INCLUDED #define MOCK_VERIFY_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "object.hpp"
#include "detail/root.hpp"
#include "detail/functor.hpp" #include "detail/functor.hpp"
#include "detail/root.hpp"
#include "object.hpp"
namespace mock namespace mock {
inline bool verify()
{ {
inline bool verify() return detail::root.verify();
{ }
return detail::root.verify(); inline bool verify(const object& o)
} {
inline bool verify( const object& o ) return o.impl_->verify();
{ }
return o.impl_->verify(); template<typename Signature>
} bool verify(const detail::functor<Signature>& f)
template< typename Signature > {
bool verify( const detail::functor< Signature >& f ) return f.verify();
{ }
return f.verify(); } // namespace mock
}
} // mock
#endif // MOCK_VERIFY_HPP_INCLUDED #endif // MOCK_VERIFY_HPP_INCLUDED

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,11 +10,11 @@
#define MOCK_TEST_DEFINED_HPP_INCLUDED #define MOCK_TEST_DEFINED_HPP_INCLUDED
#ifdef BOOST_AUTO_TEST_MAIN #ifdef BOOST_AUTO_TEST_MAIN
#undef BOOST_AUTO_TEST_MAIN # undef BOOST_AUTO_TEST_MAIN
#endif #endif
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
MOCK_FUNCTION( f, 0, void(), f ) MOCK_FUNCTION(f, 0, void(), f)
#endif // MOCK_TEST_DEFINED_HPP_INCLUDED #endif // MOCK_TEST_DEFINED_HPP_INCLUDED

File diff suppressed because it is too large Load diff

View file

@ -9,68 +9,68 @@
#include <turtle/detail/invocation.hpp> #include <turtle/detail/invocation.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
BOOST_AUTO_TEST_CASE( unlimited ) BOOST_AUTO_TEST_CASE(unlimited)
{ {
mock::detail::unlimited invocation; mock::detail::unlimited invocation;
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
} }
BOOST_AUTO_TEST_CASE( once ) BOOST_AUTO_TEST_CASE(once)
{ {
mock::detail::once invocation; mock::detail::once invocation;
BOOST_CHECK( ! invocation.verify() ); BOOST_CHECK(!invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( invocation.exhausted() ); BOOST_CHECK(invocation.exhausted());
BOOST_CHECK( ! invocation.invoke() ); BOOST_CHECK(!invocation.invoke());
} }
BOOST_AUTO_TEST_CASE( never ) BOOST_AUTO_TEST_CASE(never)
{ {
mock::detail::never invocation; mock::detail::never invocation;
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( invocation.exhausted() ); BOOST_CHECK(invocation.exhausted());
BOOST_CHECK( ! invocation.invoke() ); BOOST_CHECK(!invocation.invoke());
} }
BOOST_AUTO_TEST_CASE( at_most ) BOOST_AUTO_TEST_CASE(at_most)
{ {
mock::detail::at_most invocation( 1 ); mock::detail::at_most invocation(1);
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( invocation.exhausted() ); BOOST_CHECK(invocation.exhausted());
BOOST_CHECK( ! invocation.invoke() ); BOOST_CHECK(!invocation.invoke());
} }
BOOST_AUTO_TEST_CASE( at_least ) BOOST_AUTO_TEST_CASE(at_least)
{ {
mock::detail::at_least invocation( 1 ); mock::detail::at_least invocation(1);
BOOST_CHECK( ! invocation.verify() ); BOOST_CHECK(!invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
} }
BOOST_AUTO_TEST_CASE( between ) BOOST_AUTO_TEST_CASE(between)
{ {
mock::detail::between invocation( 1, 2 ); mock::detail::between invocation(1, 2);
BOOST_CHECK( ! invocation.verify() ); BOOST_CHECK(!invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( ! invocation.exhausted() ); BOOST_CHECK(!invocation.exhausted());
BOOST_CHECK( invocation.invoke() ); BOOST_CHECK(invocation.invoke());
BOOST_CHECK( invocation.verify() ); BOOST_CHECK(invocation.verify());
BOOST_CHECK( invocation.exhausted() ); BOOST_CHECK(invocation.exhausted());
BOOST_CHECK( ! invocation.invoke() ); BOOST_CHECK(!invocation.invoke());
} }

View file

@ -9,147 +9,148 @@
#include <turtle/detail/is_functor.hpp> #include <turtle/detail/is_functor.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
#pragma warning( push, 0 ) # pragma warning(push, 0)
#endif #endif
#include <boost/lambda/lambda.hpp> #include <boost/lambda/lambda.hpp>
#include <boost/phoenix/phoenix.hpp> #include <boost/phoenix/phoenix.hpp>
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
#pragma warning( pop ) # pragma warning(pop)
#endif #endif
#include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/function.hpp>
namespace namespace {
struct declared_but_not_defined;
BOOST_MPL_ASSERT_NOT((mock::detail::is_functor<declared_but_not_defined, int>));
template<typename T>
void is_functor(T)
{ {
struct declared_but_not_defined; BOOST_MPL_ASSERT((mock::detail::is_functor<T, int>));
BOOST_MPL_ASSERT_NOT(( }
mock::detail::is_functor< declared_but_not_defined, int > )); template<typename T>
void is_not_functor(T)
{
BOOST_MPL_ASSERT_NOT((mock::detail::is_functor<T, int>));
}
template< typename T > void f0() {}
void is_functor( T ) bool f1(int)
{
return false;
}
bool f2(std::string, int)
{
return false;
}
} // namespace
BOOST_AUTO_TEST_CASE(data_is_not_functor)
{
is_not_functor(42);
}
BOOST_AUTO_TEST_CASE(function_is_functor)
{
is_functor(f0);
is_functor(f1);
is_functor(f2);
}
BOOST_AUTO_TEST_CASE(function_pointer_is_functor)
{
is_functor(&f0);
is_functor(&f1);
is_functor(&f2);
}
BOOST_AUTO_TEST_CASE(std_ptr_fun_is_functor)
{
is_functor(std::ptr_fun(&f1));
is_functor(std::ptr_fun(&f2));
}
BOOST_AUTO_TEST_CASE(std_bind_first_is_functor)
{
is_functor(std::bind1st(std::ptr_fun(&f2), ""));
}
namespace {
struct unary_functor0 : public std::unary_function<void, void>
{};
struct unary_functor1 : public std::unary_function<int, void>
{};
} // namespace
BOOST_AUTO_TEST_CASE(std_unary_functor_is_functor)
{
is_functor(unary_functor0());
is_functor(unary_functor1());
}
BOOST_AUTO_TEST_CASE(boost_bind_is_functor)
{
is_functor(boost::bind(&f0));
is_functor(boost::bind(&f1, _1));
is_functor(boost::bind(&f2, "", _1));
}
BOOST_AUTO_TEST_CASE(boost_lambda_is_functor)
{
is_functor(boost::lambda::_1 < 42);
}
BOOST_AUTO_TEST_CASE(boost_phoenix_is_functor)
{
is_functor(boost::phoenix::arg_names::arg1 < 42);
is_functor(boost::phoenix::arg_names::_1 < 42);
}
BOOST_AUTO_TEST_CASE(boost_function_is_functor)
{
is_functor(boost::function<void()>());
}
namespace {
struct result_type_functor
{
typedef void result_type;
};
} // namespace
BOOST_AUTO_TEST_CASE(class_with_result_type_is_functor)
{
is_functor(result_type_functor());
}
namespace {
struct sig_functor
{
template<typename Args>
struct sig
{ {
BOOST_MPL_ASSERT(( mock::detail::is_functor< T, int > )); typedef void type;
}
template< typename T >
void is_not_functor( T )
{
BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< T, int > ));
}
void f0() {}
bool f1( int ) { return false; }
bool f2( std::string, int ) { return false; }
}
BOOST_AUTO_TEST_CASE( data_is_not_functor )
{
is_not_functor( 42 );
}
BOOST_AUTO_TEST_CASE( function_is_functor )
{
is_functor( f0 );
is_functor( f1 );
is_functor( f2 );
}
BOOST_AUTO_TEST_CASE( function_pointer_is_functor )
{
is_functor( &f0 );
is_functor( &f1 );
is_functor( &f2 );
}
BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor )
{
is_functor( std::ptr_fun( &f1 ) );
is_functor( std::ptr_fun( &f2 ) );
}
BOOST_AUTO_TEST_CASE( std_bind_first_is_functor )
{
is_functor( std::bind1st( std::ptr_fun( &f2 ), "" ) );
}
namespace
{
struct unary_functor0 : public std::unary_function< void, void >
{};
struct unary_functor1 : public std::unary_function< int, void >
{};
}
BOOST_AUTO_TEST_CASE( std_unary_functor_is_functor )
{
is_functor( unary_functor0() );
is_functor( unary_functor1() );
}
BOOST_AUTO_TEST_CASE( boost_bind_is_functor )
{
is_functor( boost::bind( &f0 ) );
is_functor( boost::bind( &f1, _1 ) );
is_functor( boost::bind( &f2, "", _1 ) );
}
BOOST_AUTO_TEST_CASE( boost_lambda_is_functor )
{
is_functor( boost::lambda::_1 < 42 );
}
BOOST_AUTO_TEST_CASE( boost_phoenix_is_functor )
{
is_functor( boost::phoenix::arg_names::arg1 < 42 );
is_functor( boost::phoenix::arg_names::_1 < 42 );
}
BOOST_AUTO_TEST_CASE( boost_function_is_functor )
{
is_functor( boost::function< void() >() );
}
namespace
{
struct result_type_functor
{
typedef void result_type;
}; };
} };
} // namespace
BOOST_AUTO_TEST_CASE( class_with_result_type_is_functor ) BOOST_AUTO_TEST_CASE(class_with_sig_is_functor)
{ {
is_functor( result_type_functor() ); is_functor(sig_functor());
}
namespace
{
struct sig_functor
{
template< typename Args >
struct sig
{
typedef void type;
};
};
}
BOOST_AUTO_TEST_CASE( class_with_sig_is_functor )
{
is_functor( sig_functor() );
} }
#ifdef MOCK_LAMBDAS #ifdef MOCK_LAMBDAS
BOOST_AUTO_TEST_CASE( cxx11_lambda_is_functor ) BOOST_AUTO_TEST_CASE(cxx11_lambda_is_functor)
{ {
is_not_functor( []() {} ); is_not_functor([]() {});
#ifdef MOCK_DECLTYPE # ifdef MOCK_DECLTYPE
is_functor( []( int ) {} ); is_functor([](int) {});
#else # else
is_not_functor( []( int ) {} ); is_not_functor([](int) {});
#endif # endif
is_not_functor( []( const std::string&, int ) {} ); is_not_functor([](const std::string&, int) {});
is_not_functor( []( int, const std::string& ) {} ); is_not_functor([](int, const std::string&) {});
} }
#endif #endif

View file

@ -7,23 +7,20 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/signature.hpp> #include <turtle/detail/signature.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/mpl/assert.hpp> #include <boost/mpl/assert.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
struct base
{ {
struct base void method_1();
{ float method_2(int) const;
void method_1(); };
float method_2( int ) const; typedef base base_type;
}; } // namespace
typedef base base_type;
}
BOOST_AUTO_TEST_CASE( mock_signature_generates_signature ) BOOST_AUTO_TEST_CASE(mock_signature_generates_signature)
{ {
BOOST_MPL_ASSERT(( BOOST_MPL_ASSERT((boost::is_same<void(), MOCK_SIGNATURE(method_1)>));
boost::is_same< void(), MOCK_SIGNATURE(method_1) > )); BOOST_MPL_ASSERT((boost::is_same<float(int), MOCK_SIGNATURE(method_2)>));
BOOST_MPL_ASSERT((
boost::is_same< float( int ), MOCK_SIGNATURE(method_2) > ));
} }

View file

@ -7,219 +7,217 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/type_name.hpp> #include <turtle/detail/type_name.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
template<typename T>
std::string to_string(const T&)
{ {
template< typename T > return boost::lexical_cast<std::string>(MOCK_TYPE_NAME(T));
std::string to_string( const T& )
{
return boost::lexical_cast< std::string >( MOCK_TYPE_NAME(T) );
}
} }
} // namespace
BOOST_AUTO_TEST_CASE( name_of_base_type_is_extracted ) BOOST_AUTO_TEST_CASE(name_of_base_type_is_extracted)
{ {
BOOST_CHECK_EQUAL( "char", to_string( 'a' ) ); BOOST_CHECK_EQUAL("char", to_string('a'));
BOOST_CHECK_EQUAL( "bool", to_string( true ) ); BOOST_CHECK_EQUAL("bool", to_string(true));
BOOST_CHECK_EQUAL( "int", to_string< int >( 0 ) ); BOOST_CHECK_EQUAL("int", to_string<int>(0));
BOOST_CHECK_EQUAL( "short", to_string< short >( 0 ) ); BOOST_CHECK_EQUAL("short", to_string<short>(0));
BOOST_CHECK_EQUAL( "long", to_string< long >( 0 ) ); BOOST_CHECK_EQUAL("long", to_string<long>(0));
BOOST_CHECK_EQUAL( "unsigned int", to_string< unsigned int >( 0 ) ); BOOST_CHECK_EQUAL("unsigned int", to_string<unsigned int>(0));
BOOST_CHECK_EQUAL( "unsigned short", to_string< unsigned short >( 0 ) ); BOOST_CHECK_EQUAL("unsigned short", to_string<unsigned short>(0));
BOOST_CHECK_EQUAL( "unsigned long", to_string< unsigned long >( 0 ) ); BOOST_CHECK_EQUAL("unsigned long", to_string<unsigned long>(0));
} }
struct my_type_in_default_namespace struct my_type_in_default_namespace
{ {
struct inner {}; struct inner
{};
}; };
BOOST_AUTO_TEST_CASE( name_of_type_in_default_namespace_is_extracted ) BOOST_AUTO_TEST_CASE(name_of_type_in_default_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "my_type_in_default_namespace", to_string( my_type_in_default_namespace() ) ); BOOST_CHECK_EQUAL("my_type_in_default_namespace", to_string(my_type_in_default_namespace()));
} }
BOOST_AUTO_TEST_CASE( name_of_inner_type_from_type_in_default_namespace_is_extracted ) BOOST_AUTO_TEST_CASE(name_of_inner_type_from_type_in_default_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "inner", to_string( my_type_in_default_namespace::inner() ) ); BOOST_CHECK_EQUAL("inner", to_string(my_type_in_default_namespace::inner()));
} }
template< typename T > template<typename T>
struct my_template_type_in_default_namespace struct my_template_type_in_default_namespace
{ {
struct inner {}; struct inner
{};
}; };
BOOST_AUTO_TEST_CASE( name_of_template_type_in_default_namespace_is_extracted ) BOOST_AUTO_TEST_CASE(name_of_template_type_in_default_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "my_template_type_in_default_namespace<int>", to_string( my_template_type_in_default_namespace<int>() ) ); BOOST_CHECK_EQUAL("my_template_type_in_default_namespace<int>",
to_string(my_template_type_in_default_namespace<int>()));
} }
BOOST_AUTO_TEST_CASE( name_of_inner_type_from_template_type_in_default_namespace_is_extracted ) BOOST_AUTO_TEST_CASE(name_of_inner_type_from_template_type_in_default_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type_in_default_namespace<int>::inner() ) ); BOOST_CHECK_EQUAL("inner", to_string(my_template_type_in_default_namespace<int>::inner()));
} }
namespace namespace {
struct my_type_in_anonymous_namespace
{};
} // namespace
BOOST_AUTO_TEST_CASE(name_of_type_in_anonymous_namespace_is_extracted)
{ {
struct my_type_in_anonymous_namespace {}; BOOST_CHECK_EQUAL("my_type_in_anonymous_namespace", to_string(my_type_in_anonymous_namespace()));
} }
BOOST_AUTO_TEST_CASE( name_of_type_in_anonymous_namespace_is_extracted ) namespace nm {
struct my_type_from_named_namespace
{};
} // namespace nm
BOOST_AUTO_TEST_CASE(name_of_type_from_named_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "my_type_in_anonymous_namespace", to_string( my_type_in_anonymous_namespace() ) ); BOOST_CHECK_EQUAL("my_type_from_named_namespace", to_string(nm::my_type_from_named_namespace()));
} }
namespace nm namespace nm { namespace inner {
{ struct my_type_in_named_inner_namespace
struct my_type_from_named_namespace {};
}
BOOST_AUTO_TEST_CASE( name_of_type_from_named_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "my_type_from_named_namespace", to_string( nm::my_type_from_named_namespace() ) );
}
namespace nm
{
namespace inner
{
struct my_type_in_named_inner_namespace {};
}
}
BOOST_AUTO_TEST_CASE( name_of_type_in_named_inner_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "my_type_in_named_inner_namespace", to_string( nm::inner::my_type_in_named_inner_namespace() ) );
}
namespace
{
namespace inner
{
struct my_type_in_unnamed_inner_namespace {};
}
}
BOOST_AUTO_TEST_CASE( name_of_type_in_unnamed_inner_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "my_type_in_unnamed_inner_namespace", to_string( inner::my_type_in_unnamed_inner_namespace() ) );
}
BOOST_AUTO_TEST_CASE( name_of_local_type_is_extracted )
{
struct my_local_type {};
BOOST_CHECK_EQUAL( "my_local_type", boost::lexical_cast< std::string >( MOCK_TYPE_NAME(my_local_type) ) );
}
namespace
{
template< typename T >
struct my_template_type
{
struct inner {};
};
}
BOOST_AUTO_TEST_CASE( name_of_template_type_in_anonymous_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "my_template_type<int>", to_string( my_template_type< int >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception>", to_string( my_template_type< std::exception >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const&>", to_string( my_template_type< int const& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const&>", to_string( my_template_type< std::exception const& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const*>", to_string( my_template_type< int const* >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const*>", to_string( my_template_type< std::exception const* >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const*&>", to_string( my_template_type< int const*& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const*&>", to_string( my_template_type< std::exception const*& >() ) );
}
BOOST_AUTO_TEST_CASE( name_of_inner_type_from_template_type_in_anonymous_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< int >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< std::exception >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< int const& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< std::exception const& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< int const* >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< std::exception const* >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< int const*& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( my_template_type< std::exception const*& >::inner() ) );
}
namespace nm
{
template< typename T >
struct my_template_type
{
struct inner {};
};
}
BOOST_AUTO_TEST_CASE( name_of_template_type_in_named_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "my_template_type<int>", to_string( nm::my_template_type< int >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception>", to_string( nm::my_template_type< std::exception >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const&>", to_string( nm::my_template_type< int const& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const&>", to_string( nm::my_template_type< std::exception const& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const*>", to_string( nm::my_template_type< int const* >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const*>", to_string( nm::my_template_type< std::exception const* >() ) );
BOOST_CHECK_EQUAL( "my_template_type<int const*&>", to_string( nm::my_template_type< int const*& >() ) );
BOOST_CHECK_EQUAL( "my_template_type<exception const*&>", to_string( nm::my_template_type< std::exception const*& >() ) );
}
BOOST_AUTO_TEST_CASE( name_of_inner_type_from_template_type_in_named_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< int >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< std::exception >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< int const& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< std::exception const& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< int const* >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< std::exception const* >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< int const*& >::inner() ) );
BOOST_CHECK_EQUAL( "inner", to_string( nm::my_template_type< std::exception const*& >::inner() ) );
}
namespace nm2
{
template< typename T >
struct my_template_type
{
template< typename U >
struct inner {};
};
}
BOOST_AUTO_TEST_CASE( name_of_template_inner_type_from_template_type_in_named_namespace_is_extracted )
{
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< int >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< std::exception >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< int const& >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< std::exception const& >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< int const* >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< std::exception const* >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< int const*& >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int>", to_string( nm2::my_template_type< std::exception const*& >::inner< int >() ) );
BOOST_CHECK_EQUAL( "inner<int const&>", to_string( nm2::my_template_type< int >::inner< int const& >() ) );
BOOST_CHECK_EQUAL( "inner<int const&>", to_string( nm2::my_template_type< std::exception >::inner< int const& >() ) );
BOOST_CHECK_EQUAL( "inner<int const*>", to_string( nm2::my_template_type< int >::inner< int const* >() ) );
BOOST_CHECK_EQUAL( "inner<int const*>", to_string( nm2::my_template_type< std::exception >::inner< int const* >() ) );
BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< int >::inner< int const*& >() ) );
BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< std::exception >::inner< int const*& >() ) );
}
namespace
{
template< typename T1, typename T2, typename T3 >
struct my_tpl
{}; {};
}} // namespace nm::inner
BOOST_AUTO_TEST_CASE(name_of_type_in_named_inner_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("my_type_in_named_inner_namespace", to_string(nm::inner::my_type_in_named_inner_namespace()));
} }
BOOST_AUTO_TEST_CASE( name_of_nested_template_with_multiple_arguments_is_extracted ) namespace { namespace inner {
struct my_type_in_unnamed_inner_namespace
{};
}} // namespace ::inner
BOOST_AUTO_TEST_CASE(name_of_type_in_unnamed_inner_namespace_is_extracted)
{ {
BOOST_CHECK_EQUAL( "vector<int, allocator<int>>", to_string( std::vector< int >() ) ); BOOST_CHECK_EQUAL("my_type_in_unnamed_inner_namespace", to_string(inner::my_type_in_unnamed_inner_namespace()));
BOOST_CHECK_EQUAL( "vector<vector<int, allocator<int>>, allocator<vector<int, allocator<int>>>>", to_string( std::vector< std::vector< int > >() ) ); }
BOOST_CHECK_EQUAL( "my_tpl<my_tpl<int, int, int>, my_tpl<int, int, int>, my_tpl<int, int, int>>", to_string( my_tpl< my_tpl< int, int, int >, my_tpl< int, int, int >, my_tpl< int, int, int > >() ) );
BOOST_AUTO_TEST_CASE(name_of_local_type_is_extracted)
{
struct my_local_type
{};
BOOST_CHECK_EQUAL("my_local_type", boost::lexical_cast<std::string>(MOCK_TYPE_NAME(my_local_type)));
}
namespace {
template<typename T>
struct my_template_type
{
struct inner
{};
};
} // namespace
BOOST_AUTO_TEST_CASE(name_of_template_type_in_anonymous_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("my_template_type<int>", to_string(my_template_type<int>()));
BOOST_CHECK_EQUAL("my_template_type<exception>", to_string(my_template_type<std::exception>()));
BOOST_CHECK_EQUAL("my_template_type<int const&>", to_string(my_template_type<int const&>()));
BOOST_CHECK_EQUAL("my_template_type<exception const&>", to_string(my_template_type<std::exception const&>()));
BOOST_CHECK_EQUAL("my_template_type<int const*>", to_string(my_template_type<int const*>()));
BOOST_CHECK_EQUAL("my_template_type<exception const*>", to_string(my_template_type<std::exception const*>()));
BOOST_CHECK_EQUAL("my_template_type<int const*&>", to_string(my_template_type<int const*&>()));
BOOST_CHECK_EQUAL("my_template_type<exception const*&>", to_string(my_template_type<std::exception const*&>()));
}
BOOST_AUTO_TEST_CASE(name_of_inner_type_from_template_type_in_anonymous_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<int>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<std::exception>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<int const&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<std::exception const&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<int const*>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<std::exception const*>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<int const*&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(my_template_type<std::exception const*&>::inner()));
}
namespace nm {
template<typename T>
struct my_template_type
{
struct inner
{};
};
} // namespace nm
BOOST_AUTO_TEST_CASE(name_of_template_type_in_named_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("my_template_type<int>", to_string(nm::my_template_type<int>()));
BOOST_CHECK_EQUAL("my_template_type<exception>", to_string(nm::my_template_type<std::exception>()));
BOOST_CHECK_EQUAL("my_template_type<int const&>", to_string(nm::my_template_type<int const&>()));
BOOST_CHECK_EQUAL("my_template_type<exception const&>", to_string(nm::my_template_type<std::exception const&>()));
BOOST_CHECK_EQUAL("my_template_type<int const*>", to_string(nm::my_template_type<int const*>()));
BOOST_CHECK_EQUAL("my_template_type<exception const*>", to_string(nm::my_template_type<std::exception const*>()));
BOOST_CHECK_EQUAL("my_template_type<int const*&>", to_string(nm::my_template_type<int const*&>()));
BOOST_CHECK_EQUAL("my_template_type<exception const*&>", to_string(nm::my_template_type<std::exception const*&>()));
}
BOOST_AUTO_TEST_CASE(name_of_inner_type_from_template_type_in_named_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<int>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<std::exception>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<int const&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<std::exception const&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<int const*>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<std::exception const*>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<int const*&>::inner()));
BOOST_CHECK_EQUAL("inner", to_string(nm::my_template_type<std::exception const*&>::inner()));
}
namespace nm2 {
template<typename T>
struct my_template_type
{
template<typename U>
struct inner
{};
};
} // namespace nm2
BOOST_AUTO_TEST_CASE(name_of_template_inner_type_from_template_type_in_named_namespace_is_extracted)
{
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<int>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<std::exception>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<int const&>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<std::exception const&>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<int const*>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<std::exception const*>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<int const*&>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int>", to_string(nm2::my_template_type<std::exception const*&>::inner<int>()));
BOOST_CHECK_EQUAL("inner<int const&>", to_string(nm2::my_template_type<int>::inner<int const&>()));
BOOST_CHECK_EQUAL("inner<int const&>", to_string(nm2::my_template_type<std::exception>::inner<int const&>()));
BOOST_CHECK_EQUAL("inner<int const*>", to_string(nm2::my_template_type<int>::inner<int const*>()));
BOOST_CHECK_EQUAL("inner<int const*>", to_string(nm2::my_template_type<std::exception>::inner<int const*>()));
BOOST_CHECK_EQUAL("inner<int const*&>", to_string(nm2::my_template_type<int>::inner<int const*&>()));
BOOST_CHECK_EQUAL("inner<int const*&>", to_string(nm2::my_template_type<std::exception>::inner<int const*&>()));
}
namespace {
template<typename T1, typename T2, typename T3>
struct my_tpl
{};
} // namespace
BOOST_AUTO_TEST_CASE(name_of_nested_template_with_multiple_arguments_is_extracted)
{
BOOST_CHECK_EQUAL("vector<int, allocator<int>>", to_string(std::vector<int>()));
BOOST_CHECK_EQUAL("vector<vector<int, allocator<int>>, allocator<vector<int, allocator<int>>>>",
to_string(std::vector<std::vector<int>>()));
BOOST_CHECK_EQUAL("my_tpl<my_tpl<int, int, int>, my_tpl<int, int, int>, my_tpl<int, int, int>>",
to_string(my_tpl<my_tpl<int, int, int>, my_tpl<int, int, int>, my_tpl<int, int, int>>()));
} }

View file

@ -8,17 +8,13 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
struct my_base
{ {
struct my_base virtual ~my_base() {}
{ virtual void my_method() = 0;
virtual ~my_base() {} virtual void my_method(int) = 0;
virtual void my_method() = 0; };
virtual void my_method( int ) = 0;
};
MOCK_BASE_CLASS( my_class, my_base ) MOCK_BASE_CLASS(my_class, my_base){MOCK_METHOD(my_method, 0)};
{ } // namespace
MOCK_METHOD( my_method, 0 )
};
}

View file

@ -8,17 +8,13 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
{ MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 1, void(int), my_method)};
MOCK_CLASS( my_class ) bool constraint(int, int);
{
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
};
bool constraint( int, int );
void test_case() void test_case()
{ {
my_class c; my_class c;
MOCK_EXPECT( c.my_method ).with( &constraint ); MOCK_EXPECT(c.my_method).with(&constraint);
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 1, void(int), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).with("42");
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).with( "42" );
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 1, void(int), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).with(mock::equal("42"));
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).with( mock::equal( "42" ) );
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 0, int(), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).returns(std::string());
MOCK_METHOD_EXT( my_method, 0, int(), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).returns( std::string() );
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 0, std::string(), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).returns(42);
MOCK_METHOD_EXT( my_method, 0, std::string(), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).returns( 42 );
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 0, void(), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).returns("42");
MOCK_METHOD_EXT( my_method, 0, void(), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).returns( "42" );
}
} }
} // namespace

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
struct my_base
{ {
struct my_base virtual ~my_base() {}
{ };
virtual ~my_base() {}
};
MOCK_BASE_CLASS( my_class, my_base ) MOCK_BASE_CLASS(my_class, my_base){MOCK_METHOD(my_method, 0)};
{ } // namespace
MOCK_METHOD( my_method, 0 )
};
}

View file

@ -8,18 +8,14 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
BOOST_STATIC_ASSERT( MOCK_MAX_ARGS == 9 ); BOOST_STATIC_ASSERT(MOCK_MAX_ARGS == 9);
namespace namespace {
struct my_base
{ {
struct my_base virtual ~my_base() {}
{ virtual void my_method(int, int, int, int, int, int, int, int, int, int) = 0;
virtual ~my_base() {} };
virtual void my_method( int, int, int, int, int, int, int, int, int, int ) = 0;
};
MOCK_BASE_CLASS( my_class, my_base ) MOCK_BASE_CLASS(my_class, my_base){MOCK_METHOD(my_method, 10)};
{ } // namespace
MOCK_METHOD( my_method, 10 )
};
}

View file

@ -8,11 +8,7 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
{ template<typename T>
template< typename T > MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 1, void(T), my_method)};
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 1, void( T ), my_method )
};
} }

View file

@ -8,16 +8,12 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
struct my_base
{ {
struct my_base virtual ~my_base() {}
{ virtual void my_method(int) = 0;
virtual ~my_base() {} };
virtual void my_method( int ) = 0;
};
MOCK_BASE_CLASS( my_class, my_base ) MOCK_BASE_CLASS(my_class, my_base){MOCK_METHOD(my_method, 2)};
{ } // namespace
MOCK_METHOD( my_method, 2 )
};
}

View file

@ -8,15 +8,11 @@
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
namespace namespace {
MOCK_CLASS(my_class){MOCK_METHOD_EXT(my_method, 1, void(int), my_method)};
void test_case()
{ {
MOCK_CLASS( my_class ) my_class c;
{ MOCK_EXPECT(c.my_method).with(42, 42);
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
};
void test_case()
{
my_class c;
MOCK_EXPECT( c.my_method ).with( 42, 42 );
}
} }
} // namespace

View file

@ -15,7 +15,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <stdexcept> #include <stdexcept>
struct mock_error_data_t : mock::detail::singleton< mock_error_data_t > struct mock_error_data_t : mock::detail::singleton<mock_error_data_t>
{ {
void reset() void reset()
{ {
@ -24,10 +24,7 @@ struct mock_error_data_t : mock::detail::singleton< mock_error_data_t >
last_message.clear(); last_message.clear();
last_context.clear(); last_context.clear();
} }
bool verify() bool verify() { return error_count == 0; }
{
return error_count == 0;
}
void call() void call()
{ {
@ -35,9 +32,7 @@ struct mock_error_data_t : mock::detail::singleton< mock_error_data_t >
last_message.clear(); last_message.clear();
++call_count; ++call_count;
} }
void fail( const std::string& message, void fail(const std::string& message, const std::string& context, const char* file, int line)
const std::string& context,
const char* file, int line )
{ {
last_context = context; last_context = context;
last_message = message; last_message = message;
@ -52,60 +47,54 @@ struct mock_error_data_t : mock::detail::singleton< mock_error_data_t >
std::string last_context; std::string last_context;
std::string last_file; std::string last_file;
int last_line; int last_line;
MOCK_SINGLETON_CONS( mock_error_data_t ); MOCK_SINGLETON_CONS(mock_error_data_t);
}; };
MOCK_SINGLETON_INST( mock_error_data ) MOCK_SINGLETON_INST(mock_error_data)
template< typename Result > template<typename Result>
struct mock_error struct mock_error
{ {
static Result abort() static Result abort() { throw std::runtime_error("aborted"); }
{
throw std::runtime_error( "aborted" );
}
static void pass( const char* /*file*/, int /*line*/ ) static void pass(const char* /*file*/, int /*line*/) {}
{}
template< typename Context > template<typename Context>
static void call( const Context& /*context*/, static void call(const Context& /*context*/, const char* /*file*/, int /*line*/)
const char* /*file*/, int /*line*/ )
{ {
mock_error_data.call(); mock_error_data.call();
} }
template< typename Context > template<typename Context>
static void fail( const std::string& message, const Context& context, static void fail(const std::string& message, const Context& context, const char* file = "", int line = 0)
const char* file = "", int line = 0 )
{ {
mock_error_data.fail( message, mock_error_data.fail(message, boost::lexical_cast<std::string>(context), file, line);
boost::lexical_cast< std::string >( context ), file, line );
} }
}; };
struct mock_error_fixture struct mock_error_fixture
{ {
mock_error_fixture() mock_error_fixture() { mock_error_data.reset(); }
{
mock_error_data.reset();
}
~mock_error_fixture() ~mock_error_fixture()
{ {
BOOST_CHECK( mock_error_data.verify() ); BOOST_CHECK(mock_error_data.verify());
BOOST_CHECK_EQUAL( 0, mock_error_data.call_count ); BOOST_CHECK_EQUAL(0, mock_error_data.call_count);
} }
}; };
#define CHECK_CALLS( calls ) \ #define CHECK_CALLS(calls) \
BOOST_CHECK_EQUAL( calls, mock_error_data.call_count ); \ BOOST_CHECK_EQUAL(calls, mock_error_data.call_count); \
mock_error_data.call_count = 0; mock_error_data.call_count = 0;
#define CHECK_ERROR( expr, error, calls, context ) \ #define CHECK_ERROR(expr, error, calls, context) \
BOOST_CHECK( mock_error_data.verify() ); \ BOOST_CHECK(mock_error_data.verify()); \
try { expr; } catch( ... ) {} \ try \
BOOST_CHECK_EQUAL( 1, mock_error_data.error_count ); \ { \
BOOST_CHECK_EQUAL( error, mock_error_data.last_message ); \ expr; \
BOOST_CHECK_EQUAL( context, mock_error_data.last_context ); \ } catch(...) \
CHECK_CALLS( calls ); \ {} \
BOOST_CHECK_EQUAL(1, mock_error_data.error_count); \
BOOST_CHECK_EQUAL(error, mock_error_data.last_message); \
BOOST_CHECK_EQUAL(context, mock_error_data.last_context); \
CHECK_CALLS(calls); \
mock_error_data.reset(); mock_error_data.reset();
#endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED #endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED

View file

@ -11,32 +11,30 @@
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
namespace namespace {
{ MOCK_CONSTRAINT(constraint_0, actual == 0)
MOCK_CONSTRAINT( constraint_0, actual == 0 ) MOCK_CONSTRAINT(constraint_1, expected, actual == expected)
MOCK_CONSTRAINT( constraint_1, expected, actual == expected ) MOCK_CONSTRAINT(constraint_2, expected_0, expected_1, actual == expected_0 || actual == expected_1)
MOCK_CONSTRAINT( constraint_2, expected_0, expected_1, actual == expected_0 || actual == expected_1 ) } // namespace
}
BOOST_AUTO_TEST_CASE( mock_constraint_is_supported_by_compilers_with_variadic_macros ) BOOST_AUTO_TEST_CASE(mock_constraint_is_supported_by_compilers_with_variadic_macros)
{ {
BOOST_CHECK( constraint_0.c_( 0 ) ); BOOST_CHECK(constraint_0.c_(0));
BOOST_CHECK( constraint_1( 0 ).c_( 0 ) ); BOOST_CHECK(constraint_1(0).c_(0));
BOOST_CHECK( constraint_2( 0, 0 ).c_( 0 ) ); BOOST_CHECK(constraint_2(0, 0).c_(0));
} }
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS
namespace namespace {
{ MOCK_CONSTRAINT_EXT(constraint_0_ext, 0, , actual == 0)
MOCK_CONSTRAINT_EXT( constraint_0_ext, 0,, actual == 0 ) MOCK_CONSTRAINT_EXT(constraint_1_ext, 1, (expected), actual == expected)
MOCK_CONSTRAINT_EXT( constraint_1_ext, 1, ( expected ), actual == expected ) MOCK_CONSTRAINT_EXT(constraint_2_ext, 2, (expected_0, expected_1), actual == expected_0 || actual == expected_1)
MOCK_CONSTRAINT_EXT( constraint_2_ext, 2, ( expected_0, expected_1 ), actual == expected_0 || actual == expected_1 ) } // namespace
}
BOOST_AUTO_TEST_CASE( mock_constraint_ext_is_supported_by_all_compilers ) BOOST_AUTO_TEST_CASE(mock_constraint_ext_is_supported_by_all_compilers)
{ {
BOOST_CHECK( constraint_0_ext.c_( 0 ) ); BOOST_CHECK(constraint_0_ext.c_(0));
BOOST_CHECK( constraint_1_ext( 0 ).c_( 0 ) ); BOOST_CHECK(constraint_1_ext(0).c_(0));
BOOST_CHECK( constraint_2_ext( 0, 0 ).c_( 0 ) ); BOOST_CHECK(constraint_2_ext(0, 0).c_(0));
} }

View file

@ -10,414 +10,379 @@
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
#include <boost/typeof/typeof.hpp> #include <boost/typeof/typeof.hpp>
BOOST_AUTO_TEST_CASE( all_comparison_constraints_can_be_instanciated ) BOOST_AUTO_TEST_CASE(all_comparison_constraints_can_be_instanciated)
{ {
mock::equal( 0 ); mock::equal(0);
mock::less( 0 ); mock::less(0);
mock::greater( 0 ); mock::greater(0);
mock::less_equal( 0 ); mock::less_equal(0);
mock::greater_equal( 0 ); mock::greater_equal(0);
} }
BOOST_AUTO_TEST_CASE( constraints_can_be_negated_using_the_not_operator ) BOOST_AUTO_TEST_CASE(constraints_can_be_negated_using_the_not_operator)
{ {
! mock::any; !mock::any;
! mock::affirm; !mock::affirm;
! mock::negate; !mock::negate;
! mock::evaluate; !mock::evaluate;
! mock::equal( 0 ); !mock::equal(0);
! mock::less( 0 ); !mock::less(0);
! mock::greater( 0 ); !mock::greater(0);
! mock::less_equal( 0 ); !mock::less_equal(0);
! mock::greater_equal( 0 ); !mock::greater_equal(0);
} }
BOOST_AUTO_TEST_CASE( constraints_can_be_combined_using_the_or_operator ) BOOST_AUTO_TEST_CASE(constraints_can_be_combined_using_the_or_operator)
{ {
mock::less( 0 ) || mock::greater( 0 ); mock::less(0) || mock::greater(0);
} }
BOOST_AUTO_TEST_CASE( constraints_can_be_combined_using_the_and_operator ) BOOST_AUTO_TEST_CASE(constraints_can_be_combined_using_the_and_operator)
{ {
mock::less( 0 ) && mock::greater( 0 ); mock::less(0) && mock::greater(0);
} }
BOOST_AUTO_TEST_CASE( equal_constraint ) BOOST_AUTO_TEST_CASE(equal_constraint)
{ {
BOOST_CHECK( mock::equal( std::string( "string" ) ).c_( "string" ) ); BOOST_CHECK(mock::equal(std::string("string")).c_("string"));
BOOST_CHECK( ! mock::equal( std::string( "string" ) ).c_( "not string" ) ); BOOST_CHECK(!mock::equal(std::string("string")).c_("not string"));
{ {
std::string s; std::string s;
BOOST_AUTO( c, mock::equal( boost::cref( s ) ) ); BOOST_AUTO(c, mock::equal(boost::cref(s)));
s = "string"; s = "string";
BOOST_CHECK( c.c_( "string" ) ); BOOST_CHECK(c.c_("string"));
} }
#ifdef MOCK_SMART_PTR #ifdef MOCK_SMART_PTR
{ {
std::unique_ptr< int > i; std::unique_ptr<int> i;
std::unique_ptr< int > j( new int( 3 ) ); std::unique_ptr<int> j(new int(3));
BOOST_CHECK( ! mock::equal( i ).c_( j ) ); BOOST_CHECK(!mock::equal(i).c_(j));
BOOST_CHECK( ! mock::equal( j ).c_( i ) ); BOOST_CHECK(!mock::equal(j).c_(i));
BOOST_CHECK( mock::equal( i ).c_( i ) ); BOOST_CHECK(mock::equal(i).c_(i));
BOOST_CHECK( mock::equal( j ).c_( j ) ); BOOST_CHECK(mock::equal(j).c_(j));
} }
#endif #endif
} }
BOOST_AUTO_TEST_CASE( equal_constraint_deref ) BOOST_AUTO_TEST_CASE(equal_constraint_deref){{int i = 3;
BOOST_CHECK(mock::equal(3).c_(&i));
BOOST_CHECK(!mock::equal(7).c_(&i));
}
{ {
{ int* i = 0;
int i = 3; BOOST_CHECK(!mock::equal(3).c_(i));
BOOST_CHECK( mock::equal( 3 ).c_( &i ) ); }
BOOST_CHECK( ! mock::equal( 7 ).c_( &i ) );
}
{
int* i = 0;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
}
#ifdef MOCK_SMART_PTR #ifdef MOCK_SMART_PTR
{ {
std::unique_ptr< int > j( new int( 3 ) ); std::unique_ptr<int> j(new int(3));
BOOST_CHECK( mock::equal( 3 ).c_( j ) ); BOOST_CHECK(mock::equal(3).c_(j));
std::unique_ptr< int > i; std::unique_ptr<int> i;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) ); BOOST_CHECK(!mock::equal(3).c_(i));
} }
#endif // MOCK_SMART_PTR #endif // MOCK_SMART_PTR
} }
BOOST_AUTO_TEST_CASE( same_constraint ) BOOST_AUTO_TEST_CASE(same_constraint){{int i = 0;
int j = 0;
BOOST_CHECK_EQUAL(i, j);
BOOST_CHECK(!mock::same(i).c_(j));
BOOST_CHECK(mock::same(i).c_(i));
}
{ {
{ int i = 0;
int i = 0; int j = 0;
int j = 0; BOOST_CHECK_EQUAL(i, j);
BOOST_CHECK_EQUAL( i, j ); mock::constraint<mock::detail::same<const boost::reference_wrapper<const int>>> c = mock::same(boost::cref(i));
BOOST_CHECK( ! mock::same( i ).c_( j ) ); BOOST_CHECK(!c.c_(j));
BOOST_CHECK( mock::same( i ).c_( i ) ); BOOST_CHECK(c.c_(i));
} }
{
int i = 0;
int j = 0;
BOOST_CHECK_EQUAL( i, j );
mock::constraint<
mock::detail::same<
const boost::reference_wrapper< const int >
>
> c = mock::same( boost::cref( i ) );
BOOST_CHECK( ! c.c_( j ) );
BOOST_CHECK( c.c_( i ) );
}
#ifdef MOCK_NULLPTR #ifdef MOCK_NULLPTR
{ {
std::nullptr_t p; std::nullptr_t p;
BOOST_CHECK( mock::same( p ).c_( p ) ); BOOST_CHECK(mock::same(p).c_(p));
} }
#endif #endif
} }
BOOST_AUTO_TEST_CASE( assign_constraint ) BOOST_AUTO_TEST_CASE(assign_constraint)
{ {
{ {
int i = 0; int i = 0;
BOOST_CHECK( mock::assign( 3 ).c_( i ) ); BOOST_CHECK(mock::assign(3).c_(i));
BOOST_CHECK_EQUAL( 3, i ); BOOST_CHECK_EQUAL(3, i);
} }
{ {
int i = 0; int i = 0;
BOOST_CHECK( mock::assign( 3 ).c_( &i ) ); BOOST_CHECK(mock::assign(3).c_(&i));
BOOST_CHECK_EQUAL( 3, i ); BOOST_CHECK_EQUAL(3, i);
} }
{ {
const int* i = 0; const int* i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::assign( &j ).c_( i ) ); BOOST_CHECK(mock::assign(&j).c_(i));
BOOST_CHECK_EQUAL( &j, i ); BOOST_CHECK_EQUAL(&j, i);
} }
{ {
int* i = 0; int* i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( ! mock::assign( j ).c_( i ) ); BOOST_CHECK(!mock::assign(j).c_(i));
BOOST_CHECK( ! i ); BOOST_CHECK(!i);
} }
{ {
int i = 0; int i = 0;
int j = 1; int j = 1;
mock::constraint< mock::constraint<mock::detail::assign<boost::reference_wrapper<const int>>> c = mock::assign(boost::cref(j));
mock::detail::assign< BOOST_CHECK(c.c_(i));
boost::reference_wrapper< const int > BOOST_CHECK_EQUAL(1, i);
>
> c = mock::assign( boost::cref( j ) );
BOOST_CHECK( c.c_( i ) );
BOOST_CHECK_EQUAL( 1, i );
j = 3; j = 3;
BOOST_CHECK( c.c_( i ) ); BOOST_CHECK(c.c_(i));
BOOST_CHECK_EQUAL( 3, i ); BOOST_CHECK_EQUAL(3, i);
} }
{ {
int i = 0; int i = 0;
int j = 1; int j = 1;
mock::constraint< mock::constraint<mock::detail::assign<boost::reference_wrapper<const int>>> c = mock::assign(boost::cref(j));
mock::detail::assign< BOOST_CHECK(c.c_(&i));
boost::reference_wrapper< const int > BOOST_CHECK_EQUAL(1, i);
>
> c = mock::assign( boost::cref( j ) );
BOOST_CHECK( c.c_( &i ) );
BOOST_CHECK_EQUAL( 1, i );
j = 3; j = 3;
BOOST_CHECK( c.c_( &i ) ); BOOST_CHECK(c.c_(&i));
BOOST_CHECK_EQUAL( 3, i ); BOOST_CHECK_EQUAL(3, i);
} }
{ {
const int* i = 0; const int* i = 0;
int k = 1; int k = 1;
int* j = &k; int* j = &k;
mock::constraint< mock::constraint<mock::detail::assign<boost::reference_wrapper<int* const>>> c = mock::assign(boost::cref(j));
mock::detail::assign< BOOST_CHECK(c.c_(i));
boost::reference_wrapper< int* const > BOOST_CHECK_EQUAL(j, i);
>
> c = mock::assign( boost::cref( j ) );
BOOST_CHECK( c.c_( i ) );
BOOST_CHECK_EQUAL( j, i );
j = 0; j = 0;
BOOST_CHECK( c.c_( i ) ); BOOST_CHECK(c.c_(i));
BOOST_CHECK_EQUAL( j, i ); BOOST_CHECK_EQUAL(j, i);
} }
} }
BOOST_AUTO_TEST_CASE( retrieve_constraint ) BOOST_AUTO_TEST_CASE(retrieve_constraint)
{ {
{ {
int i = 0; int i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, j ); BOOST_CHECK_EQUAL(i, j);
} }
{ {
int* i = 0; int* i = 0;
int j = 1; int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( &j ) ); BOOST_CHECK(mock::retrieve(i).c_(&j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
const int* i = 0; const int* i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
const int* i = 0; const int* i = 0;
int j = 1; int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
int* i = 0; int* i = 0;
int j = 1; int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
const int* i = 0; const int* i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
int** i = 0; int** i = 0;
int* j = 0; int* j = 0;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
const int** i = 0; const int** i = 0;
const int* j = 0; const int* j = 0;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
{ {
int i = 0; int i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) ); BOOST_CHECK(mock::retrieve(boost::ref(i)).c_(j));
BOOST_CHECK_EQUAL( i, j ); BOOST_CHECK_EQUAL(i, j);
} }
{ {
const int* i = 0; const int* i = 0;
const int j = 1; const int j = 1;
BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) ); BOOST_CHECK(mock::retrieve(boost::ref(i)).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
#ifdef MOCK_NULLPTR #ifdef MOCK_NULLPTR
{ {
std::nullptr_t* i = 0; std::nullptr_t* i = 0;
std::nullptr_t j; std::nullptr_t j;
BOOST_CHECK( mock::retrieve( i ).c_( j ) ); BOOST_CHECK(mock::retrieve(i).c_(j));
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL(i, &j);
} }
#endif #endif
#ifdef MOCK_SMART_PTR #ifdef MOCK_SMART_PTR
{ {
std::unique_ptr< int > i; std::unique_ptr<int> i;
std::unique_ptr< int > j( new int( 3 ) ); std::unique_ptr<int> j(new int(3));
BOOST_CHECK( mock::retrieve( i ).c_( boost::move( j ) ) ); BOOST_CHECK(mock::retrieve(i).c_(boost::move(j)));
BOOST_REQUIRE( i ); BOOST_REQUIRE(i);
BOOST_CHECK_EQUAL( 3, *i ); BOOST_CHECK_EQUAL(3, *i);
BOOST_CHECK( !j ); BOOST_CHECK(!j);
} }
#endif #endif
} }
namespace namespace {
struct A
{};
struct B
{ {
struct A B& operator=(const A&) { return *this; }
{ };
}; } // namespace
struct B
{
B& operator=( const A& )
{
return *this;
}
};
}
BOOST_AUTO_TEST_CASE( retrieve_constraint_uses_assignment_operator ) BOOST_AUTO_TEST_CASE(retrieve_constraint_uses_assignment_operator)
{ {
B b; B b;
const A a = A(); const A a = A();
mock::retrieve( b ).c_( a ); mock::retrieve(b).c_(a);
} }
BOOST_AUTO_TEST_CASE( affirm_constraint ) BOOST_AUTO_TEST_CASE(affirm_constraint)
{ {
{ {
int* i = 0; int* i = 0;
int j; int j;
BOOST_CHECK( ! mock::affirm.c_( i ) ); BOOST_CHECK(!mock::affirm.c_(i));
BOOST_CHECK( mock::affirm.c_( &j ) ); BOOST_CHECK(mock::affirm.c_(&j));
} }
{ {
#ifdef MOCK_SMART_PTR #ifdef MOCK_SMART_PTR
std::unique_ptr< int > i; std::unique_ptr<int> i;
std::unique_ptr< int > j( new int( 3 ) ); std::unique_ptr<int> j(new int(3));
BOOST_CHECK( ! mock::affirm.c_( i ) ); BOOST_CHECK(!mock::affirm.c_(i));
BOOST_CHECK( mock::affirm.c_( j ) ); BOOST_CHECK(mock::affirm.c_(j));
#endif #endif
} }
} }
BOOST_AUTO_TEST_CASE( negate_constraint ) BOOST_AUTO_TEST_CASE(negate_constraint)
{ {
int* i = 0; int* i = 0;
int j; int j;
BOOST_CHECK( mock::negate.c_( i ) ); BOOST_CHECK(mock::negate.c_(i));
BOOST_CHECK( ! mock::negate.c_( &j ) ); BOOST_CHECK(!mock::negate.c_(&j));
} }
namespace namespace {
bool return_true()
{ {
bool return_true() return true;
{ }
return true; bool return_false()
} {
bool return_false() return false;
{ }
return false; } // namespace
}
BOOST_AUTO_TEST_CASE(call_constraint)
{
BOOST_CHECK(mock::call(&return_true).c_());
BOOST_CHECK(!mock::call(&return_false).c_());
} }
BOOST_AUTO_TEST_CASE( call_constraint ) BOOST_AUTO_TEST_CASE(evaluate_constraint)
{ {
BOOST_CHECK( mock::call( &return_true ).c_() ); BOOST_CHECK(mock::evaluate.c_(&return_true));
BOOST_CHECK( ! mock::call( &return_false ).c_() ); BOOST_CHECK(!mock::evaluate.c_(&return_false));
} }
BOOST_AUTO_TEST_CASE( evaluate_constraint ) BOOST_AUTO_TEST_CASE(contain_constraint_with_const_char_ptr)
{ {
BOOST_CHECK( mock::evaluate.c_( &return_true ) ); BOOST_CHECK(mock::contain("string").c_("this is a string"));
BOOST_CHECK( ! mock::evaluate.c_( &return_false ) ); BOOST_CHECK(mock::contain("string").c_(std::string("this is a string")));
} BOOST_CHECK(!mock::contain("not found").c_("this is a string"));
BOOST_CHECK(!mock::contain("not found").c_(std::string("this is a string")));
BOOST_AUTO_TEST_CASE( contain_constraint_with_const_char_ptr )
{
BOOST_CHECK( mock::contain( "string" ).c_( "this is a string" ) );
BOOST_CHECK( mock::contain( "string" ).c_( std::string( "this is a string" ) ) );
BOOST_CHECK( ! mock::contain( "not found" ).c_( "this is a string" ) );
BOOST_CHECK( ! mock::contain( "not found" ).c_( std::string( "this is a string" ) ) );
{ {
const char* s = 0; const char* s = 0;
mock::constraint< mock::constraint<mock::detail::contain<boost::reference_wrapper<const char* const>>> c =
mock::detail::contain< mock::contain(boost::cref(s));
boost::reference_wrapper< const char* const >
>
> c = mock::contain( boost::cref( s ) );
s = "string"; s = "string";
BOOST_CHECK( c.c_( "this is a string" ) ); BOOST_CHECK(c.c_("this is a string"));
BOOST_CHECK( c.c_( std::string( "this is a string" ) ) ); BOOST_CHECK(c.c_(std::string("this is a string")));
s = "not found"; s = "not found";
BOOST_CHECK( ! c.c_( "this is a string" ) ); BOOST_CHECK(!c.c_("this is a string"));
BOOST_CHECK( ! c.c_( std::string( "this is a string" ) ) ); BOOST_CHECK(!c.c_(std::string("this is a string")));
} }
} }
BOOST_AUTO_TEST_CASE( contain_constraint_with_strings ) BOOST_AUTO_TEST_CASE(contain_constraint_with_strings)
{ {
BOOST_CHECK( mock::contain( std::string( "string" ) ).c_( "this is a string" ) ); BOOST_CHECK(mock::contain(std::string("string")).c_("this is a string"));
BOOST_CHECK( mock::contain( std::string( "string" ) ).c_( std::string( "this is a string" ) ) ); BOOST_CHECK(mock::contain(std::string("string")).c_(std::string("this is a string")));
BOOST_CHECK( ! mock::contain( std::string( "not found" ) ).c_( "this is a string" ) ); BOOST_CHECK(!mock::contain(std::string("not found")).c_("this is a string"));
BOOST_CHECK( ! mock::contain( std::string( "not found" ) ).c_( std::string( "this is a string" ) ) ); BOOST_CHECK(!mock::contain(std::string("not found")).c_(std::string("this is a string")));
{ {
std::string s; std::string s;
mock::constraint< mock::constraint<mock::detail::contain<boost::reference_wrapper<const std::string>>> c =
mock::detail::contain< mock::contain(boost::cref(s));
boost::reference_wrapper< const std::string >
>
> c = mock::contain( boost::cref( s ) );
s = "string"; s = "string";
BOOST_CHECK( c.c_( "this is a string" ) ); BOOST_CHECK(c.c_("this is a string"));
BOOST_CHECK( c.c_( std::string( "this is a string" ) ) ); BOOST_CHECK(c.c_(std::string("this is a string")));
s = "not found"; s = "not found";
BOOST_CHECK( ! c.c_( "this is a string" ) ); BOOST_CHECK(!c.c_("this is a string"));
BOOST_CHECK( ! c.c_( std::string( "this is a string" ) ) ); BOOST_CHECK(!c.c_(std::string("this is a string")));
} }
} }
namespace namespace {
struct type_with_overloaded_address_operator
{ {
struct type_with_overloaded_address_operator void operator&() {}
{ void operator&() const {}
void operator&() {} };
void operator&() const {} } // namespace
};
}
BOOST_AUTO_TEST_CASE( type_with_overloaded_address_operator_can_be_used_in_constraints ) BOOST_AUTO_TEST_CASE(type_with_overloaded_address_operator_can_be_used_in_constraints)
{ {
type_with_overloaded_address_operator t; type_with_overloaded_address_operator t;
mock::same( t ).c_( t ); mock::same(t).c_(t);
mock::retrieve( t ).c_( t ); mock::retrieve(t).c_(t);
type_with_overloaded_address_operator* pt; type_with_overloaded_address_operator* pt;
mock::retrieve( pt ).c_( t ); mock::retrieve(pt).c_(t);
} }
BOOST_AUTO_TEST_CASE( close_constraint ) BOOST_AUTO_TEST_CASE(close_constraint)
{ {
BOOST_CHECK( mock::close( 12.0, 0.0001 ).c_( 12 ) ); BOOST_CHECK(mock::close(12.0, 0.0001).c_(12));
BOOST_CHECK( ! mock::close( 12.0, 0.0001 ).c_( 13 ) ); BOOST_CHECK(!mock::close(12.0, 0.0001).c_(13));
} }
BOOST_AUTO_TEST_CASE( close_fraction_constraint ) BOOST_AUTO_TEST_CASE(close_fraction_constraint)
{ {
BOOST_CHECK( mock::close_fraction( 12.0, 0.0001 ).c_( 12 ) ); BOOST_CHECK(mock::close_fraction(12.0, 0.0001).c_(12));
BOOST_CHECK( ! mock::close_fraction( 12.0, 0.0001 ).c_( 13 ) ); BOOST_CHECK(!mock::close_fraction(12.0, 0.0001).c_(13));
} }
BOOST_AUTO_TEST_CASE( small_constraint ) BOOST_AUTO_TEST_CASE(small_constraint)
{ {
BOOST_CHECK( mock::small( 0.0001 ).c_( 0. ) ); BOOST_CHECK(mock::small(0.0001).c_(0.));
BOOST_CHECK( ! mock::small( 0.0001 ).c_( 12. ) ); BOOST_CHECK(!mock::small(0.0001).c_(12.));
} }
BOOST_AUTO_TEST_CASE( near_constraint ) BOOST_AUTO_TEST_CASE(near_constraint)
{ {
BOOST_CHECK( mock::near( 12.0, 0.0001 ).c_( 12 ) ); BOOST_CHECK(mock::near(12.0, 0.0001).c_(12));
BOOST_CHECK( ! mock::near( 12.0, 0.0001 ).c_( 13 ) ); BOOST_CHECK(!mock::near(12.0, 0.0001).c_(13));
} }

View file

@ -10,16 +10,14 @@
#include <turtle/exception.hpp> #include <turtle/exception.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
BOOST_AUTO_TEST_CASE( a_mock_exception_is_not_an_std_exception_to_not_mess_with_user_exceptions ) BOOST_AUTO_TEST_CASE(a_mock_exception_is_not_an_std_exception_to_not_mess_with_user_exceptions)
{ {
try try
{ {
throw mock::exception(); throw mock::exception();
} } catch(std::exception&)
catch( std::exception& )
{ {
BOOST_FAIL( "mock::exception must not be an std::exception" ); BOOST_FAIL("mock::exception must not be an std::exception");
} } catch(mock::exception&)
catch( mock::exception& )
{} {}
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,70 +9,66 @@
#include <turtle/detail/function.hpp> #include <turtle/detail/function.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
namespace namespace {
template<typename Expected, typename Actual>
bool match(Expected expected, Actual actual)
{ {
template< typename Expected, typename Actual > return mock::matcher<Actual, Expected>(expected)(actual);
bool match( Expected expected, Actual actual ) }
{ } // namespace
return mock::matcher< Actual, Expected >( expected )( actual );
} BOOST_AUTO_TEST_CASE(int_and_int_can_be_compared)
{
BOOST_CHECK(match(3, 3));
BOOST_CHECK(!match(3, 4));
BOOST_CHECK(!match(4, 3));
} }
BOOST_AUTO_TEST_CASE( int_and_int_can_be_compared ) BOOST_AUTO_TEST_CASE(ref_to_int_and_int_can_be_compared)
{
BOOST_CHECK( match( 3, 3 ) );
BOOST_CHECK( ! match( 3, 4 ) );
BOOST_CHECK( ! match( 4, 3 ) );
}
BOOST_AUTO_TEST_CASE( ref_to_int_and_int_can_be_compared )
{ {
const int i = 3; const int i = 3;
BOOST_CHECK( match( 3, boost::cref( i ) ) ); BOOST_CHECK(match(3, boost::cref(i)));
BOOST_CHECK( ! match( 4, boost::cref( i ) ) ); BOOST_CHECK(!match(4, boost::cref(i)));
} }
namespace namespace {
struct fixture
{ {
struct fixture fixture() : text("same text"), actual(text.c_str())
{ {
fixture() const char* static_string = "same text";
: text( "same text" ) BOOST_REQUIRE(actual != static_string);
, actual( text.c_str() ) BOOST_REQUIRE(actual == std::string(static_string));
{ }
const char* static_string = "same text"; std::string text;
BOOST_REQUIRE( actual != static_string ); const char* actual;
BOOST_REQUIRE( actual == std::string( static_string ) ); };
} } // namespace
std::string text;
const char* actual;
};
}
BOOST_FIXTURE_TEST_CASE( const_char_pointer_and_const_char_pointer_can_be_compared, fixture ) BOOST_FIXTURE_TEST_CASE(const_char_pointer_and_const_char_pointer_can_be_compared, fixture)
{ {
const char* expected = "same text"; const char* expected = "same text";
BOOST_CHECK( match( expected, actual ) ); BOOST_CHECK(match(expected, actual));
const char* unexpected = "different text"; const char* unexpected = "different text";
BOOST_CHECK( ! match( actual, unexpected ) ); BOOST_CHECK(!match(actual, unexpected));
} }
BOOST_FIXTURE_TEST_CASE( const_char_pointer_and_string_literal_can_be_compared, fixture ) BOOST_FIXTURE_TEST_CASE(const_char_pointer_and_string_literal_can_be_compared, fixture)
{ {
BOOST_CHECK( match( "same text", actual ) ); BOOST_CHECK(match("same text", actual));
BOOST_CHECK( ! match( "different text", actual ) ); BOOST_CHECK(!match("different text", actual));
} }
BOOST_FIXTURE_TEST_CASE( const_char_pointer_and_const_char_array_can_be_compared, fixture ) BOOST_FIXTURE_TEST_CASE(const_char_pointer_and_const_char_array_can_be_compared, fixture)
{ {
const char expected[10] = "same text"; const char expected[10] = "same text";
BOOST_CHECK( match( expected, actual ) ); BOOST_CHECK(match(expected, actual));
const char unexpected[15] = "different text"; const char unexpected[15] = "different text";
BOOST_CHECK( ! match( unexpected, actual ) ); BOOST_CHECK(!match(unexpected, actual));
} }
BOOST_FIXTURE_TEST_CASE( const_char_pointer_and_std_string_can_be_compared, fixture ) BOOST_FIXTURE_TEST_CASE(const_char_pointer_and_std_string_can_be_compared, fixture)
{ {
BOOST_CHECK( match( std::string( "same text" ), actual ) ); BOOST_CHECK(match(std::string("same text"), actual));
BOOST_CHECK( ! match( std::string( "different text" ), actual ) ); BOOST_CHECK(!match(std::string("different text"), actual));
} }

View file

@ -8,32 +8,31 @@
#include "mock_error.hpp" #include "mock_error.hpp"
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/repetition/enum.hpp>
#include <boost/test/auto_unit_test.hpp>
#define IDENTITY(z, n, d) d #define IDENTITY(z, n, d) d
namespace namespace {
struct my_custom_mock
{ {
struct my_custom_mock MOCK_METHOD_EXT(method, MOCK_MAX_ARGS, void(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, int)), tag)
{ MOCK_METHOD_EXT(method2, MOCK_MAX_ARGS, int(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, int)), tag_2)
MOCK_METHOD_EXT( method, MOCK_MAX_ARGS, void( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, int) ), tag ) };
MOCK_METHOD_EXT( method2, MOCK_MAX_ARGS, int( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, int) ), tag_2 ) } // namespace
};
}
BOOST_FIXTURE_TEST_CASE( call_mock_method_with_max_number_of_args, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(call_mock_method_with_max_number_of_args, mock_error_fixture)
{ {
my_custom_mock m; my_custom_mock m;
MOCK_EXPECT( m.tag ).once().with( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0) ); MOCK_EXPECT(m.tag).once().with(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0));
m.method( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0) ); m.method(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0));
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
BOOST_FIXTURE_TEST_CASE( call_mock_method_with_max_number_of_args_and_a_return_value, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(call_mock_method_with_max_number_of_args_and_a_return_value, mock_error_fixture)
{ {
my_custom_mock m; my_custom_mock m;
MOCK_EXPECT( m.tag_2 ).once().with( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0) ).returns( 42 ); MOCK_EXPECT(m.tag_2).once().with(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0)).returns(42);
BOOST_CHECK_EQUAL( 42, m.method2( BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0) ) ); BOOST_CHECK_EQUAL(42, m.method2(BOOST_PP_ENUM(MOCK_MAX_ARGS, IDENTITY, 0)));
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }

View file

@ -8,461 +8,385 @@
#include "mock_error.hpp" #include "mock_error.hpp"
#include <turtle/mock.hpp> #include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
template<typename T>
void my_function(T& t)
{ {
template< typename T > t.my_method("some parameter");
void my_function( T& t )
{
t.my_method( "some parameter" );
}
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( my_method, 1, void( const std::string& ), my_tag )
};
} }
MOCK_CLASS(mock_class){MOCK_METHOD_EXT(my_method, 1, void(const std::string&), my_tag)};
} // namespace
BOOST_FIXTURE_TEST_CASE( mock_object_for_static_polymorphism, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_for_static_polymorphism, mock_error_fixture)
{ {
const mock_class m; const mock_class m;
MOCK_EXPECT( m.my_tag ).once().with( "some parameter" ); MOCK_EXPECT(m.my_tag).once().with("some parameter");
my_function( m ); my_function(m);
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
{ MOCK_CLASS(mock_class_with_operator){MOCK_CONST_METHOD_EXT(operator+=, 1, mock_class_with_operator &(int), addition)};
MOCK_CLASS( mock_class_with_operator )
{
MOCK_CONST_METHOD_EXT( operator+=, 1, mock_class_with_operator&( int ), addition )
};
} }
BOOST_FIXTURE_TEST_CASE( mock_addition_operator, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_addition_operator, mock_error_fixture)
{ {
mock_class_with_operator m; mock_class_with_operator m;
MOCK_EXPECT( m.addition ).once().returns( boost::ref( m ) ); MOCK_EXPECT(m.addition).once().returns(boost::ref(m));
m += 1; m += 1;
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
{ MOCK_CLASS(mock_class_with_conversion_operator){MOCK_CONVERSION_OPERATOR(operator, int, conversion)};
MOCK_CLASS( mock_class_with_conversion_operator )
{
MOCK_CONVERSION_OPERATOR( operator, int, conversion )
};
} }
BOOST_FIXTURE_TEST_CASE( mock_conversion_operator, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_conversion_operator, mock_error_fixture)
{ {
mock_class_with_conversion_operator m; mock_class_with_conversion_operator m;
MOCK_EXPECT( m.conversion ).once().returns( 42 ); MOCK_EXPECT(m.conversion).once().returns(42);
BOOST_CHECK_EQUAL( 42, static_cast< int >( m ) ); BOOST_CHECK_EQUAL(42, static_cast<int>(m));
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
template<typename T>
MOCK_CLASS(mock_template_class_with_conversion_operator){MOCK_CONVERSION_OPERATOR_TPL(operator, T, conversion)};
}
BOOST_FIXTURE_TEST_CASE(mock_template_conversion_operator, mock_error_fixture)
{ {
template< typename T > mock_template_class_with_conversion_operator<int> m;
MOCK_CLASS( mock_template_class_with_conversion_operator ) MOCK_EXPECT(m.conversion).once().returns(42);
{ BOOST_CHECK_EQUAL(42, static_cast<int>(m));
MOCK_CONVERSION_OPERATOR_TPL( operator, T, conversion ) CHECK_CALLS(1);
};
} }
BOOST_FIXTURE_TEST_CASE( mock_template_conversion_operator, mock_error_fixture ) namespace {
{ MOCK_CLASS(mock_class_with_const_conversion_operator){MOCK_CONST_CONVERSION_OPERATOR(operator, int, conversion)};
mock_template_class_with_conversion_operator< int > m;
MOCK_EXPECT( m.conversion ).once().returns( 42 );
BOOST_CHECK_EQUAL( 42, static_cast< int >( m ) );
CHECK_CALLS( 1 );
} }
namespace BOOST_FIXTURE_TEST_CASE(mock_const_conversion_operator, mock_error_fixture)
{
MOCK_CLASS( mock_class_with_const_conversion_operator )
{
MOCK_CONST_CONVERSION_OPERATOR( operator, int, conversion )
};
}
BOOST_FIXTURE_TEST_CASE( mock_const_conversion_operator, mock_error_fixture )
{ {
mock_class_with_const_conversion_operator m; mock_class_with_const_conversion_operator m;
MOCK_EXPECT( m.conversion ).once().returns( 42 ); MOCK_EXPECT(m.conversion).once().returns(42);
int i = m; int i = m;
BOOST_CHECK_EQUAL( 42, i ); BOOST_CHECK_EQUAL(42, i);
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
{ MOCK_CLASS(mock_class_with_non_const_conversion_operator){MOCK_CONST_CONVERSION_OPERATOR(operator, int, conversion)};
MOCK_CLASS( mock_class_with_non_const_conversion_operator )
{
MOCK_CONST_CONVERSION_OPERATOR( operator, int, conversion )
};
} }
BOOST_FIXTURE_TEST_CASE( mock_non_const_conversion_operator, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_non_const_conversion_operator, mock_error_fixture)
{ {
mock_class_with_non_const_conversion_operator m; mock_class_with_non_const_conversion_operator m;
MOCK_EXPECT( m.conversion ).once().returns( 42 ); MOCK_EXPECT(m.conversion).once().returns(42);
int i = m; int i = m;
BOOST_CHECK_EQUAL( 42, i ); BOOST_CHECK_EQUAL(42, i);
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
template<typename T>
MOCK_CLASS(mock_template_class_with_const_conversion_operator){
MOCK_CONST_CONVERSION_OPERATOR_TPL(operator, T, conversion)};
}
BOOST_FIXTURE_TEST_CASE(mock_template_const_conversion_operator, mock_error_fixture)
{ {
template< typename T > mock_template_class_with_const_conversion_operator<int> m;
MOCK_CLASS( mock_template_class_with_const_conversion_operator ) MOCK_EXPECT(m.conversion).once().returns(42);
{ BOOST_CHECK_EQUAL(42, static_cast<int>(m));
MOCK_CONST_CONVERSION_OPERATOR_TPL( operator, T, conversion ) CHECK_CALLS(1);
};
} }
BOOST_FIXTURE_TEST_CASE( mock_template_const_conversion_operator, mock_error_fixture ) namespace {
template<typename T>
MOCK_CLASS(mock_template_class_with_non_const_conversion_operator){
MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(operator, T, conversion)};
}
BOOST_FIXTURE_TEST_CASE(mock_template_non_const_conversion_operator, mock_error_fixture)
{ {
mock_template_class_with_const_conversion_operator< int > m; mock_template_class_with_non_const_conversion_operator<int> m;
MOCK_EXPECT( m.conversion ).once().returns( 42 ); MOCK_EXPECT(m.conversion).once().returns(42);
BOOST_CHECK_EQUAL( 42, static_cast< int >( m ) ); BOOST_CHECK_EQUAL(42, static_cast<int>(m));
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
{ MOCK_CLASS(my_mock){MOCK_CONST_METHOD_EXT(my_method, 1, void(int), my_method)
template< typename T > MOCK_CONST_METHOD_EXT(my_method_2, 1, void(int), my_method_2)};
MOCK_CLASS( mock_template_class_with_non_const_conversion_operator )
{
MOCK_NON_CONST_CONVERSION_OPERATOR_TPL( operator, T, conversion )
};
} }
BOOST_FIXTURE_TEST_CASE( mock_template_non_const_conversion_operator, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(MOCK_CONST_METHOD_EXT_macro_defines_a_bindable_method, mock_error_fixture)
{
mock_template_class_with_non_const_conversion_operator< int > m;
MOCK_EXPECT( m.conversion ).once().returns( 42 );
BOOST_CHECK_EQUAL( 42, static_cast< int >( m ) );
CHECK_CALLS( 1 );
}
namespace
{
MOCK_CLASS( my_mock )
{
MOCK_CONST_METHOD_EXT( my_method, 1, void( int ), my_method )
MOCK_CONST_METHOD_EXT( my_method_2, 1, void( int ), my_method_2 )
};
}
BOOST_FIXTURE_TEST_CASE( MOCK_CONST_METHOD_EXT_macro_defines_a_bindable_method, mock_error_fixture )
{ {
my_mock m; my_mock m;
boost::bind( &my_mock::my_method, &m, 42 ); boost::bind(&my_mock::my_method, &m, 42);
} }
BOOST_FIXTURE_TEST_CASE( MOCK_VERIFY_macro, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(MOCK_VERIFY_macro, mock_error_fixture)
{ {
my_mock m; my_mock m;
MOCK_VERIFY( m.my_method ); MOCK_VERIFY(m.my_method);
} }
BOOST_FIXTURE_TEST_CASE( MOCK_RESET_macro, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(MOCK_RESET_macro, mock_error_fixture)
{ {
my_mock m; my_mock m;
MOCK_RESET( m.my_method ); MOCK_RESET(m.my_method);
} }
BOOST_FIXTURE_TEST_CASE( MOCK_EXPECT_macro, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(MOCK_EXPECT_macro, mock_error_fixture)
{ {
my_mock m; my_mock m;
MOCK_EXPECT( m.my_method ).once().with( 42 ); MOCK_EXPECT(m.my_method).once().with(42);
m.my_method( 42 ); m.my_method(42);
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
namespace namespace {
template<typename T>
std::string to_string(const T& t)
{ {
template< typename T > std::stringstream s;
std::string to_string( const T& t ) s << t;
{ return s.str();
std::stringstream s;
s << t;
return s.str();
}
} }
} // namespace
BOOST_FIXTURE_TEST_CASE( mock_object_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_is_named, mock_error_fixture)
{ {
my_mock m; my_mock m;
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m.my_method ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m.my_method)));
BOOST_CHECK_EQUAL( "?.my_mock::my_method_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_method_2 ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_method_2)));
BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_HELPER( m.my_method ) ) ); BOOST_CHECK_EQUAL("m.my_mock::my_method", to_string(MOCK_HELPER(m.my_method)));
BOOST_CHECK_EQUAL( "m.my_mock::my_method_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_method_2 ) ) ); BOOST_CHECK_EQUAL("m.my_mock::my_method_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_method_2)));
BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m.my_method ) ) ); BOOST_CHECK_EQUAL("m.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m.my_method)));
BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_HELPER( m.my_method ) ) ); BOOST_CHECK_EQUAL("m.my_mock::my_method", to_string(MOCK_HELPER(m.my_method)));
} }
#ifdef MOCK_AUTO_PTR #ifdef MOCK_AUTO_PTR
BOOST_FIXTURE_TEST_CASE( mock_object_auto_pointer_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_auto_pointer_is_named, mock_error_fixture)
{ {
std::auto_ptr< my_mock > m( new my_mock ); std::auto_ptr<my_mock> m(new my_mock);
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
} }
BOOST_FIXTURE_TEST_CASE( mock_object_const_auto_pointer_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_const_auto_pointer_is_named, mock_error_fixture)
{ {
const std::auto_ptr< my_mock > m( new my_mock ); const std::auto_ptr<my_mock> m(new my_mock);
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
} }
#endif // MOCK_AUTO_PTR #endif // MOCK_AUTO_PTR
BOOST_FIXTURE_TEST_CASE( mock_object_shared_pointer_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_shared_pointer_is_named, mock_error_fixture)
{ {
boost::shared_ptr< my_mock > m( new my_mock ); boost::shared_ptr<my_mock> m(new my_mock);
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
} }
BOOST_FIXTURE_TEST_CASE( mock_object_const_shared_pointer_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_object_const_shared_pointer_is_named, mock_error_fixture)
{ {
const boost::shared_ptr< my_mock > m( new my_mock ); const boost::shared_ptr<my_mock> m(new my_mock);
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("?.my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_ANONYMOUS_HELPER(m->my_method)));
BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_HELPER( m->my_method ) ) ); BOOST_CHECK_EQUAL("m->my_mock::my_method", to_string(MOCK_HELPER(m->my_method)));
} }
namespace namespace {
struct my_custom_mock
{ {
struct my_custom_mock MOCK_METHOD_EXT(my_method, 0, void(), my_tag)
{ MOCK_METHOD_EXT(my_method_2, 0, void(), my_tag_2)
MOCK_METHOD_EXT( my_method, 0, void(), my_tag ) };
MOCK_METHOD_EXT( my_method_2, 0, void(), my_tag_2 ) } // namespace
};
}
BOOST_FIXTURE_TEST_CASE( custom_mock_object_without_macros_and_without_inheriting_from_object_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(custom_mock_object_without_macros_and_without_inheriting_from_object_is_named,
mock_error_fixture)
{ {
my_custom_mock m; my_custom_mock m;
BOOST_CHECK_EQUAL( "?.my_custom_mock::my_tag", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("?.my_custom_mock::my_tag", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "?.my_custom_mock::my_tag_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag_2 ) ) ); BOOST_CHECK_EQUAL("?.my_custom_mock::my_tag_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag_2)));
BOOST_CHECK_EQUAL( "m.my_custom_mock::my_tag", to_string( MOCK_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock::my_tag", to_string(MOCK_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "m.my_custom_mock::my_tag_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag_2 ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock::my_tag_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag_2)));
BOOST_CHECK_EQUAL( "m.my_custom_mock::my_tag", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock::my_tag", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "m.my_custom_mock::my_tag", to_string( MOCK_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock::my_tag", to_string(MOCK_HELPER(m.my_tag)));
} }
namespace namespace {
struct my_custom_mock_object : mock::object
{ {
struct my_custom_mock_object : mock::object MOCK_METHOD_EXT(my_method, 0, void(), my_tag)
{ MOCK_METHOD_EXT(my_method_2, 0, void(), my_tag_2)
MOCK_METHOD_EXT( my_method, 0, void(), my_tag ) };
MOCK_METHOD_EXT( my_method_2, 0, void(), my_tag_2 ) } // namespace
};
}
BOOST_FIXTURE_TEST_CASE( custom_mock_object_without_macros_is_named, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(custom_mock_object_without_macros_is_named, mock_error_fixture)
{ {
my_custom_mock_object m; my_custom_mock_object m;
BOOST_CHECK_EQUAL( "?.my_custom_mock_object::my_tag", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("?.my_custom_mock_object::my_tag", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "?.my_custom_mock_object::my_tag_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag_2 ) ) ); BOOST_CHECK_EQUAL("?.my_custom_mock_object::my_tag_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag_2)));
BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_tag", to_string( MOCK_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock_object::my_tag", to_string(MOCK_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_tag_2", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag_2 ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock_object::my_tag_2", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag_2)));
BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_tag", to_string( MOCK_ANONYMOUS_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock_object::my_tag", to_string(MOCK_ANONYMOUS_HELPER(m.my_tag)));
BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_tag", to_string( MOCK_HELPER( m.my_tag ) ) ); BOOST_CHECK_EQUAL("m.my_custom_mock_object::my_tag", to_string(MOCK_HELPER(m.my_tag)));
} }
BOOST_FIXTURE_TEST_CASE( mock_functor, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_functor, mock_error_fixture)
{ {
MOCK_FUNCTOR( f1, void() ); MOCK_FUNCTOR(f1, void());
MOCK_FUNCTOR( f2, int( const std::string& ) ); MOCK_FUNCTOR(f2, int(const std::string&));
} }
namespace namespace {
template<typename T>
struct tpl_functor_class
{ {
template< typename T > MOCK_FUNCTOR_TPL(f, void(T));
struct tpl_functor_class };
{ } // namespace
MOCK_FUNCTOR_TPL( f, void( T ) );
}; BOOST_FIXTURE_TEST_CASE(mock_functor_reset, mock_error_fixture)
{
MOCK_FUNCTOR(f, void());
MOCK_RESET(f);
mock::reset(f);
} }
BOOST_FIXTURE_TEST_CASE( mock_functor_reset, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_functor_verify, mock_error_fixture)
{ {
MOCK_FUNCTOR( f, void() ); MOCK_FUNCTOR(f, void());
MOCK_RESET( f ); MOCK_VERIFY(f);
mock::reset( f ); mock::verify(f);
} }
BOOST_FIXTURE_TEST_CASE( mock_functor_verify, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(mock_functor_is_named, mock_error_fixture)
{ {
MOCK_FUNCTOR( f, void() ); MOCK_FUNCTOR(f, void());
MOCK_VERIFY( f ); BOOST_CHECK_EQUAL("f", to_string(MOCK_HELPER(f)));
mock::verify( f );
} }
BOOST_FIXTURE_TEST_CASE( mock_functor_is_named, mock_error_fixture ) namespace {
{ MOCK_FUNCTION(mock_function, 1, float(int), mock_function)
MOCK_FUNCTOR( f, void() );
BOOST_CHECK_EQUAL( "f", to_string( MOCK_HELPER( f ) ) );
} }
namespace BOOST_FIXTURE_TEST_CASE(mock_function_is_named, mock_error_fixture)
{ {
MOCK_FUNCTION( mock_function, 1, float( int ), mock_function ) BOOST_CHECK_EQUAL("mock_function", to_string(MOCK_HELPER(mock_function)));
} }
BOOST_FIXTURE_TEST_CASE( mock_function_is_named, mock_error_fixture ) namespace {
{ MOCK_CLASS(static_function_class){MOCK_STATIC_METHOD(f, 1, float(int), f)};
BOOST_CHECK_EQUAL( "mock_function", to_string( MOCK_HELPER( mock_function ) ) );
} }
namespace BOOST_FIXTURE_TEST_CASE(mock_static_function_is_named, mock_error_fixture)
{ {
MOCK_CLASS( static_function_class ) BOOST_CHECK_EQUAL("static_function_class::f", to_string(MOCK_HELPER(static_function_class::f)));
{
MOCK_STATIC_METHOD( f, 1, float( int ), f )
};
} }
BOOST_FIXTURE_TEST_CASE( mock_static_function_is_named, mock_error_fixture ) namespace {
MOCK_CLASS(round_parenthesized_signature)
{ {
BOOST_CHECK_EQUAL( "static_function_class::f", to_string( MOCK_HELPER( static_function_class::f ) ) ); MOCK_METHOD_EXT(m0, 0, BOOST_IDENTITY_TYPE((std::map<int, int>())), m0)
} MOCK_STATIC_METHOD(m1, 0, BOOST_IDENTITY_TYPE((std::map<int, int>())), m1)
MOCK_FUNCTOR(f0, BOOST_IDENTITY_TYPE((std::map<int, int>())));
namespace };
{ MOCK_FUNCTION(fun0, 0, BOOST_IDENTITY_TYPE((std::map<int, int>())), fun0)
MOCK_CLASS( round_parenthesized_signature ) } // namespace
{
MOCK_METHOD_EXT( m0, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())), m0 )
MOCK_STATIC_METHOD( m1, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())), m1 )
MOCK_FUNCTOR( f0, BOOST_IDENTITY_TYPE((std::map< int, int >())) );
};
MOCK_FUNCTION( fun0, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())), fun0 )
}
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
namespace namespace {
struct base
{ {
struct base virtual ~base() {}
{
virtual ~base()
{}
virtual void m1() = 0; virtual void m1() = 0;
virtual void m10() const = 0; virtual void m10() const = 0;
virtual void m11() = 0; virtual void m11() = 0;
}; };
MOCK_BASE_CLASS( variadic, base ) MOCK_BASE_CLASS(variadic, base){MOCK_METHOD(m1, 0) MOCK_METHOD(m2, 0, void()) MOCK_METHOD(m3, 0, void(), m3)
{ MOCK_CONST_METHOD(m10, 0) MOCK_CONST_METHOD(m4, 0, void())
MOCK_METHOD( m1, 0 ) MOCK_CONST_METHOD(m5, 0, void(), m5) MOCK_NON_CONST_METHOD(m11, 0)
MOCK_METHOD( m2, 0, void() ) MOCK_NON_CONST_METHOD(m6, 0, void()) MOCK_NON_CONST_METHOD(m7, 0, void(), m7)
MOCK_METHOD( m3, 0, void(), m3 ) MOCK_STATIC_METHOD(m8, 0, void()) MOCK_STATIC_METHOD(m9, 0, void(), m9)};
MOCK_CONST_METHOD( m10, 0 )
MOCK_CONST_METHOD( m4, 0, void() )
MOCK_CONST_METHOD( m5, 0, void(), m5 )
MOCK_NON_CONST_METHOD( m11, 0 )
MOCK_NON_CONST_METHOD( m6, 0, void() )
MOCK_NON_CONST_METHOD( m7, 0, void(), m7 )
MOCK_STATIC_METHOD( m8, 0, void() )
MOCK_STATIC_METHOD( m9, 0, void(), m9 )
};
template< typename T > template<typename T>
MOCK_BASE_CLASS( variadic_tpl, base ) MOCK_BASE_CLASS(variadic_tpl, base){MOCK_METHOD(m1, 0, void()) MOCK_METHOD_TPL(m2, 0, T())
{ MOCK_METHOD_TPL(m3, 0, T(), m3) MOCK_CONST_METHOD_TPL(m4, 0, T())
MOCK_METHOD( m1, 0, void() ) MOCK_CONST_METHOD_TPL(m5, 0, T(), m5) MOCK_NON_CONST_METHOD_TPL(m6, 0, T())
MOCK_METHOD_TPL( m2, 0, T() ) MOCK_NON_CONST_METHOD_TPL(m7, 0, T(), m7) MOCK_STATIC_METHOD_TPL(m8, 0, T())
MOCK_METHOD_TPL( m3, 0, T(), m3 ) MOCK_STATIC_METHOD_TPL(m9, 0, T(), m9)};
MOCK_CONST_METHOD_TPL( m4, 0, T() )
MOCK_CONST_METHOD_TPL( m5, 0, T(), m5 )
MOCK_NON_CONST_METHOD_TPL( m6, 0, T() )
MOCK_NON_CONST_METHOD_TPL( m7, 0, T(), m7 )
MOCK_STATIC_METHOD_TPL( m8, 0, T() )
MOCK_STATIC_METHOD_TPL( m9, 0, T(), m9 )
};
MOCK_BASE_CLASS( comma_base, std::map< int, int > ) MOCK_BASE_CLASS(comma_base, std::map<int, int>){};
{};
MOCK_FUNCTION( fun1, 0, void() ) MOCK_FUNCTION(fun1, 0, void())
MOCK_FUNCTION( fun2, 0, void(), fun2 ) MOCK_FUNCTION(fun2, 0, void(), fun2)
MOCK_FUNCTION( fun3, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())) ) MOCK_FUNCTION(fun3, 0, BOOST_IDENTITY_TYPE((std::map<int, int>())))
MOCK_FUNCTOR( f_variadic, std::map< int, int >() ); MOCK_FUNCTOR(f_variadic, std::map<int, int>());
} } // namespace
#else // MOCK_VARIADIC_MACROS #else // MOCK_VARIADIC_MACROS
namespace namespace {
struct base
{ {
struct base virtual ~base() {}
{
virtual ~base()
{}
virtual void m1() = 0; virtual void m1() = 0;
}; };
MOCK_BASE_CLASS( derived, base ) MOCK_BASE_CLASS(derived, base){MOCK_METHOD(m1, 0)};
{
MOCK_METHOD( m1, 0 )
};
template< typename T > template<typename T>
MOCK_BASE_CLASS( derived_tpl, base ) MOCK_BASE_CLASS(derived_tpl, base){MOCK_METHOD_EXT(m1, 0, void(), m1)};
{ } // namespace
MOCK_METHOD_EXT( m1, 0, void(), m1 )
};
}
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
# define MOCK_STDCALL __stdcall # define MOCK_STDCALL __stdcall
#else #else
# define MOCK_STDCALL # define MOCK_STDCALL
#endif #endif
namespace stdcall namespace stdcall {
struct base
{ {
struct base virtual ~base() {}
{
virtual ~base()
{}
virtual void MOCK_STDCALL m1() = 0; virtual void MOCK_STDCALL m1() = 0;
}; };
MOCK_BASE_CLASS( derived, base ) MOCK_BASE_CLASS(derived, base){
{ MOCK_CONSTRUCTOR(MOCK_STDCALL derived, 0, (), derived) MOCK_DESTRUCTOR(MOCK_STDCALL ~derived, derived)
MOCK_CONSTRUCTOR( MOCK_STDCALL derived, 0, (), derived ) MOCK_CONVERSION_OPERATOR(MOCK_STDCALL operator, int, to_int) MOCK_METHOD_EXT(MOCK_STDCALL m1, 0, void(), m1)
MOCK_DESTRUCTOR( MOCK_STDCALL ~derived, derived ) MOCK_METHOD_EXT(MOCK_STDCALL m2, 0, void(), m2)
MOCK_CONVERSION_OPERATOR( MOCK_STDCALL operator, int, to_int )
MOCK_METHOD_EXT( MOCK_STDCALL m1, 0, void(), m1 )
MOCK_METHOD_EXT( MOCK_STDCALL m2, 0, void(), m2 )
#ifdef MOCK_VARIADIC_MACROS #ifdef MOCK_VARIADIC_MACROS
MOCK_METHOD( MOCK_STDCALL m3, 0, void(), m3 ) MOCK_METHOD(MOCK_STDCALL m3, 0, void(), m3)
#endif #endif
MOCK_STATIC_METHOD( MOCK_STDCALL m4, 0, void(), m4 ) MOCK_STATIC_METHOD(MOCK_STDCALL m4, 0, void(), m4)};
};
MOCK_FUNCTION( MOCK_STDCALL f, 0, void(), f ) MOCK_FUNCTION(MOCK_STDCALL f, 0, void(), f)
} } // namespace stdcall

View file

@ -7,102 +7,81 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include "mock_error.hpp" #include "mock_error.hpp"
#include <turtle/detail/function.hpp>
#include <turtle/reset.hpp> #include <turtle/reset.hpp>
#include <turtle/verify.hpp> #include <turtle/verify.hpp>
#include <turtle/detail/function.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/test/auto_unit_test.hpp>
namespace namespace {
{ struct object : mock::object
struct object : mock::object {};
{};
object static_o; object static_o;
} } // namespace
BOOST_FIXTURE_TEST_CASE( verifying_an_empty_object_succeeds, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(verifying_an_empty_object_succeeds, mock_error_fixture)
{ {
object o; object o;
BOOST_CHECK( mock::verify( o ) ); BOOST_CHECK(mock::verify(o));
} }
namespace namespace {
struct fixture : mock_error_fixture
{ {
struct fixture : mock_error_fixture fixture() { mock::detail::configure(o, e, "instance", MOCK_TYPE_NAME(o), "name"); }
{ object o;
fixture() mock::detail::function<void()> e;
{ };
mock::detail::configure( o, e, "instance", MOCK_TYPE_NAME(o), "name" ); } // namespace
}
object o;
mock::detail::function< void() > e;
};
}
BOOST_FIXTURE_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails, fixture ) BOOST_FIXTURE_TEST_CASE(verifying_an_object_containing_a_failing_expectation_fails, fixture)
{ {
e.expect().once(); e.expect().once();
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify(o)), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify( o ) ), mock::reset(o);
"verification failed", 0, "instanceobject::name\n. once()" ); BOOST_CHECK(mock::verify(o));
mock::reset( o );
BOOST_CHECK( mock::verify( o ) );
} }
BOOST_FIXTURE_TEST_CASE( verifying_all_objects_with_one_of_them_containing_a_failing_expectation_fails, fixture ) BOOST_FIXTURE_TEST_CASE(verifying_all_objects_with_one_of_them_containing_a_failing_expectation_fails, fixture)
{ {
e.expect().once(); e.expect().once();
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify()), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify() ),
"verification failed", 0, "instanceobject::name\n. once()" );
mock::reset(); mock::reset();
BOOST_CHECK( mock::verify() ); BOOST_CHECK(mock::verify());
} }
BOOST_FIXTURE_TEST_CASE( resetting_an_object_containing_a_failing_expectation_and_verifying_it_succeeds, fixture ) BOOST_FIXTURE_TEST_CASE(resetting_an_object_containing_a_failing_expectation_and_verifying_it_succeeds, fixture)
{ {
e.expect().once(); e.expect().once();
mock::reset( o ); mock::reset(o);
BOOST_CHECK( mock::verify( o ) ); BOOST_CHECK(mock::verify(o));
} }
BOOST_FIXTURE_TEST_CASE( an_object_is_assignable_by_sharing_its_state, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(an_object_is_assignable_by_sharing_its_state, mock_error_fixture)
{ {
object o1; object o1;
mock::detail::function< void() > e; mock::detail::function<void()> e;
{ {
object o2; object o2;
mock::detail::configure( o2, e, "instance", MOCK_TYPE_NAME(o2), "name" ); mock::detail::configure(o2, e, "instance", MOCK_TYPE_NAME(o2), "name");
e.expect().once(); e.expect().once();
o1 = o2; o1 = o2;
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify(o1)), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify( o1 ) ), CHECK_ERROR(BOOST_CHECK(!mock::verify(o2)), "verification failed", 0, "instanceobject::name\n. once()");
"verification failed", 0, "instanceobject::name\n. once()" );
CHECK_ERROR(
BOOST_CHECK( ! mock::verify( o2 ) ),
"verification failed", 0, "instanceobject::name\n. once()" );
} }
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify(o1)), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify( o1 ) ),
"verification failed", 0, "instanceobject::name\n. once()" );
} }
BOOST_FIXTURE_TEST_CASE( an_object_is_copiable_by_sharing_its_state, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(an_object_is_copiable_by_sharing_its_state, mock_error_fixture)
{ {
boost::scoped_ptr< object > o2( new object ); boost::scoped_ptr<object> o2(new object);
const object o1( *o2 ); const object o1(*o2);
mock::detail::function< void() > e; mock::detail::function<void()> e;
mock::detail::configure( *o2, e, "instance", MOCK_TYPE_NAME(*o2), "name" ); mock::detail::configure(*o2, e, "instance", MOCK_TYPE_NAME(*o2), "name");
e.expect().once(); e.expect().once();
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify(*o2)), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify( *o2 ) ), CHECK_ERROR(BOOST_CHECK(!mock::verify(o1)), "verification failed", 0, "instanceobject::name\n. once()");
"verification failed", 0, "instanceobject::name\n. once()" );
CHECK_ERROR(
BOOST_CHECK( ! mock::verify( o1 ) ),
"verification failed", 0, "instanceobject::name\n. once()" );
o2.reset(); o2.reset();
CHECK_ERROR( CHECK_ERROR(BOOST_CHECK(!mock::verify(o1)), "verification failed", 0, "instanceobject::name\n. once()");
BOOST_CHECK( ! mock::verify( o1 ) ),
"verification failed", 0, "instanceobject::name\n. once()" );
} }

View file

@ -7,108 +7,110 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include "mock_error.hpp" #include "mock_error.hpp"
#include <turtle/sequence.hpp>
#include <turtle/detail/function.hpp> #include <turtle/detail/function.hpp>
#include <turtle/sequence.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_throws, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(registering_to_a_sequence_and_calling_out_of_order_throws, mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void( int ) > e; mock::detail::function<void(int)> e;
e.expect().once().with( 1 ).in( s ); e.expect().once().with(1).in(s);
e.expect().once().with( 2 ).in( s ); e.expect().once().with(2).in(s);
BOOST_CHECK_NO_THROW( e( 2 ) ); BOOST_CHECK_NO_THROW(e(2));
CHECK_ERROR( e( 1 ), "sequence failed", 1, "?( 1 )\n. once().with( 1 )\nv once().with( 2 )" ); CHECK_ERROR(e(1), "sequence failed", 1, "?( 1 )\n. once().with( 1 )\nv once().with( 2 )");
} }
BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_multiple_invocations_throws, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(registering_to_a_sequence_and_calling_out_of_order_multiple_invocations_throws,
mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void( int ) > e; mock::detail::function<void(int)> e;
e.expect().with( 1 ).in( s ); e.expect().with(1).in(s);
e.expect().once().with( 2 ).in( s ); e.expect().once().with(2).in(s);
BOOST_CHECK_NO_THROW( e( 1 ) ); BOOST_CHECK_NO_THROW(e(1));
BOOST_CHECK_NO_THROW( e( 2 ) ); BOOST_CHECK_NO_THROW(e(2));
CHECK_ERROR( e( 1 ), "sequence failed", 2, "?( 1 )\n. unlimited().with( 1 )\nv once().with( 2 )" ); CHECK_ERROR(e(1), "sequence failed", 2, "?( 1 )\n. unlimited().with( 1 )\nv once().with( 2 )");
} }
BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_and_calling_in_order_is_valid, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(registering_to_a_sequence_and_calling_in_order_is_valid, mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void( int ) > e; mock::detail::function<void(int)> e;
e.expect().once().with( 1 ).in( s ); e.expect().once().with(1).in(s);
e.expect().once().with( 2 ).in( s ); e.expect().once().with(2).in(s);
BOOST_CHECK_NO_THROW( e( 1 ) ); BOOST_CHECK_NO_THROW(e(1));
BOOST_CHECK_NO_THROW( e( 2 ) ); BOOST_CHECK_NO_THROW(e(2));
BOOST_CHECK( e.verify() ); BOOST_CHECK(e.verify());
CHECK_CALLS( 2 ); CHECK_CALLS(2);
} }
BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_and_multiply_calling_in_order_is_valid, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(registering_to_a_sequence_and_multiply_calling_in_order_is_valid, mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void( int ) > e; mock::detail::function<void(int)> e;
e.expect().exactly( 2 ).with( 1 ).in( s ); e.expect().exactly(2).with(1).in(s);
e.expect().exactly( 2 ).with( 2 ).in( s ); e.expect().exactly(2).with(2).in(s);
BOOST_CHECK_NO_THROW( e( 1 ) ); BOOST_CHECK_NO_THROW(e(1));
BOOST_CHECK_NO_THROW( e( 1 ) ); BOOST_CHECK_NO_THROW(e(1));
BOOST_CHECK_NO_THROW( e( 2 ) ); BOOST_CHECK_NO_THROW(e(2));
BOOST_CHECK_NO_THROW( e( 2 ) ); BOOST_CHECK_NO_THROW(e(2));
BOOST_CHECK( e.verify() ); BOOST_CHECK(e.verify());
CHECK_CALLS( 4 ); CHECK_CALLS(4);
} }
BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_enforces_call_order_verification_between_two_different_expectations, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(registering_to_a_sequence_enforces_call_order_verification_between_two_different_expectations,
mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void() > e1, e2; mock::detail::function<void()> e1, e2;
e1.expect().once().in( s ); e1.expect().once().in(s);
e2.expect().once().in( s ); e2.expect().once().in(s);
BOOST_CHECK_NO_THROW( e2() ); BOOST_CHECK_NO_THROW(e2());
CHECK_ERROR( e1(), "sequence failed", 1, "?()\n. once()" ); CHECK_ERROR(e1(), "sequence failed", 1, "?()\n. once()");
} }
BOOST_FIXTURE_TEST_CASE( destroying_a_sequence_does_not_remove_order_call_enforcement, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(destroying_a_sequence_does_not_remove_order_call_enforcement, mock_error_fixture)
{ {
mock::detail::function< void() > e1, e2; mock::detail::function<void()> e1, e2;
{ {
mock::sequence s; mock::sequence s;
e1.expect().once().in( s ); e1.expect().once().in(s);
e2.expect().once().in( s ); e2.expect().once().in(s);
} }
BOOST_CHECK_NO_THROW( e2() ); BOOST_CHECK_NO_THROW(e2());
CHECK_ERROR( e1(), "sequence failed", 1, "?()\n. once()" ); CHECK_ERROR(e1(), "sequence failed", 1, "?()\n. once()");
} }
BOOST_FIXTURE_TEST_CASE( resetting_an_expectation_removes_it_from_order_call_enforcement, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(resetting_an_expectation_removes_it_from_order_call_enforcement, mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< void() > e1, e2; mock::detail::function<void()> e1, e2;
e1.expect().once().in( s ); e1.expect().once().in(s);
e2.expect().once().in( s ); e2.expect().once().in(s);
e1.reset(); e1.reset();
BOOST_CHECK_NO_THROW( e2() ); BOOST_CHECK_NO_THROW(e2());
BOOST_CHECK( e1.verify() ); BOOST_CHECK(e1.verify());
BOOST_CHECK( e2.verify() ); BOOST_CHECK(e2.verify());
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
BOOST_FIXTURE_TEST_CASE( an_expectation_can_be_used_in_several_sequences, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(an_expectation_can_be_used_in_several_sequences, mock_error_fixture)
{ {
mock::sequence s1, s2; mock::sequence s1, s2;
mock::detail::function< void() > e; mock::detail::function<void()> e;
e.expect().once().in( s1, s2 ); e.expect().once().in(s1, s2);
BOOST_CHECK_NO_THROW( e() ); BOOST_CHECK_NO_THROW(e());
BOOST_CHECK( e.verify() ); BOOST_CHECK(e.verify());
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }
BOOST_FIXTURE_TEST_CASE( a_result_specification_is_set_after_a_sequence, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE(a_result_specification_is_set_after_a_sequence, mock_error_fixture)
{ {
mock::sequence s; mock::sequence s;
mock::detail::function< int() > e; mock::detail::function<int()> e;
e.expect().once().in( s ).returns( 3 ); e.expect().once().in(s).returns(3);
BOOST_CHECK_EQUAL( 3, e() ); BOOST_CHECK_EQUAL(3, e());
BOOST_CHECK( e.verify() ); BOOST_CHECK(e.verify());
CHECK_CALLS( 1 ); CHECK_CALLS(1);
} }