mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Merge pull request #107 from Flamefire/clang-format
Format code using Clang-Format 10 and enforce via CI
This commit is contained in:
commit
3dda0bf328
97 changed files with 11189 additions and 10842 deletions
162
.clang-format
Normal file
162
.clang-format
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: Mozilla
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
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: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: AfterColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 120
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: true
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
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: '(Test)?$'
|
||||||
|
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: true
|
||||||
|
ObjCSpaceBeforeProtocolList: false
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
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: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: c++14
|
||||||
|
StatementMacros:
|
||||||
|
- MOCK_BASE_CLASS
|
||||||
|
- MOCK_CLASS
|
||||||
|
- MOCK_CONSTRUCTOR
|
||||||
|
- MOCK_CONSTRUCTOR_TPL
|
||||||
|
- MOCK_CONST_CONVERSION_OPERATOR
|
||||||
|
- MOCK_CONST_CONVERSION_OPERATOR_TPL
|
||||||
|
- MOCK_CONST_METHOD
|
||||||
|
- MOCK_CONST_METHOD_EXT
|
||||||
|
- MOCK_CONST_METHOD_EXT_TPL
|
||||||
|
- MOCK_CONST_METHOD_TPL
|
||||||
|
- MOCK_CONVERSION_OPERATOR
|
||||||
|
- MOCK_DESTRUCTOR
|
||||||
|
- MOCK_METHOD
|
||||||
|
- MOCK_METHOD_EXT
|
||||||
|
- MOCK_METHOD_EXT_TPL
|
||||||
|
- MOCK_METHOD_TPL
|
||||||
|
- MOCK_NON_CONST_CONVERSION_OPERATOR
|
||||||
|
- MOCK_NON_CONST_CONVERSION_OPERATOR_TPL
|
||||||
|
- MOCK_NON_CONST_METHOD
|
||||||
|
- MOCK_NON_CONST_METHOD_EXT
|
||||||
|
- MOCK_NON_CONST_METHOD_EXT_TPL
|
||||||
|
- MOCK_NON_CONST_METHOD_TPL
|
||||||
|
- MOCK_STATIC_METHOD
|
||||||
|
- MOCK_STATIC_METHOD_TPL
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
||||||
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
|
@ -23,6 +23,15 @@ env:
|
||||||
DOCBOOK_DTD_DIR: /usr/share/xml/docbook/schema/dtd/4.2
|
DOCBOOK_DTD_DIR: /usr/share/xml/docbook/schema/dtd/4.2
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
Formatting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Formatting
|
||||||
|
uses: DoozyX/clang-format-lint-action@v0.13
|
||||||
|
with:
|
||||||
|
clangFormatVersion: 10
|
||||||
|
|
||||||
posix:
|
posix:
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,11 @@
|
||||||
class calculator
|
class calculator
|
||||||
{
|
{
|
||||||
view& v;
|
view& v;
|
||||||
public:
|
|
||||||
calculator( view& v ): v(v){}
|
|
||||||
|
|
||||||
void add( int a, int b ){ v.display(a + b); } // the result will be sent to the view 'v'
|
public:
|
||||||
|
calculator(view& v) : v(v) {}
|
||||||
|
|
||||||
|
void add(int a, int b) { v.display(a + b); } // the result will be sent to the view 'v'
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,152 +15,135 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.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_free_function )
|
BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_free_function)
|
||||||
{
|
{
|
||||||
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_custom_constraint )
|
BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_custom_constraint)
|
||||||
{
|
{
|
||||||
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 - mock::unwrap_ref(expected_) ) <= mock::unwrap_ref(threshold_) ;
|
return std::abs(actual - mock::unwrap_ref(expected_)) <= mock::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_near )
|
BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_plus_or_minus_one_near)
|
||||||
{
|
{
|
||||||
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_near_cref )
|
BOOST_AUTO_TEST_CASE(forty_one_plus_one_is_forty_two_plus_or_minus_one_near_cref)
|
||||||
{
|
{
|
||||||
mock_view v;
|
mock_view v;
|
||||||
calculator c( v );
|
calculator c(v);
|
||||||
int expected = 0, threshold = 0;
|
int expected = 0, threshold = 0;
|
||||||
MOCK_EXPECT( v.display ).with( near( std::cref( expected ), std::cref( threshold ) ) );
|
MOCK_EXPECT(v.display).with(near(std::cref(expected), std::cref(threshold)));
|
||||||
expected = 42;
|
expected = 42;
|
||||||
threshold = 1;
|
threshold = 1;
|
||||||
c.add( 41, 1 );
|
c.add(41, 1);
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
|
||||||
// Example of a "strong type" float
|
// Example of a "strong type" float
|
||||||
struct float_wrapper{
|
struct float_wrapper
|
||||||
|
{
|
||||||
float value;
|
float value;
|
||||||
float_wrapper(float value): value(value){}
|
float_wrapper(float value) : value(value) {}
|
||||||
operator float() const { return value; }
|
operator float() const { return value; }
|
||||||
friend std::ostream& operator<<( std::ostream& s, const float_wrapper& f)
|
friend std::ostream& operator<<(std::ostream& s, const float_wrapper& f) { return s << f.value; }
|
||||||
{
|
|
||||||
return s << f.value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( near_constraint_works_with_with_float_wrapper_and_cref )
|
BOOST_AUTO_TEST_CASE(near_constraint_works_with_with_float_wrapper_and_cref)
|
||||||
{
|
{
|
||||||
mock_view v;
|
mock_view v;
|
||||||
calculator c( v );
|
calculator c(v);
|
||||||
float_wrapper expected = 0, threshold = 0;
|
float_wrapper expected = 0, threshold = 0;
|
||||||
// This works even without the unwrap_ref
|
// This works even without the unwrap_ref
|
||||||
MOCK_EXPECT( v.display ).once().with( near( expected, threshold ) );
|
MOCK_EXPECT(v.display).once().with(near(expected, threshold));
|
||||||
// This requires 2 implicit conversion: from reference_wrapper to float_wrapper, then to float
|
// This requires 2 implicit conversion: from reference_wrapper to float_wrapper, then to float
|
||||||
// so unwrap_ref in near is required as C++ allows only 1 implicit conversion
|
// so unwrap_ref in near is required as C++ allows only 1 implicit conversion
|
||||||
MOCK_EXPECT( v.display ).once().with( near( std::cref( expected ), std::cref( threshold ) ) );
|
MOCK_EXPECT(v.display).once().with(near(std::cref(expected), std::cref(threshold)));
|
||||||
expected = 42;
|
expected = 42;
|
||||||
threshold = 1;
|
threshold = 1;
|
||||||
c.add(0, 0);
|
c.add(0, 0);
|
||||||
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
|
||||||
|
|
@ -169,12 +152,12 @@ BOOST_AUTO_TEST_CASE( near_constraint_works_with_with_float_wrapper_and_cref )
|
||||||
//]
|
//]
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//[ custom_policy
|
//[ custom_policy
|
||||||
template< typename Result >
|
template<typename Result>
|
||||||
struct custom_policy
|
struct custom_policy
|
||||||
{
|
{
|
||||||
static Result abort()
|
static Result abort()
|
||||||
|
|
@ -182,17 +165,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.
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +183,7 @@ struct custom_policy
|
||||||
//]
|
//]
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef MOCK_ERROR_POLICY
|
#undef MOCK_ERROR_POLICY
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,15 @@
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
std::function<void()> error_handler_abort;
|
std::function<void()> error_handler_abort;
|
||||||
std::function<void(const char*, int)> error_handler_pass;
|
std::function<void(const char*, int)> error_handler_pass;
|
||||||
std::function<void(const std::string&, const char*, int)> error_handler_call;
|
std::function<void(const std::string&, const char*, int)> error_handler_call;
|
||||||
std::function<void(const char* message, const std::string&, const char*, int)> error_handler_fail;
|
std::function<void(const char* message, const std::string&, const char*, int)> error_handler_fail;
|
||||||
|
|
||||||
template< typename Result >
|
template<typename Result>
|
||||||
struct configurable_mock_error
|
struct configurable_mock_error
|
||||||
{
|
{
|
||||||
static Result abort()
|
static Result abort()
|
||||||
|
|
@ -24,25 +24,22 @@ struct configurable_mock_error
|
||||||
return Result();
|
return Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pass( const char* file, int line )
|
static void pass(const char* file, int line) { error_handler_pass(file, line); }
|
||||||
{
|
|
||||||
error_handler_pass(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)
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << context;
|
s << context;
|
||||||
error_handler_call( s.str(), file, line );
|
error_handler_call(s.str(), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Context >
|
template<typename Context>
|
||||||
static void fail( const char* message, const Context& context, const char* file = "", int line = 0 )
|
static void fail(const char* message, const Context& context, const char* file = "", int line = 0)
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << context;
|
s << context;
|
||||||
error_handler_fail( message, s.str(), file, line );
|
error_handler_fail(message, s.str(), file, line);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -50,8 +47,8 @@ struct configurable_mock_error
|
||||||
#define MOCK_USE_BOOST_TEST
|
#define MOCK_USE_BOOST_TEST
|
||||||
|
|
||||||
//[ prerequisite
|
//[ prerequisite
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
//]
|
//]
|
||||||
#include "calculator.hpp"
|
#include "calculator.hpp"
|
||||||
#include "mock_view.hpp"
|
#include "mock_view.hpp"
|
||||||
|
|
@ -69,124 +66,114 @@ struct Fixture
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(GettingStarted, Fixture)
|
BOOST_FIXTURE_TEST_SUITE(GettingStarted, Fixture)
|
||||||
|
|
||||||
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_reset )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_reset)
|
||||||
{
|
{
|
||||||
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_expect )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_expect)
|
||||||
{
|
{
|
||||||
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_then_1_plus_0_is_1 )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_then_1_plus_0_is_1)
|
||||||
{
|
{
|
||||||
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( add_several_numbers_in_sequences )
|
BOOST_AUTO_TEST_CASE(add_several_numbers_in_sequences)
|
||||||
{
|
{
|
||||||
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
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
view& v;
|
view& v;
|
||||||
public:
|
|
||||||
calculator( view& v ): v(v) {}
|
|
||||||
|
|
||||||
void add( int a, int b ){ v.display(a + b); }
|
public:
|
||||||
|
calculator(view& v) : v(v) {}
|
||||||
|
|
||||||
|
void add(int a, int b) { v.display(a + b); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CatchFailureFixture: Fixture
|
struct CatchFailureFixture : Fixture
|
||||||
{
|
{
|
||||||
static bool aborted;
|
static bool aborted;
|
||||||
static std::string fail_msg;
|
static std::string fail_msg;
|
||||||
|
|
||||||
static void abort()
|
static void abort() { aborted = true; }
|
||||||
{
|
static void fail(const std::string& message, const std::string&, const char* = "", int = 0) { fail_msg = message; }
|
||||||
aborted = true;
|
|
||||||
}
|
|
||||||
static void fail( const std::string& message, const std::string&, const char* = "", int = 0 ){
|
|
||||||
fail_msg = message;
|
|
||||||
}
|
|
||||||
CatchFailureFixture()
|
CatchFailureFixture()
|
||||||
{
|
{
|
||||||
error_handler_abort = abort;
|
error_handler_abort = abort;
|
||||||
|
|
@ -201,22 +188,21 @@ struct CatchFailureFixture: Fixture
|
||||||
bool CatchFailureFixture::aborted = false;
|
bool CatchFailureFixture::aborted = false;
|
||||||
std::string CatchFailureFixture::fail_msg;
|
std::string CatchFailureFixture::fail_msg;
|
||||||
|
|
||||||
struct AssertMissingAction: CatchFailureFixture{
|
struct AssertMissingAction : CatchFailureFixture
|
||||||
void teardown(){
|
{
|
||||||
assert_failure("missing action");
|
void teardown() { assert_failure("missing action"); }
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE( MissingReturnActionSuite, AssertMissingAction)
|
BOOST_FIXTURE_TEST_SUITE(MissingReturnActionSuite, AssertMissingAction)
|
||||||
//[ action_test
|
//[ action_test
|
||||||
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_with_action )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_with_action)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
|
|
@ -6,53 +6,46 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/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:
|
||||||
MOCK_BASE_CLASS( mock_base, base )
|
virtual void method(const int);
|
||||||
{
|
};
|
||||||
void method( const int i )
|
|
||||||
{
|
void derived::method(int) {}
|
||||||
method_stub( i );
|
|
||||||
}
|
|
||||||
MOCK_METHOD( method_stub, 1, void( int ), method )
|
|
||||||
};
|
|
||||||
//]
|
//]
|
||||||
}
|
} // namespace limitations_const_parameter_warning_explanation
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
//[ limitations_const_parameter_warning_solution
|
||||||
|
MOCK_BASE_CLASS(mock_base, base)
|
||||||
|
{
|
||||||
|
void method(const int i) { method_stub(i); }
|
||||||
|
MOCK_METHOD(method_stub, 1, void(int), method)
|
||||||
|
};
|
||||||
|
//]
|
||||||
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(check_method_stub_is_called)
|
BOOST_AUTO_TEST_CASE(check_method_stub_is_called)
|
||||||
{
|
{
|
||||||
mock_base b;
|
mock_base b;
|
||||||
MOCK_EXPECT(b.method).once().with(1);
|
MOCK_EXPECT(b.method).once().with(1);
|
||||||
// Example user code taking a base* (or smart pointer variant)
|
// Example user code taking a base* (or smart pointer variant)
|
||||||
auto callMethod = [](base* bPtr){ bPtr->method(1); };
|
auto callMethod = [](base* bPtr) { bPtr->method(1); };
|
||||||
callMethod(&b);
|
callMethod(&b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,35 +6,34 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/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);
|
||||||
//]
|
//]
|
||||||
//[ limitations_literal_zero_solution_3
|
//[ limitations_literal_zero_solution_3
|
||||||
MOCK_EXPECT( m.method ).with( nullptr );
|
MOCK_EXPECT(m.method).with(nullptr);
|
||||||
//]
|
//]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
//[ limitations_non_virtual_method_problem
|
//[ limitations_non_virtual_method_problem
|
||||||
class base
|
class base
|
||||||
|
|
@ -19,9 +19,9 @@ 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)
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,31 +6,36 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
//[ limitations_protected_private_method_problem
|
//[ limitations_protected_private_method_problem
|
||||||
class base
|
class base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void call()
|
||||||
{
|
{
|
||||||
public:
|
method_1();
|
||||||
void call(){ method_1(); method_2(); }
|
method_2();
|
||||||
protected:
|
}
|
||||||
virtual void method_1() = 0;
|
|
||||||
private:
|
protected:
|
||||||
virtual void method_2() = 0;
|
virtual void method_1() = 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_1, 0, void())
|
||||||
MOCK_METHOD( method_2, 0, void() )
|
MOCK_METHOD(method_2, 0, void())
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mocked_methods_are_called)
|
BOOST_AUTO_TEST_CASE(mocked_methods_are_called)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,30 +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)
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/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() = default;
|
virtual ~base() = default;
|
||||||
|
|
||||||
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, 0, void() )
|
MOCK_METHOD(method, 0, void())
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_method_from_templated_class)
|
BOOST_AUTO_TEST_CASE(call_method_from_templated_class)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,31 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
namespace limitations_template_method_problem
|
namespace limitations_template_method_problem {
|
||||||
{
|
|
||||||
//[ limitations_template_method_problem
|
//[ limitations_template_method_problem
|
||||||
class concept_class
|
class concept_class
|
||||||
{
|
{
|
||||||
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(int), method_int)
|
||||||
MOCK_METHOD( method, 1, void( const char* ), method_string )
|
MOCK_METHOD(method, 1, void(const char*), method_string)
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
@ -42,46 +41,45 @@ BOOST_AUTO_TEST_CASE(mocked_templated_methods_are_called)
|
||||||
MOCK_EXPECT(b.method_string).once().with(mock::equal(std::string("string")));
|
MOCK_EXPECT(b.method_string).once().with(mock::equal(std::string("string")));
|
||||||
function_under_test(b);
|
function_under_test(b);
|
||||||
}
|
}
|
||||||
}
|
} // 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
|
class concept_class
|
||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
@ -94,4 +92,4 @@ BOOST_AUTO_TEST_CASE(dispatch_methods_are_called)
|
||||||
MOCK_EXPECT(b.create_string).once().returns("");
|
MOCK_EXPECT(b.create_string).once().returns("");
|
||||||
function_under_test(b);
|
function_under_test(b);
|
||||||
}
|
}
|
||||||
}
|
} // namespace limitations_template_method_problem_2
|
||||||
|
|
|
||||||
|
|
@ -6,31 +6,27 @@
|
||||||
// (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 <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
//[ limitations_throw_specifier_problem
|
//[ limitations_throw_specifier_problem
|
||||||
struct base_class
|
struct base_class
|
||||||
{
|
{
|
||||||
virtual ~base_class() = default;
|
virtual ~base_class() = default;
|
||||||
|
|
||||||
virtual void method() throw() = 0;
|
virtual void method() throw() = 0;
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[ 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() override
|
void method() throw() override { method_proxy(); }
|
||||||
{
|
MOCK_METHOD(method_proxy, 0, void(), method)
|
||||||
method_proxy();
|
};
|
||||||
}
|
|
||||||
MOCK_METHOD( method_proxy, 0, void(), method )
|
|
||||||
};
|
|
||||||
//]
|
//]
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_method_proxy)
|
BOOST_AUTO_TEST_CASE(call_method_proxy)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@
|
||||||
#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)
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
#endif // MOCK_VIEW
|
#endif // MOCK_VIEW
|
||||||
|
|
|
||||||
|
|
@ -6,42 +6,41 @@
|
||||||
// (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 <boost/test/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/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);
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
int calculator::add( int a, int b ){ return a + b; }
|
int calculator::add(int a, int b)
|
||||||
|
{
|
||||||
|
return a + 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;
|
||||||
|
|
@ -52,26 +51,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_without_mock_object )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_without_mock_object)
|
||||||
{
|
{
|
||||||
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_with_mock_object )
|
BOOST_AUTO_TEST_CASE(zero_plus_zero_is_zero_with_mock_object)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -7,68 +7,66 @@
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
//[ async_call_problem
|
//[ async_call_problem
|
||||||
namespace mock_test
|
namespace mock_test {
|
||||||
|
class base_class
|
||||||
{
|
{
|
||||||
class base_class
|
public:
|
||||||
{
|
virtual void method() = 0;
|
||||||
public:
|
};
|
||||||
virtual void method() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class my_class
|
class my_class
|
||||||
{
|
{
|
||||||
base_class& b;
|
base_class& b;
|
||||||
public:
|
|
||||||
explicit my_class( base_class& );
|
|
||||||
|
|
||||||
void flush(); // repetitively calling this method will in turn call base_class::method at some point
|
public:
|
||||||
};
|
explicit my_class(base_class&);
|
||||||
}
|
|
||||||
|
void flush(); // repetitively calling this method will in turn call base_class::method at some point
|
||||||
|
};
|
||||||
|
} // namespace mock_test
|
||||||
//]
|
//]
|
||||||
|
|
||||||
namespace mock_test
|
namespace mock_test {
|
||||||
|
my_class::my_class(base_class& b) : b(b) {}
|
||||||
|
void my_class::flush()
|
||||||
{
|
{
|
||||||
my_class::my_class( base_class& b): b(b){}
|
static int counter = 7;
|
||||||
void my_class::flush()
|
if(--counter == 0)
|
||||||
{
|
b.method();
|
||||||
static int counter = 7;
|
|
||||||
if(--counter == 0)
|
|
||||||
b.method();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace mock_test
|
||||||
|
|
||||||
//[ async_call_solution
|
//[ async_call_solution
|
||||||
|
#include <turtle/mock.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <turtle/mock.hpp>
|
|
||||||
|
|
||||||
namespace mock_test
|
namespace mock_test {
|
||||||
|
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_BASE_CLASS(mock_base_class, base_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD( method, 0 )
|
MOCK_METHOD(method, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( method_is_called )
|
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;
|
||||||
MOCK_EXPECT( m.method ).once().calls( [&done](){ done = true; } );
|
MOCK_EXPECT(m.method).once().calls([&done]() { done = true; });
|
||||||
check( done, [&c](){ c.flush(); } ); // just wait on done, flushing from time to time
|
check(done, [&c]() { c.flush(); }); // just wait on done, flushing from time to time
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace mock_test
|
||||||
|
|
||||||
//]
|
//]
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,17 @@ static void someFunctor(int newValue);
|
||||||
//[ invoke_functor_problem
|
//[ invoke_functor_problem
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
class base_class
|
class base_class
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void method( const std::function< void( int ) >& functor ) = 0;
|
virtual void method(const std::function<void(int)>& functor) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// the function will call 'method' with a functor to be applied
|
// the function will call 'method' with a functor to be applied
|
||||||
void function(base_class& c) { c.method(someFunctor); }
|
void function(base_class& c)
|
||||||
|
{
|
||||||
|
c.method(someFunctor);
|
||||||
|
}
|
||||||
//]
|
//]
|
||||||
|
|
||||||
// Some test-only code to verify what is described
|
// Some test-only code to verify what is described
|
||||||
|
|
@ -42,21 +45,22 @@ struct CheckReceivedValue
|
||||||
#define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, CheckReceivedValue)
|
#define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, CheckReceivedValue)
|
||||||
|
|
||||||
//[ invoke_functor_solution
|
//[ invoke_functor_solution
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
MOCK_BASE_CLASS(mock_class, base_class)
|
||||||
{
|
{
|
||||||
MOCK_BASE_CLASS( mock_class, base_class )
|
MOCK_METHOD(method, 1)
|
||||||
{
|
};
|
||||||
MOCK_METHOD( method, 1 )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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( [](const auto &functor){ functor(42); } ); // whenever 'method' is called, invoke the functor with 42
|
MOCK_EXPECT(mock.method).calls([](const auto& functor) {
|
||||||
function( mock );
|
functor(42);
|
||||||
|
}); // whenever 'method' is called, invoke the functor with 42
|
||||||
|
function(mock);
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
|
|
||||||
|
|
@ -7,31 +7,28 @@
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
//[ quick_constraint_problem
|
//[ quick_constraint_problem
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/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
|
||||||
|
|
@ -39,18 +36,21 @@ 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
|
||||||
std::ostringstream s;
|
{
|
||||||
s << actual;
|
std::ostringstream s;
|
||||||
return s.str() == expected;
|
s << actual;
|
||||||
}
|
return s.str() == 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));
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
|
|
||||||
|
|
@ -7,55 +7,59 @@
|
||||||
// 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
|
||||||
//]
|
//]
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
static base_class* global_b = nullptr;
|
||||||
|
my_class::my_class(base_class& b)
|
||||||
{
|
{
|
||||||
static base_class* global_b = nullptr;
|
global_b = &b;
|
||||||
my_class::my_class( base_class& b){ global_b = &b; }
|
|
||||||
void my_class::process()
|
|
||||||
{
|
|
||||||
int secret_value = 42;
|
|
||||||
global_b->method(secret_value);
|
|
||||||
global_b->method(secret_value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void my_class::process()
|
||||||
|
{
|
||||||
|
int secret_value = 42;
|
||||||
|
global_b->method(secret_value);
|
||||||
|
global_b->method(secret_value);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
//[ retrieve_cref_solution
|
//[ retrieve_cref_solution
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
MOCK_BASE_CLASS(mock_base_class, base_class)
|
||||||
{
|
{
|
||||||
MOCK_BASE_CLASS( mock_base_class, base_class )
|
MOCK_METHOD(method, 1)
|
||||||
{
|
};
|
||||||
MOCK_METHOD( method, 1 )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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( std::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(std::cref(value)); // on second call compare the previously retrieved value with the newly received one
|
||||||
c.process();
|
c.process();
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
|
|
||||||
|
|
@ -12,37 +12,36 @@
|
||||||
#define MOCK_MAKE_TEST_PASS 1
|
#define MOCK_MAKE_TEST_PASS 1
|
||||||
|
|
||||||
#if MOCK_MAKE_TEST_PASS
|
#if MOCK_MAKE_TEST_PASS
|
||||||
#undef BOOST_AUTO_TEST_CASE
|
# undef BOOST_AUTO_TEST_CASE
|
||||||
#define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, mock::cleanup)
|
# define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, mock::cleanup)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//[ static_objects_problem
|
//[ static_objects_problem
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
#include <boost/test/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' outlives the test case
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( static_objects_problem )
|
MOCK_FUNCTION(f, 1, void(my_class*)) // being static 'f' outlives 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
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
@ -51,25 +50,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();
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
// (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>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
@ -16,18 +16,20 @@
|
||||||
|
|
||||||
// Dummy to detect if the assertion unexpectedly succeeded to test what is explained
|
// Dummy to detect if the assertion unexpectedly succeeded to test what is explained
|
||||||
#undef BOOST_CHECK_THROW
|
#undef BOOST_CHECK_THROW
|
||||||
#define BOOST_CHECK_THROW(expr, exc) \
|
#define BOOST_CHECK_THROW(expr, exc) \
|
||||||
try { \
|
try \
|
||||||
expr; \
|
{ \
|
||||||
} catch(const exc&) { \
|
expr; \
|
||||||
std::cerr << "Exception thrown but should not"; \
|
} catch(const exc&) \
|
||||||
}
|
{ \
|
||||||
|
std::cerr << "Exception thrown but should not"; \
|
||||||
|
}
|
||||||
|
|
||||||
//[ 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
|
|
@ -13,7 +13,7 @@
|
||||||
class view
|
class view
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void display( int result ) = 0;
|
virtual void display(int result) = 0;
|
||||||
};
|
};
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,34 +11,33 @@
|
||||||
|
|
||||||
#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 char* file = "file://unknown-location", int line = 0 )
|
const Context& context,
|
||||||
|
const char* file = "file://unknown-location",
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -14,29 +14,28 @@
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.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
|
||||||
|
|
||||||
#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(__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
|
||||||
|
|
|
||||||
|
|
@ -12,243 +12,284 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "unwrap_reference.hpp"
|
#include "unwrap_reference.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 <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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
|
{ \
|
||||||
|
(void)actual; \
|
||||||
|
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(std::forward<T##n>(e##n))
|
||||||
namespace detail \
|
|
||||||
{ \
|
|
||||||
struct Name \
|
|
||||||
{ \
|
|
||||||
template< typename Actual > \
|
|
||||||
bool operator()( const Actual& actual ) const \
|
|
||||||
{ \
|
|
||||||
(void) actual; 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) mock::unwrap_ref(expected##n)
|
||||||
expected##n( std::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)
|
||||||
mock::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) std::decay_t<const T##n>
|
||||||
Expected_##n expected##n;
|
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_TPL_TYPE(z, n, d) \
|
|
||||||
std::decay_t< const T##n >
|
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
|
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
|
||||||
const mock::unwrap_reference_t< Expected_##n >& \
|
const mock::unwrap_reference_t<Expected_##n>& 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) T##n&& BOOST_PP_ARRAY_ELEM(n, Args)
|
||||||
T##n&& BOOST_PP_ARRAY_ELEM(n, Args)
|
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_ARGS(z, n, Args) \
|
#define MOCK_CONSTRAINT_ARGS(z, n, Args) T##n&& e##n
|
||||||
T##n&& e##n
|
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \
|
#define MOCK_CONSTRAINT_PARAM(z, n, Args) std::forward<T##n>(BOOST_PP_ARRAY_ELEM(n, Args))
|
||||||
std::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 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, \
|
32, \
|
||||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
31, \
|
||||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
|
30, \
|
||||||
|
29, \
|
||||||
|
28, \
|
||||||
|
27, \
|
||||||
|
26, \
|
||||||
|
25, \
|
||||||
|
24, \
|
||||||
|
23, \
|
||||||
|
22, \
|
||||||
|
21, \
|
||||||
|
20, \
|
||||||
|
19, \
|
||||||
|
18, \
|
||||||
|
17, \
|
||||||
|
16, \
|
||||||
|
15, \
|
||||||
|
14, \
|
||||||
|
13, \
|
||||||
|
12, \
|
||||||
|
11, \
|
||||||
|
10, \
|
||||||
|
9, \
|
||||||
|
8, \
|
||||||
|
7, \
|
||||||
|
6, \
|
||||||
|
5, \
|
||||||
|
4, \
|
||||||
|
3, \
|
||||||
|
2, \
|
||||||
|
1, ), )
|
||||||
#else // BOOST_MSVC
|
#else // BOOST_MSVC
|
||||||
# define MOCK_VARIADIC_SIZE(...) \
|
# define MOCK_VARIADIC_SIZE(...) \
|
||||||
MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
||||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
|
32, \
|
||||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
31, \
|
||||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
|
30, \
|
||||||
|
29, \
|
||||||
|
28, \
|
||||||
|
27, \
|
||||||
|
26, \
|
||||||
|
25, \
|
||||||
|
24, \
|
||||||
|
23, \
|
||||||
|
22, \
|
||||||
|
21, \
|
||||||
|
20, \
|
||||||
|
19, \
|
||||||
|
18, \
|
||||||
|
17, \
|
||||||
|
16, \
|
||||||
|
15, \
|
||||||
|
14, \
|
||||||
|
13, \
|
||||||
|
12, \
|
||||||
|
11, \
|
||||||
|
10, \
|
||||||
|
9, \
|
||||||
|
8, \
|
||||||
|
7, \
|
||||||
|
6, \
|
||||||
|
5, \
|
||||||
|
4, \
|
||||||
|
3, \
|
||||||
|
2, \
|
||||||
|
1, )
|
||||||
#endif // BOOST_MSVC
|
#endif // BOOST_MSVC
|
||||||
#define MOCK_VARIADIC_SIZE_I( \
|
#define MOCK_VARIADIC_SIZE_I(e0, \
|
||||||
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, \
|
e1, \
|
||||||
e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, \
|
e2, \
|
||||||
e25, e26, e27, e28, e29, e30, e31, size, ...) size
|
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)), BOOST_PP_ARRAY_ELEM(n, Array))
|
||||||
Name, n, \
|
|
||||||
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_CONSTRAINT_HPP_INCLUDED
|
#endif // MOCK_CONSTRAINT_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -12,300 +12,243 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "constraint.hpp"
|
#include "constraint.hpp"
|
||||||
#include "detail/move_helper.hpp"
|
#include "detail/move_helper.hpp"
|
||||||
#include "unwrap_reference.hpp"
|
|
||||||
#include "detail/void_t.hpp"
|
#include "detail/void_t.hpp"
|
||||||
|
#include "unwrap_reference.hpp"
|
||||||
#include <boost/version.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
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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 std::common_type_t< T1, T2 > common_type;
|
typedef std::common_type_t<T1, T2> 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<class T, class U = T, class = void>
|
template<class T, class U = T, class = void>
|
||||||
struct has_equal_to: std::false_type
|
struct has_equal_to : std::false_type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<class T, class U>
|
template<class T, class U>
|
||||||
struct has_equal_to<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>>: std::true_type
|
struct has_equal_to<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>> : std::true_type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
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 operator()(const Actual& actual,
|
||||||
template< typename Actual >
|
std::enable_if_t<has_equal_to<Actual, unwrap_reference_t<Expected>>::value>* = 0) const
|
||||||
bool operator()( const Actual& actual,
|
|
||||||
std::enable_if_t<
|
|
||||||
has_equal_to<
|
|
||||||
Actual,
|
|
||||||
unwrap_reference_t< Expected >
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
return actual == unwrap_ref( expected_ );
|
return actual == unwrap_ref(expected_);
|
||||||
}
|
}
|
||||||
template< typename Actual >
|
template<typename Actual>
|
||||||
bool operator()( const Actual& actual,
|
bool operator()(const Actual& actual,
|
||||||
std::enable_if_t<
|
std::enable_if_t<!has_equal_to<Actual, unwrap_reference_t<Expected>>::value>* = 0) const
|
||||||
!has_equal_to<
|
|
||||||
Actual,
|
|
||||||
unwrap_reference_t< Expected >
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
return actual && *actual == unwrap_ref( expected_ );
|
return actual && *actual == 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_(std::addressof(unwrap_ref(expected))) {}
|
||||||
: expected_( std::addressof( unwrap_ref( expected ) ) )
|
template<typename Actual>
|
||||||
{}
|
bool operator()(const Actual& actual) const
|
||||||
template< typename Actual >
|
|
||||||
bool operator()( const Actual& actual ) const
|
|
||||||
{
|
{
|
||||||
return std::addressof( actual ) == expected_;
|
return std::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 unwrap_reference_t< Expected >* expected_;
|
const unwrap_reference_t<Expected>* expected_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Expected >
|
template<typename Expected>
|
||||||
struct retrieve
|
struct retrieve
|
||||||
{
|
{
|
||||||
explicit retrieve( Expected& expected )
|
explicit retrieve(Expected& expected) : expected_(std::addressof(unwrap_ref(expected))) {}
|
||||||
: expected_( std::addressof( unwrap_ref( expected ) ) )
|
template<typename Actual>
|
||||||
{}
|
bool operator()(
|
||||||
template< typename Actual >
|
const Actual& actual,
|
||||||
bool operator()( const Actual& actual,
|
std::enable_if_t<!std::is_convertible<const Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
|
||||||
std::enable_if_t<
|
|
||||||
!std::is_convertible<
|
|
||||||
const Actual*,
|
|
||||||
unwrap_reference_t< Expected >
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
*expected_ = actual;
|
*expected_ = actual;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template< typename Actual >
|
template<typename Actual>
|
||||||
bool operator()( Actual&& actual,
|
bool operator()(
|
||||||
std::enable_if_t<
|
Actual&& actual,
|
||||||
!std::is_convertible<
|
std::enable_if_t<!std::is_convertible<const Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
|
||||||
const Actual*,
|
|
||||||
unwrap_reference_t< Expected >
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
*expected_ = std::move( actual );
|
*expected_ = std::move(actual);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template< typename Actual >
|
template<typename Actual>
|
||||||
bool operator()( Actual& actual,
|
bool operator()(Actual& actual,
|
||||||
std::enable_if_t<
|
std::enable_if_t<std::is_convertible<Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
|
||||||
std::is_convertible< Actual*,
|
|
||||||
unwrap_reference_t< Expected >
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
*expected_ = std::addressof( actual );
|
*expected_ = std::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_) << " )";
|
||||||
}
|
}
|
||||||
unwrap_reference_t< Expected >* expected_;
|
unwrap_reference_t<Expected>* 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 = unwrap_ref( expected_ );
|
actual = unwrap_ref(expected_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template< typename Actual >
|
template<typename Actual>
|
||||||
bool operator()( Actual* actual,
|
bool operator()(Actual* actual,
|
||||||
std::enable_if_t<
|
std::enable_if_t<std::is_convertible<unwrap_reference_t<Expected>, Actual>::value>* = 0) const
|
||||||
std::is_convertible<
|
|
||||||
unwrap_reference_t< Expected >,
|
|
||||||
Actual
|
|
||||||
>::value
|
|
||||||
>* = 0 ) const
|
|
||||||
{
|
{
|
||||||
if( ! actual )
|
if(!actual)
|
||||||
return false;
|
return false;
|
||||||
*actual = unwrap_ref( expected_ );
|
*actual = 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( unwrap_ref( expected_ ) )
|
return actual.find(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<T>> equal(T&& t)
|
||||||
|
{
|
||||||
|
return detail::equal<T>(std::forward<T>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template<typename T>
|
||||||
constraint< detail::equal< T > > equal( T&& t )
|
constraint<detail::same<T>> same(T& t)
|
||||||
{
|
{
|
||||||
return detail::equal< T >( std::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
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,13 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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:
|
||||||
typedef std::function< Signature > functor_type;
|
typedef std::function<Signature> functor_type;
|
||||||
typedef std::function< Result() > action_type;
|
typedef std::function<Result()> action_type;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Meant to be subclassed and not be directly used
|
// Meant to be subclassed and not be directly used
|
||||||
|
|
@ -33,41 +30,29 @@ namespace detail
|
||||||
action_base(action_base&&) = delete;
|
action_base(action_base&&) = delete;
|
||||||
action_base& operator=(const action_base&) = delete;
|
action_base& operator=(const action_base&) = delete;
|
||||||
action_base& operator=(action_base&&) = delete;
|
action_base& operator=(action_base&&) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
const functor_type& functor() const { return f_; }
|
||||||
|
bool valid() const { return f_ || a_; }
|
||||||
|
Result trigger() const { return a_(); }
|
||||||
|
|
||||||
const functor_type& functor() const
|
void calls(const functor_type& f)
|
||||||
{
|
{
|
||||||
return f_;
|
if(!f)
|
||||||
}
|
throw std::invalid_argument("null functor");
|
||||||
bool valid() const
|
|
||||||
{
|
|
||||||
return f_ || a_;
|
|
||||||
}
|
|
||||||
Result trigger() const
|
|
||||||
{
|
|
||||||
return a_();
|
|
||||||
}
|
|
||||||
|
|
||||||
void calls( const functor_type& f )
|
|
||||||
{
|
|
||||||
if( ! f )
|
|
||||||
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_ = [e]() -> Result { throw e; };
|
a_ = [e]() -> Result { throw e; };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void set( const action_type& a )
|
void set(const action_type& a) { a_ = a; }
|
||||||
{
|
template<typename Y>
|
||||||
a_ = a;
|
void set(const std::reference_wrapper<Y>& r)
|
||||||
}
|
|
||||||
template< typename Y >
|
|
||||||
void set( const std::reference_wrapper< Y >& r )
|
|
||||||
{
|
{
|
||||||
a_ = [r]() -> Result { return r.get(); };
|
a_ = [r]() -> Result { return r.get(); };
|
||||||
}
|
}
|
||||||
|
|
@ -77,26 +62,26 @@ 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( std::ref( store( v ) ) );
|
this->set(std::ref(store(v)));
|
||||||
}
|
}
|
||||||
template< typename Y >
|
template<typename Y>
|
||||||
void returns( const std::reference_wrapper< Y >& r )
|
void returns(const std::reference_wrapper<Y>& r)
|
||||||
{
|
{
|
||||||
this->set( r );
|
this->set(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Value >
|
template<typename Value>
|
||||||
void moves( Value&& v )
|
void moves(Value&& v)
|
||||||
{
|
{
|
||||||
auto vRef = std::ref( store( std::move( v ) ) );
|
auto vRef = std::ref(store(std::move(v)));
|
||||||
this->set([vRef](){ return std::move(vRef.get()); });
|
this->set([vRef]() { return std::move(vRef.get()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -107,44 +92,43 @@ namespace detail
|
||||||
value& operator=(const value&) = delete;
|
value& operator=(const value&) = delete;
|
||||||
virtual ~value() = default;
|
virtual ~value() = default;
|
||||||
};
|
};
|
||||||
template< typename T >
|
template<typename T>
|
||||||
struct value_imp : value
|
struct value_imp : value
|
||||||
{
|
{
|
||||||
typedef std::remove_const_t<std::remove_reference_t<T>> type;
|
typedef std::remove_const_t<std::remove_reference_t<T>> type;
|
||||||
|
|
||||||
template< typename U >
|
template<typename U>
|
||||||
value_imp( U&& t ) : t_( std::forward<U>( t ) )
|
value_imp(U&& t) : t_(std::forward<U>(t))
|
||||||
{}
|
{}
|
||||||
type t_;
|
type t_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T >
|
template<typename T>
|
||||||
typename value_imp<T>::type& store( T&& t )
|
typename value_imp<T>::type& store(T&& t)
|
||||||
{
|
{
|
||||||
v_ = std::make_unique< value_imp<T> >( std::forward<T>( t ) );
|
v_ = std::make_unique<value_imp<T>>(std::forward<T>(t));
|
||||||
return static_cast< value_imp< T >& >( *v_ ).t_;
|
return static_cast<value_imp<T>&>(*v_).t_;
|
||||||
}
|
}
|
||||||
template< typename T >
|
template<typename T>
|
||||||
std::remove_reference_t< Result >& store( T* t )
|
std::remove_reference_t<Result>& store(T* t)
|
||||||
{
|
{
|
||||||
v_ = std::make_unique< value_imp<Result> >( t );
|
v_ = std::make_unique<value_imp<Result>>(t);
|
||||||
return static_cast< value_imp< Result >& >( *v_ ).t_;
|
return static_cast<value_imp<Result>&>(*v_).t_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr< value > v_;
|
std::unique_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( [](){} );
|
this->set([]() {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_ACTION_HPP_INCLUDED
|
#endif // MOCK_ACTION_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -10,43 +10,38 @@
|
||||||
#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,
|
||||||
void update( parent& p,
|
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 )
|
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,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
|
class context
|
||||||
|
|
@ -30,17 +27,16 @@ namespace detail
|
||||||
|
|
||||||
virtual ~context() = default;
|
virtual ~context() = default;
|
||||||
|
|
||||||
virtual void add( const void* p, verifiable& v,
|
virtual void add(const void* p,
|
||||||
boost::unit_test::const_string instance,
|
verifiable& v,
|
||||||
boost::optional< type_name > type,
|
boost::unit_test::const_string instance,
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -8,115 +8,83 @@
|
||||||
|
|
||||||
#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##_(std::forward<T##n>(a##n))
|
||||||
BOOST_PP_IF(n, &&,) c##n##_( std::forward< 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) std::forward<T##n>(a##n)
|
||||||
std::forward< 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,144 +92,103 @@ 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_( std::make_unique< unlimited >() )
|
: invocation_(std::make_unique<unlimited>()),
|
||||||
, matcher_(
|
matcher_(std::make_unique<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()),
|
||||||
std::make_unique<
|
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_( std::make_unique< unlimited >() )
|
: invocation_(std::make_unique<unlimited>()),
|
||||||
, matcher_(
|
matcher_(std::make_unique<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()), file_(file),
|
||||||
std::make_unique<
|
line_(line)
|
||||||
default_matcher<
|
|
||||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
|
||||||
>
|
|
||||||
> () )
|
|
||||||
, file_( file )
|
|
||||||
, line_( line )
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
expectation(expectation &&) = default;
|
expectation(expectation&&) = default;
|
||||||
expectation(expectation const&) = default;
|
expectation(expectation const&) = default;
|
||||||
expectation& operator=(expectation &&) = default;
|
expectation& operator=(expectation&&) = default;
|
||||||
expectation& operator=(expectation const&) = default;
|
expectation& operator=(expectation const&) = default;
|
||||||
|
|
||||||
~expectation()
|
~expectation()
|
||||||
{
|
{
|
||||||
for( auto& sequence: sequences_)
|
for(auto& sequence : sequences_)
|
||||||
sequence->remove( this );
|
sequence->remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void invoke( std::unique_ptr< invocation > i )
|
void invoke(std::unique_ptr<invocation> i) { invocation_ = std::move(i); }
|
||||||
{
|
|
||||||
invocation_ = std::move(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_ = std::make_unique<
|
matcher_ = std::make_unique<single_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_)),
|
||||||
single_matcher<
|
void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>(
|
||||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ),
|
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_ = std::make_unique<
|
matcher_ = std::make_unique<multi_matcher<Constraint, void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>(c);
|
||||||
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( auto& sequence: sequences_)
|
for(auto& sequence : sequences_)
|
||||||
{
|
{
|
||||||
if( ! sequence->is_valid( this ) )
|
if(!sequence->is_valid(this))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool result = invocation_->invoke();
|
bool result = invocation_->invoke();
|
||||||
for( auto& sequence: sequences_)
|
for(auto& sequence : sequences_)
|
||||||
sequence->invalidate( this );
|
sequence->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<<( std::ostream& s, const expectation& e )
|
friend std::ostream& operator<<(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:
|
||||||
std::unique_ptr< invocation > invocation_;
|
std::unique_ptr<invocation> invocation_;
|
||||||
std::unique_ptr<
|
std::unique_ptr<matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>> matcher_;
|
||||||
matcher_base<
|
std::vector<std::shared_ptr<sequence_impl>> sequences_;
|
||||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
|
||||||
>
|
|
||||||
> matcher_;
|
|
||||||
std::vector< std::shared_ptr<sequence_impl> > 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
|
||||||
|
|
|
||||||
|
|
@ -13,38 +13,29 @@
|
||||||
#include "../stream.hpp"
|
#include "../stream.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
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_(std::addressof(t)) {}
|
||||||
: t_( std::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
|
||||||
|
|
|
||||||
|
|
@ -10,74 +10,62 @@
|
||||||
#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/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/optional.hpp>
|
#include <list>
|
||||||
#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 std::reference_wrapper<Y>& r)
|
||||||
{
|
{
|
||||||
e_->returns( r );
|
e_->returns(r);
|
||||||
}
|
|
||||||
template< typename Y >
|
|
||||||
void returns( const std::reference_wrapper< Y >& r )
|
|
||||||
{
|
|
||||||
e_->returns( r );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
E* e_;
|
E* e_;
|
||||||
|
|
@ -92,8 +80,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
|
||||||
|
|
|
||||||
|
|
@ -9,79 +9,65 @@
|
||||||
#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_FORWARD(z, n, d) \
|
#define MOCK_FORWARD(z, n, d) std::forward<T##n>(t##n)
|
||||||
std::forward< 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 std::enable_shared_from_this<
|
public std::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_(std::make_shared<mutex>()) {}
|
||||||
: context_( 0 )
|
|
||||||
, valid_( true )
|
|
||||||
, exceptions_( exceptions() )
|
|
||||||
, mutex_( std::make_shared< mutex >() )
|
|
||||||
{}
|
|
||||||
virtual ~function_impl()
|
virtual ~function_impl()
|
||||||
{
|
{
|
||||||
if( valid_ && exceptions_ >= exceptions() )
|
if(valid_ && exceptions_ >= exceptions())
|
||||||
{
|
{
|
||||||
for( const auto& expectation: expectations_ )
|
for(const auto& expectation : expectations_)
|
||||||
{
|
{
|
||||||
if( ! expectation.verify() )
|
if(!expectation.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_context(this) << lazy_expectations(this),
|
||||||
<< lazy_expectations( this ),
|
expectation.file(),
|
||||||
expectation.file(), expectation.line() );
|
expectation.line());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( context_ )
|
if(context_)
|
||||||
context_->remove( *this );
|
context_->remove(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool verify() const
|
virtual bool verify() const
|
||||||
{
|
{
|
||||||
lock _( mutex_ );
|
lock _(mutex_);
|
||||||
for( const auto& expectation: expectations_ )
|
for(const auto& expectation : expectations_)
|
||||||
{
|
{
|
||||||
if( ! expectation.verify() )
|
if(!expectation.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 ),
|
expectation.file(),
|
||||||
expectation.file(), expectation.line() );
|
expectation.line());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid_;
|
return valid_;
|
||||||
|
|
@ -89,115 +75,103 @@ namespace detail
|
||||||
|
|
||||||
virtual void reset()
|
virtual void reset()
|
||||||
{
|
{
|
||||||
lock _( mutex_ );
|
lock _(mutex_);
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
std::shared_ptr< function_impl > guard =
|
std::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;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wrapper( const std::shared_ptr< mutex >& m, expectation_type& e )
|
wrapper(const std::shared_ptr<mutex>& m, expectation_type& e) : base_type(e), lock_(m) {}
|
||||||
: base_type( e )
|
|
||||||
, lock_( m )
|
|
||||||
{}
|
|
||||||
wrapper(const wrapper&) = delete;
|
wrapper(const wrapper&) = delete;
|
||||||
wrapper( wrapper&& x ) = default;
|
wrapper(wrapper&& x) = default;
|
||||||
wrapper& operator=(const wrapper&) = delete;
|
wrapper& operator=(const wrapper&) = delete;
|
||||||
wrapper& operator=( wrapper&& x ) = default;
|
wrapper& operator=(wrapper&& x) = default;
|
||||||
wrapper& once()
|
wrapper& once()
|
||||||
{
|
{
|
||||||
this->e_->invoke( std::make_unique< detail::once >() );
|
this->e_->invoke(std::make_unique<detail::once>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
wrapper& never()
|
wrapper& never()
|
||||||
{
|
{
|
||||||
this->e_->invoke( std::make_unique< detail::never >() );
|
this->e_->invoke(std::make_unique<detail::never>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
wrapper& exactly( std::size_t count )
|
wrapper& exactly(std::size_t count)
|
||||||
{
|
{
|
||||||
this->e_->invoke( std::make_unique< detail::exactly >( count ) );
|
this->e_->invoke(std::make_unique<detail::exactly>(count));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
wrapper& at_least( std::size_t min )
|
wrapper& at_least(std::size_t min)
|
||||||
{
|
{
|
||||||
this->e_->invoke( std::make_unique< detail::at_least >( min ) );
|
this->e_->invoke(std::make_unique<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( std::make_unique< detail::at_most >( max ) );
|
this->e_->invoke(std::make_unique<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( std::make_unique< detail::between >( min, max ) );
|
this->e_->invoke(std::make_unique<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( TT&& t )
|
void moves(TT&& t)
|
||||||
{
|
{
|
||||||
this->e_->moves( std::move( t ) );
|
this->e_->moves(std::move(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
lock lock_;
|
lock lock_;
|
||||||
|
|
@ -206,82 +180,78 @@ 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_.emplace_back( file, line );
|
expectations_.emplace_back(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_.emplace_back( );
|
expectations_.emplace_back();
|
||||||
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( const auto& expectation: expectations_ )
|
for(const auto& expectation : expectations_)
|
||||||
{
|
{
|
||||||
if( expectation.is_valid(
|
if(expectation.is_valid(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _)))
|
||||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) )
|
|
||||||
{
|
{
|
||||||
if( ! expectation.invoke() )
|
if(!expectation.invoke())
|
||||||
{
|
{
|
||||||
error_type::fail( "sequence failed",
|
error_type::fail(
|
||||||
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
|
"sequence failed", MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
|
||||||
return error_type::abort();
|
return error_type::abort();
|
||||||
}
|
}
|
||||||
if( ! expectation.valid() )
|
if(!expectation.valid())
|
||||||
{
|
{
|
||||||
error_type::fail( "missing action",
|
error_type::fail(
|
||||||
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
|
"missing action", MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
|
||||||
return error_type::abort();
|
return error_type::abort();
|
||||||
}
|
}
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
error_type::call( MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
|
error_type::call(MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
|
||||||
if( expectation.functor() )
|
if(expectation.functor())
|
||||||
return expectation.functor()(
|
return expectation.functor()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _));
|
||||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
|
|
||||||
return expectation.trigger();
|
return expectation.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,
|
||||||
boost::unit_test::const_string instance,
|
const void* p,
|
||||||
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<<( std::ostream& s, const function_impl& impl )
|
friend std::ostream& operator<<(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;
|
||||||
|
|
@ -291,26 +261,23 @@ 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( const auto& expectation: e.impl_->expectations_ )
|
for(const auto& expectation : e.impl_->expectations_)
|
||||||
s << std::endl << expectation;
|
s << std::endl << expectation;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
const function_impl* impl_;
|
const function_impl* impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::list< expectation_type > expectations_;
|
std::list<expectation_type> expectations_;
|
||||||
context* context_;
|
context* context_;
|
||||||
mutable bool valid_;
|
mutable bool valid_;
|
||||||
const int exceptions_;
|
const int exceptions_;
|
||||||
const std::shared_ptr< mutex > mutex_;
|
const std::shared_ptr<mutex> mutex_;
|
||||||
};
|
};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#undef MOCK_FUNCTION_FORMAT
|
#undef MOCK_FUNCTION_FORMAT
|
||||||
#undef MOCK_FUNCTION_CONTEXT
|
#undef MOCK_FUNCTION_CONTEXT
|
||||||
|
|
|
||||||
|
|
@ -8,90 +8,68 @@
|
||||||
|
|
||||||
#include "function_impl_template.hpp"
|
#include "function_impl_template.hpp"
|
||||||
|
|
||||||
#define MOCK_FORWARD(z, n, d) \
|
#define MOCK_FORWARD(z, n, d) std::forward<T##n>(t##n)
|
||||||
std::forward< 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) ) >
|
|
||||||
{
|
{
|
||||||
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_(std::make_shared<impl_type>()) {}
|
||||||
: impl_( std::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_FORWARD, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
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_FORWARD, _) );
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
||||||
boost::unit_test::const_string instance,
|
const void* p,
|
||||||
boost::optional< type_name > type,
|
boost::unit_test::const_string instance,
|
||||||
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:
|
||||||
std::shared_ptr< impl_type > impl_;
|
std::shared_ptr<impl_type> impl_;
|
||||||
};
|
};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#undef MOCK_FORWARD
|
#undef MOCK_FORWARD
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -11,48 +11,39 @@
|
||||||
|
|
||||||
#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( const auto* verifiable: verifiables_ )
|
for(const auto* verifiable : verifiables_)
|
||||||
if( ! verifiable->verify() )
|
if(!verifiable->verify())
|
||||||
valid = false;
|
valid = false;
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
const auto verifiables = verifiables_;
|
const auto verifiables = verifiables_;
|
||||||
for( auto* verifiable: verifiables )
|
for(auto* verifiable : verifiables)
|
||||||
if( std::find( verifiables_.begin(), verifiables_.end(), verifiable ) != verifiables_.end() )
|
if(std::find(verifiables_.begin(), verifiables_.end(), verifiable) != verifiables_.end())
|
||||||
verifiable->reset();
|
verifiable->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector< verifiable* > verifiables_;
|
std::vector<verifiable*> verifiables_;
|
||||||
};
|
};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_GROUP_HPP_INCLUDED
|
#endif // MOCK_GROUP_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,11 @@
|
||||||
#define MOCK_INVOCATION_HPP_INCLUDED
|
#define MOCK_INVOCATION_HPP_INCLUDED
|
||||||
|
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
#include <stdexcept>
|
|
||||||
#include <ostream>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <ostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class invocation
|
class invocation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -32,66 +29,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_ << " )";
|
||||||
}
|
}
|
||||||
|
|
@ -100,40 +82,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_ << " )";
|
||||||
}
|
}
|
||||||
|
|
@ -142,12 +112,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_ << " )";
|
||||||
}
|
}
|
||||||
|
|
@ -156,17 +124,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
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,14 @@
|
||||||
#include "void_t.hpp"
|
#include "void_t.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/// Trait to return true if F is a functor that can be called with a single argument Arg
|
/// Trait to return true if F is a functor that can be called with a single argument Arg
|
||||||
template< typename F, typename Arg, class = void >
|
template<typename F, typename Arg, class = void>
|
||||||
struct is_functor : std::false_type
|
struct is_functor : std::false_type
|
||||||
{};
|
{};
|
||||||
template< typename F, typename Arg >
|
template<typename F, typename Arg>
|
||||||
struct is_functor< F, Arg, void_t<decltype( std::declval<F>()( std::declval<Arg>() ) )> >: std::true_type
|
struct is_functor<F, Arg, void_t<decltype(std::declval<F>()(std::declval<Arg>()))>> : std::true_type
|
||||||
{};
|
{};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_IS_FUNCTOR_HPP_INCLUDED
|
#endif // MOCK_IS_FUNCTOR_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,14 @@
|
||||||
// (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))>
|
||||||
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
matcher_base() = default;
|
matcher_base() = default;
|
||||||
|
|
@ -25,19 +21,17 @@ namespace detail
|
||||||
matcher_base& operator=(const matcher_base&) = delete;
|
matcher_base& operator=(const matcher_base&) = delete;
|
||||||
virtual ~matcher_base() = default;
|
virtual ~matcher_base() = default;
|
||||||
|
|
||||||
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<<( std::ostream& s, const matcher_base& m )
|
friend std::ostream& operator<<(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
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,9 @@
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
template<typename T>
|
||||||
namespace detail
|
using ref_arg = std::conditional<std::is_reference<T>::value, T, std::add_rvalue_reference_t<T>>;
|
||||||
{
|
}} // namespace mock::detail
|
||||||
template< typename T >
|
|
||||||
using ref_arg = std::conditional<
|
|
||||||
std::is_reference< T >::value,
|
|
||||||
T,
|
|
||||||
std::add_rvalue_reference_t< T >
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED
|
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -15,65 +15,52 @@
|
||||||
|
|
||||||
#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
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lock( const std::shared_ptr< mutex >& m )
|
lock(const std::shared_ptr<mutex>& m) : m_(m) { m_->lock(); }
|
||||||
: m_( m )
|
|
||||||
{
|
|
||||||
m_->lock();
|
|
||||||
}
|
|
||||||
~lock()
|
~lock()
|
||||||
{
|
{
|
||||||
if( m_ )
|
if(m_)
|
||||||
m_->unlock();
|
m_->unlock();
|
||||||
}
|
}
|
||||||
lock( const lock& ) = delete;
|
lock(const lock&) = delete;
|
||||||
lock( lock&& x ) = default;
|
lock(lock&& x) = default;
|
||||||
lock& operator=( const lock& ) = delete;
|
lock& operator=(const lock&) = delete;
|
||||||
lock& operator=( lock&& x ) = default;
|
lock& operator=(lock&& x) = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr< mutex > m_;
|
std::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
|
struct mutex
|
||||||
{
|
{
|
||||||
mutex() = default;
|
mutex() = default;
|
||||||
mutex(const mutex&) = delete;
|
mutex(const mutex&) = delete;
|
||||||
mutex& operator=(const mutex&) = delete;
|
mutex& operator=(const mutex&) = delete;
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -82,70 +69,66 @@ namespace detail
|
||||||
scoped_lock(const scoped_lock&) = delete;
|
scoped_lock(const scoped_lock&) = delete;
|
||||||
scoped_lock& operator=(const scoped_lock&) = delete;
|
scoped_lock& operator=(const scoped_lock&) = delete;
|
||||||
|
|
||||||
scoped_lock( mutex& ) {}
|
scoped_lock(mutex&) {}
|
||||||
~scoped_lock() {}
|
~scoped_lock() {}
|
||||||
};
|
};
|
||||||
class lock
|
class lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lock( const std::shared_ptr< mutex >& ) {}
|
lock(const std::shared_ptr<mutex>&) {}
|
||||||
~lock() {}
|
~lock() {}
|
||||||
lock(const lock&) = delete;
|
lock(const lock&) = delete;
|
||||||
lock( lock&& ) = default;
|
lock(lock&&) = default;
|
||||||
lock& operator=( const lock& ) = delete;
|
lock& operator=(const lock&) = delete;
|
||||||
lock& operator=( lock&& ) = default;
|
lock& operator=(lock&&) = default;
|
||||||
};
|
};
|
||||||
}
|
}} // 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 char* file = "unknown location", int line = 0 )
|
const Context& context,
|
||||||
|
const char* file = "unknown location",
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -10,56 +10,51 @@
|
||||||
#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/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 std::enable_shared_from_this<object_impl>
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class object_impl : public context, public verifiable,
|
|
||||||
public std::enable_shared_from_this< object_impl >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
object_impl()
|
object_impl() : mutex_(std::make_shared<mutex>()) {}
|
||||||
: mutex_( std::make_shared< mutex >() )
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void add( const void* /*p*/, verifiable& v,
|
virtual void add(const void* /*p*/,
|
||||||
boost::unit_test::const_string instance,
|
verifiable& v,
|
||||||
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( 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_);
|
||||||
const auto it = children_.find( &v );
|
const auto it = children_.find(&v);
|
||||||
if( it != children_.end() )
|
if(it != children_.end())
|
||||||
s << it->second;
|
s << it->second;
|
||||||
else
|
else
|
||||||
s << "?";
|
s << "?";
|
||||||
|
|
@ -67,23 +62,22 @@ 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_);
|
||||||
std::shared_ptr< object_impl > guard = shared_from_this();
|
std::shared_ptr<object_impl> guard = shared_from_this();
|
||||||
group_.reset();
|
group_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
group group_;
|
group group_;
|
||||||
parent parent_;
|
parent parent_;
|
||||||
std::map< const verifiable*, child > children_;
|
std::map<const verifiable*, child> children_;
|
||||||
const std::shared_ptr< mutex > mutex_;
|
const std::shared_ptr<mutex> mutex_;
|
||||||
};
|
};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_OBJECT_IMPL_HPP_INCLUDED
|
#endif // MOCK_OBJECT_IMPL_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -11,58 +11,55 @@
|
||||||
|
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
template<class...>
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template< class... >
|
|
||||||
struct tuple;
|
struct tuple;
|
||||||
|
|
||||||
template< std::size_t I, class T >
|
template<std::size_t I, class T>
|
||||||
struct tuple_element;
|
struct tuple_element;
|
||||||
|
|
||||||
template< std::size_t I, class H, class... T >
|
template<std::size_t I, class H, class... T>
|
||||||
struct tuple_element<I, tuple<H, T...>> : tuple_element<I-1, tuple<T...>>
|
struct tuple_element<I, tuple<H, T...>> : tuple_element<I - 1, tuple<T...>>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template< class H, class... T >
|
template<class H, class... T>
|
||||||
struct tuple_element<0, tuple<H, T...>>
|
struct tuple_element<0, tuple<H, T...>>
|
||||||
{
|
{
|
||||||
using type = H;
|
using type = H;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Signature >
|
template<typename Signature>
|
||||||
struct result_type;
|
struct result_type;
|
||||||
|
|
||||||
template< typename R, typename... Args >
|
template<typename R, typename... Args>
|
||||||
struct result_type< R(Args...) >
|
struct result_type<R(Args...)>
|
||||||
{
|
{
|
||||||
using type = R;
|
using type = R;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Signature >
|
template<typename Signature>
|
||||||
struct function_arity;
|
struct function_arity;
|
||||||
|
|
||||||
template< typename R, typename... Args >
|
template<typename R, typename... Args>
|
||||||
struct function_arity< R(Args...) >
|
struct function_arity<R(Args...)>
|
||||||
{
|
{
|
||||||
static constexpr size_t value = sizeof...(Args);
|
static constexpr size_t value = sizeof...(Args);
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Signature >
|
template<typename Signature>
|
||||||
struct parameter_types;
|
struct parameter_types;
|
||||||
|
|
||||||
template< typename R, typename... Args >
|
template<typename R, typename... Args>
|
||||||
struct parameter_types< R(Args...) >
|
struct parameter_types<R(Args...)>
|
||||||
{
|
{
|
||||||
using type = tuple<Args...>;
|
using type = tuple<Args...>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Signature, int n >
|
template<typename Signature, int n>
|
||||||
struct parameter
|
struct parameter
|
||||||
{
|
{
|
||||||
static_assert(n < function_arity<Signature>::value, "Function signature has not that many parameters");
|
static_assert(n < function_arity<Signature>::value, "Function signature has not that many parameters");
|
||||||
using type = typename tuple_element< n, typename parameter_types<Signature>::type >::type;
|
using type = typename tuple_element<n, typename parameter_types<Signature>::type>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -74,7 +71,6 @@ namespace detail
|
||||||
};
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using parameter_type_t = typename parameter_type<T>::type;
|
using parameter_type_t = typename parameter_type<T>::type;
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_PARAMETER_HPP_INCLUDED
|
#endif // MOCK_PARAMETER_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -11,35 +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() = default;
|
parent() = default;
|
||||||
parent( boost::unit_test::const_string instance,
|
parent(boost::unit_test::const_string instance, boost::optional<type_name> type)
|
||||||
boost::optional< type_name > type )
|
: instance_(instance), type_(type)
|
||||||
: instance_( instance )
|
|
||||||
, type_( type )
|
|
||||||
{}
|
{}
|
||||||
friend std::ostream& operator<<( std::ostream& s, const parent& p )
|
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
|
||||||
|
|
|
||||||
|
|
@ -10,110 +10,96 @@
|
||||||
#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,
|
||||||
boost::unit_test::const_string instance,
|
verifiable& v,
|
||||||
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)
|
||||||
{
|
{
|
||||||
scoped_lock _( mutex_ );
|
scoped_lock _(mutex_);
|
||||||
auto it = children_.lower_bound( &v );
|
auto 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_);
|
||||||
const auto it = children_.find( &v );
|
const auto 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_;
|
||||||
|
|
@ -121,14 +107,13 @@ namespace detail
|
||||||
};
|
};
|
||||||
|
|
||||||
parents_t parents_;
|
parents_t parents_;
|
||||||
std::map< const verifiable*, counter_child > children_;
|
std::map<const verifiable*, counter_child> children_;
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -15,49 +15,41 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class sequence_impl
|
class sequence_impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sequence_impl()
|
sequence_impl() : mutex_(std::make_shared<mutex>()) {}
|
||||||
: mutex_( std::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_);
|
||||||
const auto it = std::find( elements_.begin(), elements_.end(), e );
|
const auto it = 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:
|
||||||
std::vector< void* > elements_;
|
std::vector<void*> elements_;
|
||||||
const std::shared_ptr< mutex > mutex_;
|
const std::shared_ptr<mutex> mutex_;
|
||||||
};
|
};
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED
|
#endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,23 @@
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
#define MOCK_NOARG
|
#define MOCK_NOARG
|
||||||
#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \
|
#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \
|
||||||
template< typename R, typename... Args > \
|
template<typename R, typename... Args> \
|
||||||
struct strip_function_qualifiers<R(Args...) cv ref > \
|
struct strip_function_qualifiers<R(Args...) cv ref> \
|
||||||
{ using type = R(Args...); }; \
|
{ \
|
||||||
template< typename R, typename... Args > \
|
using type = R(Args...); \
|
||||||
struct strip_function_qualifiers<R(Args..., ...) cv ref > \
|
}; \
|
||||||
{ using type = R(Args..., ...); };
|
template<typename R, typename... Args> \
|
||||||
|
struct strip_function_qualifiers<R(Args..., ...) cv ref> \
|
||||||
|
{ \
|
||||||
|
using type = R(Args..., ...); \
|
||||||
|
};
|
||||||
|
|
||||||
#define MOCK_STRIP_FUNCTION_QUALIFIERS_REF(cv) \
|
#define MOCK_STRIP_FUNCTION_QUALIFIERS_REF(cv) \
|
||||||
MOCK_STRIP_FUNCTION_QUALIFIERS(cv,) \
|
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ) \
|
||||||
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \
|
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \
|
||||||
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&)
|
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&)
|
||||||
|
|
||||||
template<typename>
|
template<typename>
|
||||||
|
|
@ -40,20 +41,20 @@ namespace detail
|
||||||
#undef MOCK_STRIP_FUNCTION_QUALIFIERS
|
#undef MOCK_STRIP_FUNCTION_QUALIFIERS
|
||||||
#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF
|
#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF
|
||||||
|
|
||||||
template< typename M >
|
template<typename M>
|
||||||
struct signature;
|
struct signature;
|
||||||
|
|
||||||
template< typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
struct signature< R(Args...) >
|
struct signature<R(Args...)>
|
||||||
{
|
{
|
||||||
using type = R(Args...);
|
using type = R(Args...);
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Sig, typename C>
|
template<typename Sig, typename C>
|
||||||
struct signature< Sig(C::*) >: signature< typename strip_function_qualifiers<Sig>::type >
|
struct signature<Sig(C::*)> : signature<typename strip_function_qualifiers<Sig>::type>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template< typename T >
|
template<typename T>
|
||||||
struct base
|
struct base
|
||||||
{
|
{
|
||||||
typedef T base_type;
|
typedef T base_type;
|
||||||
|
|
@ -62,16 +63,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<std::remove_cv_t<std::remove_reference_t<decltype( \
|
||||||
std::remove_cv_t< std::remove_reference_t < decltype( \
|
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
|
||||||
|
|
|
||||||
|
|
@ -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&))
|
singleton(singleton const&) = delete;
|
||||||
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
|
singleton& operator=(singleton const&) = delete;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BOOST_DEFAULTED_FUNCTION(singleton(), {})
|
singleton() = default;
|
||||||
BOOST_DEFAULTED_FUNCTION(~singleton(), {})
|
~singleton() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // 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() = default
|
type() = default
|
||||||
|
|
||||||
#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
|
||||||
|
|
|
||||||
|
|
@ -10,37 +10,33 @@
|
||||||
#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>
|
||||||
#include <stdexcept>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <typeinfo>
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <typeinfo>
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#include <cxxabi.h>
|
# include <cstdlib>
|
||||||
#include <cstdlib>
|
# include <cxxabi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class type_name
|
class type_name
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit type_name( const std::type_info& info )
|
explicit type_name(const std::type_info& 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:
|
||||||
static void serialize( std::ostream& s, const std::type_info& info )
|
static void serialize(std::ostream& s, const std::type_info& info)
|
||||||
{
|
{
|
||||||
const char* name = info.name();
|
const char* name = info.name();
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
@ -49,60 +45,59 @@ namespace detail
|
||||||
{
|
{
|
||||||
void operator()(const void* p) { std::free(const_cast<void*>(p)); }
|
void operator()(const void* p) { std::free(const_cast<void*>(p)); }
|
||||||
};
|
};
|
||||||
std::unique_ptr< const char, Deleter > demangled(
|
std::unique_ptr<const char, Deleter> demangled(abi::__cxa_demangle(name, 0, 0, &status));
|
||||||
abi::__cxa_demangle( name, 0, 0, &status ));
|
if(!status && demangled)
|
||||||
if( ! status && demangled )
|
serialize(s, demangled.get());
|
||||||
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;
|
||||||
|
|
||||||
static void serialize( std::ostream& s, std::string name )
|
static void serialize(std::ostream& s, std::string name)
|
||||||
{
|
{
|
||||||
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 << '>';
|
||||||
}
|
}
|
||||||
static void list( std::ostream& s, const std::string& name )
|
static void list(std::ostream& s, const std::string& name)
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
static std::string clean( std::string name )
|
static std::string clean(std::string name)
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
static size_type rfind( const std::string& name, char c )
|
static size_type rfind(const std::string& name, char c)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
@ -110,17 +105,16 @@ namespace detail
|
||||||
|
|
||||||
const std::type_info* info_;
|
const std::type_info* info_;
|
||||||
};
|
};
|
||||||
template< typename T >
|
template<typename T>
|
||||||
type_name make_type_name()
|
type_name make_type_name()
|
||||||
{
|
{
|
||||||
return type_name( typeid(T) );
|
return type_name(typeid(T));
|
||||||
}
|
}
|
||||||
template< typename T >
|
template<typename T>
|
||||||
type_name make_type_name( const T& )
|
type_name make_type_name(const T&)
|
||||||
{
|
{
|
||||||
return type_name( typeid(T) );
|
return type_name(typeid(T));
|
||||||
}
|
}
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_TYPE_NAME_HPP_INCLUDED
|
#endif // MOCK_TYPE_NAME_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@
|
||||||
|
|
||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class verifiable
|
class verifiable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -27,7 +24,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
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,7 @@
|
||||||
#ifndef MOCK_VOID_T_HPP_INCLUDED
|
#ifndef MOCK_VOID_T_HPP_INCLUDED
|
||||||
#define MOCK_VOID_T_HPP_INCLUDED
|
#define MOCK_VOID_T_HPP_INCLUDED
|
||||||
|
|
||||||
namespace mock
|
namespace mock { namespace detail {
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename...>
|
template<typename...>
|
||||||
struct make_void
|
struct make_void
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +18,6 @@ namespace detail
|
||||||
/// Standard helper to implement the detection idiom. Returns always void
|
/// Standard helper to implement the detection idiom. Returns always void
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
using void_t = typename make_void<Ts...>::type;
|
using void_t = typename make_void<Ts...>::type;
|
||||||
}
|
}} // namespace mock::detail
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_VOID_T_HPP_INCLUDED
|
#endif // MOCK_VOID_T_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -10,190 +10,187 @@
|
||||||
#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 "stream.hpp"
|
||||||
#include <boost/detail/container_fwd.hpp>
|
#include <boost/detail/container_fwd.hpp>
|
||||||
#include <boost/none.hpp>
|
#include <boost/none.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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 << ')';
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_callable_impl: std::false_type
|
struct is_callable_impl : std::false_type
|
||||||
{};
|
{};
|
||||||
template<typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
struct is_callable_impl<R(Args...)>: std::true_type
|
struct is_callable_impl<R(Args...)> : std::true_type
|
||||||
{};
|
{};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_callable: is_callable_impl< std::remove_cv_t<T> >
|
struct is_callable : is_callable_impl<std::remove_cv_t<T>>
|
||||||
{};
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
stream& operator<<(stream& s, const std::pair<T1, T2>& p)
|
||||||
|
{
|
||||||
|
return s << '(' << mock::format(p.first) << ',' << mock::format(p.second) << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T1, typename T2 >
|
template<typename T, typename A>
|
||||||
stream& operator<<( stream& s, const std::pair< T1, T2 >& p )
|
stream& operator<<(stream& s, const std::deque<T, A>& t)
|
||||||
{
|
{
|
||||||
return s << '(' << mock::format( p.first )
|
detail::serialize(s, t.begin(), t.end());
|
||||||
<< ',' << mock::format( p.second ) << ')';
|
return s;
|
||||||
}
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::list<T, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::vector<T, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename K, typename T, typename C, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::map<K, T, C, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename K, typename T, typename C, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::multimap<K, T, C, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T, typename C, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::set<T, C, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T, typename C, typename A>
|
||||||
|
stream& operator<<(stream& s, const std::multiset<T, C, A>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const boost::assign_detail::generic_list<T>& t)
|
||||||
|
{
|
||||||
|
detail::serialize(s, t.begin(), t.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const boost::reference_wrapper<T>& t)
|
||||||
|
{
|
||||||
|
return s << mock::format(t.get());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const std::reference_wrapper<T>& t)
|
||||||
|
{
|
||||||
|
return s << mock::format(t.get());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const boost::shared_ptr<T>& t)
|
||||||
|
{
|
||||||
|
return s << mock::format(t.get());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const boost::weak_ptr<T>& t)
|
||||||
|
{
|
||||||
|
return s << mock::format(t.lock());
|
||||||
|
}
|
||||||
|
inline stream& operator<<(stream& s, const boost::none_t&)
|
||||||
|
{
|
||||||
|
return s << "none";
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
stream& operator<<(stream& s, const boost::optional<T>& t)
|
||||||
|
{
|
||||||
|
if(t)
|
||||||
|
return s << mock::format(t.get());
|
||||||
|
return s << boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
template< typename T, typename A >
|
template<typename T>
|
||||||
stream& operator<<( stream& s, const std::deque< T, A >& t )
|
stream& operator<<(stream& s, const std::shared_ptr<T>& t)
|
||||||
{
|
{
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
return s << mock::format(t.get());
|
||||||
return s;
|
}
|
||||||
}
|
template<typename T>
|
||||||
template< typename T, typename A >
|
stream& operator<<(stream& s, const std::weak_ptr<T>& t)
|
||||||
stream& operator<<( stream& s, const std::list< T, A >& t )
|
{
|
||||||
{
|
return s << mock::format(t.lock());
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
}
|
||||||
return s;
|
template<typename T, typename D>
|
||||||
}
|
stream& operator<<(stream& s, const std::unique_ptr<T, D>& p)
|
||||||
template< typename T, typename A >
|
{
|
||||||
stream& operator<<( stream& s, const std::vector< T, A >& t )
|
return s << mock::format(p.get());
|
||||||
{
|
}
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename K, typename T, typename C, typename A >
|
|
||||||
stream& operator<<( stream& s, const std::map< K, T, C, A >& t )
|
|
||||||
{
|
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename K, typename T, typename C, typename A >
|
|
||||||
stream& operator<<( stream& s, const std::multimap< K, T, C, A >& t )
|
|
||||||
{
|
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename T, typename C, typename A >
|
|
||||||
stream& operator<<( stream& s, const std::set< T, C, A >& t )
|
|
||||||
{
|
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename T, typename C, typename A >
|
|
||||||
stream& operator<<( stream& s, const std::multiset< T, C, A >& t )
|
|
||||||
{
|
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s,
|
|
||||||
const boost::assign_detail::generic_list< T >& t )
|
|
||||||
{
|
|
||||||
detail::serialize( s, t.begin(), t.end() );
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const boost::reference_wrapper< T >& t )
|
|
||||||
{
|
|
||||||
return s << mock::format( t.get() );
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const std::reference_wrapper< T >& t )
|
|
||||||
{
|
|
||||||
return s << mock::format( t.get() );
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const boost::shared_ptr< T >& t )
|
|
||||||
{
|
|
||||||
return s << mock::format( t.get() );
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const boost::weak_ptr< T >& t )
|
|
||||||
{
|
|
||||||
return s << mock::format( t.lock() );
|
|
||||||
}
|
|
||||||
inline stream& operator<<( stream& s, const boost::none_t& )
|
|
||||||
{
|
|
||||||
return s << "none";
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const boost::optional< T >& t )
|
|
||||||
{
|
|
||||||
if( t )
|
|
||||||
return s << mock::format( t.get() );
|
|
||||||
return s << boost::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename T >
|
template<typename T>
|
||||||
stream& operator<<( stream& s, const std::shared_ptr< T >& t )
|
stream& operator<<(stream& s, const boost::lambda::lambda_functor<T>&)
|
||||||
{
|
{
|
||||||
return s << mock::format( t.get() );
|
return s << '?';
|
||||||
}
|
}
|
||||||
template< typename T >
|
template<typename T>
|
||||||
stream& operator<<( stream& s, const std::weak_ptr< T >& t )
|
stream& operator<<(stream& s, const boost::phoenix::actor<T>&)
|
||||||
{
|
{
|
||||||
return s << mock::format( t.lock() );
|
return s << '?';
|
||||||
}
|
}
|
||||||
template< typename T, typename D >
|
|
||||||
stream& operator<<( stream& s, const std::unique_ptr< T, D >& p )
|
|
||||||
{
|
|
||||||
return s << mock::format( p.get() );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename T >
|
inline stream& operator<<(stream& s, std::nullptr_t)
|
||||||
stream& operator<<( stream& s, const boost::lambda::lambda_functor< T >& )
|
{
|
||||||
{
|
return s << "nullptr";
|
||||||
return s << '?';
|
}
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
stream& operator<<( stream& s, const boost::phoenix::actor< T >& )
|
|
||||||
{
|
|
||||||
return s << '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
inline stream& operator<<( stream& s, std::nullptr_t )
|
template<typename T>
|
||||||
{
|
std::enable_if_t<detail::is_callable<T>::value, stream&> operator<<(stream& s, T*)
|
||||||
return s << "nullptr";
|
{
|
||||||
}
|
return s << '?';
|
||||||
|
}
|
||||||
template< typename T >
|
template<typename T>
|
||||||
std::enable_if_t< detail::is_callable< T >::value, stream& >
|
std::enable_if_t<!detail::is_callable<T>::value, stream&> operator<<(stream& s, T* t)
|
||||||
operator<<( stream& s, T* )
|
{
|
||||||
{
|
*s.s_ << t;
|
||||||
return s << '?';
|
return s;
|
||||||
}
|
}
|
||||||
template< typename T >
|
} // namespace mock
|
||||||
std::enable_if_t< !detail::is_callable< T >::value, stream& >
|
|
||||||
operator<<( stream& s, T* t )
|
|
||||||
{
|
|
||||||
*s.s_ << t;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
} // mock
|
|
||||||
|
|
||||||
#endif // MOCK_LOG_HPP_INCLUDED
|
#endif // MOCK_LOG_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -10,95 +10,71 @@
|
||||||
#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 "log.hpp"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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()(std::add_lvalue_reference_t<const Actual> actual)
|
||||||
{
|
{
|
||||||
public:
|
return mock::equal(mock::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()( std::add_lvalue_reference_t< const Actual > actual )
|
|
||||||
{
|
|
||||||
return mock::equal( mock::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_( std::forward< 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_;
|
||||||
std::enable_if_t<
|
};
|
||||||
detail::is_functor< Functor, Actual >::value
|
|
||||||
>
|
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_(std::forward<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_( std::forward< typename detail::ref_arg< Actual >::type >( actual ) );
|
};
|
||||||
}
|
|
||||||
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
|
template<typename Actual, typename Functor>
|
||||||
{
|
class matcher<Actual, Functor, std::enable_if_t<detail::is_functor<Functor, Actual>::value>>
|
||||||
return s << mock::format( m.c_ );
|
{
|
||||||
}
|
public:
|
||||||
private:
|
explicit matcher(const Functor& f) : c_(f) {}
|
||||||
Functor c_;
|
bool operator()(typename detail::ref_arg<Actual>::type actual)
|
||||||
};
|
{
|
||||||
} // mock
|
return c_(std::forward<typename detail::ref_arg<Actual>::type>(actual));
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -9,168 +9,153 @@
|
||||||
#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 "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>
|
||||||
|
|
||||||
/// MOCK_CLASS( name )
|
/// MOCK_CLASS( name )
|
||||||
/// Define a class
|
/// Define a class
|
||||||
#define MOCK_CLASS(T) \
|
#define MOCK_CLASS(T) struct T : mock::object
|
||||||
struct T : mock::object
|
|
||||||
|
|
||||||
/// MOCK_PROTECT_FUNCTION_SIG( signature )
|
/// MOCK_PROTECT_FUNCTION_SIG( signature )
|
||||||
/// Use this with MOCK_FUNCTION/MOCK_*_METHOD if the return type contains commas
|
/// Use this with MOCK_FUNCTION/MOCK_*_METHOD if the return type contains commas
|
||||||
#define MOCK_PROTECT_FUNCTION_SIG(...) \
|
#define MOCK_PROTECT_FUNCTION_SIG(...) mock::detail::parameter_type_t<void(__VA_ARGS__)>
|
||||||
mock::detail::parameter_type_t<void (__VA_ARGS__)>
|
|
||||||
|
|
||||||
/// Internal compatibility macro if function signature is passed via BOOST_IDENTITY_TYPE
|
/// Internal compatibility macro if function signature is passed via BOOST_IDENTITY_TYPE
|
||||||
/// TODO: Remove support for doing that and move remove_pointer_t to MOCK_PROTECT_FUNCTION_SIG
|
/// TODO: Remove support for doing that and move remove_pointer_t to MOCK_PROTECT_FUNCTION_SIG
|
||||||
#define MOCK_FUNCTION_TYPE(...) \
|
#define MOCK_FUNCTION_TYPE(...) std::remove_pointer_t<__VA_ARGS__>
|
||||||
std::remove_pointer_t< __VA_ARGS__ >
|
|
||||||
|
|
||||||
/// MOCK_BASE_CLASS( name, base )
|
/// MOCK_BASE_CLASS( name, base )
|
||||||
/// Define a class deriving from a base class
|
/// Define a class deriving from a base class
|
||||||
#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__ >
|
|
||||||
|
|
||||||
/// MOCK_FUNCTOR( name, signature )
|
/// MOCK_FUNCTOR( name, signature )
|
||||||
/// Define a callable variable/member
|
/// Define a callable variable/member
|
||||||
#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
|
|
||||||
/// MOCK_FUNCTOR_TPL( name, signature )
|
/// MOCK_FUNCTOR_TPL( name, signature )
|
||||||
#define MOCK_FUNCTOR_TPL(f, ...) static_assert(false, "MOCK_FUNCTOR_TPL has been replaced by MOCK_FUNCTOR")
|
#define MOCK_FUNCTOR_TPL(f, ...) static_assert(false, "MOCK_FUNCTOR_TPL has been replaced by MOCK_FUNCTOR")
|
||||||
|
|
||||||
#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) \
|
#define MOCK_METHOD_HELPER(S, t) \
|
||||||
mutable mock::detail::function< MOCK_FUNCTION_TYPE(S) > t##_mock_; \
|
mutable mock::detail::function<MOCK_FUNCTION_TYPE(S)> t##_mock_; \
|
||||||
mock::detail::function< MOCK_FUNCTION_TYPE(S) >& t##_mock( \
|
mock::detail::function<MOCK_FUNCTION_TYPE(S)>& 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, \
|
||||||
mock::detail::configure( *this, t##_mock_, \
|
t##_mock_, \
|
||||||
instance.substr( 0, instance.rfind( BOOST_PP_STRINGIZE(t) ) ), \
|
instance.substr(0, instance.rfind(BOOST_PP_STRINGIZE(t))), \
|
||||||
mock::detail::make_type_name(*this), \
|
mock::detail::make_type_name(*this), \
|
||||||
BOOST_PP_STRINGIZE(t) ); \
|
BOOST_PP_STRINGIZE(t)); \
|
||||||
return t##_mock_; \
|
return t##_mock_; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOCK_PARAM(S, tpn) \
|
#define MOCK_PARAM(S, tpn) tpn mock::detail::parameter < MOCK_FUNCTION_TYPE(S)
|
||||||
tpn mock::detail::parameter< MOCK_FUNCTION_TYPE(S)
|
#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 mock::detail::result_type< \
|
tpn mock::detail::result_type<MOCK_FUNCTION_TYPE(S)>::type M(MOCK_DECL_PARAMS(n, S, tpn)) c
|
||||||
MOCK_FUNCTION_TYPE(S) >::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) BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, std::forward < MOCK_PARAM(S, tpn))
|
||||||
#define MOCK_FORWARD_PARAMS(n, S, tpn) \
|
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
|
||||||
BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, \
|
MOCK_DECL(M, n, S, c, tpn) \
|
||||||
std::forward< MOCK_PARAM(S, tpn))
|
{ \
|
||||||
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
|
static_assert(n == mock::detail::function_arity<MOCK_FUNCTION_TYPE(S)>::value, "Arity mismatch"); \
|
||||||
MOCK_DECL(M, n, S, c, tpn) \
|
return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
|
||||||
{ \
|
|
||||||
static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE(S) >::value, "Arity mismatch" ); \
|
|
||||||
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)
|
MOCK_METHOD_HELPER(S, t)
|
||||||
#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)
|
MOCK_METHOD_HELPER(S, t)
|
||||||
#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)
|
MOCK_METHOD_HELPER(S, t)
|
||||||
|
|
||||||
/// MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
/// MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||||
/// generates both const and non-const operators
|
/// generates both const and non-const operators
|
||||||
#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)
|
||||||
/// MOCK_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
/// MOCK_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||||
/// generates only a const operator
|
/// generates only a const operator
|
||||||
#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)
|
||||||
/// MOCK_NON_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
/// MOCK_NON_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||||
/// generates only a non-const operator
|
/// generates only a non-const operator
|
||||||
#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) MOCK_CONVERSION_OPERATOR(M, T, t)
|
#define MOCK_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_CONVERSION_OPERATOR(M, T, t)
|
||||||
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_CONST_CONVERSION_OPERATOR(M, T, t)
|
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_CONST_CONVERSION_OPERATOR(M, T, t)
|
||||||
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t)
|
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t)
|
||||||
|
|
||||||
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
||||||
s mock::detail::function< MOCK_FUNCTION_TYPE(S) >& t##_mock( \
|
s mock::detail::function<MOCK_FUNCTION_TYPE(S)>& 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)> f; \
|
||||||
static mock::detail::function< MOCK_FUNCTION_TYPE(S) > 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)
|
||||||
|
|
||||||
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
|
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
|
||||||
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
|
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
|
||||||
#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,)
|
|
||||||
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
|
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
|
||||||
/// must be used if the signature uses a template parameter of the class
|
/// must be used if the signature uses a template parameter of the class
|
||||||
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
|
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
|
||||||
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) \
|
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
|
||||||
MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
|
|
||||||
|
|
||||||
/// MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
|
/// MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
|
||||||
#define MOCK_DESTRUCTOR(T, t) \
|
#define MOCK_DESTRUCTOR(T, t) \
|
||||||
T() { try { MOCK_ANONYMOUS_HELPER(t)(); } catch( ... ) {} } \
|
T() \
|
||||||
|
{ \
|
||||||
|
try \
|
||||||
|
{ \
|
||||||
|
MOCK_ANONYMOUS_HELPER(t)(); \
|
||||||
|
} catch(...) \
|
||||||
|
{} \
|
||||||
|
} \
|
||||||
MOCK_METHOD_HELPER(void(), t)
|
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) \
|
||||||
{ \
|
{ \
|
||||||
static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE(S) >::value, "Arity mismatch" ); \
|
static_assert(n == mock::detail::function_arity<MOCK_FUNCTION_TYPE(S)>::value, "Arity mismatch"); \
|
||||||
return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \
|
return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
|
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
|
||||||
|
|
@ -179,79 +164,64 @@
|
||||||
|
|
||||||
/// MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
/// MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
||||||
/// generates both const and non-const methods
|
/// generates both const and non-const methods
|
||||||
#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, ))
|
||||||
/// MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
/// MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
||||||
/// generates only the const version of the method
|
/// generates only the const version of the method
|
||||||
#define MOCK_CONST_METHOD(M, ...) \
|
#define MOCK_CONST_METHOD(M, ...) \
|
||||||
MOCK_CONST_METHOD_EXT(M, \
|
MOCK_CONST_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, ))
|
||||||
/// MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
/// MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
||||||
/// generates only the non-const version of the method
|
/// generates only the non-const version of the method
|
||||||
#define MOCK_NON_CONST_METHOD(M, ...) \
|
#define MOCK_NON_CONST_METHOD(M, ...) \
|
||||||
MOCK_NON_CONST_METHOD_EXT(M, \
|
MOCK_NON_CONST_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, ))
|
||||||
|
|
||||||
|
|
||||||
/// MOCK_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// must be used if the signature uses a template parameter of the class
|
/// must be used if the signature uses a template parameter of the class
|
||||||
/// generates both const and non-const methods
|
/// generates both const and non-const methods
|
||||||
#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__, ), \
|
|
||||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
|
||||||
/// MOCK_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// must be used if the signature uses a template parameter of the class
|
/// must be used if the signature uses a template parameter of the class
|
||||||
/// generates only the const version of the method
|
/// generates only the const version of the method
|
||||||
#define MOCK_CONST_METHOD_TPL(M, n, ...) \
|
#define MOCK_CONST_METHOD_TPL(M, n, ...) \
|
||||||
MOCK_CONST_METHOD_EXT_TPL(M, n, \
|
MOCK_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, ))
|
|
||||||
/// MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// must be used if the signature uses a template parameter of the class
|
/// must be used if the signature uses a template parameter of the class
|
||||||
/// generates only the non-const version of the method
|
/// generates only the non-const version of the method
|
||||||
#define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
|
#define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
|
||||||
MOCK_NON_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, ))
|
|
||||||
|
|
||||||
/// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// if 'identifier' is omitted it will default to 'name'
|
/// if 'identifier' is omitted it will default to 'name'
|
||||||
#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,)
|
|
||||||
|
|
||||||
/// MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// if 'identifier' is omitted it will default to 'name'
|
/// if 'identifier' is omitted it will default to 'name'
|
||||||
#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,)
|
|
||||||
|
|
||||||
/// MOCK_STATIC_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
/// MOCK_STATIC_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||||
/// must be used if the signature uses a template parameter of the class
|
/// must be used if the signature uses a template parameter of the class
|
||||||
/// if 'identifier' is omitted it will default to 'name'
|
/// if 'identifier' is omitted it will default to 'name'
|
||||||
#define MOCK_STATIC_METHOD_TPL(F, n, ...) \
|
#define MOCK_STATIC_METHOD_TPL(F, n, ...) \
|
||||||
MOCK_FUNCTION_AUX(F, n, \
|
MOCK_FUNCTION_AUX( \
|
||||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static, typename)
|
||||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
|
|
||||||
static, typename)
|
|
||||||
|
|
||||||
/// MOCK_EXPECT( identifier )
|
/// MOCK_EXPECT( identifier )
|
||||||
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect( __FILE__, __LINE__ )
|
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect(__FILE__, __LINE__)
|
||||||
/// MOCK_RESET( identifier )
|
/// MOCK_RESET( identifier )
|
||||||
#define MOCK_RESET(t) MOCK_HELPER(t).reset( __FILE__, __LINE__ )
|
#define MOCK_RESET(t) MOCK_HELPER(t).reset(__FILE__, __LINE__)
|
||||||
/// MOCK_VERIFY( identifier )
|
/// MOCK_VERIFY( identifier )
|
||||||
#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
|
||||||
|
|
|
||||||
|
|
@ -10,61 +10,61 @@
|
||||||
#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/test/utils/basic_cstring/basic_cstring.hpp>
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace mock
|
namespace mock {
|
||||||
{
|
class object;
|
||||||
class object;
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
template<typename E>
|
||||||
template< typename E >
|
E& configure(const object& o,
|
||||||
E& configure( const object& o, E& e,
|
E& e,
|
||||||
boost::unit_test::const_string instance,
|
|
||||||
boost::optional< type_name > type,
|
|
||||||
boost::unit_test::const_string name );
|
|
||||||
|
|
||||||
template< typename T, typename E >
|
|
||||||
E& configure( const T& t, E& e,
|
|
||||||
boost::unit_test::const_string instance,
|
|
||||||
boost::optional< type_name > type,
|
|
||||||
boost::unit_test::const_string name,
|
|
||||||
std::enable_if_t< !std::is_base_of< object, T >::value >* = 0 )
|
|
||||||
{
|
|
||||||
e.configure( detail::root, &t, instance, type, name );
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class object
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
object()
|
|
||||||
: impl_( std::make_shared< detail::object_impl >() )
|
|
||||||
{}
|
|
||||||
protected:
|
|
||||||
~object() = default;
|
|
||||||
public:
|
|
||||||
std::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::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);
|
||||||
|
|
||||||
|
template<typename T, typename E>
|
||||||
|
E& configure(const T& t,
|
||||||
|
E& e,
|
||||||
|
boost::unit_test::const_string instance,
|
||||||
|
boost::optional<type_name> type,
|
||||||
|
boost::unit_test::const_string name,
|
||||||
|
std::enable_if_t<!std::is_base_of<object, T>::value>* = 0)
|
||||||
{
|
{
|
||||||
e.configure( *o.impl_, o.impl_.get(), instance, type, name );
|
e.configure(detail::root, &t, instance, type, name);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
} // namespace detail
|
||||||
} // mock
|
class object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
object() : impl_(std::make_shared<detail::object_impl>()) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~object() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::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);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace mock
|
||||||
|
|
||||||
#endif // MOCK_OBJECT_HPP_INCLUDED
|
#endif // MOCK_OBJECT_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,14 @@
|
||||||
#include "detail/sequence_impl.hpp"
|
#include "detail/sequence_impl.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace mock
|
namespace mock {
|
||||||
|
class sequence
|
||||||
{
|
{
|
||||||
class sequence
|
public:
|
||||||
{
|
sequence() : impl_(std::make_shared<detail::sequence_impl>()) {}
|
||||||
public:
|
|
||||||
sequence()
|
|
||||||
: impl_( std::make_shared< detail::sequence_impl >() )
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::shared_ptr< detail::sequence_impl > impl_;
|
std::shared_ptr<detail::sequence_impl> impl_;
|
||||||
};
|
};
|
||||||
} // mock
|
} // namespace mock
|
||||||
|
|
||||||
#endif // MOCK_SEQUENCE_HPP_INCLUDED
|
#endif // MOCK_SEQUENCE_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -13,33 +13,24 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#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
|
struct holder
|
||||||
{
|
{
|
||||||
|
|
@ -48,16 +39,14 @@ namespace conversion
|
||||||
holder& operator=(const holder&) = delete;
|
holder& operator=(const holder&) = delete;
|
||||||
|
|
||||||
virtual ~holder() = default;
|
virtual ~holder() = default;
|
||||||
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
|
||||||
|
|
@ -69,72 +58,57 @@ namespace conversion
|
||||||
|
|
||||||
struct any
|
struct any
|
||||||
{
|
{
|
||||||
template< typename T >
|
template<typename T>
|
||||||
any( const T& t ): h_( std::make_unique< holder_imp<T> >( t ) )
|
any(const T& t) : h_(std::make_unique<holder_imp<T>>(t))
|
||||||
{}
|
{}
|
||||||
std::unique_ptr<holder> h_;
|
std::unique_ptr<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
|
||||||
|
|
|
||||||
|
|
@ -12,31 +12,30 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace mock
|
namespace mock {
|
||||||
|
template<class T>
|
||||||
|
struct unwrap_reference
|
||||||
{
|
{
|
||||||
template<class T>
|
using type = T;
|
||||||
struct unwrap_reference
|
};
|
||||||
{
|
template<class T>
|
||||||
using type = T;
|
struct unwrap_reference<std::reference_wrapper<T>>
|
||||||
};
|
{
|
||||||
template<class T>
|
using type = T;
|
||||||
struct unwrap_reference<std::reference_wrapper<T>>
|
};
|
||||||
{
|
template<class T>
|
||||||
using type = T;
|
struct unwrap_reference<const std::reference_wrapper<T>>
|
||||||
};
|
{
|
||||||
template<class T>
|
using type = T;
|
||||||
struct unwrap_reference<const std::reference_wrapper<T>>
|
};
|
||||||
{
|
template<class T>
|
||||||
using type = T;
|
using unwrap_reference_t = typename unwrap_reference<T>::type;
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
using unwrap_reference_t = typename unwrap_reference<T>::type;
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
BOOST_FORCEINLINE unwrap_reference_t<T>& unwrap_ref( T& t ) noexcept
|
BOOST_FORCEINLINE unwrap_reference_t<T>& unwrap_ref(T& t) noexcept
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace mock
|
||||||
|
|
||||||
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
|
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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
|
|
@ -9,68 +9,68 @@
|
||||||
#include <turtle/detail/invocation.hpp>
|
#include <turtle/detail/invocation.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,110 +9,115 @@
|
||||||
#include <turtle/detail/is_functor.hpp>
|
#include <turtle/detail/is_functor.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/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/bind.hpp>
|
#include <boost/bind/bind.hpp>
|
||||||
#include <boost/bind/placeholders.hpp>
|
#include <boost/bind/placeholders.hpp>
|
||||||
|
#include <boost/function.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
struct declared_but_not_defined;
|
||||||
|
static_assert(!mock::detail::is_functor<declared_but_not_defined, int>::value, "Should not be a functor");
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void is_functor(T)
|
||||||
{
|
{
|
||||||
struct declared_but_not_defined;
|
static_assert(mock::detail::is_functor<T, int>::value, "Should be a functor taking an int");
|
||||||
static_assert( !mock::detail::is_functor< declared_but_not_defined, int >::value, "Should not be a functor" );
|
}
|
||||||
|
template<typename T>
|
||||||
template< typename T >
|
void is_not_functor(T)
|
||||||
void is_functor( T )
|
{
|
||||||
{
|
static_assert(!mock::detail::is_functor<T, int>::value, "Should not be a functor taking an int");
|
||||||
static_assert( mock::detail::is_functor< T, int >::value, "Should be a functor taking an int");
|
|
||||||
}
|
|
||||||
template< typename T >
|
|
||||||
void is_not_functor( T )
|
|
||||||
{
|
|
||||||
static_assert( !mock::detail::is_functor< T, int >::value, "Should not be a functor taking an int" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void f0() {}
|
|
||||||
bool f1( int ) { return false; }
|
|
||||||
bool f2( std::string, int ) { return false; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( data_is_not_functor )
|
void f0() {}
|
||||||
|
bool f1(int)
|
||||||
{
|
{
|
||||||
is_not_functor( 42 );
|
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 )
|
BOOST_AUTO_TEST_CASE(function_is_functor)
|
||||||
{
|
{
|
||||||
is_not_functor( f0 );
|
is_not_functor(f0);
|
||||||
is_functor( f1 );
|
is_functor(f1);
|
||||||
is_not_functor( f2 );
|
is_not_functor(f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( function_pointer_is_functor )
|
BOOST_AUTO_TEST_CASE(function_pointer_is_functor)
|
||||||
{
|
{
|
||||||
is_not_functor( &f0 );
|
is_not_functor(&f0);
|
||||||
is_functor( &f1 );
|
is_functor(&f1);
|
||||||
is_not_functor( &f2 );
|
is_not_functor(&f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor )
|
BOOST_AUTO_TEST_CASE(std_ptr_fun_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( std::ptr_fun( &f1 ) );
|
is_functor(std::ptr_fun(&f1));
|
||||||
is_not_functor( std::ptr_fun( &f2 ) );
|
is_not_functor(std::ptr_fun(&f2));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( std_bind_first_is_functor )
|
BOOST_AUTO_TEST_CASE(std_bind_first_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( std::bind1st( std::ptr_fun( &f2 ), "" ) );
|
is_functor(std::bind1st(std::ptr_fun(&f2), ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( bind_is_functor )
|
BOOST_AUTO_TEST_CASE(bind_is_functor)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
#if BOOST_VERSION >= 106000
|
#if BOOST_VERSION >= 106000
|
||||||
using namespace boost::placeholders;
|
using namespace boost::placeholders;
|
||||||
#endif
|
#endif
|
||||||
is_functor( boost::bind( &f0 ) );
|
is_functor(boost::bind(&f0));
|
||||||
is_functor( boost::bind( &f1, _1 ) );
|
is_functor(boost::bind(&f1, _1));
|
||||||
is_functor( boost::bind( &f2, "", _1 ) );
|
is_functor(boost::bind(&f2, "", _1));
|
||||||
}
|
}
|
||||||
is_functor( std::bind( &f0 ) );
|
is_functor(std::bind(&f0));
|
||||||
is_functor( std::bind( &f1, std::placeholders::_1 ) );
|
is_functor(std::bind(&f1, std::placeholders::_1));
|
||||||
is_functor( std::bind( &f2, "", std::placeholders::_1 ) );
|
is_functor(std::bind(&f2, "", std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( boost_lambda_is_functor )
|
BOOST_AUTO_TEST_CASE(boost_lambda_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( boost::lambda::_1 < 42 );
|
is_functor(boost::lambda::_1 < 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( boost_phoenix_is_functor )
|
BOOST_AUTO_TEST_CASE(boost_phoenix_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( boost::phoenix::arg_names::arg1 < 42 );
|
is_functor(boost::phoenix::arg_names::arg1 < 42);
|
||||||
is_functor( boost::phoenix::arg_names::_1 < 42 );
|
is_functor(boost::phoenix::arg_names::_1 < 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( boost_function_is_functor )
|
BOOST_AUTO_TEST_CASE(boost_function_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( boost::function< void(int) >() );
|
is_functor(boost::function<void(int)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( std_function_is_functor )
|
BOOST_AUTO_TEST_CASE(std_function_is_functor)
|
||||||
{
|
{
|
||||||
is_functor( std::function< void(int) >() );
|
is_functor(std::function<void(int)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( cxx11_lambda_is_functor )
|
BOOST_AUTO_TEST_CASE(cxx11_lambda_is_functor)
|
||||||
{
|
{
|
||||||
is_not_functor( []() {} );
|
is_not_functor([]() {});
|
||||||
is_functor( []( int ) {} );
|
is_functor([](int) {});
|
||||||
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&) {});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,17 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
static_assert( std::is_same< void(), MOCK_SIGNATURE(method_1) >::value, "!");
|
static_assert(std::is_same<void(), MOCK_SIGNATURE(method_1)>::value, "!");
|
||||||
static_assert( std::is_same< float( int ), MOCK_SIGNATURE(method_2) >::value, "!");
|
static_assert(std::is_same<float(int), MOCK_SIGNATURE(method_2)>::value, "!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,218 +10,216 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
template<typename T>
|
||||||
|
std::string to_string(const T& t)
|
||||||
{
|
{
|
||||||
template< typename T >
|
std::ostringstream s;
|
||||||
std::string to_string( const T& t)
|
s << mock::detail::make_type_name(t);
|
||||||
{
|
return s.str();
|
||||||
std::ostringstream s;
|
|
||||||
s << mock::detail::make_type_name(t);
|
|
||||||
return s.str();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // 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", to_string( 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", to_string(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>>()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,16 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
struct my_base
|
||||||
{
|
{
|
||||||
struct my_base
|
virtual ~my_base() = default;
|
||||||
{
|
virtual void my_method() = 0;
|
||||||
virtual ~my_base() = default;
|
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 )
|
MOCK_METHOD(my_method, 0)
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@ MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT(my_method, 1, void(int), my_method)
|
MOCK_METHOD_EXT(my_method, 1, void(int), my_method)
|
||||||
};
|
};
|
||||||
bool constraint(int, int) { return true; }
|
bool constraint(int, int)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
|
MOCK_METHOD_EXT(my_method, 1, void(int), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).with( "42" );
|
MOCK_EXPECT(c.my_method).with("42");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
|
MOCK_METHOD_EXT(my_method, 1, void(int), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).with( mock::equal( "42" ) );
|
MOCK_EXPECT(c.my_method).with(mock::equal("42"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 0, int(), my_method )
|
MOCK_METHOD_EXT(my_method, 0, int(), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).returns( std::string() );
|
MOCK_EXPECT(c.my_method).returns(std::string());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 0, std::string(), my_method )
|
MOCK_METHOD_EXT(my_method, 0, std::string(), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).returns( 42 );
|
MOCK_EXPECT(c.my_method).returns(42);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 0, void(), my_method )
|
MOCK_METHOD_EXT(my_method, 0, void(), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).returns( "42" );
|
MOCK_EXPECT(c.my_method).returns("42");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,14 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
struct my_base
|
||||||
{
|
{
|
||||||
struct my_base
|
virtual ~my_base() = default;
|
||||||
{
|
};
|
||||||
virtual ~my_base() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
MOCK_BASE_CLASS( my_class, my_base )
|
MOCK_BASE_CLASS(my_class, my_base)
|
||||||
{
|
{
|
||||||
MOCK_METHOD( my_method, 0 )
|
MOCK_METHOD(my_method, 0)
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,17 @@
|
||||||
|
|
||||||
#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() = default;
|
||||||
{
|
virtual void my_method(int, int, int, int, int, int, int, int, int, int) = 0;
|
||||||
virtual ~my_base() = default;
|
};
|
||||||
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 )
|
MOCK_METHOD(my_method, 10)
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,15 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
struct my_base
|
||||||
{
|
{
|
||||||
struct my_base
|
virtual ~my_base() = default;
|
||||||
{
|
virtual void my_method(int) = 0;
|
||||||
virtual ~my_base() = default;
|
};
|
||||||
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 )
|
MOCK_METHOD(my_method, 2)
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
MOCK_CLASS( my_class )
|
MOCK_CLASS(my_class)
|
||||||
{
|
{
|
||||||
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
|
MOCK_METHOD_EXT(my_method, 1, void(int), my_method)
|
||||||
};
|
};
|
||||||
void test_case()
|
void test_case()
|
||||||
{
|
{
|
||||||
my_class c;
|
my_class c;
|
||||||
MOCK_EXPECT( c.my_method ).with( 42, 42 );
|
MOCK_EXPECT(c.my_method).with(42, 42);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
#define MOCK_ERROR_POLICY mock_error
|
#define MOCK_ERROR_POLICY mock_error
|
||||||
#include <turtle/detail/singleton.hpp>
|
#include <turtle/detail/singleton.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <stdexcept>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#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,59 +47,56 @@ 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*/, const char* /*file*/, int /*line*/ )
|
static void call(const Context& /*context*/, 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, const char* file = "", int line = 0 )
|
static void fail(const std::string& message, const Context& context, const char* file = "", int line = 0)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << context; // Context can be streamed
|
s << context; // Context can be streamed
|
||||||
mock_error_data.fail( message, s.str(), file, line );
|
mock_error_data.fail(message, s.str(), 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
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,15 @@
|
||||||
#include <turtle/constraint.hpp>
|
#include <turtle/constraint.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,386 +9,372 @@
|
||||||
#include <turtle/constraints.hpp>
|
#include <turtle/constraints.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.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;
|
||||||
auto c = mock::equal( std::cref( s ) );
|
auto c = mock::equal(std::cref(s));
|
||||||
s = "string";
|
s = "string";
|
||||||
BOOST_CHECK( c.c_( "string" ) );
|
BOOST_CHECK(c.c_("string"));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( equal_constraint_deref )
|
BOOST_AUTO_TEST_CASE(equal_constraint_deref)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
int i = 3;
|
int i = 3;
|
||||||
BOOST_CHECK( mock::equal( 3 ).c_( &i ) );
|
BOOST_CHECK(mock::equal(3).c_(&i));
|
||||||
BOOST_CHECK( ! mock::equal( 7 ).c_( &i ) );
|
BOOST_CHECK(!mock::equal(7).c_(&i));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int* i = 0;
|
int* i = 0;
|
||||||
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
|
BOOST_CHECK(!mock::equal(3).c_(i));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( same_constraint )
|
BOOST_AUTO_TEST_CASE(same_constraint)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
BOOST_CHECK_EQUAL( i, j );
|
BOOST_CHECK_EQUAL(i, j);
|
||||||
BOOST_CHECK( ! mock::same( i ).c_( j ) );
|
BOOST_CHECK(!mock::same(i).c_(j));
|
||||||
BOOST_CHECK( mock::same( i ).c_( i ) );
|
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);
|
||||||
auto c = mock::same( i );
|
auto c = mock::same(i);
|
||||||
BOOST_CHECK( ! c.c_( j ) );
|
BOOST_CHECK(!c.c_(j));
|
||||||
BOOST_CHECK( c.c_( i ) );
|
BOOST_CHECK(c.c_(i));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::nullptr_t p;
|
std::nullptr_t p;
|
||||||
BOOST_CHECK( mock::same( p ).c_( p ) );
|
BOOST_CHECK(mock::same(p).c_(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<std::reference_wrapper<const int>>> c = mock::assign(std::cref(j));
|
||||||
mock::detail::assign<
|
BOOST_CHECK(c.c_(i));
|
||||||
std::reference_wrapper< const int >
|
BOOST_CHECK_EQUAL(1, i);
|
||||||
>
|
|
||||||
> c = mock::assign( std::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;
|
||||||
auto c = mock::assign( std::cref( j ) );
|
auto c = mock::assign(std::cref(j));
|
||||||
BOOST_CHECK( c.c_( &i ) );
|
BOOST_CHECK(c.c_(&i));
|
||||||
BOOST_CHECK_EQUAL( 1, 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;
|
||||||
auto c = mock::assign( std::cref( j ) );
|
auto c = mock::assign(std::cref(j));
|
||||||
BOOST_CHECK( c.c_( i ) );
|
BOOST_CHECK(c.c_(i));
|
||||||
BOOST_CHECK_EQUAL( j, 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( 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);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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_( std::move( j ) ) );
|
BOOST_CHECK(mock::retrieve(i).c_(std::move(j)));
|
||||||
BOOST_REQUIRE( i );
|
BOOST_REQUIRE(i);
|
||||||
BOOST_CHECK_EQUAL( 3, *i );
|
BOOST_CHECK_EQUAL(3, *i);
|
||||||
BOOST_CHECK( !j );
|
BOOST_CHECK(!j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
auto c = mock::contain( std::cref( s ) );
|
auto c = mock::contain(std::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<std::reference_wrapper<const std::string>>> c =
|
||||||
mock::detail::contain<
|
mock::contain(std::cref(s));
|
||||||
std::reference_wrapper< const std::string >
|
|
||||||
>
|
|
||||||
> c = mock::contain( std::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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,14 @@
|
||||||
#include <turtle/exception.hpp>
|
#include <turtle/exception.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/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
|
|
@ -9,70 +9,66 @@
|
||||||
#include <turtle/detail/function.hpp>
|
#include <turtle/detail/function.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/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, std::cref( i ) ) );
|
BOOST_CHECK(match(3, std::cref(i)));
|
||||||
BOOST_CHECK( ! match( 4, std::cref( i ) ) );
|
BOOST_CHECK(!match(4, std::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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,32 +8,31 @@
|
||||||
|
|
||||||
#include "mock_error.hpp"
|
#include "mock_error.hpp"
|
||||||
#include <turtle/mock.hpp>
|
#include <turtle/mock.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <boost/preprocessor/repetition/enum.hpp>
|
#include <boost/preprocessor/repetition/enum.hpp>
|
||||||
|
#include <boost/test/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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,404 +11,385 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
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_CLASS( mock_class_with_operator )
|
MOCK_CONST_METHOD_EXT(operator+=, 1, mock_class_with_operator &(int), addition)
|
||||||
{
|
};
|
||||||
MOCK_CONST_METHOD_EXT( operator+=, 1, mock_class_with_operator&( int ), addition )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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( std::ref( m ) );
|
MOCK_EXPECT(m.addition).once().returns(std::ref(m));
|
||||||
m += 1;
|
m += 1;
|
||||||
CHECK_CALLS( 1 );
|
CHECK_CALLS(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
MOCK_CLASS(mock_class_with_conversion_operator)
|
||||||
{
|
{
|
||||||
MOCK_CLASS( mock_class_with_conversion_operator )
|
MOCK_CONVERSION_OPERATOR(operator, int, conversion)
|
||||||
{
|
};
|
||||||
MOCK_CONVERSION_OPERATOR( operator, int, conversion )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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) };
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
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_template_class_with_conversion_operator< int > m;
|
MOCK_CONST_CONVERSION_OPERATOR(operator, int, conversion)
|
||||||
MOCK_EXPECT( m.conversion ).once().returns( 42 );
|
};
|
||||||
BOOST_CHECK_EQUAL( 42, static_cast< int >( m ) );
|
} // namespace
|
||||||
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_CLASS( mock_class_with_non_const_conversion_operator )
|
MOCK_CONST_CONVERSION_OPERATOR(operator, int, conversion)
|
||||||
{
|
};
|
||||||
MOCK_CONST_CONVERSION_OPERATOR( operator, int, conversion )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
template< typename T >
|
MOCK_CONST_CONVERSION_OPERATOR_TPL(operator, T, conversion)
|
||||||
MOCK_CLASS( mock_template_class_with_const_conversion_operator )
|
};
|
||||||
{
|
} // namespace
|
||||||
MOCK_CONST_CONVERSION_OPERATOR_TPL( operator, T, conversion )
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE( mock_template_const_conversion_operator, mock_error_fixture )
|
BOOST_FIXTURE_TEST_CASE(mock_template_const_conversion_operator, mock_error_fixture)
|
||||||
{
|
{
|
||||||
mock_template_class_with_const_conversion_operator< int > m;
|
mock_template_class_with_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 {
|
||||||
|
template<typename T>
|
||||||
|
MOCK_CLASS(mock_template_class_with_non_const_conversion_operator)
|
||||||
{
|
{
|
||||||
template< typename T >
|
MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(operator, T, conversion)
|
||||||
MOCK_CLASS( mock_template_class_with_non_const_conversion_operator )
|
};
|
||||||
{
|
} // namespace
|
||||||
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_template_non_const_conversion_operator, mock_error_fixture)
|
||||||
{
|
{
|
||||||
mock_template_class_with_non_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_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)
|
||||||
MOCK_CONST_METHOD_EXT( my_method, 1, void( int ), my_method )
|
};
|
||||||
MOCK_CONST_METHOD_EXT( my_method_2, 1, void( int ), my_method_2 )
|
} // namespace
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE( MOCK_CONST_METHOD_EXT_macro_defines_a_bindable_method, mock_error_fixture )
|
BOOST_FIXTURE_TEST_CASE(MOCK_CONST_METHOD_EXT_macro_defines_a_bindable_method, mock_error_fixture)
|
||||||
{
|
{
|
||||||
my_mock m;
|
my_mock m;
|
||||||
const auto f = std::bind( &my_mock::my_method, &m, 42 );
|
const auto f = std::bind(&my_mock::my_method, &m, 42);
|
||||||
(void) f;
|
(void)f;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
std::shared_ptr< my_mock > m( new my_mock );
|
std::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 std::shared_ptr< my_mock > m( new my_mock );
|
const std::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(f, void(T));
|
||||||
struct tpl_functor_class
|
};
|
||||||
{
|
} // namespace
|
||||||
MOCK_FUNCTOR( f, void( T ) );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE( mock_functor_reset, mock_error_fixture )
|
BOOST_FIXTURE_TEST_CASE(mock_functor_reset, mock_error_fixture)
|
||||||
{
|
{
|
||||||
MOCK_FUNCTOR( f, void() );
|
MOCK_FUNCTOR(f, void());
|
||||||
MOCK_RESET( f );
|
MOCK_RESET(f);
|
||||||
mock::reset( f );
|
mock::reset(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE( mock_functor_verify, mock_error_fixture )
|
BOOST_FIXTURE_TEST_CASE(mock_functor_verify, mock_error_fixture)
|
||||||
{
|
{
|
||||||
MOCK_FUNCTOR( f, void() );
|
MOCK_FUNCTOR(f, void());
|
||||||
MOCK_VERIFY( f );
|
MOCK_VERIFY(f);
|
||||||
mock::verify( f );
|
mock::verify(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE( mock_functor_is_named, mock_error_fixture )
|
BOOST_FIXTURE_TEST_CASE(mock_functor_is_named, mock_error_fixture)
|
||||||
{
|
{
|
||||||
MOCK_FUNCTOR( f, void() );
|
MOCK_FUNCTOR(f, void());
|
||||||
BOOST_CHECK_EQUAL( "f", to_string( MOCK_HELPER( f ) ) );
|
BOOST_CHECK_EQUAL("f", to_string(MOCK_HELPER(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
MOCK_FUNCTION(mock_function, 1, float(int), mock_function)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL( "mock_function", to_string( MOCK_HELPER( mock_function ) ) );
|
MOCK_STATIC_METHOD(f, 1, float(int), f)
|
||||||
}
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
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, MOCK_PROTECT_FUNCTION_SIG(std::map<int, int>()), m0)
|
||||||
}
|
MOCK_STATIC_METHOD(m1, 0, MOCK_PROTECT_FUNCTION_SIG(std::map<int, int>()), m1)
|
||||||
|
MOCK_FUNCTOR(f0, MOCK_PROTECT_FUNCTION_SIG(std::map<int, int>()));
|
||||||
|
};
|
||||||
|
MOCK_FUNCTION(fun0, 0, MOCK_PROTECT_FUNCTION_SIG(std::map<int, int>()), fun0)
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
|
struct base
|
||||||
{
|
{
|
||||||
MOCK_CLASS( round_parenthesized_signature )
|
virtual ~base() = default;
|
||||||
{
|
|
||||||
MOCK_METHOD_EXT( m0, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()), m0 )
|
|
||||||
MOCK_STATIC_METHOD( m1, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()), m1 )
|
|
||||||
MOCK_FUNCTOR( f0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()) );
|
|
||||||
};
|
|
||||||
MOCK_FUNCTION( fun0, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()), fun0 )
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
virtual void m1() = 0;
|
||||||
|
virtual void m10() const = 0;
|
||||||
|
virtual void m11() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
MOCK_BASE_CLASS(variadic, base)
|
||||||
{
|
{
|
||||||
struct base
|
MOCK_METHOD(m1, 0)
|
||||||
{
|
MOCK_METHOD(m2, 0, void())
|
||||||
virtual ~base() = default;
|
MOCK_METHOD(m3, 0, void(), m3)
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
virtual void m1() = 0;
|
template<typename T>
|
||||||
virtual void m10() const = 0;
|
MOCK_BASE_CLASS(variadic_tpl, base)
|
||||||
virtual void m11() = 0;
|
{
|
||||||
};
|
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_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( variadic, base )
|
MOCK_BASE_CLASS(comma_base, std::map<int, int>)
|
||||||
{
|
{};
|
||||||
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_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 >
|
MOCK_FUNCTION(fun1, 0, void())
|
||||||
MOCK_BASE_CLASS( variadic_tpl, base )
|
MOCK_FUNCTION(fun2, 0, void(), fun2)
|
||||||
{
|
MOCK_FUNCTION(fun3, 0, MOCK_PROTECT_FUNCTION_SIG(std::map<int, int>()))
|
||||||
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_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_FUNCTOR(f_variadic, std::map<int, int>());
|
||||||
{};
|
} // namespace
|
||||||
|
|
||||||
MOCK_FUNCTION( fun1, 0, void() )
|
|
||||||
MOCK_FUNCTION( fun2, 0, void(), fun2 )
|
|
||||||
MOCK_FUNCTION( fun3, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()) )
|
|
||||||
|
|
||||||
MOCK_FUNCTOR( f_variadic, std::map< int, int >() );
|
|
||||||
}
|
|
||||||
|
|
||||||
#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() = default;
|
||||||
{
|
|
||||||
virtual ~base() = default;
|
|
||||||
|
|
||||||
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_CONSTRUCTOR(MOCK_STDCALL derived, 0, (), derived)
|
||||||
MOCK_DESTRUCTOR( MOCK_STDCALL ~derived, derived )
|
MOCK_DESTRUCTOR(MOCK_STDCALL ~derived, derived)
|
||||||
MOCK_CONVERSION_OPERATOR( MOCK_STDCALL operator, int, to_int )
|
MOCK_CONVERSION_OPERATOR(MOCK_STDCALL operator, int, to_int)
|
||||||
MOCK_METHOD_EXT( MOCK_STDCALL m1, 0, void(), m1 )
|
MOCK_METHOD_EXT(MOCK_STDCALL m1, 0, void(), m1)
|
||||||
MOCK_METHOD_EXT( MOCK_STDCALL m2, 0, void(), m2 )
|
MOCK_METHOD_EXT(MOCK_STDCALL m2, 0, void(), m2)
|
||||||
MOCK_METHOD( MOCK_STDCALL m3, 0, void(), m3 )
|
MOCK_METHOD(MOCK_STDCALL m3, 0, void(), m3)
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
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::detail::make_type_name(o), "name"); }
|
||||||
{
|
object o;
|
||||||
fixture()
|
mock::detail::function<void()> e;
|
||||||
{
|
};
|
||||||
mock::detail::configure( o, e, "instance", mock::detail::make_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::detail::make_type_name(o2), "name" );
|
mock::detail::configure(o2, e, "instance", mock::detail::make_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)
|
||||||
{
|
{
|
||||||
auto o2 = std::make_unique<object>();
|
auto o2 = std::make_unique<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::detail::make_type_name(*o2), "name" );
|
mock::detail::configure(*o2, e, "instance", mock::detail::make_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()" );
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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/unit_test.hpp>
|
#include <boost/test/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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue