Merge pull request #88 from Flamefire/c++11

Port to C++11/C++14 removing superflous Boost facilities
This commit is contained in:
Alexander Grund 2022-01-23 19:40:34 +01:00 committed by GitHub
commit b5bb500bd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 1468 additions and 1690 deletions

160
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,160 @@
# Copyright 2022 Alexander Grund
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
NET_RETRY_COUNT: 5
DOCBOOK_XSL_DIR: /usr/share/xml/docbook/stylesheet/docbook-xsl
DOCBOOK_DTD_DIR: /usr/share/xml/docbook/schema/dtd/4.2
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- { compiler: gcc-5, cxxstd: '14', boostBranch: boost-1.65.0, os: ubuntu-18.04 }
- { compiler: gcc-5, cxxstd: '14', boostBranch: boost-1.77.0, os: ubuntu-18.04 }
- { compiler: gcc-5, cxxstd: '14,1z', boostBranch: master, os: ubuntu-18.04 }
- { compiler: gcc-11,cxxstd: '14,17,20', boostBranch: master, os: ubuntu-20.04 }
# Linux, clang
- { compiler: clang-5.0, cxxstd: '14', boostBranch: boost-1.65.0, os: ubuntu-18.04 }
- { compiler: clang-5.0, cxxstd: '14', boostBranch: boost-1.77.0, os: ubuntu-18.04 }
- { compiler: clang-5.0, cxxstd: '14,1z', boostBranch: master, os: ubuntu-18.04 }
- { compiler: clang-12, cxxstd: '14,17,20', boostBranch: master, os: ubuntu-20.04 }
- { name: Collect coverage, coverage: yes,
compiler: gcc-8, cxxstd: '14', boostBranch: master, os: ubuntu-20.04 }
timeout-minutes: 120
runs-on: ${{matrix.os}}
env:
BOOST_ROOT: ${{github.workspace}}/boost-root
PROJECT_DIR: ${{github.workspace}}/repo
steps:
- uses: actions/checkout@v2
if: '!matrix.coverage'
with:
path: ${{env.PROJECT_DIR}}
- uses: actions/checkout@v2
if: 'matrix.coverage'
with:
path: ${{env.PROJECT_DIR}}
fetch-depth: 0
# Checking out Boost and all its submodules takes ages...
- name: Cache Boost
uses: actions/cache@v2
with:
path: boost-root
key: boost-${{matrix.boostBranch}}
- name: Checkout Boost
uses: actions/checkout@v2
with:
repository: boostorg/boost
ref: ${{matrix.boostBranch}}
submodules: true
path: boost-root
persist-credentials: false
- name: Install packages and setup env
run: |
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
CXX=${{matrix.compiler}}
CXX="${CXX/gcc-/g++-}"
# Package names are g++-* and clang-*, so set this before correcting CXX for Clang
pkgs="$CXX xsltproc docbook-xsl docbook-xml lcov ccache"
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs
CXX="ccache ${CXX/clang-/clang++-}"
echo "CXX=$CXX" >> $GITHUB_ENV
echo "CC=${{matrix.compiler}}" >> $GITHUB_ENV
if [[ "$CXX" =~ clang ]]; then
B2_TOOLSET=clang
else
B2_TOOLSET=gcc
fi
echo "B2_TOOLSET=$B2_TOOLSET" >> $GITHUB_ENV
echo "using $B2_TOOLSET : : $CXX ;" > ~/user-config.jam
- name: Cache ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{matrix.os}}-${{matrix.compiler}}-${{matrix.boostBranch}}
- name: Prepare boost
working-directory: boost-root
run: ./bootstrap.sh && ./b2 headers
- name: Boost build
working-directory: ${{env.PROJECT_DIR}}
run: |
if [[ "${{matrix.boostBranch}}" == "master" ]]; then
B2_FLAGS="cxxstd=${{matrix.cxxstd}}"
else
B2_FLAGS="cxxflags=-std=c++${{matrix.cxxstd}}"
fi
if [[ "${{matrix.coverage}}" == "yes" ]]; then
B2_FLAGS="$B2_FLAGS cxxflags=--coverage linkflags=--coverage"
fi
scripts/build.sh --toolset=$B2_TOOLSET $B2_FLAGS -j3
- name: Collect coverage
if: matrix.coverage
working-directory: ${{env.PROJECT_DIR}}
run: |
lcov --version
lcov --gcov-tool=gcov-8 --directory "$PROJECT_DIR/test" --base-directory "$BOOST_ROOT" --capture --output-file all.info
# dump a summary on the console
lcov --list all.info
# Limit to our files (header-only in this case)
lcov --extract all.info "$PROJECT_DIR/include/*" --output-file coverage.info
# Output what was collected
lcov --list coverage.info
- name: Upload coverage
if: matrix.coverage
uses: coverallsapp/github-action@master
with:
path-to-lcov: ${{env.PROJECT_DIR}}/coverage.info
github-token: ${{secrets.GITHUB_TOKEN}}
- name: Build required boost libs
working-directory: boost-root
run: |
./b2 --toolset=$B2_TOOLSET --with-test --with-thread --with-chrono --with-system --with-atomic --with-date_time -a -j3
# Add lib folder to LD_LIBRARY_PATH, so the tests can load them
echo "LD_LIBRARY_PATH=$PWD/stage/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
- name: CMake build
working-directory: ${{env.PROJECT_DIR}}
run: |
mkdir build && cd build
CXX_STANDARD="${{matrix.cxxstd}}"
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-std=c++${CXX_STANDARD##*,}" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_VERBOSE_MAKEFILE=ON
cmake --build . --config Debug -- -j3
ctest --output-on-failure --build-config Debug -j3
- name: Cleanup Boost folder
if: ${{ always() }}
working-directory: boost-root
run: git clean -fxd

View file

@ -1,85 +0,0 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Copyright Antony Polukhin 2014.
# Copyright Alexander Grund 2020.
language: cpp
branches:
only:
- master
env:
- CXX_STANDARD=17 BRANCH_TO_TEST=master
- CXX_STANDARD=14 BRANCH_TO_TEST=master
- CXX_STANDARD=14 BRANCH_TO_TEST=boost-1.58.0
- CXX_STANDARD=14 BRANCH_TO_TEST=boost-1.59.0
- CXX_STANDARD=14 BRANCH_TO_TEST=boost-1.67.0
compiler:
- clang
- gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise
packages:
- gcc-5
- g++-5
- clang-5.0
- lld-5.0
- xsltproc
- docbook-xsl
- docbook-xml
- python-yaml
- lcov
before_install:
- DOCBOOK_XSL_DIR=/usr/share/xml/docbook/stylesheet/docbook-xsl
- DOCBOOK_DTD_DIR=/usr/share/xml/docbook/schema/dtd/4.2
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 60 --slave /usr/bin/g++ g++ /usr/bin/g++-5
- gcc --version
# Files, which coverage results must be ignored (files from other projects). Example: - IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/path.cpp'
- IGNORE_COVERAGE='*/boost-local/*'
# From this point and below code is same for all the Boost libs
# Cloning Boost libraries (fast nondeep cloning)
- PROJECT_DIR=`pwd`
- git --version
- BOOST_ROOT=$HOME/boost-local
- git clone -b $BRANCH_TO_TEST --depth 1 https://github.com/boostorg/boost.git $BOOST_ROOT
- cd $BOOST_ROOT
- git submodule update --init --depth 1
- ./bootstrap.sh
- ./b2 headers
script:
- cd $PROJECT_DIR
- export BOOST_ROOT
# `--coverage` flags required to generate coverage info for Coveralls
- scripts/build.sh --toolset=$CC "cxxflags=-std=c++$CXX_STANDARD -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations --coverage" "linkflags=--coverage" -j3
# CMake build
- cd $BOOST_ROOT && ./b2 --with-test --with-thread --with-chrono --with-system --with-atomic --with-date_time -a -j3 # Build required libs
- mkdir $PROJECT_DIR/build && cd $PROJECT_DIR/build
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-std=c++$CXX_STANDARD"
- cmake --build . --config Debug -- -j3
- ctest --output-on-failure --build-config Debug
after_success:
- cd $PROJECT_DIR
# Preparing Coveralls data by
# ... changing data format to a readable one
- lcov --directory "$PROJECT_DIR/test" --capture --output-file coverage.info
# ... erasing /test/ /doc/example/ folder data
- lcov --remove coverage.info "/usr*" $IGNORE_COVERAGE "*/test/*" "*/doc/example/*" -o coverage.info
# Output what was collected
- lcov --list coverage.info
# Sending data to Coveralls
- gem install coveralls-lcov
- coveralls-lcov coverage.info

View file

@ -13,7 +13,6 @@ else()
endif()
option(TURTLE_INSTALL "Enable to add install target" ${IS_ROOT_PROJECT})
option(TURTLE_AUTO_PTR "Enable support for auto_ptr" OFF)
# Default boost libs are static on windows and dynamic on linux
if(WIN32 AND NOT DEFINED Boost_USE_STATIC_LIBS)
@ -27,10 +26,9 @@ configure_file(version.hpp.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/turtle/vers
add_library(turtle INTERFACE)
add_library(turtle::turtle ALIAS turtle)
target_include_directories(turtle INTERFACE $<BUILD_INTERFACE:include;${CMAKE_CURRENT_BINARY_DIR}/include>)
target_compile_features(turtle INTERFACE cxx_std_14)
target_link_libraries(turtle INTERFACE Boost::boost Boost::disable_autolinking)
if(NOT TURTLE_AUTO_PTR)
target_compile_definitions(turtle INTERFACE MOCK_NO_AUTO_PTR)
endif()
if(BUILD_TESTING)
add_subdirectory(test)

View file

@ -14,7 +14,7 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
BOOST: 1_60_0
BOOST: 1_65_1
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
BOOST: 1_65_1
@ -26,10 +26,10 @@ environment:
CXX_STANDARD: 14
# CXX_STANDARD: 17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
BOOST: 1_60_0
BOOST: 1_65_1
CMAKE: true
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
BOOST: 1_71_0
BOOST: 1_77_0
CMAKE: true
install:

View file

@ -11,6 +11,9 @@
Released -
* Allow auto-deducing signature in `MOCK_METHOD_(NON_)CONST`
* Replaced Boost facilities with std:: equivalents where existing in C++14
* Deprecated MOCK_FUNCTOR_TPL as no longer required, use the non _TPL variant even for templates
* Added MOCK_PROTECT_FUNCTION_SIG to pass function signatures with commas in the return type
[endsect]

View file

@ -98,7 +98,7 @@ The purpose of the 'near' template function is to :
* remove the burden of specifying the template parameter when instantiating near_constraint
* wrap the constraint in a mock::constraint so that it plays nicely with !, && and ||.
The use of boost::unwrap_ref provides support for passing arguments as references with boost::ref and boost::cref and delaying their initialization, for instance :
The use of mock::unwrap_ref provides support for passing arguments as references with std::ref and std::cref and delaying their initialization, for instance :
[near_constraint_cref_test]

View file

@ -9,15 +9,16 @@
#ifndef CALCULATOR
#define CALCULATOR
class view;
#include "view.hpp"
//[ calculator
class calculator
{
view& v;
public:
calculator( view& v );
calculator( view& v ): v(v){}
void add( int a, int b ); // the result will be sent to the view 'v'
void add( int a, int b ){ v.display(a + b); } // the result will be sent to the view 'v'
};
//]

View file

@ -12,6 +12,7 @@
//]
#include "calculator.hpp"
#include "mock_view.hpp"
#include <boost/test/unit_test.hpp>
//[ mock_stream_user_type
namespace user_namespace
@ -36,7 +37,7 @@ bool custom_constraint( int actual )
//]
//[ custom_constraint_free_function_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_free_function )
{
mock_view v;
calculator c( v );
@ -64,7 +65,7 @@ struct custom_constraint
//]
//[ custom_constraint_functor_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_custom_constraint )
{
mock_view v;
calculator c( v );
@ -86,8 +87,7 @@ struct near_constraint
template< typename Actual >
bool operator()( Actual actual ) const
{
return std::abs( actual - boost::unwrap_ref( expected_ ) )
< boost::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 )
@ -109,7 +109,7 @@ mock::constraint< near_constraint< Expected > > near( Expected expected, Expecte
namespace near_constraint_test
{
//[ near_constraint_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one_near )
{
mock_view v;
calculator c( v );
@ -122,17 +122,44 @@ BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
namespace near_constraint_cref_test
{
//[ near_constraint_cref_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one_near_cref )
{
mock_view v;
calculator c( v );
int expected, threshold;
MOCK_EXPECT( v.display ).with( near( boost::cref( expected ), boost::cref( threshold ) ) );
int expected = 0, threshold = 0;
MOCK_EXPECT( v.display ).with( near( std::cref( expected ), std::cref( threshold ) ) );
expected = 42;
threshold = 1;
c.add( 41, 1 );
}
//]
// Example of a "strong type" float
struct float_wrapper{
float value;
float_wrapper(float value): value(value){}
operator float() const { return value; }
friend std::ostream& operator<<( std::ostream& s, const float_wrapper& f)
{
return s << f.value;
}
};
BOOST_AUTO_TEST_CASE( near_constraint_works_with_with_float_wrapper_and_cref )
{
mock_view v;
calculator c( v );
float_wrapper expected = 0, threshold = 0;
// This works even without the unwrap_ref
MOCK_EXPECT( v.display ).once().with( near( expected, threshold ) );
// 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
MOCK_EXPECT( v.display ).once().with( near( std::cref( expected ), std::cref( threshold ) ) );
expected = 42;
threshold = 1;
c.add(0, 0);
c.add(41, 1);
}
}
#undef MOCK_MAX_ARGS
@ -141,6 +168,11 @@ BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
#include <turtle/mock.hpp>
//]
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//[ custom_policy
template< typename Result >
struct custom_policy
@ -167,6 +199,10 @@ struct custom_policy
};
//]
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#undef MOCK_ERROR_POLICY
//[ define_custom_policy
#define MOCK_ERROR_POLICY custom_policy

View file

@ -6,14 +6,69 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <functional>
#include <string>
#include <sstream>
std::function<void()> error_handler_abort;
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 char* message, const std::string&, const char*, int)> error_handler_fail;
template< typename Result >
struct configurable_mock_error
{
static Result abort()
{
error_handler_abort();
return Result();
}
static void pass( const char* file, int line )
{
error_handler_pass(file, line);
}
template< typename Context >
static void call( const Context& context, const char* file, int line )
{
std::stringstream s;
s << context;
error_handler_call( s.str(), file, line );
}
template< typename Context >
static void fail( const char* message, const Context& context, const char* file = "", int line = 0 )
{
std::stringstream s;
s << context;
error_handler_fail( message, s.str(), file, line );
}
};
#define MOCK_ERROR_POLICY configurable_mock_error
#define MOCK_USE_BOOST_TEST
//[ prerequisite
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
//]
#include "calculator.hpp"
#include "mock_view.hpp"
struct Fixture
{
Fixture()
{
error_handler_abort = mock::error<void>::abort;
error_handler_pass = mock::error<void>::pass;
error_handler_call = mock::error<void>::call<std::string>;
error_handler_fail = mock::error<void>::fail<std::string>;
}
};
BOOST_FIXTURE_TEST_SUITE(GettingStarted, Fixture)
namespace phases
{
//[ phases
@ -30,7 +85,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace verify_reset
{
//[ verify_reset
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_reset )
{
mock_view v;
calculator c( v );
@ -49,7 +104,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace expectations
{
//[ expectations
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_expect )
{
mock_view v;
calculator c( v );
@ -63,7 +118,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace sequence
{
//[ sequence
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_then_1_plus_0_is_1 )
{
mock_view v;
calculator c( v );
@ -79,7 +134,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace several_sequences
{
//[ several_sequences
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( add_several_numbers_in_sequences )
{
mock_view v;
calculator c( v );
@ -94,6 +149,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
}
//]
}
BOOST_AUTO_TEST_SUITE_END()
namespace action
{
@ -112,13 +168,48 @@ MOCK_BASE_CLASS( mock_view, view )
class calculator
{
view& v;
public:
calculator( view& v );
calculator( view& v ): v(v) {}
void add( int a, int b );
void add( int a, int b ){ v.display(a + b); }
};
struct CatchFailureFixture: Fixture
{
static bool aborted;
static std::string fail_msg;
static void abort()
{
aborted = true;
}
static void fail( const std::string& message, const std::string&, const char* = "", int = 0 ){
fail_msg = message;
}
CatchFailureFixture()
{
error_handler_abort = abort;
error_handler_fail = fail;
}
void assert_failure(const std::string& required_message)
{
BOOST_CHECK(aborted);
BOOST_CHECK(fail_msg.find(required_message) != std::string::npos);
}
};
bool CatchFailureFixture::aborted = false;
std::string CatchFailureFixture::fail_msg;
struct AssertMissingAction: CatchFailureFixture{
void teardown(){
assert_failure("missing action");
}
};
BOOST_FIXTURE_TEST_SUITE( MissingReturnActionSuite, AssertMissingAction)
//[ action_test
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_with_action )
{
mock_view v;
calculator c( v );
@ -127,3 +218,5 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
}
//]
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,48 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
{
//[ limitations_comma_in_macro_problem
template< typename T1, typename T2 >
struct my_base_class
{};
//]
}
namespace limitations_comma_in_macro_solution_1
{
//[ limitations_comma_in_macro_solution_1
typedef my_base_class< int, int > my_base_type;
MOCK_BASE_CLASS( my_mock, my_base_type )
{};
//]
}
namespace limitations_comma_in_macro_solution_2
{
//[ limitations_comma_in_macro_solution_2
template< typename T1, typename T2 >
MOCK_BASE_CLASS( my_mock, my_base_class< T1 BOOST_PP_COMMA() T2 > )
{};
//]
}
namespace limitations_comma_in_macro_solution_3
{
//[ limitations_comma_in_macro_solution_3
template< typename T1, typename T2 >
struct my_mock : my_base_class< T1, T2 >, mock::object
{};
//]
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -35,7 +34,7 @@ namespace limitations_const_parameter_warning_explanation
//]
}
namespace limitations_const_parameter_warning_solution
namespace
{
//[ limitations_const_parameter_warning_solution
MOCK_BASE_CLASS( mock_base, base )
@ -48,3 +47,12 @@ namespace limitations_const_parameter_warning_solution
};
//]
}
BOOST_AUTO_TEST_CASE(check_method_stub_is_called)
{
mock_base b;
MOCK_EXPECT(b.method).once().with(1);
// Example user code taking a base* (or smart pointer variant)
auto callMethod = [](base* bPtr){ bPtr->method(1); };
callMethod(&b);
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -35,9 +34,7 @@ BOOST_AUTO_TEST_CASE( literal_zero )
//[ limitations_literal_zero_solution_2
MOCK_EXPECT( m.method ).with( mock::negate );
//]
#ifdef MOCK_NULLPTR
//[ limitations_literal_zero_solution_3
MOCK_EXPECT( m.method ).with( nullptr );
//]
#endif
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
//[ limitations_non_virtual_method_problem
@ -25,3 +24,10 @@ MOCK_BASE_CLASS( mock_base, base )
MOCK_METHOD( method, 0 )
};
//]
BOOST_AUTO_TEST_CASE(method_not_called_through_base)
{
mock_base b;
MOCK_EXPECT(b.method).never();
static_cast<base*>(&b)->method(); // Doesn't call the mocked method as asserted above
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -15,6 +14,8 @@ namespace
//[ limitations_protected_private_method_problem
class base
{
public:
void call(){ method_1(); method_2(); }
protected:
virtual void method_1() = 0;
private:
@ -30,3 +31,11 @@ namespace
};
//]
}
BOOST_AUTO_TEST_CASE(mocked_methods_are_called)
{
mock_base b;
MOCK_EXPECT(b.method_1).once();
MOCK_EXPECT(b.method_2).once();
static_cast<base*>(&b)->call();
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -17,8 +16,7 @@ namespace
class base
{
public:
virtual ~base()
{}
virtual ~base() = default;
virtual void method() = 0;
};
@ -28,7 +26,14 @@ namespace
template< typename T >
MOCK_BASE_CLASS( mock_base, base< T > )
{
MOCK_METHOD( method, 1, void() )
MOCK_METHOD( method, 0, void() )
};
//]
}
BOOST_AUTO_TEST_CASE(call_method_from_templated_class)
{
mock_base<int> b;
MOCK_EXPECT(b.method).once();
static_cast<base<int>*>(&b)->method();
}

View file

@ -6,19 +6,17 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace limitations_template_method_problem
{
//[ limitations_template_method_problem
class concept
class concept_class
{
public:
template< typename T >
void method( T t )
{}
void method( T t );
};
template< typename T >
@ -36,12 +34,20 @@ MOCK_CLASS( mock_concept )
MOCK_METHOD( method, 1, void( const char* ), method_string )
};
//]
BOOST_AUTO_TEST_CASE(mocked_templated_methods_are_called)
{
mock_concept b;
MOCK_EXPECT(b.method_int).once().with(42);
MOCK_EXPECT(b.method_string).once().with(mock::equal(std::string("string")));
function_under_test(b);
}
}
namespace limitations_template_method_problem_2
{
//[ limitations_template_method_problem_2
class concept
class concept_class
{
public:
template< typename T >
@ -80,4 +86,12 @@ std::string mock_concept::create< std::string >()
return create_string();
}
//]
BOOST_AUTO_TEST_CASE(dispatch_methods_are_called)
{
mock_concept b;
MOCK_EXPECT(b.create_int).once().returns(0);
MOCK_EXPECT(b.create_string).once().returns("");
function_under_test(b);
}
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -15,17 +14,16 @@ namespace
//[ limitations_throw_specifier_problem
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method() throw ();
virtual void method() throw() = 0;
};
//]
//[ limitations_throw_specifier_solution
MOCK_BASE_CLASS( mock_class, base_class )
{
void method() throw ()
void method() throw() override
{
method_proxy();
}
@ -33,3 +31,10 @@ namespace
};
//]
}
BOOST_AUTO_TEST_CASE(call_method_proxy)
{
mock_class b;
MOCK_EXPECT(b.method).once();
static_cast<base_class*>(&b)->method();
}

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
#include "calculator.hpp"
#include "mock_view.hpp"
@ -22,6 +21,8 @@ public:
};
//]
int calculator::add( int a, int b ){ return a + b; }
//[ simple_zero_plus_zero_is_zero
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
@ -51,7 +52,7 @@ public:
//]
//[ zero_plus_zero_is_zero_without_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_without_mock_object )
{
my_view v;
calculator c( v );
@ -65,7 +66,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace with_mock_object
{
//[ zero_plus_zero_is_zero_with_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_with_mock_object )
{
mock_view v;
calculator c( v );

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//[ async_call_problem
namespace
namespace mock_test
{
class base_class
{
@ -17,6 +17,7 @@ namespace
class my_class
{
base_class& b;
public:
explicit my_class( base_class& );
@ -25,14 +26,23 @@ namespace
}
//]
namespace mock_test
{
my_class::my_class( base_class& b): b(b){}
void my_class::flush()
{
static int counter = 7;
if(--counter == 0)
b.method();
}
}
//[ async_call_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <turtle/mock.hpp>
namespace
namespace mock_test
{
template< typename F >
void check( bool& condition, F flush, int attempts = 100, int sleep = 100 )
@ -49,25 +59,16 @@ namespace
{
MOCK_METHOD( method, 0 )
};
void set_bool(bool& b)
{
b = true;
}
}
BOOST_AUTO_TEST_CASE( method_is_called )
{
mock_base_class m;
my_class c( m );
bool done = false;
// when method is called it will set done to true
// Note: Boost 1.57 introduced a bug preventing usage of the lambda with clang in C++98
// See: https://svn.boost.org/trac10/ticket/10785
#if defined(BOOST_CLANG) && (BOOST_VERSION >= 105700)
MOCK_EXPECT( m.method ).once().calls( boost::bind(&set_bool, done) );
#else
MOCK_EXPECT( m.method ).once().calls( boost::lambda::var( done ) = true );
#endif
check( done, boost::bind( &my_class::flush, &c ) ); // just wait on done, flushing from time to time
MOCK_EXPECT( m.method ).once().calls( [&done](){ done = true; } );
check( done, [&c](){ c.flush(); } ); // just wait on done, flushing from time to time
}
}
//]

View file

@ -6,25 +6,43 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[ invoke_functor_problem
#include <boost/function.hpp>
// Intentionally duplicate to have complete examples and minimal user visible, yet tested test code
#include <boost/test/unit_test.hpp>
static void someFunctor(int newValue);
//[ invoke_functor_problem
#include <functional>
namespace
{
class base_class
{
public:
virtual void method( const boost::function< void( int ) >& functor ) = 0;
virtual void method( const std::function< void( int ) >& functor ) = 0;
};
void function( base_class& ); // 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); }
//]
// Some test-only code to verify what is described
static int receivedValue = 0;
static void someFunctor(int newValue)
{
receivedValue = newValue;
}
// Check that the functor was called with 42
struct CheckReceivedValue
{
void teardown()
{
BOOST_CHECK(receivedValue == 42); // functor was called and received the value 42
}
};
// And force using it w/o showing that in the docs
#undef BOOST_AUTO_TEST_CASE
#define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, CheckReceivedValue)
//[ invoke_functor_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/bind/apply.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -38,7 +56,7 @@ namespace
BOOST_AUTO_TEST_CASE( how_to_invoke_a_functor_passed_as_parameter_of_a_mock_method )
{
mock_class mock;
MOCK_EXPECT( mock.method ).calls( boost::bind( boost::apply< void >(), _1, 42 ) ); // whenever 'method' is called, invoke the functor with 42
MOCK_EXPECT( mock.method ).calls( [](const auto &functor){ functor(42); } ); // whenever 'method' is called, invoke the functor with 42
function( mock );
}
//]

View file

@ -7,8 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//[ quick_constraint_problem
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
#include <iostream>
@ -36,13 +35,15 @@ namespace
//]
//[ quick_constraint_solution
#include <boost/lexical_cast.hpp>
#include <sstream>
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
{
return boost::lexical_cast< std::string >( actual ) == expected;
std::ostringstream s;
s << actual;
return s.str() == expected;
}
} // mock

View file

@ -25,9 +25,20 @@ namespace
}
//]
namespace
{
static base_class* global_b = nullptr;
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);
}
}
//[ retrieve_cref_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace
@ -44,7 +55,7 @@ BOOST_AUTO_TEST_CASE( method_is_called_two_times_with_the_same_value )
my_class c( mock );
int value;
MOCK_EXPECT( mock.method ).once().with( mock::retrieve( value ) ); // on first call retrieve the value, this expectation takes precedence because it can never fail
MOCK_EXPECT( mock.method ).once().with( boost::cref( value ) ); // on second call compare the previously retrieved value with the newly received one
MOCK_EXPECT( mock.method ).once().with( std::cref( value ) ); // on second call compare the previously retrieved value with the newly received one
c.process();
}
//]

View file

@ -6,9 +6,18 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/test/unit_test.hpp>
// Used to make this test file pass. Define to 0 to see other tests fail
#define MOCK_MAKE_TEST_PASS 1
#if MOCK_MAKE_TEST_PASS
#undef BOOST_AUTO_TEST_CASE
#define BOOST_AUTO_TEST_CASE(name) BOOST_FIXTURE_TEST_CASE(name, mock::cleanup)
#endif
//[ static_objects_problem
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
#include <ostream>
@ -16,8 +25,7 @@ namespace
{
struct my_class
{
my_class( int i )
: i_( i )
my_class( int i ) : i_( i )
{}
int i_;
@ -28,7 +36,7 @@ namespace
return os << "my_class " << c->i_; // the 'c' pointer must be valid when logging
}
MOCK_FUNCTION( f, 1, void( my_class* ) ) // being static 'f' outlive the test case
MOCK_FUNCTION( f, 1, void( my_class* ) ) // being static 'f' outlives the test case
}
BOOST_AUTO_TEST_CASE( static_objects_problem )

View file

@ -9,6 +9,19 @@
#include <turtle/mock.hpp>
#include "calculator.hpp"
#include "mock_view.hpp"
#include <boost/test/unit_test.hpp>
#include <iostream>
#include <limits>
#include <stdexcept>
// Dummy to detect if the assertion unexpectedly succeeded to test what is explained
#undef BOOST_CHECK_THROW
#define BOOST_CHECK_THROW(expr, exc) \
try { \
expr; \
} catch(const exc&) { \
std::cerr << "Exception thrown but should not"; \
}
//[ overflow_throws
BOOST_AUTO_TEST_CASE( overflow_throws )

View file

@ -6,8 +6,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
namespace class_example_1
@ -121,8 +120,7 @@ namespace member_function_example_1
//[ member_function_example_1
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method( int ) = 0;
};
@ -138,8 +136,7 @@ namespace member_function_example_2
//[ member_function_example_2
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method( int, const std::string& ) = 0;
virtual void method( float ) = 0;
};
@ -157,8 +154,7 @@ namespace member_function_example_3
//[ member_function_example_3
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method( float ) = 0;
virtual void method( float ) const = 0;
};
@ -175,8 +171,7 @@ namespace member_function_example_4
//[ member_function_example_4
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method( float ) = 0;
virtual void method( float ) const = 0;
};
@ -194,8 +189,7 @@ namespace member_function_example_5
//[ member_function_example_5
struct base_class
{
virtual ~base_class()
{}
virtual ~base_class() = default;
virtual void method( float ) = 0;
};
@ -379,10 +373,11 @@ MOCK_CLASS( mock_class )
namespace function_example_1
{
//[ function_example_1
MOCK_FUNCTION( f, 1, float( int ) )
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_function )
{
MOCK_EXPECT(f).once().with(3);
f( 3 );
}
//]
@ -403,6 +398,7 @@ namespace functor_example_1
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT(f).once().with(3);
f( 3 );
}
//]
@ -414,12 +410,13 @@ namespace functor_example_2
template< typename T >
struct mock_class
{
MOCK_FUNCTOR_TPL( f, void( T ) );
MOCK_FUNCTOR( f, void( T ) );
};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor_inside_a_class )
{
mock_class< int > c;
MOCK_EXPECT(c.f).once().with(3);
c.f( 3 );
}
//]
@ -441,6 +438,9 @@ BOOST_AUTO_TEST_CASE( demonstrates_configuring_mock_objects )
MOCK_EXPECT( c.method ).once().with( 0 ).in( s ).returns( 42 );
MOCK_EXPECT( c.method2 ).never().with( "ok", mock::any );
MOCK_EXPECT( c.method2 ).at_least( 2 ).in( s ).throws( std::runtime_error( "error !" ) );
BOOST_TEST(c.method(0) == 42);
BOOST_CHECK_THROW(c.method("not ok", 1.f), std::runtime_error);
BOOST_CHECK_THROW(c.method("not ok", 2.f), std::runtime_error);
}
//]
}
@ -451,13 +451,18 @@ namespace invocation_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
MOCK_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_invocations_on_a_mock_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once(); // can only be called once
MOCK_EXPECT( c.method ); // can be called an unlimited number of times
MOCK_EXPECT( c.method2 ); // can be called an unlimited number of times
c.method(42, "Hello world!");
c.method2(42);
c.method2(42);
c.method2(42);
}
//]
}
@ -469,6 +474,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int, const std::string& ) );
MOCK_EXPECT( f ).once();
f(42, "Hello world!");
}
//]
}
@ -481,6 +487,7 @@ MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_function )
{
MOCK_EXPECT( f ).once();
f(42);
}
//]
}
@ -490,14 +497,17 @@ namespace invocation_example_4
//[ invocation_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, void( int ) )
MOCK_STATIC_METHOD( method1, 1, void( int ) )
MOCK_STATIC_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_static_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once();
MOCK_EXPECT( mock_class::method ).once(); // does the same
MOCK_EXPECT( c.method1 ).once();
MOCK_EXPECT( mock_class::method2 ).once(); // does the same (but for the other method)
c.method1(42);
c.method2(42);
}
//]
}
@ -507,14 +517,17 @@ namespace constraints_example_1
//[ constraints_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
MOCK_METHOD( method1, 2, void( int, const std::string& ) )
MOCK_METHOD( method2, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_builtin_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::equal( 3 ), mock::equal( "some string" ) );
MOCK_EXPECT( c.method ).with( 3, "some string" ); // equivalent to the previous one using short-cuts
MOCK_EXPECT( c.method1 ).with( mock::equal( 3 ), mock::equal( "some string" ) );
MOCK_EXPECT( c.method2 ).with( 3, "some string" ); // similar to the previous one using short-cuts
c.method1(3, "some string");
c.method2(3, "some string");
}
//]
}
@ -536,6 +549,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_free_functi
{
mock_class c;
MOCK_EXPECT( c.method ).with( &custom_constraint );
c.method(42);
}
//]
}
@ -557,6 +571,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_standard_li
{
mock_class c;
MOCK_EXPECT( c.method ).with( std::bind1st( std::ptr_fun( &custom_constraint ), 42 ) ); // std::ptr_fun creates an std::unary_function
c.method(42);
}
//]
}
@ -574,10 +589,12 @@ bool custom_constraint( int expected, int actual )
return expected == actual;
}
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_bind )
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_std_bind )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::bind( &custom_constraint, 42, _1 ) );
using namespace std::placeholders;
MOCK_EXPECT( c.method ).with( std::bind( &custom_constraint, 42, _1 ) );
c.method(42);
}
//]
}
@ -598,6 +615,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_lambda
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::lambda::_1 == 42 );
c.method(42);
}
//]
}
@ -611,20 +629,21 @@ namespace constraints_example_6
//[ constraints_example_6
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
MOCK_METHOD( method1, 1, void( int ) )
MOCK_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_phoenix )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::arg1 == 42 );
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::_1 == 42 );
MOCK_EXPECT( c.method1 ).with( boost::phoenix::arg_names::arg1 == 42 );
MOCK_EXPECT( c.method2 ).with( boost::phoenix::arg_names::_1 == 42 );
c.method1(42);
c.method2(42);
}
//]
}
#ifdef MOCK_LAMBDAS
namespace constraints_example_7
{
//[ constraints_example_7
@ -637,12 +656,11 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_constraint_with_cxx11_lambda )
{
mock_class c;
MOCK_EXPECT( c.method ).with( []( int actual ) { return 42 == actual; } );
c.method(42);
}
//]
}
#endif
namespace constraints_example_8
{
//[ constraints_example_8
@ -655,6 +673,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_combining_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::less( 4 ) && mock::greater( 2 ), ! mock::equal( "" ) );
c.method(3, "Hello World!");
}
//]
}
@ -676,6 +695,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_one_constraint_for_all_arguments )
{
mock_class c;
MOCK_EXPECT( c.method ).with( &custom_constraint );
c.method("1234", 4);
}
//]
}
@ -707,12 +727,13 @@ BOOST_AUTO_TEST_CASE( demonstrates_enforcing_several_expectation_orders )
MOCK_EXPECT( c_1.method_1 ).in( s_1 );
MOCK_EXPECT( c_2.method_2 ).in( s_2 ); // c_1.method_1 and c_2.method_2 are in different sequences and can be called in any order
MOCK_EXPECT( c_3.method_3 ).in( s_1, s_2 ); // c_3.method_3 must be called after both c_1.method_1 and c_2.method_2
c_2.method_2();
c_1.method_1();
c_3.method_3();
}
//]
}
#ifdef MOCK_LAMBDAS
namespace action_example_1
{
//[ action_example_1
@ -729,18 +750,22 @@ int function( int i )
BOOST_AUTO_TEST_CASE( demonstrates_configuring_actions )
{
mock_class c;
MOCK_EXPECT( c.method ).returns( 42 );
MOCK_EXPECT( c.method ).moves( 42 ); // returns by moving the value
MOCK_EXPECT( c.method ).throws( std::runtime_error( "error !" ) );
MOCK_EXPECT( c.method ).calls( &function ); // forwards 'method' parameter to 'function'
MOCK_EXPECT( c.method ).calls( boost::bind( &function, 42 ) ); // drops 'method' parameter and binds 42 as parameter to 'function'
MOCK_EXPECT( c.method ).calls( []( int i ) { return i; } ); // uses a C++11 lambda
MOCK_EXPECT( c.method ).once().returns( 42 );
MOCK_EXPECT( c.method ).once().moves( 42 ); // returns by moving the value
MOCK_EXPECT( c.method ).once().throws( std::runtime_error( "error !" ) );
MOCK_EXPECT( c.method ).once().calls( &function ); // forwards 'method' parameter to 'function'
MOCK_EXPECT( c.method ).once().calls( std::bind( &function, 42 ) ); // drops 'method' parameter and binds 42 as parameter to 'function'
MOCK_EXPECT( c.method ).once().calls( []( int i ) { return i; } ); // uses a C++11 lambda
BOOST_TEST(c.method(0) == 42);
BOOST_TEST(c.method(1) == 42);
BOOST_CHECK_THROW(c.method(0), std::runtime_error);
BOOST_TEST(c.method(2) == 2);
BOOST_TEST(c.method(3) == 42);
BOOST_TEST(c.method(4) == 4);
}
//]
}
#endif
namespace action_example_2
{
//[ action_example_2
@ -753,7 +778,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_configuring_actions_with_references )
{
mock_class c;
int i = 0;
MOCK_EXPECT( c.method ).returns( boost::ref( i ) ); // wrap i to store a reference
MOCK_EXPECT( c.method ).returns( std::ref( i ) ); // wrap i to store a reference
c.method() = 42; // really change i and not just the stored copy
BOOST_CHECK_EQUAL( 42, i ); // indeed
}
@ -926,46 +951,3 @@ BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
}
//]
}
namespace helpers_example_4
{
//[ helpers_example_4
MOCK_CONSTRAINT_EXT( any, 0,, true ) // this is (almost) how mock::any is defined
MOCK_CONSTRAINT_EXT( forty_two, 0,, actual == 42 ) // this defines a 'forty_two' constraint
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( forty_two );
MOCK_EXPECT( f ).with( any );
}
//]
}
namespace helpers_example_5
{
//[ helpers_example_5
MOCK_CONSTRAINT_EXT( equal, 1, ( expected ), actual == expected ) // this is how mock::equal is defined
MOCK_CONSTRAINT_EXT( near, 1, ( expected ), std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42 ) );
MOCK_EXPECT( f ).with( equal( 42 ) );
}
//]
}
namespace helpers_example_6
{
//[ helpers_example_6
MOCK_CONSTRAINT_EXT( near, 2, ( expected, tolerance ), std::abs( actual - expected ) < tolerance ) // this is how mock::near is defined
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
}
//]
}

View file

@ -12,7 +12,6 @@
[import example/limitations_template_base_class_method.cpp]
[import example/limitations_template_method.cpp]
[import example/limitations_protected_private_method.cpp]
[import example/limitations_comma_in_macro.cpp]
[import example/limitations_const_parameter_warning.cpp]
This section lists the library known limitations.
@ -76,7 +75,7 @@ Given :
[limitations_template_method_problem]
writing a mock object modeling 'concept' requires to list all the possible versions of 'method' :
writing a mock object modeling the 'concept class' requires to list all the possible versions of 'method' :
[limitations_template_method_solution]
@ -151,43 +150,6 @@ A workaround would be to write a proxy member function :
[endsect]
[section Compilers without support for variadic macros fail on commas in MOCK_BASE_CLASS]
For compilers without support for variadic macros given :
[limitations_comma_in_macro_problem]
the following code does not compile :
MOCK_BASE_CLASS( my_mock, my_base_class< int, int > ) // this fails because the pre-processor believes the macro to be called with 3 arguments
{};
One workaround is :
[limitations_comma_in_macro_solution_1]
Of course this is not always possible, as in :
template< typename T1, typename T2 >
MOCK_BASE_CLASS( my_mock, my_base_type< T1, T2 > )
{};
Another workaround would make use of [@http://www.boost.org/libs/preprocessor Boost.Preprocessor] :
[limitations_comma_in_macro_solution_2]
Actually BOOST_PP_COMMA implementation is quite trivial, being only :
#define BOOST_PP_COMMA() ,
Finally another workaround would be to not use the macro at all :
[limitations_comma_in_macro_solution_3]
Note that [@http://www.boost.org/libs/utility/identity_type/doc/html/index.html Boost.IdentityType] is of little help here because the type is by essence very often abstract, which doesn't work well for some compilers (e.g. gcc).
[endsect]
[section Warning C4505: '...' : unreferenced local function has been removed]
Example :

View file

@ -105,8 +105,6 @@ Synopsis :
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the MOCK_METHOD_EXT familly set of macros must be used.]
Synopsis :
MOCK_METHOD_EXT( [calling convention] name, arity, signature, identifier ) // generates both const and non-const methods
@ -167,8 +165,6 @@ Synopsis :
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the identifier cannot be omitted and must be given explicitly.]
Example :
[static_member_function_example_1]
@ -277,8 +273,6 @@ Synopsis :
[note In case of a calling convention specified, all four parameters must be provided.]
[warning For compilers without support for variadic macros the identifier cannot be omitted and must be given explicitly.]
Example :
[function_example_1]
@ -415,13 +409,13 @@ Constraints :
[[mock::evaluate] [['actual]()] [evaluates ['actual] as a functor returning a ['bool] and taking no argument]]
]
[important When passing ['expected] directly as a shortcut mock::call is implied for a function, a function pointer, an instance of a type with a result_type member typedef (support for standard library, [@http://www.boost.org/libs/bind/bind.html Boost.Bind], [@http://www.boost.org/libs/function Boost.Function] functors), an instance of a type with a sig member (support for [@http://www.boost.org/libs/lambda Boost.Lambda] functors), an instance of a type with a result member (support for [@http://www.boost.org/libs/phoenix Boost.Phoenix] functors); mock::equal is implied for anything else.]
[important When passing ['expected] directly as a shortcut mock::call is implied for a callable (function, function pointer, functor, ...); mock::equal is implied for anything else.]
[warning Because mock::assign and mock::retrieve have side effects they may modify ['expected] in unexpected ways. For instance they may be called again after their expectations have already been exhausted because of the way the [link turtle.getting_started.expectation_selection_algorithm expectation selection algorithm] works. Therefore it is probably a good idea to use an [link turtle.reference.expectation.actions action] instead.]
[note For mock::assign and mock::retrieve the switch to one form or another is made depending on whichever is the most relevant based on types involved.]
[note All constraints accepting a parameter support the use of boost::ref and boost::cref in order to delay initialization.]
[note All constraints accepting a parameter support the use of std::ref and std::cref in order to delay initialization.]
[note All constraints can be combined using the && and || operators, as well as negated with the ! operator.]
@ -437,7 +431,7 @@ Example using a standard library functor :
[constraints_example_3]
Example using [@http://www.boost.org/libs/bind Boost.Bind] :
Example using std::bind :
[constraints_example_4]
@ -497,7 +491,7 @@ Synopsis :
[note The returns and moves actions are not available for mock methods returning void, including constructors and destructors.]
[note Actions are captured by copy, boost::ref and boost::cref can however be used to turn the copies into references.]
[note Actions are captured by copy, std::ref and std::cref can however be used to turn the copies into references.]
Example :
@ -581,38 +575,18 @@ Synopsis :
The expression manipulates a received parameter ['actual] in order to implement the constraint, as well as extra optional arguments named ['expected_1], ['expected_2], ...
For compilers without support for variadic macros the alternate following macro must be used.
Synopsis :
MOCK_CONSTRAINT_EXT( name, arity, ( expected_1, expected_2, ... ), expression ) // defines a constraint 'name' based on the given 'expression'
Of course this macro is also available for compilers which support variadic macros.
Example without any extra argument :
[helpers_example_1]
or with the alternate more portable macro :
[helpers_example_4]
Example with one extra argument :
[helpers_example_2]
or with the alternate more portable macro :
[helpers_example_5]
Example with two extra arguments :
[helpers_example_3]
or with the alternate more portable macro :
[helpers_example_6]
[endsect]
[endsect]

View file

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

View file

@ -11,7 +11,7 @@
#include "config.hpp"
#include "log.hpp"
#include <boost/ref.hpp>
#include "unwrap_reference.hpp"
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/variadic/to_array.hpp>
@ -19,16 +19,15 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/array.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/decay.hpp>
#include <functional>
#include <type_traits>
namespace mock
{
template< typename Constraint >
struct constraint
{
constraint()
{}
constraint() {}
constraint( const Constraint& c )
: c_( c )
{}
@ -136,7 +135,7 @@ namespace detail
template< typename Actual > \
bool operator()( const Actual& actual ) const \
{ \
return Expr; \
(void) actual; return Expr; \
} \
friend std::ostream& operator<<( std::ostream& s, const Name& ) \
{ \
@ -147,10 +146,10 @@ namespace detail
const mock::constraint< detail::Name > Name;
#define MOCK_CONSTRAINT_ASSIGN(z, n, d) \
expected##n( boost::forward< T##n >(e##n) )
expected##n( std::forward< T##n >(e##n) )
#define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) \
boost::unwrap_ref( expected##n )
mock::unwrap_ref( expected##n )
#define MOCK_CONSTRAINT_FORMAT(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) mock::format( c.expected##n )
@ -159,20 +158,20 @@ namespace detail
Expected_##n expected##n;
#define MOCK_CONSTRAINT_TPL_TYPE(z, n, d) \
typename boost::decay< const T##n >::type
std::decay_t< const T##n >
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
const typename boost::unwrap_reference< Expected_##n >::type& \
const mock::unwrap_reference_t< Expected_##n >& \
BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARG(z, n, Args) \
BOOST_FWD_REF(T##n) BOOST_PP_ARRAY_ELEM(n, Args)
T##n&& BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARGS(z, n, Args) \
BOOST_FWD_REF(T##n) e##n
T##n&& e##n
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \
boost::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) \
namespace detail \
@ -221,8 +220,6 @@ namespace detail
MOCK_NARY_CONSTRAINT, \
MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
#ifdef MOCK_VARIADIC_MACROS
#ifdef BOOST_MSVC
# define MOCK_VARIADIC_SIZE(...) \
BOOST_PP_CAT(MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
@ -254,6 +251,4 @@ namespace detail
MOCK_CONSTRAINT_AUX( \
Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
#endif // MOCK_VARIADIC_MACROS
#endif // MOCK_CONSTRAINT_HPP_INCLUDED

View file

@ -11,19 +11,18 @@
#include "config.hpp"
#include "constraint.hpp"
#include "detail/addressof.hpp"
#include "detail/move_helper.hpp"
#include <boost/ref.hpp>
#include "unwrap_reference.hpp"
#include "detail/void_t.hpp"
#include <boost/version.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/common_type.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/has_equal_to.hpp>
#if BOOST_VERSION >= 107000
#include <boost/test/tools/floating_point_comparison.hpp>
#else
#include <boost/test/floating_point_comparison.hpp>
#endif
#include <functional>
#include <memory>
#include <type_traits>
namespace mock
{
@ -65,7 +64,7 @@ namespace detail
template< typename T1, typename T2, typename Tolerance >
bool is_close( const T1& t1, const T2& t2, const Tolerance& tolerance )
{
typedef typename boost::common_type< T1, T2 >::type common_type;
typedef std::common_type_t< T1, T2 > common_type;
return boost::math::fpc::close_at_tolerance< common_type >(
tolerance, boost::math::fpc::FPC_STRONG )( t1, t2 );
}
@ -107,13 +106,21 @@ namespace detail
# define MOCK_NEAR_DEFINED
#endif
MOCK_NARY_CONSTRAINT( near, 2, ( expected, tolerance ),
std::abs( actual - expected ) < tolerance )
std::abs( actual - expected ) <= tolerance )
#ifdef MOCK_NEAR_DEFINED
# pragma pop_macro( "near" )
#endif
namespace detail
{
template<class T, class U = T, class = void>
struct has_equal_to: std::false_type
{};
template<class T, class U>
struct has_equal_to<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>>: std::true_type
{};
template< typename Expected >
struct equal
{
@ -122,27 +129,25 @@ namespace detail
{}
template< typename Actual >
bool operator()( const Actual& actual,
typename boost::enable_if<
boost::has_equal_to<
std::enable_if_t<
has_equal_to<
Actual,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
unwrap_reference_t< Expected >
>::value
>* = 0 ) const
{
return actual == boost::unwrap_ref( expected_ );
return actual == unwrap_ref( expected_ );
}
template< typename Actual >
bool operator()( const Actual& actual,
typename boost::disable_if<
boost::has_equal_to<
std::enable_if_t<
!has_equal_to<
Actual,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
unwrap_reference_t< Expected >
>::value
>* = 0 ) const
{
return actual && *actual == boost::unwrap_ref( expected_ );
return actual && *actual == unwrap_ref( expected_ );
}
friend std::ostream& operator<<( std::ostream& s, const equal& e )
{
@ -155,71 +160,66 @@ namespace detail
struct same
{
explicit same( const Expected& expected )
: expected_( detail::addressof( boost::unwrap_ref( expected ) ) )
: expected_( std::addressof( unwrap_ref( expected ) ) )
{}
template< typename Actual >
bool operator()( const Actual& actual ) const
{
return detail::addressof( actual ) == expected_;
return std::addressof( actual ) == expected_;
}
friend std::ostream& operator<<( std::ostream& os, const same& s )
{
return os << "same( " << mock::format( *s.expected_ ) << " )";
}
const typename
boost::unwrap_reference< Expected >::type* expected_;
const unwrap_reference_t< Expected >* expected_;
};
template< typename Expected >
struct retrieve
{
explicit retrieve( Expected& expected )
: expected_( detail::addressof( boost::unwrap_ref( expected ) ) )
: expected_( std::addressof( unwrap_ref( expected ) ) )
{}
template< typename Actual >
bool operator()( const Actual& actual,
typename boost::disable_if<
boost::is_convertible<
std::enable_if_t<
!std::is_convertible<
const Actual*,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
unwrap_reference_t< Expected >
>::value
>* = 0 ) const
{
*expected_ = actual;
return true;
}
template< typename Actual >
bool operator()( BOOST_RV_REF(Actual) actual,
typename boost::disable_if<
boost::is_convertible<
bool operator()( Actual&& actual,
std::enable_if_t<
!std::is_convertible<
const Actual*,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
unwrap_reference_t< Expected >
>::value
>* = 0 ) const
{
*expected_ = boost::move( actual );
*expected_ = std::move( actual );
return true;
}
template< typename Actual >
bool operator()( Actual& actual,
typename boost::enable_if<
boost::is_convertible< Actual*,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
std::enable_if_t<
std::is_convertible< Actual*,
unwrap_reference_t< Expected >
>::value
>* = 0 ) const
{
*expected_ = detail::addressof( actual );
*expected_ = std::addressof( actual );
return true;
}
friend std::ostream& operator<<( std::ostream& s, const retrieve& r )
{
return s << "retrieve( " << mock::format( *r.expected_ ) << " )";
}
typename
boost::unwrap_reference< Expected >::type* expected_;
unwrap_reference_t< Expected >* expected_;
};
template< typename Expected >
@ -231,22 +231,21 @@ namespace detail
template< typename Actual >
bool operator()( Actual& actual ) const
{
actual = boost::unwrap_ref( expected_ );
actual = unwrap_ref( expected_ );
return true;
}
template< typename Actual >
bool operator()( Actual* actual,
typename boost::enable_if<
boost::is_convertible<
typename
boost::unwrap_reference< Expected >::type,
std::enable_if_t<
std::is_convertible<
unwrap_reference_t< Expected >,
Actual
>
>::type* = 0 ) const
>::value
>* = 0 ) const
{
if( ! actual )
return false;
*actual = boost::unwrap_ref( expected_ );
*actual = unwrap_ref( expected_ );
return true;
}
friend std::ostream& operator<<( std::ostream& s, const assign& a )
@ -264,7 +263,7 @@ namespace detail
{}
bool operator()( const std::string& actual ) const
{
return actual.find( boost::unwrap_ref( expected_ ) )
return actual.find( unwrap_ref( expected_ ) )
!= std::string::npos;
}
friend std::ostream& operator<<( std::ostream& s, const contain& n )
@ -276,9 +275,9 @@ namespace detail
}
template< typename T >
constraint< detail::equal< typename detail::forward_type< T >::type > > equal( BOOST_FWD_REF(T) t )
constraint< detail::equal< T > > equal( T&& t )
{
return detail::equal< typename detail::forward_type< T >::type >( boost::forward< T >( t ) );
return detail::equal< T >( std::forward< T >( t ) );
}
template< typename T >

View file

@ -10,14 +10,9 @@
#define MOCK_ACTION_HPP_INCLUDED
#include "../config.hpp"
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <functional>
#include <memory>
#include <type_traits>
namespace mock
{
@ -27,15 +22,19 @@ namespace detail
class action_base
{
private:
#ifdef MOCK_HDR_FUNCTIONAL
typedef std::function< Signature > functor_type;
typedef std::function< Result() > action_type;
#else
typedef boost::function< Signature > functor_type;
typedef boost::function< Result() > action_type;
#endif
protected:
// Meant to be subclassed and not be directly used
// Non-relocatable (contained functions may wrap references/pointers which could be invalidated)
action_base() = default;
action_base(const action_base&) = delete;
action_base(action_base&&) = delete;
action_base& operator=(const action_base&) = delete;
action_base& operator=(action_base&&) = delete;
public:
const functor_type& functor() const
{
return f_;
@ -59,7 +58,7 @@ namespace detail
template< typename Exception >
void throws( Exception e )
{
a_ = boost::bind( &do_throw< Exception >, e );
a_ = [e]() -> Result { throw e; };
}
protected:
@ -68,23 +67,12 @@ namespace detail
a_ = a;
}
template< typename Y >
void set( const boost::reference_wrapper< Y >& r )
void set( const std::reference_wrapper< Y >& r )
{
a_ = boost::bind( &do_ref< Y >, r.get_pointer() );
a_ = [r]() -> Result { return r.get(); };
}
private:
template< typename T >
static T& do_ref( T* t )
{
return *t;
}
template< typename T >
static Result do_throw( T t )
{
throw t;
}
functor_type f_;
action_type a_;
};
@ -96,77 +84,54 @@ namespace detail
template< typename Value >
void returns( const Value& v )
{
this->set( boost::ref( store( v ) ) );
this->set( std::ref( store( v ) ) );
}
template< typename Y >
void returns( const boost::reference_wrapper< Y >& r )
void returns( const std::reference_wrapper< Y >& r )
{
this->set( r );
}
template< typename Value >
void moves( BOOST_RV_REF(Value) v )
void moves( Value&& v )
{
this->set(
boost::bind(
&move< typename boost::remove_reference< Value >::type >,
boost::ref( store( boost::move( v ) ) ) ) );
auto vRef = std::ref( store( std::move( v ) ) );
this->set([vRef](){ return std::move(vRef.get()); });
}
private:
template< typename Value >
static BOOST_RV_REF(Value) move( Value& t )
struct value
{
return boost::move( t );
}
struct value : boost::noncopyable
{
virtual ~value()
{}
value() = default;
value(const value&) = delete;
value& operator=(const value&) = delete;
virtual ~value() = default;
};
template< typename T >
struct value_imp : value
{
typedef
typename boost::remove_const<
typename boost::remove_reference<
T
>::type
>::type value_type;
typedef std::remove_const_t<std::remove_reference_t<T>> type;
value_imp( BOOST_RV_REF(value_type) t )
: t_( boost::move( t ) )
template< typename U >
value_imp( U&& t ) : t_( std::forward<U>( t ) )
{}
value_imp( const value_type& t )
: t_( t )
{}
template< typename Y >
value_imp( Y* y )
: t_( y )
{}
value_type t_;
type t_;
};
template< typename T >
T& store( BOOST_RV_REF(T) t )
typename value_imp<T>::type& store( T&& t )
{
v_.reset( new value_imp< T >( boost::move( t ) ) );
v_ = std::make_unique< value_imp<T> >( std::forward<T>( t ) );
return static_cast< value_imp< T >& >( *v_ ).t_;
}
template< typename T >
T& store( const T& t )
std::remove_reference_t< Result >& store( T* t )
{
v_.reset( new value_imp< T >( t ) );
return static_cast< value_imp< T >& >( *v_ ).t_;
}
template< typename T >
typename boost::remove_reference< Result >::type& store( T* t )
{
v_.reset( new value_imp< Result >( t ) );
v_ = std::make_unique< value_imp<Result> >( t );
return static_cast< value_imp< Result >& >( *v_ ).t_;
}
boost::shared_ptr< value > v_;
std::unique_ptr< value > v_;
};
template< typename Signature >
@ -175,51 +140,10 @@ namespace detail
public:
action()
{
this->set( boost::bind( &do_nothing ) );
this->set( [](){} );
}
private:
static void do_nothing()
{}
};
#ifdef MOCK_AUTO_PTR
template< typename Result, typename Signature >
class action< std::auto_ptr< Result >, Signature >
: public action_base< std::auto_ptr< Result >, Signature >
{
public:
action()
{}
action( const action& rhs )
: v_( rhs.v_.release() )
{
if( v_.get() )
returns( boost::ref( v_ ) );
}
template< typename Y >
void returns( Y* r )
{
v_.reset( r );
this->set( boost::ref( v_ ) );
}
template< typename Y >
void returns( std::auto_ptr< Y > r )
{
v_ = r;
this->set( boost::ref( v_ ) );
}
template< typename Y >
void returns( const boost::reference_wrapper< Y >& r )
{
this->set( r );
}
private:
mutable std::auto_ptr< Result > v_;
};
#endif // MOCK_AUTO_PTR
}
} // mock

View file

@ -1,36 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_ADDRESSOF_HPP_INCLUDED
#define MOCK_ADDRESSOF_HPP_INCLUDED
#include "../config.hpp"
#include <boost/utility/addressof.hpp>
namespace mock
{
namespace detail
{
using boost::addressof;
#ifdef MOCK_NULLPTR
inline const std::nullptr_t* addressof( const std::nullptr_t& p )
{
return &p;
}
inline std::nullptr_t* addressof( std::nullptr_t& p )
{
return &p;
}
#endif
}
} // mock
#endif // MOCK_ADDRESSOF_HPP_INCLUDED

View file

@ -11,7 +11,6 @@
#include "../config.hpp"
#include "type_name.hpp"
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream>
@ -22,11 +21,14 @@ namespace detail
{
class verifiable;
class context : boost::noncopyable
class context
{
public:
context() {}
virtual ~context() {}
context() = default;
context(const context&) = delete;
context& operator=(const context&) = delete;
virtual ~context() = default;
virtual void add( const void* p, verifiable& v,
boost::unit_test::const_string instance,

View file

@ -15,7 +15,7 @@
matcher< T##n, Constraint_##n > c##n##_;
#define MOCK_EXPECTATION_IS_VALID(z, n, d) \
BOOST_PP_IF(n, &&,) c##n##_( mock::detail::move_if_not_lvalue_reference< T##n >( a##n ) )
BOOST_PP_IF(n, &&,) c##n##_( std::forward< T##n >( a##n ) )
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) c##n##_
@ -24,7 +24,7 @@
BOOST_PP_IF(n, << ", " <<,) "any"
#define MOCK_EXPECTATION_PARAM(z, n, Args) \
mock::detail::move_if_not_lvalue_reference< T##n >( a##n )
std::forward< T##n >( a##n )
#define MOCK_REF_ARG(z, n, d) \
typename ref_arg< T##n >::type a##n
@ -133,9 +133,9 @@ namespace detail
{
public:
expectation()
: invocation_( boost::make_shared< unlimited >() )
: invocation_( std::make_unique< unlimited >() )
, matcher_(
boost::make_shared<
std::make_unique<
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
@ -144,9 +144,9 @@ namespace detail
, line_( 0 )
{}
expectation( const char* file, int line )
: invocation_( boost::make_shared< unlimited >() )
: invocation_( std::make_unique< unlimited >() )
, matcher_(
boost::make_shared<
std::make_unique<
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
@ -162,14 +162,13 @@ namespace detail
~expectation()
{
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
(*it)->remove( this );
for( auto& sequence: sequences_)
sequence->remove( this );
}
void invoke( const boost::shared_ptr< invocation >& i )
void invoke( std::unique_ptr< invocation > i )
{
invocation_ = i;
invocation_ = std::move(i);
}
#ifndef MOCK_NUM_ARGS_0
@ -179,22 +178,22 @@ namespace detail
expectation& with(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
{
matcher_.reset(
new single_matcher<
matcher_ = std::make_unique<
single_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ),
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) ) );
>>( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) );
return *this;
}
#if MOCK_NUM_ARGS > 1
template< typename Constraint >
expectation& with( const Constraint& c )
{
matcher_.reset(
new multi_matcher<
matcher_ = std::make_unique<
multi_matcher<
Constraint,
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( c ) );
>>( c );
return *this;
}
#endif
@ -220,14 +219,14 @@ namespace detail
bool invoke() const
{
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
if( ! (*it)->is_valid( this ) )
for( auto& sequence: sequences_)
{
if( ! sequence->is_valid( this ) )
return false;
}
bool result = invocation_->invoke();
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
(*it)->invalidate( this );
for( auto& sequence: sequences_)
sequence->invalidate( this );
return result;
}
@ -240,8 +239,7 @@ namespace detail
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' : '.' )
<< ' ' << *e.invocation_
@ -252,18 +250,13 @@ namespace detail
}
private:
typedef std::vector<
boost::shared_ptr< sequence_impl >
> sequences_type;
typedef sequences_type::const_iterator sequences_cit;
boost::shared_ptr< invocation > invocation_;
boost::shared_ptr<
std::unique_ptr< invocation > invocation_;
std::unique_ptr<
matcher_base<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> matcher_;
sequences_type sequences_;
std::vector< std::shared_ptr<sequence_impl> > sequences_;
const char* file_;
int line_;
};

View file

@ -11,7 +11,7 @@
#include "../config.hpp"
#include "../stream.hpp"
#include "addressof.hpp"
#include <memory>
namespace mock
{
@ -21,7 +21,7 @@ namespace detail
struct formatter
{
explicit formatter( const T& t )
: t_( detail::addressof( t ) )
: t_( std::addressof( t ) )
{}
void serialize( stream& s ) const
{

View file

@ -30,11 +30,6 @@
#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/lazy_ostream.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/call_traits.hpp>
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
#include <boost/move/move.hpp>
#include <boost/optional.hpp>
#include <ostream>
#include <vector>
@ -80,7 +75,7 @@ namespace detail
e_->returns( r );
}
template< typename Y >
void returns( const boost::reference_wrapper< Y >& r )
void returns( const std::reference_wrapper< Y >& r )
{
e_->returns( r );
}

View file

@ -24,8 +24,8 @@
<< ')' \
<< lazy_expectations( this )
#define MOCK_MOVE(z, n, d) \
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
#define MOCK_FORWARD(z, n, d) \
std::forward< T##n >( t##n )
namespace mock
{
@ -36,7 +36,7 @@ namespace detail
template< typename R
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) >
class function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: public verifiable, public boost::enable_shared_from_this<
: public verifiable, public std::enable_shared_from_this<
function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )> >
{
public:
@ -47,19 +47,24 @@ namespace detail
: context_( 0 )
, valid_( true )
, exceptions_( exceptions() )
, mutex_( boost::make_shared< mutex >() )
, mutex_( std::make_shared< mutex >() )
{}
virtual ~function_impl()
{
if( valid_ && exceptions_ >= exceptions() )
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( ! it->verify() )
{
for( const auto& expectation: expectations_ )
{
if( ! expectation.verify() )
{
error_type::fail( "untriggered expectation",
boost::unit_test::lazy_ostream::instance()
<< lazy_context( this )
<< lazy_expectations( this ),
it->file(), it->line() );
expectation.file(), expectation.line() );
}
}
}
if( context_ )
context_->remove( *this );
}
@ -67,16 +72,17 @@ namespace detail
virtual bool verify() const
{
lock _( mutex_ );
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( ! it->verify() )
for( const auto& expectation: expectations_ )
{
if( ! expectation.verify() )
{
valid_ = false;
error_type::fail( "verification failed",
boost::unit_test::lazy_ostream::instance()
<< lazy_context( this )
<< lazy_expectations( this ),
it->file(), it->line() );
expectation.file(), expectation.line() );
}
}
return valid_;
}
@ -85,7 +91,7 @@ namespace detail
{
lock _( mutex_ );
valid_ = true;
boost::shared_ptr< function_impl > guard =
std::shared_ptr< function_impl > guard =
this->shared_from_this();
expectations_.clear();
}
@ -99,55 +105,44 @@ namespace detail
{
private:
typedef wrapper_base< R, expectation_type > base_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(wrapper)
public:
wrapper( const boost::shared_ptr< mutex >& m, expectation_type& e )
wrapper( const std::shared_ptr< mutex >& m, expectation_type& e )
: base_type( e )
, lock_( m )
{}
wrapper( BOOST_RV_REF( wrapper ) x )
: base_type( x )
, lock_( boost::move( x.lock_) )
{}
wrapper& operator=( BOOST_RV_REF( wrapper ) x )
{
static_cast< base_type& >( *this ) = x;
lock_ = boost::move( x.lock_ );
return *this;
}
wrapper(const wrapper&) = delete;
wrapper( wrapper&& x ) = default;
wrapper& operator=(const wrapper&) = delete;
wrapper& operator=( wrapper&& x ) = default;
wrapper& once()
{
this->e_->invoke( boost::make_shared< detail::once >() );
this->e_->invoke( std::make_unique< detail::once >() );
return *this;
}
wrapper& never()
{
this->e_->invoke( boost::make_shared< detail::never >() );
this->e_->invoke( std::make_unique< detail::never >() );
return *this;
}
wrapper& exactly( std::size_t count )
{
this->e_->invoke(
boost::make_shared< detail::exactly >( count ) );
this->e_->invoke( std::make_unique< detail::exactly >( count ) );
return *this;
}
wrapper& at_least( std::size_t min )
{
this->e_->invoke(
boost::make_shared< detail::at_least >( min ) );
this->e_->invoke( std::make_unique< detail::at_least >( min ) );
return *this;
}
wrapper& at_most( std::size_t max )
{
this->e_->invoke(
boost::make_shared< detail::at_most >( max ) );
this->e_->invoke( std::make_unique< detail::at_most >( max ) );
return *this;
}
wrapper& between( std::size_t min, std::size_t max )
{
this->e_->invoke(
boost::make_shared< detail::between >( min, max ) );
this->e_->invoke( std::make_unique< detail::between >( min, max ) );
return *this;
}
@ -200,9 +195,9 @@ namespace detail
this->e_->throws( t );
}
template< typename TT >
void moves( BOOST_RV_REF(TT) t )
void moves( TT&& t )
{
this->e_->moves( boost::move( t ) );
this->e_->moves( std::move( t ) );
}
lock lock_;
@ -214,14 +209,14 @@ namespace detail
wrapper expect( const char* file, int line )
{
lock _( mutex_ );
expectations_.push_back( expectation_type( file, line ) );
expectations_.emplace_back( file, line );
valid_ = true;
return wrapper( mutex_, expectations_.back() );
}
wrapper expect()
{
lock _( mutex_ );
expectations_.push_back( expectation_type() );
expectations_.emplace_back( );
valid_ = true;
return wrapper( mutex_, expectations_.back() );
}
@ -231,30 +226,30 @@ namespace detail
{
lock _( mutex_ );
valid_ = false;
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( it->is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) ) )
for( const auto& expectation: expectations_ )
{
if( ! it->invoke() )
if( expectation.is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) )
{
if( ! expectation.invoke() )
{
error_type::fail( "sequence failed",
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
return error_type::abort();
}
if( ! it->valid() )
if( ! expectation.valid() )
{
error_type::fail( "missing action",
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
return error_type::abort();
}
valid_ = true;
error_type::call(
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
if( it->functor() )
return it->functor()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
return it->trigger();
error_type::call( MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
if( expectation.functor() )
return expectation.functor()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
return expectation.trigger();
}
}
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT );
return error_type::abort();
@ -272,8 +267,7 @@ namespace detail
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_ );
return s << lazy_context( &impl ) << lazy_expectations( &impl );
@ -284,8 +278,7 @@ namespace detail
lazy_context( const function_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_ )
c.impl_->context_->serialize( s, *c.impl_ );
@ -301,29 +294,24 @@ namespace detail
lazy_expectations( const function_impl* impl )
: impl_( impl )
{}
friend std::ostream& operator<<(
std::ostream& s, const lazy_expectations& e )
friend std::ostream& operator<<( std::ostream& s, const lazy_expectations& e )
{
for( expectations_cit it = e.impl_->expectations_.begin();
it != e.impl_->expectations_.end(); ++it )
s << std::endl << *it;
for( const auto& expectation: e.impl_->expectations_ )
s << std::endl << expectation;
return s;
}
const function_impl* impl_;
};
typedef std::list< expectation_type > expectations_type;
typedef typename expectations_type::const_iterator expectations_cit;
expectations_type expectations_;
std::list< expectation_type > expectations_;
context* context_;
mutable bool valid_;
const int exceptions_;
const boost::shared_ptr< mutex > mutex_;
const std::shared_ptr< mutex > mutex_;
};
}
} // mock
#undef MOCK_FUNCTION_FORMAT
#undef MOCK_FUNCTION_CONTEXT
#undef MOCK_MOVE
#undef MOCK_FORWARD

View file

@ -8,8 +8,8 @@
#include "function_impl_template.hpp"
#define MOCK_MOVE(z, n, d) \
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
#define MOCK_FORWARD(z, n, d) \
std::forward< T##n >( t##n )
namespace mock
{
@ -21,15 +21,6 @@ namespace detail
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) >
class function< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{
public:
typedef R result_type;
template< typename Args >
struct sig
{
typedef R type;
};
private:
typedef function_impl<
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
@ -39,7 +30,7 @@ namespace detail
public:
function()
: impl_( boost::make_shared< impl_type >() )
: impl_( std::make_shared< impl_type >() )
{}
bool verify() const
@ -74,7 +65,7 @@ namespace detail
R operator()(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
}
friend std::ostream& operator<<( std::ostream& s, const function& f )
@ -98,9 +89,9 @@ namespace detail
}
private:
boost::shared_ptr< impl_type > impl_;
std::shared_ptr< impl_type > impl_;
};
}
} // mock
#undef MOCK_MOVE
#undef MOCK_FORWARD

View file

@ -36,27 +36,21 @@ namespace detail
bool verify() const
{
bool valid = true;
for( verifiables_cit it = verifiables_.begin();
it != verifiables_.end(); ++it )
if( ! (*it)->verify() )
for( const auto* verifiable: verifiables_ )
if( ! verifiable->verify() )
valid = false;
return valid;
}
void reset()
{
const verifiables_t verifiables = verifiables_;
for( verifiables_cit it = verifiables.begin();
it != verifiables.end(); ++it )
if( std::find( verifiables_.begin(), verifiables_.end(), *it )
!= verifiables_.end() )
(*it)->reset();
const auto verifiables = verifiables_;
for( auto* verifiable: verifiables )
if( std::find( verifiables_.begin(), verifiables_.end(), verifiable ) != verifiables_.end() )
verifiable->reset();
}
private:
typedef std::vector< verifiable* > verifiables_t;
typedef verifiables_t::const_iterator verifiables_cit;
verifiables_t verifiables_;
std::vector< verifiable* > verifiables_;
};
}
} // mock

View file

@ -10,7 +10,6 @@
#define MOCK_INVOCATION_HPP_INCLUDED
#include "../config.hpp"
#include <boost/noncopyable.hpp>
#include <stdexcept>
#include <ostream>
#include <limits>
@ -19,11 +18,14 @@ namespace mock
{
namespace detail
{
class invocation : private boost::noncopyable
class invocation
{
public:
invocation() {}
virtual ~invocation() {}
invocation() = default;
invocation(const invocation&) = delete;
invocation& operator=(const invocation&) = delete;
virtual ~invocation() = default;
virtual bool invoke() = 0;
virtual bool verify() const = 0;

View file

@ -10,51 +10,19 @@
#define MOCK_IS_FUNCTOR_HPP_INCLUDED
#include "../config.hpp"
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/utility/declval.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/or.hpp>
#include "void_t.hpp"
#include <type_traits>
namespace mock
{
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF( result_type )
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( sig )
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( result )
#ifdef MOCK_DECLTYPE
template< typename F, typename P >
struct is_callable
{
typedef boost::type_traits::yes_type yes_type;
typedef boost::type_traits::no_type no_type;
template< typename T >
static yes_type check(
decltype( boost::declval< T >()( boost::declval< P >() ) )* );
template< typename T >
static no_type check( ... );
typedef boost::mpl::bool_<
sizeof( check< F >( 0 ) ) == sizeof( yes_type ) > type;
};
#endif // MOCK_DECLTYPE
template< typename T, typename P >
struct is_functor
: boost::mpl::or_<
boost::function_types::is_callable_builtin< T >,
#ifdef MOCK_DECLTYPE
is_callable< T, P >,
#endif
has_result_type< T >,
has_result< T >,
has_sig< T >
>
/// 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 >
struct is_functor : std::false_type
{};
template< typename F, typename Arg >
struct is_functor< F, Arg, void_t<decltype( std::declval<F>()( std::declval<Arg>() ) )> >: std::true_type
{};
}
} // mock

View file

@ -18,16 +18,17 @@ namespace detail
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: boost::noncopyable
{
public:
virtual ~matcher_base() {}
matcher_base() = default;
matcher_base(const matcher_base&) = delete;
matcher_base& operator=(const matcher_base&) = delete;
virtual ~matcher_base() = default;
virtual bool operator()(
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 );
return s;

View file

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

View file

@ -11,9 +11,7 @@
#include "../config.hpp"
#include "singleton.hpp"
#include <boost/move/move.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
#ifdef MOCK_THREAD_SAFE
@ -38,11 +36,8 @@ namespace detail
struct lock
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(lock)
public:
lock( const boost::shared_ptr< mutex >& m )
lock( const std::shared_ptr< mutex >& m )
: m_( m )
{
m_->lock();
@ -52,21 +47,13 @@ namespace detail
if( m_ )
m_->unlock();
}
lock( BOOST_RV_REF( lock ) x )
: m_( x.m_ )
{
// Explicit reset to avoid unlock in destructor
x.m_.reset();
}
lock& operator=( BOOST_RV_REF( lock ) x )
{
m_ = x.m_;
x.m_.reset();
return *this;
}
lock( const lock& ) = delete;
lock( lock&& x ) = default;
lock& operator=( const lock& ) = delete;
lock& operator=( lock&& x ) = default;
private:
boost::shared_ptr< mutex > m_;
std::shared_ptr< mutex > m_;
};
}
} // mock
@ -77,8 +64,12 @@ namespace mock
{
namespace detail
{
struct mutex : boost::noncopyable
struct mutex
{
mutex() = default;
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
void lock()
{}
void unlock()
@ -86,29 +77,23 @@ namespace detail
};
// Dummy lock classes.
// Constructor + Destructor make it RAII classes for compilers and avoid unused variable warnings
struct scoped_lock : boost::noncopyable
struct scoped_lock
{
scoped_lock( mutex& )
{}
~scoped_lock()
{}
};
class lock : boost::noncopyable
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(lock)
scoped_lock(const scoped_lock&) = delete;
scoped_lock& operator=(const scoped_lock&) = delete;
public:
lock( const boost::shared_ptr< mutex >& )
{}
~lock()
{}
lock( BOOST_RV_REF( lock ) )
{}
lock& operator=( BOOST_RV_REF( lock ) )
scoped_lock( mutex& ) {}
~scoped_lock() {}
};
class lock
{
return *this;
}
public:
lock( const std::shared_ptr< mutex >& ) {}
~lock() {}
lock(const lock&) = delete;
lock( lock&& ) = default;
lock& operator=( const lock& ) = delete;
lock& operator=( lock&& ) = default;
};
}
} // mock

View file

@ -17,8 +17,6 @@
#include "child.hpp"
#include "mutex.hpp"
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
namespace mock
@ -26,11 +24,11 @@ namespace mock
namespace detail
{
class object_impl : public context, public verifiable,
public boost::enable_shared_from_this< object_impl >
public std::enable_shared_from_this< object_impl >
{
public:
object_impl()
: mutex_( boost::make_shared< mutex >() )
: mutex_( std::make_shared< mutex >() )
{}
virtual void add( const void* /*p*/, verifiable& v,
@ -60,7 +58,7 @@ namespace detail
virtual void serialize( std::ostream& s, const verifiable& v ) const
{
lock _( mutex_ );
children_cit it = children_.find( &v );
const auto it = children_.find( &v );
if( it != children_.end() )
s << it->second;
else
@ -75,18 +73,15 @@ namespace detail
virtual void reset()
{
lock _( mutex_ );
boost::shared_ptr< object_impl > guard = shared_from_this();
std::shared_ptr< object_impl > guard = shared_from_this();
group_.reset();
}
private:
typedef std::map< const verifiable*, child > children_t;
typedef children_t::const_iterator children_cit;
group group_;
parent parent_;
children_t children_;
const boost::shared_ptr< mutex > mutex_;
std::map< const verifiable*, child > children_;
const std::shared_ptr< mutex > mutex_;
};
}
} // mock

View file

@ -10,24 +10,70 @@
#define MOCK_PARAMETER_HPP_INCLUDED
#include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/mpl/at.hpp>
namespace mock
{
namespace detail
{
template< class... >
struct tuple;
template< std::size_t I, class T >
struct tuple_element;
template< std::size_t I, class H, class... T >
struct tuple_element<I, tuple<H, T...>> : tuple_element<I-1, tuple<T...>>
{};
template< class H, class... T >
struct tuple_element<0, tuple<H, T...>>
{
using type = H;
};
template< typename Signature >
struct result_type;
template< typename R, typename... Args >
struct result_type< R(Args...) >
{
using type = R;
};
template< typename Signature >
struct function_arity;
template< typename R, typename... Args >
struct function_arity< R(Args...) >
{
static constexpr size_t value = sizeof...(Args);
};
template< typename Signature >
struct parameter_types;
template< typename R, typename... Args >
struct parameter_types< R(Args...) >
{
using type = tuple<Args...>;
};
template< typename Signature, int n >
struct parameter
{
typedef typename
boost::mpl::at_c<
typename
boost::function_types::parameter_types< Signature >,
n
>::type type;
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;
};
template<typename T>
struct parameter_type;
template<typename T, typename U>
struct parameter_type<T(U)>
{
using type = U;
};
template<typename T>
using parameter_type_t = typename parameter_type<T>::type;
}
} // mock

View file

@ -22,8 +22,7 @@ namespace detail
class parent
{
public:
parent()
{}
parent() = default;
parent( boost::unit_test::const_string instance,
boost::optional< type_name > type )
: instance_( instance )

View file

@ -33,7 +33,7 @@ namespace detail
boost::unit_test::const_string name )
{
scoped_lock _( mutex_ );
children_t::iterator it = children_.lower_bound( &v );
auto it = children_.lower_bound( &v );
if( it == children_.end() ||
children_.key_comp()( &v, it->first ) )
it = children_.insert( it,
@ -67,7 +67,7 @@ namespace detail
virtual void serialize( std::ostream& s, const verifiable& v ) const
{
scoped_lock _( mutex_ );
children_cit it = children_.find( &v );
const auto it = children_.find( &v );
if( it != children_.end() )
s << it->second;
else
@ -120,11 +120,8 @@ namespace detail
child child_;
};
typedef std::map< const verifiable*, counter_child > children_t;
typedef children_t::const_iterator children_cit;
parents_t parents_;
children_t children_;
std::map< const verifiable*, counter_child > children_;
group group_;
mutable mutex mutex_;

View file

@ -11,20 +11,19 @@
#include "../config.hpp"
#include "mutex.hpp"
#include <boost/noncopyable.hpp>
#include <boost/make_shared.hpp>
#include <algorithm>
#include <memory>
#include <vector>
namespace mock
{
namespace detail
{
class sequence_impl : private boost::noncopyable
class sequence_impl
{
public:
sequence_impl()
: mutex_( boost::make_shared< mutex >() )
: mutex_( std::make_shared< mutex >() )
{}
void add( void* e )
@ -49,17 +48,14 @@ namespace detail
void invalidate( const void* e )
{
lock _( mutex_ );
elements_type::iterator it =
std::find( elements_.begin(), elements_.end(), e );
const auto it = std::find( elements_.begin(), elements_.end(), e );
if( it != elements_.end() )
elements_.erase( elements_.begin(), it );
}
private:
typedef std::vector< void* > elements_type;
elements_type elements_;
const boost::shared_ptr< mutex > mutex_;
std::vector< void* > elements_;
const std::shared_ptr< mutex > mutex_;
};
}
} // mock

View file

@ -10,33 +10,47 @@
#define MOCK_SIGNATURE_HPP_INCLUDED
#include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/pop_front.hpp>
#define BOOST_TYPEOF_SILENT
#include <boost/typeof/typeof.hpp>
#include <type_traits>
namespace mock
{
namespace detail
{
#define MOCK_NOARG
#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \
template< typename R, typename... 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) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv,) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&)
template<typename>
struct strip_function_qualifiers;
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(MOCK_NOARG)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(volatile)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const volatile)
#undef MOCK_NOARG
#undef MOCK_STRIP_FUNCTION_QUALIFIERS
#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF
template< typename M >
struct signature :
boost::function_types::function_type<
boost::mpl::joint_view<
boost::mpl::single_view<
typename
boost::function_types::result_type< M >::type
>,
typename boost::mpl::pop_front<
typename
boost::function_types::parameter_types< M >
>::type
>
>
struct signature;
template< typename R, typename... Args>
struct signature< R(Args...) >
{
using type = R(Args...);
};
template< typename Sig, typename C>
struct signature< Sig(C::*) >: signature< typename strip_function_qualifiers<Sig>::type >
{};
template< typename T >
@ -55,9 +69,9 @@ namespace detail
#define MOCK_SIGNATURE(M) \
mock::detail::signature< \
BOOST_TYPEOF( \
mock::detail::ambiguous_method_requires_to_specify_signature( \
&base_type::M ) ) \
std::remove_cv_t< std::remove_reference_t < decltype( \
mock::detail::ambiguous_method_requires_to_specify_signature( &base_type::M ) \
) > > \
>::type
#endif // MOCK_SIGNATURE_HPP_INCLUDED

View file

@ -38,7 +38,7 @@ protected:
#define MOCK_SINGLETON_CONS( type ) \
private: \
friend class mock::detail::singleton< type >; \
type() {}
type() = default
#define MOCK_SINGLETON_INST( inst ) \
static BOOST_JOIN( inst, _t )& inst = BOOST_JOIN( inst, _t )::instance();

View file

@ -15,17 +15,8 @@
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 107000
# include <boost/core/typeinfo.hpp>
# define MOCK_TYPEID( t ) BOOST_CORE_TYPEID(t)
# define MOCK_TYPEINFO boost::core::typeinfo
#else
# include <boost/detail/sp_typeinfo.hpp>
# define MOCK_TYPEID( t ) BOOST_SP_TYPEID(t)
# define MOCK_TYPEINFO boost::detail::sp_typeinfo
#endif
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include <memory>
#include <typeinfo>
#include <ostream>
#ifdef __GNUC__
@ -33,8 +24,6 @@
#include <cstdlib>
#endif
#define MOCK_TYPE_NAME( t ) mock::detail::type_name( MOCK_TYPEID(t) )
namespace mock
{
namespace detail
@ -42,7 +31,7 @@ namespace detail
class type_name
{
public:
explicit type_name( const MOCK_TYPEINFO& info )
explicit type_name( const std::type_info& info )
: info_( &info )
{}
friend std::ostream& operator<<( std::ostream& s, const type_name& t )
@ -51,15 +40,17 @@ namespace detail
return s;
}
private:
void serialize( std::ostream& s,
const MOCK_TYPEINFO& info ) const
static void serialize( std::ostream& s, const std::type_info& info )
{
const char* name = info.name();
#ifdef __GNUC__
int status = 0;
boost::shared_ptr< char > demangled(
abi::__cxa_demangle( name, 0, 0, &status ),
&std::free );
struct Deleter
{
void operator()(const void* p) { std::free(const_cast<void*>(p)); }
};
std::unique_ptr< const char, Deleter > demangled(
abi::__cxa_demangle( name, 0, 0, &status ));
if( ! status && demangled )
serialize( s, demangled.get() );
else
@ -69,7 +60,7 @@ namespace detail
typedef std::string::size_type size_type;
void serialize( std::ostream& s, std::string name ) const
static void serialize( std::ostream& s, std::string name )
{
const size_type nm = rfind( name, ':' ) + 1;
const size_type tpl = name.find( '<', nm );
@ -80,7 +71,7 @@ namespace detail
list( s, name.substr( tpl + 1, name.rfind( '>' ) - tpl - 1 ) );
s << '>';
}
void list( std::ostream& s, const std::string& name ) const
static void list( std::ostream& s, const std::string& name )
{
const size_type comma = rfind( name, ',' );
if( comma != std::string::npos )
@ -90,7 +81,7 @@ namespace detail
}
serialize( s, name.substr( comma + 1 ) );
}
std::string clean( std::string name ) const
static std::string clean( std::string name )
{
boost::algorithm::trim( name );
boost::algorithm::erase_all( name, "class " );
@ -102,7 +93,7 @@ namespace detail
boost::algorithm::replace_all( name, "* ", "*" );
return name;
}
size_type rfind( const std::string& name, char c ) const
static size_type rfind( const std::string& name, char c )
{
size_type count = 0;
for( size_type i = name.size() - 1; i > 0; --i )
@ -117,8 +108,18 @@ namespace detail
return std::string::npos;
}
const MOCK_TYPEINFO* info_;
const std::type_info* info_;
};
template< typename T >
type_name make_type_name()
{
return type_name( typeid(T) );
}
template< typename T >
type_name make_type_name( const T& )
{
return type_name( typeid(T) );
}
}
} // mock

View file

@ -10,17 +10,18 @@
#define MOCK_VERIFIABLE_HPP_INCLUDED
#include "../config.hpp"
#include <boost/noncopyable.hpp>
namespace mock
{
namespace detail
{
class verifiable : private boost::noncopyable
class verifiable
{
public:
verifiable() {}
virtual ~verifiable() {}
verifiable() = default;
verifiable(const verifiable&) = delete;
verifiable& operator=(const verifiable&) = delete;
virtual ~verifiable() = default;
virtual bool verify() const = 0;

View file

@ -0,0 +1,27 @@
// http://turtle.sourceforge.net
//
// Copyright Alexander Grund 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_VOID_T_HPP_INCLUDED
#define MOCK_VOID_T_HPP_INCLUDED
namespace mock
{
namespace detail
{
template<typename...>
struct make_void
{
using type = void;
};
/// Standard helper to implement the detection idiom. Returns always void
template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
}
} // mock
#endif // MOCK_VOID_T_HPP_INCLUDED

View file

@ -12,11 +12,10 @@
#include "config.hpp"
#include "stream.hpp"
#include "format.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/detail/container_fwd.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/none.hpp>
#include <memory>
#include <type_traits>
namespace boost
{
@ -51,15 +50,16 @@ namespace detail
s << (it == begin ? "" : ",") << mock::format( *it );
s << ')';
}
}
#ifdef MOCK_AUTO_PTR
template<typename T>
stream& operator<<( stream& s, const std::auto_ptr< T >& t )
{
return s << mock::format( t.get() );
struct is_callable_impl: std::false_type
{};
template<typename R, typename... Args>
struct is_callable_impl<R(Args...)>: std::true_type
{};
template<typename T>
struct is_callable: is_callable_impl< std::remove_cv_t<T> >
{};
}
#endif // MOCK_AUTO_PTR
template< typename T1, typename T2 >
stream& operator<<( stream& s, const std::pair< T1, T2 >& p )
@ -123,6 +123,11 @@ namespace detail
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() );
@ -144,7 +149,6 @@ namespace detail
return s << boost::none;
}
#ifdef MOCK_SMART_PTR
template< typename T >
stream& operator<<( stream& s, const std::shared_ptr< T >& t )
{
@ -160,7 +164,6 @@ namespace detail
{
return s << mock::format( p.get() );
}
#endif
template< typename T >
stream& operator<<( stream& s, const boost::lambda::lambda_functor< T >& )
@ -173,27 +176,19 @@ namespace detail
return s << '?';
}
#ifdef MOCK_NULLPTR
inline stream& operator<<( stream& s, std::nullptr_t )
{
return s << "nullptr";
}
#endif
template< typename T >
typename boost::enable_if<
boost::function_types::is_callable_builtin< T >,
stream&
>::type
std::enable_if_t< detail::is_callable< T >::value, stream& >
operator<<( stream& s, T* )
{
return s << '?';
}
template< typename T >
typename boost::disable_if<
boost::function_types::is_callable_builtin< T >,
stream&
>::type
std::enable_if_t< !detail::is_callable< T >::value, stream& >
operator<<( stream& s, T* t )
{
*s.s_ << t;

View file

@ -14,10 +14,9 @@
#include "constraints.hpp"
#include "detail/is_functor.hpp"
#include "detail/move_helper.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/ref.hpp>
#include <cstring>
#include <functional>
#include <type_traits>
namespace mock
{
@ -28,13 +27,11 @@ namespace mock
explicit matcher( Expected expected )
: expected_( expected )
{}
bool operator()( typename boost::add_reference< const Actual >::type actual )
bool operator()( std::add_lvalue_reference_t< const Actual > actual )
{
return mock::equal(
boost::unwrap_ref( expected_ ) ).c_( actual );
return mock::equal( mock::unwrap_ref( expected_ ) ).c_( actual );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
{
return s << mock::format( m.expected_ );
}
@ -53,8 +50,7 @@ namespace mock
{
return std::strcmp( actual, expected_ ) == 0;
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
{
return s << mock::format( m.expected_ );
}
@ -71,10 +67,9 @@ namespace mock
{}
bool operator()( typename detail::ref_arg< Actual >::type actual )
{
return c_( mock::detail::move_if_not_lvalue_reference< typename detail::ref_arg< Actual >::type >( actual ) );
return c_( std::forward< typename detail::ref_arg< Actual >::type >( actual ) );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
{
return s << mock::format( m.c_ );
}
@ -84,9 +79,9 @@ namespace mock
template< typename Actual, typename Functor >
class matcher< Actual, Functor,
typename boost::enable_if<
detail::is_functor< Functor, Actual >
>::type
std::enable_if_t<
detail::is_functor< Functor, Actual >::value
>
>
{
public:
@ -95,10 +90,9 @@ namespace mock
{}
bool operator()( typename detail::ref_arg< Actual >::type actual )
{
return c_( mock::detail::move_if_not_lvalue_reference< typename detail::ref_arg< Actual >::type >( actual ) );
return c_( std::forward< typename detail::ref_arg< Actual >::type >( actual ) );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
{
return s << mock::format( m.c_ );
}

View file

@ -21,79 +21,72 @@
#include "detail/parameter.hpp"
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/utility/identity_type.hpp>
#include <boost/mpl/assert.hpp>
/// MOCK_CLASS( name )
/// Define a class
#define MOCK_CLASS(T) \
struct T : mock::object
#define MOCK_FUNCTION_TYPE(S, tpn) \
tpn boost::remove_pointer< tpn BOOST_IDENTITY_TYPE(S) >::type
/// MOCK_PROTECT_FUNCTION_SIG( signature )
/// Use this with MOCK_FUNCTION/MOCK_*_METHOD if the return type contains commas
#define MOCK_PROTECT_FUNCTION_SIG(...) \
mock::detail::parameter_type_t<void (__VA_ARGS__)>
#ifdef MOCK_VARIADIC_MACROS
/// 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
#define MOCK_FUNCTION_TYPE(...) \
std::remove_pointer_t< __VA_ARGS__ >
/// MOCK_BASE_CLASS( name, base )
/// Define a class deriving from a base class
#define MOCK_BASE_CLASS(T, ...) \
struct T : __VA_ARGS__, mock::object, mock::detail::base< __VA_ARGS__ >
/// MOCK_FUNCTOR( name, signature )
/// Define a callable variable/member
#define MOCK_FUNCTOR(f, ...) \
mock::detail::functor< MOCK_FUNCTION_TYPE((__VA_ARGS__),) > f, f##_mock
#define MOCK_FUNCTOR_TPL(f, ...) \
mock::detail::functor< \
MOCK_FUNCTION_TYPE((__VA_ARGS__), typename) > f, f##_mock
#else // MOCK_VARIADIC_MACROS
#define MOCK_BASE_CLASS(T, I) \
struct T : I, mock::object, mock::detail::base< I >
#define MOCK_FUNCTOR(f, S) \
mock::detail::functor< MOCK_FUNCTION_TYPE((S),) > f, f##_mock
#define MOCK_FUNCTOR_TPL(f, S) \
mock::detail::functor< \
MOCK_FUNCTION_TYPE((S), typename) > f, f##_mock
#endif // MOCK_VARIADIC_MACROS
mock::detail::functor< MOCK_FUNCTION_TYPE(__VA_ARGS__) > f, f##_mock
/// MOCK_FUNCTOR_TPL( name, signature )
#define MOCK_FUNCTOR_TPL(f, ...) static_assert(false, "MOCK_FUNCTOR_TPL has been replaced by MOCK_FUNCTOR")
#define MOCK_HELPER(t) \
t##_mock( mock::detail::root, BOOST_PP_STRINGIZE(t) )
#define MOCK_ANONYMOUS_HELPER(t) \
t##_mock( mock::detail::root, "?." )
#define MOCK_METHOD_HELPER(S, t, tpn) \
mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \
mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) >& t##_mock( \
#define MOCK_METHOD_HELPER(S, t) \
mutable mock::detail::function< MOCK_FUNCTION_TYPE(S) > t##_mock_; \
mock::detail::function< MOCK_FUNCTION_TYPE(S) >& t##_mock( \
const mock::detail::context&, \
const boost::unit_test::const_string& instance ) const \
{ \
mock::detail::configure( *this, t##_mock_, \
instance.substr( 0, instance.rfind( BOOST_PP_STRINGIZE(t) ) ), \
MOCK_TYPE_NAME(*this), \
mock::detail::make_type_name(*this), \
BOOST_PP_STRINGIZE(t) ); \
return t##_mock_; \
}
#define MOCK_PARAM(S, tpn) \
tpn mock::detail::parameter< MOCK_FUNCTION_TYPE((S), tpn)
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_PARAMS(n, S, tpn) \
BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
#define MOCK_DECL(M, n, S, c, tpn) \
tpn boost::function_types::result_type< \
MOCK_FUNCTION_TYPE((S), tpn) >::type M( \
tpn mock::detail::result_type< \
MOCK_FUNCTION_TYPE(S) >::type M( \
MOCK_DECL_PARAMS(n, S, tpn) ) c
#define MOCK_FORWARD_PARAM(z, n, d) \
BOOST_PP_COMMA_IF(n) d, n >::type >( p##n )
#define MOCK_FORWARD_PARAMS(n, S, tpn) \
BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, \
mock::detail::move_if_not_lvalue_reference< MOCK_PARAM(S, tpn))
std::forward< MOCK_PARAM(S, tpn))
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
MOCK_DECL(M, n, S, c, tpn) \
{ \
BOOST_MPL_ASSERT_RELATION( n, ==, \
boost::function_types::function_arity< \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
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) ); \
}
@ -101,53 +94,52 @@
#define MOCK_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,,) \
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) \
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) \
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) \
MOCK_METHOD_AUX(M, n, S, t,, typename) \
MOCK_METHOD_AUX(M, n, S, t, const, typename) \
MOCK_METHOD_HELPER(S, t, typename)
MOCK_METHOD_HELPER(S, t)
#define MOCK_CONST_METHOD_EXT_TPL(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, const, typename) \
MOCK_METHOD_HELPER(S, t, typename)
MOCK_METHOD_HELPER(S, t)
#define MOCK_NON_CONST_METHOD_EXT_TPL(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t,, typename) \
MOCK_METHOD_HELPER(S, t, typename)
MOCK_METHOD_HELPER(S, t)
/// MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
/// generates both const and non-const operators
#define MOCK_CONVERSION_OPERATOR(M, T, t) \
M T() const { 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 )
/// generates only a const operator
#define MOCK_CONST_CONVERSION_OPERATOR(M, T, 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 )
/// generates only a non-const operator
#define MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, 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) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename)
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename)
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) \
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
MOCK_METHOD_HELPER(T(), t, typename)
#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_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t)
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
s mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) >& t##_mock( \
s mock::detail::function< MOCK_FUNCTION_TYPE(S) >& t##_mock( \
mock::detail::context& context, \
boost::unit_test::const_string instance ) \
{ \
static mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > f; \
static mock::detail::function< MOCK_FUNCTION_TYPE(S) > f; \
return f( context, instance ); \
}
@ -158,96 +150,108 @@
} \
MOCK_FUNCTION_HELPER(void A, t, static, tpn)
/// 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.
#define MOCK_CONSTRUCTOR(T, n, A, t) \
MOCK_CONSTRUCTOR_AUX(T, n, A, t,)
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
/// 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.
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) \
MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
/// MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
#define MOCK_DESTRUCTOR(T, t) \
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) \
MOCK_FUNCTION_HELPER(S, t, s, tpn) \
s MOCK_DECL(F, n, S,,tpn) \
{ \
BOOST_MPL_ASSERT_RELATION( n, ==, \
boost::function_types::function_arity< \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE(S) >::value, "Arity mismatch" ); \
return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \
}
#ifdef MOCK_VARIADIC_MACROS
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
#define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1
#define MOCK_VARIADIC_ELEM_2(e0, e1, e2, ...) e2
/// MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates both const and non-const methods
#define MOCK_METHOD(M, ...) \
MOCK_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates only the const version of the method
#define MOCK_CONST_METHOD(M, ...) \
MOCK_CONST_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates only the non-const version of the method
#define MOCK_NON_CONST_METHOD(M, ...) \
MOCK_NON_CONST_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
/// must be used if the signature uses a template parameter of the class
/// generates both const and non-const methods
#define MOCK_METHOD_TPL(M, n, ...) \
MOCK_METHOD_EXT_TPL(M, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
/// MOCK_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
/// must be used if the signature uses a template parameter of the class
/// generates only the const version of the method
#define MOCK_CONST_METHOD_TPL(M, n, ...) \
MOCK_CONST_METHOD_EXT_TPL(M, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
/// MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
/// must be used if the signature uses a template parameter of the class
/// generates only the non-const version of the method
#define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
MOCK_NON_CONST_METHOD_EXT_TPL(M, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
/// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] )
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_FUNCTION(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
inline,)
/// MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] )
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_STATIC_METHOD(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
static,)
/// MOCK_STATIC_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
/// must be used if the signature uses a template parameter of the class
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_STATIC_METHOD_TPL(F, n, ...) \
MOCK_FUNCTION_AUX(F, n, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
static, typename)
#else // MOCK_VARIADIC_MACROS
#define MOCK_METHOD(M, n) \
MOCK_METHOD_EXT(M, n, MOCK_SIGNATURE(M), M)
#define MOCK_FUNCTION(F, n, S, t) \
MOCK_FUNCTION_AUX(F, n, S, t, inline,)
#define MOCK_STATIC_METHOD(F, n, S, t) \
MOCK_FUNCTION_AUX(F, n, S, t, static,)
#define MOCK_STATIC_METHOD_TPL(F, n, S, t) \
MOCK_FUNCTION_AUX(F, n, S, t, static, typename)
#endif // MOCK_VARIADIC_MACROS
/// MOCK_EXPECT( identifier )
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect( __FILE__, __LINE__ )
/// MOCK_RESET( identifier )
#define MOCK_RESET(t) MOCK_HELPER(t).reset( __FILE__, __LINE__ )
/// MOCK_VERIFY( identifier )
#define MOCK_VERIFY(t) MOCK_HELPER(t).verify( __FILE__, __LINE__ )
#endif // MOCK_MOCK_HPP_INCLUDED

View file

@ -14,10 +14,9 @@
#include "detail/type_name.hpp"
#include "detail/object_impl.hpp"
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
#include <memory>
#include <type_traits>
namespace mock
{
@ -36,9 +35,7 @@ namespace detail
boost::unit_test::const_string instance,
boost::optional< type_name > type,
boost::unit_test::const_string name,
typename boost::disable_if<
typename boost::is_base_of< object, T >
>::type* = 0 )
std::enable_if_t< !std::is_base_of< object, T >::value >* = 0 )
{
e.configure( detail::root, &t, instance, type, name );
return e;
@ -48,13 +45,12 @@ namespace detail
{
public:
object()
: impl_( boost::make_shared< detail::object_impl >() )
: impl_( std::make_shared< detail::object_impl >() )
{}
protected:
~object()
{}
~object() = default;
public:
boost::shared_ptr< detail::object_impl > impl_;
std::shared_ptr< detail::object_impl > impl_;
};
namespace detail

View file

@ -11,6 +11,7 @@
#include "config.hpp"
#include "detail/sequence_impl.hpp"
#include <memory>
namespace mock
{
@ -18,10 +19,10 @@ namespace mock
{
public:
sequence()
: impl_( boost::make_shared< detail::sequence_impl >() )
: impl_( std::make_shared< detail::sequence_impl >() )
{}
boost::shared_ptr< detail::sequence_impl > impl_;
std::shared_ptr< detail::sequence_impl > impl_;
};
} // mock

View file

@ -10,7 +10,7 @@
#define MOCK_STREAM_HPP_INCLUDED
#include "config.hpp"
#include <boost/noncopyable.hpp>
#include <memory>
#include <ostream>
namespace mock
@ -41,10 +41,13 @@ namespace conversion
return s << '?';
}
struct holder : boost::noncopyable
struct holder
{
virtual ~holder()
{}
holder() = default;
holder(const holder&) = delete;
holder& operator=(const holder&) = delete;
virtual ~holder() = default;
virtual void serialize( std::ostream& s ) const = 0;
};
@ -64,17 +67,12 @@ namespace conversion
const T& t_;
};
struct any : boost::noncopyable
struct any
{
template< typename T >
any( const T& t )
: h_( new holder_imp< T >( t ) )
any( const T& t ): h_( std::make_unique< holder_imp<T> >( t ) )
{}
~any()
{
delete h_;
}
holder* h_;
std::unique_ptr<holder> h_;
};
}
}

View file

@ -0,0 +1,42 @@
// http://turtle.sourceforge.net
//
// Copyright Alexander Grund 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
#define MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
#include <functional>
#include <type_traits>
namespace mock
{
template<class T>
struct unwrap_reference
{
using type = T;
};
template<class T>
struct unwrap_reference<std::reference_wrapper<T>>
{
using type = T;
};
template<class T>
struct unwrap_reference<const std::reference_wrapper<T>>
{
using type = T;
};
template<class T>
using unwrap_reference_t = typename unwrap_reference<T>::type;
template<class T>
BOOST_FORCEINLINE unwrap_reference_t<T>& unwrap_ref( T& t ) noexcept
{
return t;
}
}
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED

View file

@ -21,6 +21,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"
target_compile_options(TurtleTestMain INTERFACE -Wno-unused-function)
endif()
if(TURTLE_WERROR)
check_cxx_compiler_flag(-Wdeprecated-declarations TURTLE_CXX_DEPRECATED_DECLARATIONS)
if(TURTLE_CXX_DEPRECATED_DECLARATIONS)
target_compile_options(TurtleTestMain INTERFACE -Wno-error=deprecated-declarations)
endif()
target_compile_options(TurtleTestMain INTERFACE -Werror)
endif()
elseif(MSVC)
@ -30,12 +34,13 @@ elseif(MSVC)
endif()
endif()
# Regular unit tests in variations
file(GLOB_RECURSE testFiles test_*.cpp)
set(testsUsingUndefinedCPP test_function test_integration)
foreach(testFile IN LISTS testFiles)
get_filename_component(name ${testFile} NAME_WE)
foreach(testVariant IN ITEMS "" _max_args _use_conversions _no_decltype _no_variadic_macros _thread_safe)
foreach(testVariant IN ITEMS "" _max_args _use_conversions _thread_safe)
set(curName ${name}${testVariant})
add_executable(${curName} ${testFile})
if(name IN_LIST testsUsingUndefinedCPP)
@ -47,17 +52,17 @@ foreach(testFile IN LISTS testFiles)
target_compile_definitions(${name}_max_args PRIVATE MOCK_MAX_ARGS=21)
target_compile_definitions(${name}_use_conversions PRIVATE MOCK_USE_CONVERSIONS)
target_compile_definitions(${name}_no_decltype PRIVATE MOCK_NO_DECLTYPE)
target_compile_definitions(${name}_no_variadic_macros PRIVATE MOCK_NO_VARIADIC_MACROS)
target_link_libraries(${name}_thread_safe PRIVATE Boost::thread)
target_compile_definitions(${name}_thread_safe PRIVATE MOCK_THREAD_SAFE BOOST_THREAD_USES_MOVE)
endforeach()
# Link test only to check for a regression
add_executable(link-test_defined EXCLUDE_FROM_ALL test_exception.cpp defined_1.cpp defined_2.cpp)
target_link_libraries(link-test_defined PRIVATE turtle::turtle TurtleTestMain)
add_test(NAME link-test_defined COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target link-test_defined --config $<CONFIG>)
# Should fail to compile
file(GLOB_RECURSE compileFailureTestFiles fail_*.cpp)
foreach(testFile IN LISTS compileFailureTestFiles)
get_filename_component(name ${testFile} NAME_WE)
@ -67,3 +72,34 @@ foreach(testFile IN LISTS compileFailureTestFiles)
add_test(NAME compile-${name} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${name} --config $<CONFIG>)
set_tests_properties(compile-${name} PROPERTIES WILL_FAIL TRUE)
endforeach()
# Examples are runnable tests
file(GLOB_RECURSE exampleFiles ${PROJECT_SOURCE_DIR}/doc/example/*.cpp)
foreach(testFile IN LISTS exampleFiles)
get_filename_component(name ${testFile} NAME_WE)
set(name "example_${name}")
add_executable(${name} ${testFile})
target_link_libraries(${name} PRIVATE turtle::turtle TurtleTestMain)
add_test(NAME ${name} COMMAND ${name})
endforeach()
file(GLOB_RECURSE exampleTargetFiles ${PROJECT_SOURCE_DIR}/doc/example/*.hpp)
foreach(name IN ITEMS customization getting_started motivation rationale)
target_sources(example_${name} PUBLIC ${exampleTargetFiles})
endforeach()
# Expected to trigger a mock failure
set_tests_properties(example_rationale PROPERTIES WILL_FAIL TRUE PASS_REGULAR_EXPRESSION "Exception thrown but should not")
foreach(name IN ITEMS example_patterns_async_call)
target_link_libraries(${name} PRIVATE Boost::thread)
target_compile_definitions(${name} PRIVATE MOCK_THREAD_SAFE BOOST_THREAD_USES_MOVE)
endforeach()
# Compile benchmarks
file(GLOB_RECURSE benchFiles bench_*.cpp)
foreach(testFile IN LISTS benchFiles)
get_filename_component(name ${testFile} NAME_WE)
add_executable(${name} EXCLUDE_FROM_ALL ${testFile})
target_link_libraries(${name} PRIVATE turtle::turtle TurtleTestMain)
add_test(NAME ${name} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${name} --config $<CONFIG>)
endforeach()

View file

@ -26,8 +26,6 @@ rule run-test ( name )
run $(name) defined_1.cpp defined_2.cpp undefined.cpp /boost//unit_test_framework : : : : $(name)_ ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_MAX_ARGS=21 : $(name)_max_args ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_USE_CONVERSIONS : $(name)_use_conversions ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_NO_DECLTYPE : $(name)_no_decltype ;
run $(name) undefined.cpp /boost//unit_test_framework : : : <define>MOCK_NO_VARIADIC_MACROS : $(name)_no_variadic_macros ;
run $(name) undefined.cpp /boost//unit_test_framework /boost//thread : : : <define>MOCK_THREAD_SAFE <define>BOOST_THREAD_USES_MOVE <threading>multi : $(name)_thread_safe ;
}

View file

@ -8,3 +8,8 @@
#define MOCK_MAX_ARGS 10
#include <turtle/mock.hpp>
int main()
{
return 0;
}

View file

@ -8,3 +8,8 @@
#define MOCK_MAX_ARGS 20
#include <turtle/mock.hpp>
int main()
{
return 0;
}

View file

@ -8,3 +8,8 @@
#define MOCK_MAX_ARGS 30
#include <turtle/mock.hpp>
int main()
{
return 0;
}

View file

@ -17,7 +17,7 @@ namespace
class base_class
{
public:
virtual ~base_class() {}
virtual ~base_class() = default;
virtual void f1( int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int, int ) = 0;
@ -1132,3 +1132,8 @@ namespace
mock_class_29 c_29;
mock_class_30 c_30;
}
int main()
{
return 0;
}

View file

@ -16,7 +16,7 @@ namespace
class base_class
{
public:
virtual ~base_class() {}
virtual ~base_class() = default;
virtual void f1( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f2( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f3( int, int, int, int, int, int, int, int, int ) = 0;
@ -1071,3 +1071,8 @@ namespace
mock_class_29 c_29;
mock_class_30 c_30;
}
int main()
{
return 0;
}

View file

@ -17,7 +17,7 @@ namespace
class base_class
{
public:
virtual ~base_class() {}
virtual ~base_class() = default;
virtual void f1( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f2( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f3( int, int, int, int, int, int, int, int, int ) = 0;
@ -1072,3 +1072,8 @@ namespace
mock_class_29 c_29;
mock_class_30 c_30;
}
int main()
{
return 0;
}

View file

@ -17,7 +17,7 @@ namespace
class base_class
{
public:
virtual ~base_class() {}
virtual ~base_class() = default;
virtual void f1( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f2( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f3( int, int, int, int, int, int, int, int, int ) = 0;
@ -1072,3 +1072,8 @@ namespace
mock_class_29 c_29;
mock_class_30 c_30;
}
int main()
{
return 0;
}

View file

@ -17,7 +17,7 @@ namespace
class base_class
{
public:
virtual ~base_class() {}
virtual ~base_class() = default;
virtual void f1( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f2( int, int, int, int, int, int, int, int, int ) = 0;
virtual void f3( int, int, int, int, int, int, int, int, int ) = 0;
@ -1072,3 +1072,8 @@ namespace
mock_class_29 c_29;
mock_class_30 c_30;
}
int main()
{
return 0;
}

View file

@ -10,27 +10,21 @@
#include "../undefined.hpp"
#include <turtle/detail/function.hpp>
#include <turtle/constraints.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/test/unit_test.hpp>
#include <functional>
#include <memory>
#include <type_traits>
// static
namespace
{
boost::function< void() > static_f;
std::function< void() > static_f;
BOOST_MPL_ASSERT((
boost::is_same< void, boost::result_of< mock::detail::function< void() >() >::type > ));
BOOST_MPL_ASSERT((
boost::is_same< int, boost::result_of< mock::detail::function< int() >() >::type > ));
BOOST_MPL_ASSERT((
boost::is_same< void, boost::result_of< mock::detail::function< void( float ) >( float ) >::type > ));
BOOST_MPL_ASSERT((
boost::is_same< int, boost::result_of< mock::detail::function< int( float ) >( float ) >::type > ));
static_assert( std::is_same< void, decltype( mock::detail::function< void() >{}() ) >::value, "!");
static_assert( std::is_same< int, decltype( mock::detail::function< int() >{}() ) >::value, "!");
static_assert( std::is_same< void, decltype( mock::detail::function< void( float ) >{}( std::declval<float>() ) ) >::value, "!");
static_assert( std::is_same< int, decltype( mock::detail::function< int( float ) >{}( std::declval<float>() ) ) >::value, "!");
}
// functor
@ -38,13 +32,13 @@ namespace
BOOST_FIXTURE_TEST_CASE( a_function_can_be_passed_as_functor, mock_error_fixture )
{
mock::detail::function< void() > f;
boost::function< void() > functor = f;
std::function< void() > functor = f;
}
BOOST_FIXTURE_TEST_CASE( a_function_can_be_passed_as_functor_using_boost_bind_and_boost_ref, mock_error_fixture )
BOOST_FIXTURE_TEST_CASE( a_function_can_be_passed_as_functor_using_std_bind_and_std_ref, mock_error_fixture )
{
mock::detail::function< void() > f;
boost::function< void() > functor = boost::bind( boost::ref( f ) );
std::function< void() > functor = std::bind( std::ref( f ) );
}
// invocations
@ -293,10 +287,14 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in
namespace
{
class my_interface : boost::noncopyable
class my_interface
{
public:
virtual ~my_interface() {}
my_interface() = default;
my_interface(const my_interface&) = delete;
my_interface& operator=(const my_interface&) = delete;
virtual ~my_interface() = default;
private:
virtual void my_method() = 0;
};
@ -354,8 +352,6 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_failing_custom_constrain
// CHECK_CALLS( 1 );
//}
#ifdef MOCK_NULLPTR
BOOST_FIXTURE_TEST_CASE( nullptr_can_be_used_in_place_of_null_pointers_in_constraints, mock_error_fixture )
{
mock::detail::function< void( int* ) > f;
@ -364,10 +360,6 @@ BOOST_FIXTURE_TEST_CASE( nullptr_can_be_used_in_place_of_null_pointers_in_constr
CHECK_CALLS( 1 );
}
#endif
#ifdef MOCK_SMART_PTR
BOOST_FIXTURE_TEST_CASE( unique_ptr_is_supported_as_parameter, mock_error_fixture )
{
mock::detail::function< void( std::unique_ptr< int > ) > f;
@ -377,8 +369,6 @@ BOOST_FIXTURE_TEST_CASE( unique_ptr_is_supported_as_parameter, mock_error_fixtur
CHECK_CALLS( 1 );
}
#endif // MOCK_SMART_PTR
// result handling
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_action, mock_error_fixture )
@ -418,7 +408,7 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_value, mock_e
{
mock::detail::function< int() > f;
int i = 42;
f.expect().returns( boost::ref( i ) );
f.expect().returns( std::ref( i ) );
i = 43;
BOOST_CHECK_EQUAL( 43, f() );
CHECK_CALLS( 1 );
@ -447,7 +437,7 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_value, mock_e
{
mock::detail::function< int&() > f;
int i = 42;
f.expect().returns( boost::ref( i ) );
f.expect().returns( std::ref( i ) );
i = 43;
BOOST_CHECK_EQUAL( 43, f() );
BOOST_CHECK_EQUAL( 12, f() = 12 );
@ -505,8 +495,7 @@ namespace
{
struct base
{
virtual ~base()
{}
virtual ~base() = default;
virtual void f() = 0;
};
struct derived : base
@ -516,67 +505,6 @@ namespace
};
}
#ifdef MOCK_AUTO_PTR
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_auto_ptr_value, mock_error_fixture )
{
{
mock::detail::function< std::auto_ptr< int >() > f;
std::auto_ptr< int > ptr( new int( 3 ) );
f.expect().returns( boost::ref( ptr ) );
BOOST_CHECK_EQUAL( 3, *ptr );
BOOST_CHECK_EQUAL( 3, *f() );
BOOST_CHECK( ! ptr.get() );
BOOST_CHECK( ! f().get() );
CHECK_CALLS( 2 );
}
{
mock::detail::function< std::auto_ptr< int >() > f;
std::auto_ptr< int > ptr( new int( 3 ) );
f.expect().returns( ptr );
BOOST_CHECK( ! ptr.get() );
BOOST_CHECK_EQUAL( 3, *f() );
BOOST_CHECK( ! f().get() );
CHECK_CALLS( 2 );
}
{
mock::detail::function< std::auto_ptr< int >() > f;
f.expect().returns( new int( 3 ) );
BOOST_CHECK_EQUAL( 3, *f() );
BOOST_CHECK( ! f().get() );
CHECK_CALLS( 2 );
}
{
mock::detail::function< std::auto_ptr< int >() > f;
f.expect().returns( std::auto_ptr< int >( new int( 3 ) ) );
BOOST_CHECK_EQUAL( 3, *f() );
BOOST_CHECK( ! f().get() );
CHECK_CALLS( 2 );
}
{
mock::detail::function< std::auto_ptr< base >() > f;
f.expect().returns( new derived );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
{
mock::detail::function< std::auto_ptr< base >() > f;
f.expect().returns( std::auto_ptr< base >( new derived ) );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
{
mock::detail::function< std::auto_ptr< base >() > f;
f.expect().returns( std::auto_ptr< derived >( new derived ) );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
}
#endif // MOCK_AUTO_PTR
#ifdef MOCK_RVALUE_REFERENCES
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_lvalue, mock_error_fixture )
{
mock::detail::function< int() > f;
@ -603,10 +531,6 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_rvalue, mock_er
CHECK_CALLS( 1 );
}
#endif
#ifdef MOCK_SMART_PTR
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_unique_ptr_lvalue, mock_error_fixture )
{
mock::detail::function< std::unique_ptr< int >() > f;
@ -626,24 +550,22 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_unique_ptr_rval
}
}
#endif // MOCK_SMART_PTR
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_shared_ptr_value, mock_error_fixture )
{
{
mock::detail::function< boost::shared_ptr< base >() > f;
mock::detail::function< std::shared_ptr< base >() > f;
f.expect().returns( new derived );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
{
mock::detail::function< const boost::shared_ptr< base >&() > f;
mock::detail::function< const std::shared_ptr< base >&() > f;
f.expect().returns( new derived );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
{
mock::detail::function< boost::shared_ptr< base >&() > f;
mock::detail::function< std::shared_ptr< base >&() > f;
f.expect().returns( new derived );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
@ -655,7 +577,7 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_by_reference, mock_er
{
mock::detail::function< base&() > f;
derived b;
f.expect().returns( boost::ref( b ) );
f.expect().returns( std::ref( b ) );
BOOST_CHECK_NO_THROW( f() );
CHECK_CALLS( 1 );
}
@ -668,7 +590,7 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_by_reference, mock_er
}
{
mock::detail::function< undefined&() > f;
f.expect().returns( boost::ref( get_undefined() ) );
f.expect().returns( std::ref( get_undefined() ) );
f.reset();
}
}
@ -705,10 +627,10 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_with
CHECK_CALLS( 1 );
}
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_without_parameters_thanks_to_boost_bind, mock_error_fixture )
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_without_parameters_thanks_to_std_bind, mock_error_fixture )
{
mock::detail::function< int( int ) > f;
f.expect().calls( boost::bind( &custom_result ) );
f.expect().calls( std::bind( &custom_result ) );
BOOST_CHECK_EQUAL( 42, f( 17 ) );
CHECK_CALLS( 1 );
}
@ -864,7 +786,7 @@ BOOST_FIXTURE_TEST_CASE( expectation_can_be_serialized_to_be_human_readable, moc
BOOST_FIXTURE_TEST_CASE( expectation_with_remaining_untriggered_matches_upon_destruction_calls_untriggered_expectation, mock_error_fixture )
{
boost::scoped_ptr< mock::detail::function< void() > > f( new mock::detail::function< void() > );
auto f = std::make_unique<mock::detail::function< void() >>();
f->expect().once();
CHECK_ERROR( f.reset(), "untriggered expectation", 0, "?\n. once()" );
}
@ -884,7 +806,7 @@ BOOST_FIXTURE_TEST_CASE( triggering_unexpected_call_call_disables_the_automatic_
BOOST_FIXTURE_TEST_CASE( adding_an_expectation_reactivates_the_verification_upon_destruction, mock_error_fixture )
{
boost::scoped_ptr< mock::detail::function< void() > > f( new mock::detail::function< void() > );
auto f = std::make_unique<mock::detail::function< void() >>();
CHECK_ERROR( (*f)(), "unexpected call", 0, "?()" );
f->expect().once();
CHECK_ERROR( f.reset(), "untriggered expectation", 0, "?\n. once()" );
@ -934,7 +856,7 @@ BOOST_FIXTURE_TEST_CASE( function_is_thread_safe, mock_error_fixture )
mock::detail::function< int() > f;
boost::thread_group group;
for( int i = 0; i < 100; ++i )
group.create_thread( boost::bind( &iterate, boost::ref( f ) ) );
group.create_thread( [&f](){ iterate(f); } );
group.join_all();
CHECK_CALLS( 100 );
}

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/invocation.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( unlimited )
{

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/is_functor.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#ifdef BOOST_MSVC
#pragma warning( push, 0 )
#endif
@ -17,23 +17,25 @@
#pragma warning( pop )
#endif
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/version.hpp>
#include <functional>
namespace
{
struct declared_but_not_defined;
BOOST_MPL_ASSERT_NOT((
mock::detail::is_functor< declared_but_not_defined, int > ));
static_assert( !mock::detail::is_functor< declared_but_not_defined, int >::value, "Should not be a functor" );
template< typename T >
void is_functor( T )
{
BOOST_MPL_ASSERT(( mock::detail::is_functor< T, 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 )
{
BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< T, int > ));
static_assert( !mock::detail::is_functor< T, int >::value, "Should not be a functor taking an int" );
}
void f0() {}
@ -48,22 +50,22 @@ BOOST_AUTO_TEST_CASE( data_is_not_functor )
BOOST_AUTO_TEST_CASE( function_is_functor )
{
is_functor( f0 );
is_not_functor( f0 );
is_functor( f1 );
is_functor( f2 );
is_not_functor( f2 );
}
BOOST_AUTO_TEST_CASE( function_pointer_is_functor )
{
is_functor( &f0 );
is_not_functor( &f0 );
is_functor( &f1 );
is_functor( &f2 );
is_not_functor( &f2 );
}
BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor )
{
is_functor( std::ptr_fun( &f1 ) );
is_functor( std::ptr_fun( &f2 ) );
is_not_functor( std::ptr_fun( &f2 ) );
}
BOOST_AUTO_TEST_CASE( std_bind_first_is_functor )
@ -71,26 +73,20 @@ BOOST_AUTO_TEST_CASE( std_bind_first_is_functor )
is_functor( std::bind1st( std::ptr_fun( &f2 ), "" ) );
}
namespace
BOOST_AUTO_TEST_CASE( bind_is_functor )
{
struct unary_functor0 : public std::unary_function< void, void >
{};
struct unary_functor1 : public std::unary_function< int, void >
{};
}
BOOST_AUTO_TEST_CASE( std_unary_functor_is_functor )
{
is_functor( unary_functor0() );
is_functor( unary_functor1() );
}
BOOST_AUTO_TEST_CASE( boost_bind_is_functor )
{
#if BOOST_VERSION >= 106000
using namespace boost::placeholders;
#endif
is_functor( boost::bind( &f0 ) );
is_functor( boost::bind( &f1, _1 ) );
is_functor( boost::bind( &f2, "", _1 ) );
}
is_functor( std::bind( &f0 ) );
is_functor( std::bind( &f1, std::placeholders::_1 ) );
is_functor( std::bind( &f2, "", std::placeholders::_1 ) );
}
BOOST_AUTO_TEST_CASE( boost_lambda_is_functor )
{
@ -105,51 +101,18 @@ BOOST_AUTO_TEST_CASE( boost_phoenix_is_functor )
BOOST_AUTO_TEST_CASE( boost_function_is_functor )
{
is_functor( boost::function< void() >() );
is_functor( boost::function< void(int) >() );
}
namespace
BOOST_AUTO_TEST_CASE( std_function_is_functor )
{
struct result_type_functor
{
typedef void result_type;
};
is_functor( std::function< void(int) >() );
}
BOOST_AUTO_TEST_CASE( class_with_result_type_is_functor )
{
is_functor( result_type_functor() );
}
namespace
{
struct sig_functor
{
template< typename Args >
struct sig
{
typedef void type;
};
};
}
BOOST_AUTO_TEST_CASE( class_with_sig_is_functor )
{
is_functor( sig_functor() );
}
#ifdef MOCK_LAMBDAS
BOOST_AUTO_TEST_CASE( cxx11_lambda_is_functor )
{
is_not_functor( []() {} );
#ifdef MOCK_DECLTYPE
is_functor( []( int ) {} );
#else
is_not_functor( []( int ) {} );
#endif
is_not_functor( []( const std::string&, int ) {} );
is_not_functor( []( int, const std::string& ) {} );
}
#endif

View file

@ -7,8 +7,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/signature.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/test/unit_test.hpp>
#include <type_traits>
namespace
{
@ -22,8 +22,6 @@ namespace
BOOST_AUTO_TEST_CASE( mock_signature_generates_signature )
{
BOOST_MPL_ASSERT((
boost::is_same< void(), MOCK_SIGNATURE(method_1) > ));
BOOST_MPL_ASSERT((
boost::is_same< float( int ), MOCK_SIGNATURE(method_2) > ));
static_assert( std::is_same< void(), MOCK_SIGNATURE(method_1) >::value, "!");
static_assert( std::is_same< float( int ), MOCK_SIGNATURE(method_2) >::value, "!");
}

View file

@ -7,15 +7,17 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/type_name.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <sstream>
namespace
{
template< typename T >
std::string to_string( const T& )
std::string to_string( const T& t)
{
return boost::lexical_cast< std::string >( MOCK_TYPE_NAME(T) );
std::ostringstream s;
s << mock::detail::make_type_name(t);
return s.str();
}
}
@ -111,7 +113,7 @@ BOOST_AUTO_TEST_CASE( name_of_type_in_unnamed_inner_namespace_is_extracted )
BOOST_AUTO_TEST_CASE( name_of_local_type_is_extracted )
{
struct my_local_type {};
BOOST_CHECK_EQUAL( "my_local_type", boost::lexical_cast< std::string >( MOCK_TYPE_NAME(my_local_type) ) );
BOOST_CHECK_EQUAL( "my_local_type", to_string( my_local_type() ) );
}
namespace

View file

@ -12,7 +12,7 @@ namespace
{
struct my_base
{
virtual ~my_base() {}
virtual ~my_base() = default;
virtual void my_method() = 0;
virtual void my_method( int ) = 0;
};

View file

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

View file

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

View file

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

View file

@ -8,8 +8,6 @@
#include <turtle/mock.hpp>
namespace
{
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 0, int(), my_method )
@ -19,4 +17,3 @@ namespace
my_class c;
MOCK_EXPECT( c.my_method ).returns( std::string() );
}
}

View file

@ -8,8 +8,6 @@
#include <turtle/mock.hpp>
namespace
{
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 0, std::string(), my_method )
@ -19,4 +17,3 @@ namespace
my_class c;
MOCK_EXPECT( c.my_method ).returns( 42 );
}
}

View file

@ -8,8 +8,6 @@
#include <turtle/mock.hpp>
namespace
{
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 0, void(), my_method )
@ -19,4 +17,3 @@ namespace
my_class c;
MOCK_EXPECT( c.my_method ).returns( "42" );
}
}

View file

@ -12,7 +12,7 @@ namespace
{
struct my_base
{
virtual ~my_base() {}
virtual ~my_base() = default;
};
MOCK_BASE_CLASS( my_class, my_base )

View file

@ -14,7 +14,7 @@ namespace
{
struct my_base
{
virtual ~my_base() {}
virtual ~my_base() = default;
virtual void my_method( int, int, int, int, int, int, int, int, int, int ) = 0;
};

View file

@ -1,18 +0,0 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/mock.hpp>
namespace
{
template< typename T >
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 1, void( T ), my_method )
};
}

View file

@ -12,7 +12,7 @@ namespace
{
struct my_base
{
virtual ~my_base() {}
virtual ~my_base() = default;
virtual void my_method( int ) = 0;
};

View file

@ -8,8 +8,6 @@
#include <turtle/mock.hpp>
namespace
{
MOCK_CLASS( my_class )
{
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
@ -19,4 +17,3 @@ namespace
my_class c;
MOCK_EXPECT( c.my_method ).with( 42, 42 );
}
}

View file

@ -11,9 +11,9 @@
#define MOCK_ERROR_POLICY mock_error
#include <turtle/detail/singleton.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <stdexcept>
#include <sstream>
struct mock_error_data_t : mock::detail::singleton< mock_error_data_t >
{
@ -68,18 +68,17 @@ struct mock_error
{}
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();
}
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 )
{
mock_error_data.fail( message,
boost::lexical_cast< std::string >( context ), file, line );
std::ostringstream s;
s << context; // Context can be streamed
mock_error_data.fail( message, s.str(), file, line );
}
};

View file

@ -7,9 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/constraint.hpp>
#include <boost/test/auto_unit_test.hpp>
#ifdef MOCK_VARIADIC_MACROS
#include <boost/test/unit_test.hpp>
namespace
{
@ -24,19 +22,3 @@ BOOST_AUTO_TEST_CASE( mock_constraint_is_supported_by_compilers_with_variadic_ma
BOOST_CHECK( constraint_1( 0 ).c_( 0 ) );
BOOST_CHECK( constraint_2( 0, 0 ).c_( 0 ) );
}
#endif // MOCK_VARIADIC_MACROS
namespace
{
MOCK_CONSTRAINT_EXT( constraint_0_ext, 0,, actual == 0 )
MOCK_CONSTRAINT_EXT( constraint_1_ext, 1, ( expected ), actual == expected )
MOCK_CONSTRAINT_EXT( constraint_2_ext, 2, ( expected_0, expected_1 ), actual == expected_0 || actual == expected_1 )
}
BOOST_AUTO_TEST_CASE( mock_constraint_ext_is_supported_by_all_compilers )
{
BOOST_CHECK( constraint_0_ext.c_( 0 ) );
BOOST_CHECK( constraint_1_ext( 0 ).c_( 0 ) );
BOOST_CHECK( constraint_2_ext( 0, 0 ).c_( 0 ) );
}

View file

@ -7,8 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/constraints.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( all_comparison_constraints_can_be_instanciated )
{
@ -48,11 +47,10 @@ BOOST_AUTO_TEST_CASE( equal_constraint )
BOOST_CHECK( ! mock::equal( std::string( "string" ) ).c_( "not string" ) );
{
std::string s;
BOOST_AUTO( c, mock::equal( boost::cref( s ) ) );
auto c = mock::equal( std::cref( s ) );
s = "string";
BOOST_CHECK( c.c_( "string" ) );
}
#ifdef MOCK_SMART_PTR
{
std::unique_ptr< int > i;
std::unique_ptr< int > j( new int( 3 ) );
@ -61,7 +59,6 @@ BOOST_AUTO_TEST_CASE( equal_constraint )
BOOST_CHECK( mock::equal( i ).c_( i ) );
BOOST_CHECK( mock::equal( j ).c_( j ) );
}
#endif
}
BOOST_AUTO_TEST_CASE( equal_constraint_deref )
@ -75,14 +72,12 @@ BOOST_AUTO_TEST_CASE( equal_constraint_deref )
int* i = 0;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
}
#ifdef MOCK_SMART_PTR
{
std::unique_ptr< int > j( new int( 3 ) );
BOOST_CHECK( mock::equal( 3 ).c_( j ) );
std::unique_ptr< int > i;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
}
#endif // MOCK_SMART_PTR
}
BOOST_AUTO_TEST_CASE( same_constraint )
@ -98,20 +93,14 @@ BOOST_AUTO_TEST_CASE( same_constraint )
int i = 0;
int j = 0;
BOOST_CHECK_EQUAL( i, j );
mock::constraint<
mock::detail::same<
const boost::reference_wrapper< const int >
>
> c = mock::same( boost::cref( i ) );
auto c = mock::same( i );
BOOST_CHECK( ! c.c_( j ) );
BOOST_CHECK( c.c_( i ) );
}
#ifdef MOCK_NULLPTR
{
std::nullptr_t p;
BOOST_CHECK( mock::same( p ).c_( p ) );
}
#endif
}
BOOST_AUTO_TEST_CASE( assign_constraint )
@ -143,9 +132,9 @@ BOOST_AUTO_TEST_CASE( assign_constraint )
int j = 1;
mock::constraint<
mock::detail::assign<
boost::reference_wrapper< const int >
std::reference_wrapper< const int >
>
> c = mock::assign( boost::cref( j ) );
> c = mock::assign( std::cref( j ) );
BOOST_CHECK( c.c_( i ) );
BOOST_CHECK_EQUAL( 1, i );
j = 3;
@ -155,11 +144,7 @@ BOOST_AUTO_TEST_CASE( assign_constraint )
{
int i = 0;
int j = 1;
mock::constraint<
mock::detail::assign<
boost::reference_wrapper< const int >
>
> c = mock::assign( boost::cref( j ) );
auto c = mock::assign( std::cref( j ) );
BOOST_CHECK( c.c_( &i ) );
BOOST_CHECK_EQUAL( 1, i );
j = 3;
@ -170,11 +155,7 @@ BOOST_AUTO_TEST_CASE( assign_constraint )
const int* i = 0;
int k = 1;
int* j = &k;
mock::constraint<
mock::detail::assign<
boost::reference_wrapper< int* const >
>
> c = mock::assign( boost::cref( j ) );
auto c = mock::assign( std::cref( j ) );
BOOST_CHECK( c.c_( i ) );
BOOST_CHECK_EQUAL( j, i );
j = 0;
@ -236,33 +217,29 @@ BOOST_AUTO_TEST_CASE( retrieve_constraint )
{
int i = 0;
const int j = 1;
BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) );
BOOST_CHECK( mock::retrieve( i ).c_( j ) );
BOOST_CHECK_EQUAL( i, j );
}
{
const int* i = 0;
const int j = 1;
BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) );
BOOST_CHECK( mock::retrieve( i ).c_( j ) );
BOOST_CHECK_EQUAL( i, &j );
}
#ifdef MOCK_NULLPTR
{
std::nullptr_t* i = 0;
std::nullptr_t j;
BOOST_CHECK( mock::retrieve( i ).c_( j ) );
BOOST_CHECK_EQUAL( i, &j );
}
#endif
#ifdef MOCK_SMART_PTR
{
std::unique_ptr< int > i;
std::unique_ptr< int > j( new int( 3 ) );
BOOST_CHECK( mock::retrieve( i ).c_( boost::move( j ) ) );
BOOST_CHECK( mock::retrieve( i ).c_( std::move( j ) ) );
BOOST_REQUIRE( i );
BOOST_CHECK_EQUAL( 3, *i );
BOOST_CHECK( !j );
}
#endif
}
namespace
@ -295,12 +272,10 @@ BOOST_AUTO_TEST_CASE( affirm_constraint )
BOOST_CHECK( mock::affirm.c_( &j ) );
}
{
#ifdef MOCK_SMART_PTR
std::unique_ptr< int > i;
std::unique_ptr< int > j( new int( 3 ) );
BOOST_CHECK( ! mock::affirm.c_( i ) );
BOOST_CHECK( mock::affirm.c_( j ) );
#endif
}
}
@ -344,11 +319,7 @@ BOOST_AUTO_TEST_CASE( contain_constraint_with_const_char_ptr )
BOOST_CHECK( ! mock::contain( "not found" ).c_( std::string( "this is a string" ) ) );
{
const char* s = 0;
mock::constraint<
mock::detail::contain<
boost::reference_wrapper< const char* const >
>
> c = mock::contain( boost::cref( s ) );
auto c = mock::contain( std::cref( s ) );
s = "string";
BOOST_CHECK( c.c_( "this is a string" ) );
BOOST_CHECK( c.c_( std::string( "this is a string" ) ) );
@ -368,9 +339,9 @@ BOOST_AUTO_TEST_CASE( contain_constraint_with_strings )
std::string s;
mock::constraint<
mock::detail::contain<
boost::reference_wrapper< const std::string >
std::reference_wrapper< const std::string >
>
> c = mock::contain( boost::cref( s ) );
> c = mock::contain( std::cref( s ) );
s = "string";
BOOST_CHECK( c.c_( "this is a string" ) );
BOOST_CHECK( c.c_( std::string( "this is a string" ) ) );

View file

@ -8,7 +8,7 @@
#define MOCK_USE_BOOST_TEST
#include <turtle/exception.hpp>
#include <boost/test/auto_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 )
{

View file

@ -9,11 +9,10 @@
#include "mock_error.hpp"
#include "undefined.hpp"
#include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/noncopyable.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <cmath>
#include <functional>
namespace
{
@ -81,11 +80,13 @@ BOOST_FIXTURE_TEST_CASE( basic_mock_object_usage, mock_error_fixture )
namespace
{
class my_ambiguited_interface : boost::noncopyable
class my_ambiguited_interface
{
public:
virtual ~my_ambiguited_interface()
{}
my_ambiguited_interface() = default;
my_ambiguited_interface(const my_ambiguited_interface&) = delete;
my_ambiguited_interface& operator=(const my_ambiguited_interface&) = delete;
virtual ~my_ambiguited_interface() = default;
virtual void my_method() = 0;
virtual void my_method( int ) = 0;
};
@ -107,11 +108,13 @@ BOOST_FIXTURE_TEST_CASE( mock_object_method_disambiguation, mock_error_fixture )
namespace
{
class my_const_ambiguited_interface : boost::noncopyable
class my_const_ambiguited_interface
{
public:
virtual ~my_const_ambiguited_interface()
{}
my_const_ambiguited_interface() = default;
my_const_ambiguited_interface(const my_const_ambiguited_interface&) = delete;
my_const_ambiguited_interface& operator=(const my_const_ambiguited_interface&) = delete;
virtual ~my_const_ambiguited_interface() = default;
virtual void my_method() = 0;
virtual void my_method() const = 0;
};
@ -153,7 +156,7 @@ namespace
BOOST_FIXTURE_TEST_CASE( mock_functor_in_namespace_is_supported, mock_error_fixture )
{
boost::function< int( float, const std::string& ) > func;
std::function< int( float, const std::string& ) > func;
MOCK_EXPECT( gf ).once().with( 3, "op" ).returns( 42 );
func = gf;
BOOST_CHECK_EQUAL( 42, func( 3, "op" ) );
@ -162,7 +165,7 @@ BOOST_FIXTURE_TEST_CASE( mock_functor_in_namespace_is_supported, mock_error_fixt
BOOST_FIXTURE_TEST_CASE( mock_functor_in_function_is_supported, mock_error_fixture )
{
boost::function< int( float, const std::string& ) > func;
std::function< int( float, const std::string& ) > func;
{
MOCK_FUNCTOR( f, int( float, const std::string& ) );
MOCK_EXPECT( f ).once().with( 3, "op" ).returns( 42 );
@ -212,8 +215,7 @@ namespace
template< typename T >
struct my_template_base_class
{
virtual ~my_template_base_class()
{}
virtual ~my_template_base_class() = default;
virtual void my_method( T ) = 0;
virtual void my_other_method() = 0;
};
@ -236,23 +238,27 @@ BOOST_FIXTURE_TEST_CASE( mocking_a_template_base_class_method_is_supported, mock
namespace
{
class my_observer : boost::noncopyable
class my_observer
{
public:
virtual ~my_observer()
{}
my_observer() = default;
my_observer(const my_observer&) = delete;
my_observer& operator=(const my_observer&) = delete;
virtual ~my_observer() = default;
virtual void notify( int value ) = 0;
};
class my_manager : boost::noncopyable
class my_manager
{
public:
virtual ~my_manager()
{}
my_manager() = default;
my_manager(const my_manager&) = delete;
my_manager& operator=(const my_manager&) = delete;
virtual ~my_manager() = default;
virtual my_observer& get_observer() const = 0;
};
class my_subject : boost::noncopyable
class my_subject
{
public:
explicit my_subject( my_manager& f )
@ -287,7 +293,7 @@ namespace
BOOST_FIXTURE_TEST_CASE( basic_mock_object_collaboration_usage, fixture )
{
MOCK_EXPECT( manager.get_observer ).returns( boost::ref( observer ) );
MOCK_EXPECT( manager.get_observer ).returns( std::ref( observer ) );
my_subject subject( manager );
MOCK_EXPECT( observer.notify ).once().with( 1 );
subject.increment();
@ -388,7 +394,7 @@ BOOST_FIXTURE_TEST_CASE( boost_optional_on_base_class_reference_as_return_type_i
{
boost_optional b;
my_mock_observer o;
MOCK_EXPECT( b.tag ).once().returns( boost::ref( o ) );
MOCK_EXPECT( b.tag ).once().returns( std::ref( o ) );
b.method();
CHECK_CALLS( 1 );
}
@ -453,7 +459,7 @@ BOOST_FIXTURE_TEST_CASE( boost_reference_wrapper_is_supported_in_value_constrain
{
MOCK_FUNCTOR( f, void( const std::string& ) );
std::string s;
MOCK_EXPECT( f ).once().with( boost::cref( s ) );
MOCK_EXPECT( f ).once().with( std::cref( s ) );
s = "string";
f( "string" );
CHECK_CALLS( 1 );
@ -587,7 +593,9 @@ namespace
template< typename T1, typename T2 >
struct my_base
{};
MOCK_BASE_CLASS( my_comma_mock, my_base< int BOOST_PP_COMMA() int > )
MOCK_BASE_CLASS( my_comma_mock, my_base< int, int > )
{};
MOCK_BASE_CLASS( my_boost_pp_comma_mock, my_base< int BOOST_PP_COMMA() int > )
{};
}
@ -640,7 +648,7 @@ BOOST_FIXTURE_TEST_CASE( mock_functor_creation_is_thread_safe, mock_error_fixtur
{
boost::thread_group group;
for( int i = 0; i < 100; ++i )
group.create_thread( boost::bind( &create_functor, i ) );
group.create_thread( [i](){ create_functor( i ); } );
group.join_all();
CHECK_CALLS( 100 );
}
@ -659,7 +667,7 @@ BOOST_FIXTURE_TEST_CASE( mock_class_is_thread_safe, mock_error_fixture )
my_mock m;
boost::thread_group group;
for( int i = 0; i < 100; ++i )
group.create_thread( boost::bind( &iterate, boost::ref( m ) ) );
group.create_thread( [&m](){ iterate(m); } );
group.join_all();
CHECK_CALLS( 100 );
}
@ -705,8 +713,6 @@ BOOST_FIXTURE_TEST_CASE( mock_method_accepts_polymorphic_multi_constraint, mock_
CHECK_CALLS( 1 );
}
#ifdef MOCK_SMART_PTR
BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_action, mock_error_fixture )
{
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
@ -775,5 +781,3 @@ struct my_unique_ptr_class
MOCK_METHOD_EXT( m, 1, void( std::unique_ptr< int > ), m )
MOCK_STATIC_METHOD( ms, 1, void( std::unique_ptr< int > ), ms )
};
#endif

View file

@ -7,11 +7,9 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/log.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#ifdef BOOST_MSVC
#pragma warning( push, 0 )
@ -25,11 +23,13 @@
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#endif
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <functional>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <memory>
#include <set>
namespace
@ -54,13 +54,19 @@ BOOST_AUTO_TEST_CASE( pointer_yields_its_value_when_serialized )
{
{
int i = 0;
std::ostringstream s;
s << &i;
const std::string pointerValue = s.str();
BOOST_CHECK_NE( "?", to_string( &i ) );
BOOST_CHECK_EQUAL( boost::lexical_cast< std::string >( &i ), to_string( &i ) );
BOOST_CHECK_EQUAL( pointerValue, to_string( &i ) );
}
{
const int i = 0;
std::ostringstream s;
s << &i;
const std::string pointerValue = s.str();
BOOST_CHECK_NE( "?", to_string( &i ) );
BOOST_CHECK_EQUAL( boost::lexical_cast< std::string >( &i ), to_string( &i ) );
BOOST_CHECK_EQUAL( pointerValue, to_string( &i ) );
}
}
@ -387,16 +393,6 @@ BOOST_AUTO_TEST_CASE( std_pairs_are_serialized )
BOOST_CHECK_EQUAL( "(3,42)", to_string( std::make_pair( 3, 42.f ) ) );
}
#ifdef MOCK_AUTO_PTR
BOOST_AUTO_TEST_CASE( std_auto_ptr_are_serialized )
{
BOOST_CHECK_NE( "?", to_string( std::auto_ptr< int >() ) );
BOOST_CHECK_NE( "?", to_string( std::auto_ptr< int >( new int( 42 ) ) ) );
}
#endif // MOCK_AUTO_PTR
BOOST_AUTO_TEST_CASE( boost_shared_ptr_are_serialized )
{
BOOST_CHECK_NE( "?", to_string( boost::shared_ptr< int >() ) );
@ -409,8 +405,6 @@ BOOST_AUTO_TEST_CASE( boost_weak_ptr_are_serialized )
BOOST_CHECK_NE( "?", to_string( boost::weak_ptr< int >( boost::shared_ptr< int >( new int( 42 ) ) ) ) );
}
#ifdef MOCK_SMART_PTR
BOOST_AUTO_TEST_CASE( std_shared_ptr_are_serialized )
{
BOOST_CHECK_NE( "?", to_string( std::shared_ptr< int >() ) );
@ -429,8 +423,6 @@ BOOST_AUTO_TEST_CASE( std_unique_ptr_are_serialized )
BOOST_CHECK_NE( "?", to_string( std::unique_ptr< int >( new int( 42 ) ) ) );
}
#endif
BOOST_AUTO_TEST_CASE( std_deques_are_serialized )
{
std::deque< int > d;
@ -521,11 +513,11 @@ BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized )
BOOST_CHECK_EQUAL( "((12,\"12\"),(42,\"42\"))", to_string( boost::assign::map_list_of( 12, "12" )( 42, "42" ) ) );
}
BOOST_AUTO_TEST_CASE( boost_reference_wrappers_are_serialized )
BOOST_AUTO_TEST_CASE( std_reference_wrappers_are_serialized )
{
const int i = 3;
BOOST_CHECK_EQUAL( "3", to_string( boost::cref( i ) ) );
BOOST_CHECK_EQUAL( "\"string\"", to_string( boost::cref( "string" ) ) );
BOOST_CHECK_EQUAL( "3", to_string( std::cref( i ) ) );
BOOST_CHECK_EQUAL( "\"string\"", to_string( std::cref( "string" ) ) );
}
namespace
@ -633,7 +625,7 @@ BOOST_AUTO_TEST_CASE( mock_detail_template_template_streamable_yields_its_value_
BOOST_AUTO_TEST_CASE( unsigned_char_is_serialized_as_int )
{
BOOST_CHECK_EQUAL( boost::lexical_cast< std::string >( static_cast< int >( 'a' ) ), to_string< unsigned char >( 'a' ) );
BOOST_CHECK_EQUAL( std::to_string( static_cast< int >( 'a' ) ), to_string< unsigned char >( 'a' ) );
}
namespace
@ -650,9 +642,10 @@ BOOST_AUTO_TEST_CASE( boost_phoenix_functor_yields_question_mark_when_serialized
BOOST_CHECK_EQUAL( "?", to_string( boost::phoenix::arg_names::_1 < 42 ) );
}
BOOST_AUTO_TEST_CASE( boost_bind_functor_yields_question_mark_when_serialized )
BOOST_AUTO_TEST_CASE( bind_functor_yields_question_mark_when_serialized )
{
BOOST_CHECK_EQUAL( "?", to_string( boost::bind( &some_function ) ) );
BOOST_CHECK_EQUAL( "?", to_string( std::bind( &some_function ) ) );
}
#ifndef BOOST_MSVC // this produces an ICE with all versions of MSVC
@ -665,15 +658,11 @@ BOOST_AUTO_TEST_CASE( boost_lambda_functor_yields_question_mark_when_serialized
#endif
#ifdef MOCK_NULLPTR
BOOST_AUTO_TEST_CASE( nullptr_is_serialized )
{
BOOST_CHECK_EQUAL( "nullptr", to_string( nullptr ) );
}
#endif
BOOST_AUTO_TEST_CASE( mock_boost_optional_yields_its_value_when_serialized )
{
BOOST_CHECK_EQUAL( "7", to_string( boost::optional< int >( 7 ) ) );

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <turtle/detail/function.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
@ -28,8 +28,8 @@ BOOST_AUTO_TEST_CASE( int_and_int_can_be_compared )
BOOST_AUTO_TEST_CASE( ref_to_int_and_int_can_be_compared )
{
const int i = 3;
BOOST_CHECK( match( 3, boost::cref( i ) ) );
BOOST_CHECK( ! match( 4, boost::cref( i ) ) );
BOOST_CHECK( match( 3, std::cref( i ) ) );
BOOST_CHECK( ! match( 4, std::cref( i ) ) );
}
namespace

View file

@ -8,7 +8,7 @@
#include "mock_error.hpp"
#include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#define IDENTITY(z, n, d) d

View file

@ -8,9 +8,8 @@
#include "mock_error.hpp"
#include <turtle/mock.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <boost/test/unit_test.hpp>
#include <functional>
namespace
{
@ -44,7 +43,7 @@ namespace
BOOST_FIXTURE_TEST_CASE( mock_addition_operator, mock_error_fixture )
{
mock_class_with_operator m;
MOCK_EXPECT( m.addition ).once().returns( boost::ref( m ) );
MOCK_EXPECT( m.addition ).once().returns( std::ref( m ) );
m += 1;
CHECK_CALLS( 1 );
}
@ -162,7 +161,8 @@ namespace
BOOST_FIXTURE_TEST_CASE( MOCK_CONST_METHOD_EXT_macro_defines_a_bindable_method, mock_error_fixture )
{
my_mock m;
boost::bind( &my_mock::my_method, &m, 42 );
const auto f = std::bind( &my_mock::my_method, &m, 42 );
(void) f;
}
BOOST_FIXTURE_TEST_CASE( MOCK_VERIFY_macro, mock_error_fixture )
@ -207,31 +207,9 @@ BOOST_FIXTURE_TEST_CASE( mock_object_is_named, mock_error_fixture )
BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_HELPER( m.my_method ) ) );
}
#ifdef MOCK_AUTO_PTR
BOOST_FIXTURE_TEST_CASE( mock_object_auto_pointer_is_named, mock_error_fixture )
{
std::auto_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) );
BOOST_CHECK_EQUAL( "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_HELPER( m->my_method ) ) );
}
BOOST_FIXTURE_TEST_CASE( mock_object_const_auto_pointer_is_named, mock_error_fixture )
{
const std::auto_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_HELPER( m->my_method ) ) );
BOOST_CHECK_EQUAL( "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_HELPER( m->my_method ) ) );
}
#endif // MOCK_AUTO_PTR
BOOST_FIXTURE_TEST_CASE( mock_object_shared_pointer_is_named, mock_error_fixture )
{
boost::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( "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 ) ) );
@ -240,7 +218,7 @@ BOOST_FIXTURE_TEST_CASE( mock_object_shared_pointer_is_named, mock_error_fixture
BOOST_FIXTURE_TEST_CASE( mock_object_const_shared_pointer_is_named, mock_error_fixture )
{
const boost::shared_ptr< my_mock > m( new my_mock );
const 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( "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 ) ) );
@ -298,7 +276,7 @@ namespace
template< typename T >
struct tpl_functor_class
{
MOCK_FUNCTOR_TPL( f, void( T ) );
MOCK_FUNCTOR( f, void( T ) );
};
}
@ -349,21 +327,18 @@ namespace
{
MOCK_CLASS( round_parenthesized_signature )
{
MOCK_METHOD_EXT( m0, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())), m0 )
MOCK_STATIC_METHOD( m1, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())), m1 )
MOCK_FUNCTOR( f0, BOOST_IDENTITY_TYPE((std::map< int, int >())) );
MOCK_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, BOOST_IDENTITY_TYPE((std::map< int, int >())), fun0 )
MOCK_FUNCTION( fun0, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()), fun0 )
}
#ifdef MOCK_VARIADIC_MACROS
namespace
{
struct base
{
virtual ~base()
{}
virtual ~base() = default;
virtual void m1() = 0;
virtual void m10() const = 0;
@ -404,37 +379,11 @@ namespace
MOCK_FUNCTION( fun1, 0, void() )
MOCK_FUNCTION( fun2, 0, void(), fun2 )
MOCK_FUNCTION( fun3, 0, BOOST_IDENTITY_TYPE((std::map< int, int >())) )
MOCK_FUNCTION( fun3, 0, MOCK_PROTECT_FUNCTION_SIG(std::map< int, int >()) )
MOCK_FUNCTOR( f_variadic, std::map< int, int >() );
}
#else // MOCK_VARIADIC_MACROS
namespace
{
struct base
{
virtual ~base()
{}
virtual void m1() = 0;
};
MOCK_BASE_CLASS( derived, base )
{
MOCK_METHOD( m1, 0 )
};
template< typename T >
MOCK_BASE_CLASS( derived_tpl, base )
{
MOCK_METHOD_EXT( m1, 0, void(), m1 )
};
}
#endif // MOCK_VARIADIC_MACROS
#ifdef BOOST_MSVC
# define MOCK_STDCALL __stdcall
#else
@ -445,8 +394,7 @@ namespace stdcall
{
struct base
{
virtual ~base()
{}
virtual ~base() = default;
virtual void MOCK_STDCALL m1() = 0;
};
@ -458,9 +406,7 @@ namespace stdcall
MOCK_CONVERSION_OPERATOR( MOCK_STDCALL operator, int, to_int )
MOCK_METHOD_EXT( MOCK_STDCALL m1, 0, void(), m1 )
MOCK_METHOD_EXT( MOCK_STDCALL m2, 0, void(), m2 )
#ifdef MOCK_VARIADIC_MACROS
MOCK_METHOD( MOCK_STDCALL m3, 0, void(), m3 )
#endif
MOCK_STATIC_METHOD( MOCK_STDCALL m4, 0, void(), m4 )
};

View file

@ -10,8 +10,8 @@
#include <turtle/reset.hpp>
#include <turtle/verify.hpp>
#include <turtle/detail/function.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/test/unit_test.hpp>
#include <memory>
namespace
{
@ -33,7 +33,7 @@ namespace
{
fixture()
{
mock::detail::configure( o, e, "instance", MOCK_TYPE_NAME(o), "name" );
mock::detail::configure( o, e, "instance", mock::detail::make_type_name(o), "name" );
}
object o;
mock::detail::function< void() > e;
@ -73,7 +73,7 @@ BOOST_FIXTURE_TEST_CASE( an_object_is_assignable_by_sharing_its_state, mock_erro
mock::detail::function< void() > e;
{
object o2;
mock::detail::configure( o2, e, "instance", MOCK_TYPE_NAME(o2), "name" );
mock::detail::configure( o2, e, "instance", mock::detail::make_type_name(o2), "name" );
e.expect().once();
o1 = o2;
CHECK_ERROR(
@ -90,10 +90,10 @@ BOOST_FIXTURE_TEST_CASE( an_object_is_assignable_by_sharing_its_state, mock_erro
BOOST_FIXTURE_TEST_CASE( an_object_is_copiable_by_sharing_its_state, mock_error_fixture )
{
boost::scoped_ptr< object > o2( new object );
auto o2 = std::make_unique<object>();
const object o1( *o2 );
mock::detail::function< void() > e;
mock::detail::configure( *o2, e, "instance", MOCK_TYPE_NAME(*o2), "name" );
mock::detail::configure( *o2, e, "instance", mock::detail::make_type_name(*o2), "name" );
e.expect().once();
CHECK_ERROR(
BOOST_CHECK( ! mock::verify( *o2 ) ),

View file

@ -9,7 +9,7 @@
#include "mock_error.hpp"
#include <turtle/sequence.hpp>
#include <turtle/detail/function.hpp>
#include <boost/test/auto_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 )
{