diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..53cf91a --- /dev/null +++ b/.github/workflows/ci.yml @@ -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 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a12eb45..0000000 --- a/.travis.yml +++ /dev/null @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 58b6828..957f3d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 $) +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) diff --git a/appveyor.yml b/appveyor.yml index 7ebd82e..40f4560 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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: diff --git a/doc/changelog.qbk b/doc/changelog.qbk index 9b5700d..20c3d4c 100644 --- a/doc/changelog.qbk +++ b/doc/changelog.qbk @@ -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] diff --git a/doc/customization.qbk b/doc/customization.qbk index 577ed88..6946cff 100644 --- a/doc/customization.qbk +++ b/doc/customization.qbk @@ -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] diff --git a/doc/example/calculator.hpp b/doc/example/calculator.hpp index 23aff87..13c83cd 100644 --- a/doc/example/calculator.hpp +++ b/doc/example/calculator.hpp @@ -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' }; //] diff --git a/doc/example/customization.cpp b/doc/example/customization.cpp index 30f69c3..d9f6cb7 100644 --- a/doc/example/customization.cpp +++ b/doc/example/customization.cpp @@ -12,6 +12,7 @@ //] #include "calculator.hpp" #include "mock_view.hpp" +#include //[ 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 //] +#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 diff --git a/doc/example/getting_started.cpp b/doc/example/getting_started.cpp index ff732c4..4cf11fe 100644 --- a/doc/example/getting_started.cpp +++ b/doc/example/getting_started.cpp @@ -6,14 +6,69 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include +#include +#include + +std::function error_handler_abort; +std::function error_handler_pass; +std::function error_handler_call; +std::function 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 +#include #include //] #include "calculator.hpp" #include "mock_view.hpp" +struct Fixture +{ + Fixture() + { + error_handler_abort = mock::error::abort; + error_handler_pass = mock::error::pass; + error_handler_call = mock::error::call; + error_handler_fail = mock::error::fail; + } +}; + +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() diff --git a/doc/example/limitations_comma_in_macro.cpp b/doc/example/limitations_comma_in_macro.cpp deleted file mode 100644 index c19ebdf..0000000 --- a/doc/example/limitations_comma_in_macro.cpp +++ /dev/null @@ -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 -#include - -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 - {}; -//] -} diff --git a/doc/example/limitations_const_parameter_warning.cpp b/doc/example/limitations_const_parameter_warning.cpp index 531bba2..88a163c 100644 --- a/doc/example/limitations_const_parameter_warning.cpp +++ b/doc/example/limitations_const_parameter_warning.cpp @@ -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 +#include #include 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); +} diff --git a/doc/example/limitations_literal_zero.cpp b/doc/example/limitations_literal_zero.cpp index 463f4ea..badd1c2 100644 --- a/doc/example/limitations_literal_zero.cpp +++ b/doc/example/limitations_literal_zero.cpp @@ -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 +#include #include 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 } diff --git a/doc/example/limitations_non_virtual_method.cpp b/doc/example/limitations_non_virtual_method.cpp index b6f0457..27e1899 100644 --- a/doc/example/limitations_non_virtual_method.cpp +++ b/doc/example/limitations_non_virtual_method.cpp @@ -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 +#include #include //[ 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(&b)->method(); // Doesn't call the mocked method as asserted above +} diff --git a/doc/example/limitations_protected_private_method.cpp b/doc/example/limitations_protected_private_method.cpp index a3a23f3..887b10f 100644 --- a/doc/example/limitations_protected_private_method.cpp +++ b/doc/example/limitations_protected_private_method.cpp @@ -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 +#include #include 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(&b)->call(); +} diff --git a/doc/example/limitations_template_base_class_method.cpp b/doc/example/limitations_template_base_class_method.cpp index 5b5461b..b8e6839 100644 --- a/doc/example/limitations_template_base_class_method.cpp +++ b/doc/example/limitations_template_base_class_method.cpp @@ -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 +#include #include 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 b; + MOCK_EXPECT(b.method).once(); + static_cast*>(&b)->method(); +} diff --git a/doc/example/limitations_template_method.cpp b/doc/example/limitations_template_method.cpp index c5c0fa7..598934e 100644 --- a/doc/example/limitations_template_method.cpp +++ b/doc/example/limitations_template_method.cpp @@ -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 +#include #include 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); +} } diff --git a/doc/example/limitations_throw_specifier.cpp b/doc/example/limitations_throw_specifier.cpp index 01e70fe..1c72731 100644 --- a/doc/example/limitations_throw_specifier.cpp +++ b/doc/example/limitations_throw_specifier.cpp @@ -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 +#include #include 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(&b)->method(); +} diff --git a/doc/example/motivation.cpp b/doc/example/motivation.cpp index 9aef368..aadc975 100644 --- a/doc/example/motivation.cpp +++ b/doc/example/motivation.cpp @@ -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 +#include #include #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 ); diff --git a/doc/example/patterns_async_call.cpp b/doc/example/patterns_async_call.cpp index e1b2a60..0e8b779 100644 --- a/doc/example/patterns_async_call.cpp +++ b/doc/example/patterns_async_call.cpp @@ -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 -#include +#include #include #include -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 } + +} + //] diff --git a/doc/example/patterns_invoke_functor.cpp b/doc/example/patterns_invoke_functor.cpp index f4d281d..a66e471 100644 --- a/doc/example/patterns_invoke_functor.cpp +++ b/doc/example/patterns_invoke_functor.cpp @@ -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 +// Intentionally duplicate to have complete examples and minimal user visible, yet tested test code +#include + +static void someFunctor(int newValue); +//[ invoke_functor_problem +#include -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 -#include +#include #include 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 ); } //] diff --git a/doc/example/patterns_quick_constraint.cpp b/doc/example/patterns_quick_constraint.cpp index a331bdc..13bec6b 100644 --- a/doc/example/patterns_quick_constraint.cpp +++ b/doc/example/patterns_quick_constraint.cpp @@ -7,8 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) //[ quick_constraint_problem -#define BOOST_AUTO_TEST_MAIN -#include +#include #include #include @@ -36,13 +35,15 @@ namespace //] //[ quick_constraint_solution -#include +#include 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 diff --git a/doc/example/patterns_retrieve_cref.cpp b/doc/example/patterns_retrieve_cref.cpp index 8be3e9a..be28298 100644 --- a/doc/example/patterns_retrieve_cref.cpp +++ b/doc/example/patterns_retrieve_cref.cpp @@ -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 +#include #include 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(); } //] diff --git a/doc/example/patterns_static_objects.cpp b/doc/example/patterns_static_objects.cpp index c385fbc..7918531 100644 --- a/doc/example/patterns_static_objects.cpp +++ b/doc/example/patterns_static_objects.cpp @@ -6,9 +6,18 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + +// 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 +#include #include #include @@ -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 ) diff --git a/doc/example/rationale.cpp b/doc/example/rationale.cpp index 170e7e7..9ece937 100644 --- a/doc/example/rationale.cpp +++ b/doc/example/rationale.cpp @@ -9,6 +9,19 @@ #include #include "calculator.hpp" #include "mock_view.hpp" +#include +#include +#include +#include + +// 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 ) diff --git a/doc/example/reference.cpp b/doc/example/reference.cpp index bb2c4d6..ae6ca2e 100644 --- a/doc/example/reference.cpp +++ b/doc/example/reference.cpp @@ -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 +#include #include 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 ) ); -} -//] -} diff --git a/doc/limitations.qbk b/doc/limitations.qbk index 46926f0..19c6294 100644 --- a/doc/limitations.qbk +++ b/doc/limitations.qbk @@ -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 : diff --git a/doc/reference.qbk b/doc/reference.qbk index 434a630..dacce89 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -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] diff --git a/include/turtle/config.hpp b/include/turtle/config.hpp index 16b0ed5..f23084d 100644 --- a/include/turtle/config.hpp +++ b/include/turtle/config.hpp @@ -12,8 +12,6 @@ #define MOCK_CONFIG_HPP_INCLUDED #include -#include -#include #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 diff --git a/include/turtle/constraint.hpp b/include/turtle/constraint.hpp index 887a22d..4708cf8 100644 --- a/include/turtle/constraint.hpp +++ b/include/turtle/constraint.hpp @@ -11,7 +11,7 @@ #include "config.hpp" #include "log.hpp" -#include +#include "unwrap_reference.hpp" #include #include #include @@ -19,16 +19,15 @@ #include #include #include -#include -#include +#include +#include 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 diff --git a/include/turtle/constraints.hpp b/include/turtle/constraints.hpp index c17320f..f29495a 100644 --- a/include/turtle/constraints.hpp +++ b/include/turtle/constraints.hpp @@ -11,19 +11,18 @@ #include "config.hpp" #include "constraint.hpp" -#include "detail/addressof.hpp" #include "detail/move_helper.hpp" -#include +#include "unwrap_reference.hpp" +#include "detail/void_t.hpp" #include -#include -#include -#include -#include #if BOOST_VERSION >= 107000 #include #else #include #endif +#include +#include +#include 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 + struct has_equal_to: std::false_type + {}; + + template + struct has_equal_to() == std::declval())>>: 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 > diff --git a/include/turtle/detail/action.hpp b/include/turtle/detail/action.hpp index a146130..714d61a 100644 --- a/include/turtle/detail/action.hpp +++ b/include/turtle/detail/action.hpp @@ -10,14 +10,9 @@ #define MOCK_ACTION_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include 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> type; - value_imp( BOOST_RV_REF(value_type) t ) - : t_( boost::move( t ) ) + template< typename U > + value_imp( U&& t ) : t_( std::forward( 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::type& store( T&& t ) { - v_.reset( new value_imp< T >( boost::move( t ) ) ); + v_ = std::make_unique< value_imp >( std::forward( 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 >( 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 diff --git a/include/turtle/detail/addressof.hpp b/include/turtle/detail/addressof.hpp deleted file mode 100644 index 4e48a8d..0000000 --- a/include/turtle/detail/addressof.hpp +++ /dev/null @@ -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 - -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 diff --git a/include/turtle/detail/context.hpp b/include/turtle/detail/context.hpp index 9b275a3..3e46813 100644 --- a/include/turtle/detail/context.hpp +++ b/include/turtle/detail/context.hpp @@ -11,7 +11,6 @@ #include "../config.hpp" #include "type_name.hpp" -#include #include #include #include @@ -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, diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index 8b4cf40..d3e74bd 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -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 > sequences_; const char* file_; int line_; }; diff --git a/include/turtle/detail/formatter.hpp b/include/turtle/detail/formatter.hpp index 18ccd73..b1377b9 100644 --- a/include/turtle/detail/formatter.hpp +++ b/include/turtle/detail/formatter.hpp @@ -11,7 +11,7 @@ #include "../config.hpp" #include "../stream.hpp" -#include "addressof.hpp" +#include 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 { diff --git a/include/turtle/detail/function.hpp b/include/turtle/detail/function.hpp index a17dfec..e231a95 100644 --- a/include/turtle/detail/function.hpp +++ b/include/turtle/detail/function.hpp @@ -30,11 +30,6 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include @@ -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 ); } diff --git a/include/turtle/detail/function_impl_template.hpp b/include/turtle/detail/function_impl_template.hpp index 3a68971..ecf6667 100644 --- a/include/turtle/detail/function_impl_template.hpp +++ b/include/turtle/detail/function_impl_template.hpp @@ -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,17 +72,18 @@ 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,31 +226,31 @@ 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( expectation.is_valid( + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) ) { - if( ! it->invoke() ) + 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 diff --git a/include/turtle/detail/function_template.hpp b/include/turtle/detail/function_template.hpp index 0ebfe14..e4de743 100644 --- a/include/turtle/detail/function_template.hpp +++ b/include/turtle/detail/function_template.hpp @@ -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 diff --git a/include/turtle/detail/group.hpp b/include/turtle/detail/group.hpp index d0668cc..16ce5a3 100644 --- a/include/turtle/detail/group.hpp +++ b/include/turtle/detail/group.hpp @@ -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 diff --git a/include/turtle/detail/invocation.hpp b/include/turtle/detail/invocation.hpp index fd1c0f6..cf37dff 100644 --- a/include/turtle/detail/invocation.hpp +++ b/include/turtle/detail/invocation.hpp @@ -10,7 +10,6 @@ #define MOCK_INVOCATION_HPP_INCLUDED #include "../config.hpp" -#include #include #include #include @@ -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; diff --git a/include/turtle/detail/is_functor.hpp b/include/turtle/detail/is_functor.hpp index 5d4de95..066cb92 100644 --- a/include/turtle/detail/is_functor.hpp +++ b/include/turtle/detail/is_functor.hpp @@ -10,51 +10,19 @@ #define MOCK_IS_FUNCTOR_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include -#include -#include +#include "void_t.hpp" +#include 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()( std::declval() ) )> >: std::true_type {}; } } // mock diff --git a/include/turtle/detail/matcher_base_template.hpp b/include/turtle/detail/matcher_base_template.hpp index 07fa326..931b8e9 100644 --- a/include/turtle/detail/matcher_base_template.hpp +++ b/include/turtle/detail/matcher_base_template.hpp @@ -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; diff --git a/include/turtle/detail/move_helper.hpp b/include/turtle/detail/move_helper.hpp index 87f1f2d..9d910ff 100644 --- a/include/turtle/detail/move_helper.hpp +++ b/include/turtle/detail/move_helper.hpp @@ -9,69 +9,18 @@ #ifndef MOCK_MOVE_HELPER_HPP_INCLUDED #define MOCK_MOVE_HELPER_HPP_INCLUDED -#include "../config.hpp" -#include -#include -#include -#include -#include -#include +#include 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 > + >; } } diff --git a/include/turtle/detail/mutex.hpp b/include/turtle/detail/mutex.hpp index b5dcb35..793a666 100644 --- a/include/turtle/detail/mutex.hpp +++ b/include/turtle/detail/mutex.hpp @@ -11,9 +11,7 @@ #include "../config.hpp" #include "singleton.hpp" -#include -#include -#include +#include #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; + scoped_lock( mutex& ) {} + ~scoped_lock() {} + }; + class lock + { public: - lock( const boost::shared_ptr< mutex >& ) - {} - ~lock() - {} - lock( BOOST_RV_REF( lock ) ) - {} - lock& operator=( BOOST_RV_REF( lock ) ) - { - return *this; - } + lock( const std::shared_ptr< mutex >& ) {} + ~lock() {} + lock(const lock&) = delete; + lock( lock&& ) = default; + lock& operator=( const lock& ) = delete; + lock& operator=( lock&& ) = default; }; } } // mock diff --git a/include/turtle/detail/object_impl.hpp b/include/turtle/detail/object_impl.hpp index 6aa215f..6f5d4eb 100644 --- a/include/turtle/detail/object_impl.hpp +++ b/include/turtle/detail/object_impl.hpp @@ -17,8 +17,6 @@ #include "child.hpp" #include "mutex.hpp" #include -#include -#include #include 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 diff --git a/include/turtle/detail/parameter.hpp b/include/turtle/detail/parameter.hpp index 38925a2..b37ce58 100644 --- a/include/turtle/detail/parameter.hpp +++ b/include/turtle/detail/parameter.hpp @@ -10,24 +10,70 @@ #define MOCK_PARAMETER_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include 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> : tuple_element> + {}; + + template< class H, class... T > + struct tuple_element<0, tuple> + { + 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; + }; + 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::value, "Function signature has not that many parameters"); + using type = typename tuple_element< n, typename parameter_types::type >::type; }; + + template + struct parameter_type; + template + struct parameter_type + { + using type = U; + }; + template + using parameter_type_t = typename parameter_type::type; } } // mock diff --git a/include/turtle/detail/parent.hpp b/include/turtle/detail/parent.hpp index 0d14e77..aedb373 100644 --- a/include/turtle/detail/parent.hpp +++ b/include/turtle/detail/parent.hpp @@ -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 ) diff --git a/include/turtle/detail/root.hpp b/include/turtle/detail/root.hpp index dae3790..09c1f95 100644 --- a/include/turtle/detail/root.hpp +++ b/include/turtle/detail/root.hpp @@ -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_; diff --git a/include/turtle/detail/sequence_impl.hpp b/include/turtle/detail/sequence_impl.hpp index c7d3ce6..f53fff9 100644 --- a/include/turtle/detail/sequence_impl.hpp +++ b/include/turtle/detail/sequence_impl.hpp @@ -11,20 +11,19 @@ #include "../config.hpp" #include "mutex.hpp" -#include -#include #include +#include #include 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 diff --git a/include/turtle/detail/signature.hpp b/include/turtle/detail/signature.hpp index 03c016c..9df1ee2 100644 --- a/include/turtle/detail/signature.hpp +++ b/include/turtle/detail/signature.hpp @@ -10,33 +10,47 @@ #define MOCK_SIGNATURE_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include -#include -#include -#include -#define BOOST_TYPEOF_SILENT -#include +#include namespace mock { namespace detail { +#define MOCK_NOARG +#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \ + template< typename R, typename... Args > \ + struct strip_function_qualifiers \ + { using type = R(Args...); }; \ + template< typename R, typename... Args > \ + struct strip_function_qualifiers \ + { 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 + 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::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 diff --git a/include/turtle/detail/singleton.hpp b/include/turtle/detail/singleton.hpp index 2080750..c8f42d6 100644 --- a/include/turtle/detail/singleton.hpp +++ b/include/turtle/detail/singleton.hpp @@ -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(); diff --git a/include/turtle/detail/type_name.hpp b/include/turtle/detail/type_name.hpp index 8264601..7f84193 100644 --- a/include/turtle/detail/type_name.hpp +++ b/include/turtle/detail/type_name.hpp @@ -15,17 +15,8 @@ #include #include #include -#if BOOST_VERSION >= 107000 -# include -# define MOCK_TYPEID( t ) BOOST_CORE_TYPEID(t) -# define MOCK_TYPEINFO boost::core::typeinfo -#else -# include -# define MOCK_TYPEID( t ) BOOST_SP_TYPEID(t) -# define MOCK_TYPEINFO boost::detail::sp_typeinfo -#endif -#include #include +#include #include #include #ifdef __GNUC__ @@ -33,8 +24,6 @@ #include #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(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 diff --git a/include/turtle/detail/verifiable.hpp b/include/turtle/detail/verifiable.hpp index 5d85c93..3390ec9 100644 --- a/include/turtle/detail/verifiable.hpp +++ b/include/turtle/detail/verifiable.hpp @@ -10,17 +10,18 @@ #define MOCK_VERIFIABLE_HPP_INCLUDED #include "../config.hpp" -#include 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; diff --git a/include/turtle/detail/void_t.hpp b/include/turtle/detail/void_t.hpp new file mode 100644 index 0000000..4c45e04 --- /dev/null +++ b/include/turtle/detail/void_t.hpp @@ -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 + struct make_void + { + using type = void; + }; + /// Standard helper to implement the detection idiom. Returns always void + template + using void_t = typename make_void::type; +} +} // mock + +#endif // MOCK_VOID_T_HPP_INCLUDED diff --git a/include/turtle/log.hpp b/include/turtle/log.hpp index 104c9fe..25a4392 100644 --- a/include/turtle/log.hpp +++ b/include/turtle/log.hpp @@ -12,11 +12,10 @@ #include "config.hpp" #include "stream.hpp" #include "format.hpp" -#include #include -#include #include #include +#include namespace boost { @@ -51,16 +50,17 @@ namespace detail s << (it == begin ? "" : ",") << mock::format( *it ); s << ')'; } + template + struct is_callable_impl: std::false_type + {}; + template + struct is_callable_impl: std::true_type + {}; + template + struct is_callable: is_callable_impl< std::remove_cv_t > + {}; } -#ifdef MOCK_AUTO_PTR - template< typename T > - stream& operator<<( stream& s, const std::auto_ptr< T >& t ) - { - return s << mock::format( t.get() ); - } -#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; diff --git a/include/turtle/matcher.hpp b/include/turtle/matcher.hpp index c6082a7..f6dbd7d 100644 --- a/include/turtle/matcher.hpp +++ b/include/turtle/matcher.hpp @@ -14,10 +14,9 @@ #include "constraints.hpp" #include "detail/is_functor.hpp" #include "detail/move_helper.hpp" -#include -#include -#include #include +#include +#include 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_ ); } diff --git a/include/turtle/mock.hpp b/include/turtle/mock.hpp index f873cee..17b5092 100644 --- a/include/turtle/mock.hpp +++ b/include/turtle/mock.hpp @@ -21,79 +21,72 @@ #include "detail/parameter.hpp" #include #include -#include -#include +/// 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 -#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 diff --git a/include/turtle/object.hpp b/include/turtle/object.hpp index d201757..70f98fa 100644 --- a/include/turtle/object.hpp +++ b/include/turtle/object.hpp @@ -14,10 +14,9 @@ #include "detail/type_name.hpp" #include "detail/object_impl.hpp" #include -#include -#include -#include #include +#include +#include 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 diff --git a/include/turtle/sequence.hpp b/include/turtle/sequence.hpp index 28a2ee9..377e920 100644 --- a/include/turtle/sequence.hpp +++ b/include/turtle/sequence.hpp @@ -11,6 +11,7 @@ #include "config.hpp" #include "detail/sequence_impl.hpp" +#include 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 diff --git a/include/turtle/stream.hpp b/include/turtle/stream.hpp index d8f3707..9f5b0a1 100644 --- a/include/turtle/stream.hpp +++ b/include/turtle/stream.hpp @@ -10,7 +10,7 @@ #define MOCK_STREAM_HPP_INCLUDED #include "config.hpp" -#include +#include #include 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 ) ) {} - ~any() - { - delete h_; - } - holder* h_; + std::unique_ptr h_; }; } } diff --git a/include/turtle/unwrap_reference.hpp b/include/turtle/unwrap_reference.hpp new file mode 100644 index 0000000..b450cff --- /dev/null +++ b/include/turtle/unwrap_reference.hpp @@ -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 +#include + +namespace mock +{ + template + struct unwrap_reference + { + using type = T; + }; + template + struct unwrap_reference> + { + using type = T; + }; + template + struct unwrap_reference> + { + using type = T; + }; + template + using unwrap_reference_t = typename unwrap_reference::type; + + template + BOOST_FORCEINLINE unwrap_reference_t& unwrap_ref( T& t ) noexcept + { + return t; + } +} + +#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f36751f..39bb8ff 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 $) +# 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 $) 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 $) +endforeach() diff --git a/test/Jamfile.jam b/test/Jamfile.jam index 39852e3..3e8768b 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -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 : : : MOCK_MAX_ARGS=21 : $(name)_max_args ; run $(name) undefined.cpp /boost//unit_test_framework : : : MOCK_USE_CONVERSIONS : $(name)_use_conversions ; - run $(name) undefined.cpp /boost//unit_test_framework : : : MOCK_NO_DECLTYPE : $(name)_no_decltype ; - run $(name) undefined.cpp /boost//unit_test_framework : : : MOCK_NO_VARIADIC_MACROS : $(name)_no_variadic_macros ; run $(name) undefined.cpp /boost//unit_test_framework /boost//thread : : : MOCK_THREAD_SAFE BOOST_THREAD_USES_MOVE multi : $(name)_thread_safe ; } diff --git a/test/bench_0_class_10_max_args.cpp b/test/bench_0_class_10_max_args.cpp index 0772e7d..99fb400 100644 --- a/test/bench_0_class_10_max_args.cpp +++ b/test/bench_0_class_10_max_args.cpp @@ -8,3 +8,8 @@ #define MOCK_MAX_ARGS 10 #include + +int main() +{ + return 0; +} diff --git a/test/bench_0_class_20_max_args.cpp b/test/bench_0_class_20_max_args.cpp index b236e09..1a52cd5 100644 --- a/test/bench_0_class_20_max_args.cpp +++ b/test/bench_0_class_20_max_args.cpp @@ -8,3 +8,8 @@ #define MOCK_MAX_ARGS 20 #include + +int main() +{ + return 0; +} diff --git a/test/bench_0_class_30_max_args.cpp b/test/bench_0_class_30_max_args.cpp index d87d02f..3eab294 100644 --- a/test/bench_0_class_30_max_args.cpp +++ b/test/bench_0_class_30_max_args.cpp @@ -8,3 +8,8 @@ #define MOCK_MAX_ARGS 30 #include + +int main() +{ + return 0; +} diff --git a/test/bench_30_classes_30_methods_30_args_30_max_args.cpp b/test/bench_30_classes_30_methods_30_args_30_max_args.cpp index 7872dc2..021d95b 100644 --- a/test/bench_30_classes_30_methods_30_args_30_max_args.cpp +++ b/test/bench_30_classes_30_methods_30_args_30_max_args.cpp @@ -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; +} diff --git a/test/bench_30_classes_30_methods_9_args.cpp b/test/bench_30_classes_30_methods_9_args.cpp index 67d1b65..17c5a52 100644 --- a/test/bench_30_classes_30_methods_9_args.cpp +++ b/test/bench_30_classes_30_methods_9_args.cpp @@ -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; +} diff --git a/test/bench_30_classes_30_methods_9_args_10_max_args.cpp b/test/bench_30_classes_30_methods_9_args_10_max_args.cpp index 61a553c..6a8023c 100644 --- a/test/bench_30_classes_30_methods_9_args_10_max_args.cpp +++ b/test/bench_30_classes_30_methods_9_args_10_max_args.cpp @@ -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; +} diff --git a/test/bench_30_classes_30_methods_9_args_20_max_args.cpp b/test/bench_30_classes_30_methods_9_args_20_max_args.cpp index fe442fa..c36c91b 100644 --- a/test/bench_30_classes_30_methods_9_args_20_max_args.cpp +++ b/test/bench_30_classes_30_methods_9_args_20_max_args.cpp @@ -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; +} diff --git a/test/bench_30_classes_30_methods_9_args_30_max_args.cpp b/test/bench_30_classes_30_methods_9_args_30_max_args.cpp index 3f6e0af..c9c4be2 100644 --- a/test/bench_30_classes_30_methods_9_args_30_max_args.cpp +++ b/test/bench_30_classes_30_methods_9_args_30_max_args.cpp @@ -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; +} diff --git a/test/detail/test_function.cpp b/test/detail/test_function.cpp index 682840a..a946fc9 100644 --- a/test/detail/test_function.cpp +++ b/test/detail/test_function.cpp @@ -10,27 +10,21 @@ #include "../undefined.hpp" #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include // 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() ) ) >::value, "!"); + static_assert( std::is_same< int, decltype( mock::detail::function< int( float ) >{}( std::declval() ) ) >::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>(); 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>(); 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 ); } diff --git a/test/detail/test_invocation.cpp b/test/detail/test_invocation.cpp index 7bec6f8..93ed575 100644 --- a/test/detail/test_invocation.cpp +++ b/test/detail/test_invocation.cpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include BOOST_AUTO_TEST_CASE( unlimited ) { diff --git a/test/detail/test_is_functor.cpp b/test/detail/test_is_functor.cpp index a6a0f38..0b58b13 100644 --- a/test/detail/test_is_functor.cpp +++ b/test/detail/test_is_functor.cpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #ifdef BOOST_MSVC #pragma warning( push, 0 ) #endif @@ -17,23 +17,25 @@ #pragma warning( pop ) #endif #include -#include +#include +#include +#include +#include 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,25 +73,19 @@ 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 ) -{ - is_functor( boost::bind( &f0 ) ); - is_functor( boost::bind( &f1, _1 ) ); - is_functor( boost::bind( &f2, "", _1 ) ); + { +#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 diff --git a/test/detail/test_signature.cpp b/test/detail/test_signature.cpp index 27f4e91..f20d2a3 100644 --- a/test/detail/test_signature.cpp +++ b/test/detail/test_signature.cpp @@ -7,8 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include +#include +#include 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, "!"); } diff --git a/test/detail/test_type_name.cpp b/test/detail/test_type_name.cpp index 292414a..0f577ef 100644 --- a/test/detail/test_type_name.cpp +++ b/test/detail/test_type_name.cpp @@ -7,15 +7,17 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include +#include +#include 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 diff --git a/test/fail_ambiguous_mock_method.cpp b/test/fail_ambiguous_mock_method.cpp index 08148ce..d1c03de 100644 --- a/test/fail_ambiguous_mock_method.cpp +++ b/test/fail_ambiguous_mock_method.cpp @@ -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; }; diff --git a/test/fail_constraint_functor_not_compatible.cpp b/test/fail_constraint_functor_not_compatible.cpp index 51558eb..e3d6aed 100644 --- a/test/fail_constraint_functor_not_compatible.cpp +++ b/test/fail_constraint_functor_not_compatible.cpp @@ -8,17 +8,14 @@ #include -namespace +MOCK_CLASS(my_class) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) - }; - bool constraint( int, int ); + MOCK_METHOD_EXT(my_method, 1, void(int), my_method) +}; +bool constraint(int, int) { return true; } - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).with( &constraint ); - } +void test_case() +{ + my_class c; + MOCK_EXPECT(c.my_method).with(&constraint); } diff --git a/test/fail_constraint_value_not_comparable.cpp b/test/fail_constraint_value_not_comparable.cpp index 0d0ef8c..dec09ac 100644 --- a/test/fail_constraint_value_not_comparable.cpp +++ b/test/fail_constraint_value_not_comparable.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).with( "42" ); - } + MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).with( "42" ); } diff --git a/test/fail_constraint_value_of_wrong_type_in_builtin_constraint.cpp b/test/fail_constraint_value_of_wrong_type_in_builtin_constraint.cpp index f54013c..8d18b82 100644 --- a/test/fail_constraint_value_of_wrong_type_in_builtin_constraint.cpp +++ b/test/fail_constraint_value_of_wrong_type_in_builtin_constraint.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).with( mock::equal( "42" ) ); - } + MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).with( mock::equal( "42" ) ); } diff --git a/test/fail_mismatch_type_in_returns_int_action.cpp b/test/fail_mismatch_type_in_returns_int_action.cpp index 1147857..c4a5aed 100644 --- a/test/fail_mismatch_type_in_returns_int_action.cpp +++ b/test/fail_mismatch_type_in_returns_int_action.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 0, int(), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).returns( std::string() ); - } + MOCK_METHOD_EXT( my_method, 0, int(), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).returns( std::string() ); } diff --git a/test/fail_mismatch_type_in_returns_string_action.cpp b/test/fail_mismatch_type_in_returns_string_action.cpp index 103613f..885a4ac 100644 --- a/test/fail_mismatch_type_in_returns_string_action.cpp +++ b/test/fail_mismatch_type_in_returns_string_action.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 0, std::string(), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).returns( 42 ); - } + MOCK_METHOD_EXT( my_method, 0, std::string(), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).returns( 42 ); } diff --git a/test/fail_mismatch_type_in_returns_void_action.cpp b/test/fail_mismatch_type_in_returns_void_action.cpp index 68b774c..d3dd35c 100644 --- a/test/fail_mismatch_type_in_returns_void_action.cpp +++ b/test/fail_mismatch_type_in_returns_void_action.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 0, void(), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).returns( "42" ); - } + MOCK_METHOD_EXT( my_method, 0, void(), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).returns( "42" ); } diff --git a/test/fail_non_existing_base_class_method_in_mock_method.cpp b/test/fail_non_existing_base_class_method_in_mock_method.cpp index 0e50e73..b30c9ef 100644 --- a/test/fail_non_existing_base_class_method_in_mock_method.cpp +++ b/test/fail_non_existing_base_class_method_in_mock_method.cpp @@ -12,7 +12,7 @@ namespace { struct my_base { - virtual ~my_base() {} + virtual ~my_base() = default; }; MOCK_BASE_CLASS( my_class, my_base ) diff --git a/test/fail_number_of_arguments_greater_than_max_constant.cpp b/test/fail_number_of_arguments_greater_than_max_constant.cpp index 7a71272..4c59c70 100644 --- a/test/fail_number_of_arguments_greater_than_max_constant.cpp +++ b/test/fail_number_of_arguments_greater_than_max_constant.cpp @@ -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; }; diff --git a/test/fail_template_argument_without_tpl_macro.cpp b/test/fail_template_argument_without_tpl_macro.cpp deleted file mode 100644 index a0e700e..0000000 --- a/test/fail_template_argument_without_tpl_macro.cpp +++ /dev/null @@ -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 - -namespace -{ - template< typename T > - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 1, void( T ), my_method ) - }; -} diff --git a/test/fail_too_many_arguments_in_mock_method.cpp b/test/fail_too_many_arguments_in_mock_method.cpp index fa4ca01..7c08f7e 100644 --- a/test/fail_too_many_arguments_in_mock_method.cpp +++ b/test/fail_too_many_arguments_in_mock_method.cpp @@ -12,7 +12,7 @@ namespace { struct my_base { - virtual ~my_base() {} + virtual ~my_base() = default; virtual void my_method( int ) = 0; }; diff --git a/test/fail_wrong_number_of_arguments_in_with.cpp b/test/fail_wrong_number_of_arguments_in_with.cpp index dc3420f..033ffd8 100644 --- a/test/fail_wrong_number_of_arguments_in_with.cpp +++ b/test/fail_wrong_number_of_arguments_in_with.cpp @@ -8,15 +8,12 @@ #include -namespace +MOCK_CLASS( my_class ) { - MOCK_CLASS( my_class ) - { - MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) - }; - void test_case() - { - my_class c; - MOCK_EXPECT( c.my_method ).with( 42, 42 ); - } + MOCK_METHOD_EXT( my_method, 1, void( int ), my_method ) +}; +void test_case() +{ + my_class c; + MOCK_EXPECT( c.my_method ).with( 42, 42 ); } diff --git a/test/mock_error.hpp b/test/mock_error.hpp index bd3fbe9..5821f52 100644 --- a/test/mock_error.hpp +++ b/test/mock_error.hpp @@ -11,9 +11,9 @@ #define MOCK_ERROR_POLICY mock_error #include -#include #include #include +#include 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 ); } }; diff --git a/test/test_constraint.cpp b/test/test_constraint.cpp index c690d07..58793f3 100644 --- a/test/test_constraint.cpp +++ b/test/test_constraint.cpp @@ -7,9 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include - -#ifdef MOCK_VARIADIC_MACROS +#include 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 ) ); -} diff --git a/test/test_constraints.cpp b/test/test_constraints.cpp index 9e918da..b92f728 100644 --- a/test/test_constraints.cpp +++ b/test/test_constraints.cpp @@ -7,8 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include +#include 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" ) ) ); diff --git a/test/test_exception.cpp b/test/test_exception.cpp index 818ddeb..a2bed75 100644 --- a/test/test_exception.cpp +++ b/test/test_exception.cpp @@ -8,7 +8,7 @@ #define MOCK_USE_BOOST_TEST #include -#include +#include BOOST_AUTO_TEST_CASE( a_mock_exception_is_not_an_std_exception_to_not_mess_with_user_exceptions ) { diff --git a/test/test_integration.cpp b/test/test_integration.cpp index 8cc3557..8b3cd93 100644 --- a/test/test_integration.cpp +++ b/test/test_integration.cpp @@ -9,11 +9,10 @@ #include "mock_error.hpp" #include "undefined.hpp" #include -#include -#include +#include #include -#include #include +#include 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 diff --git a/test/test_log.cpp b/test/test_log.cpp index 728eb20..a512ac6 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -7,11 +7,9 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include -#include #include -#include #include #ifdef BOOST_MSVC #pragma warning( push, 0 ) @@ -25,11 +23,13 @@ #include #include #endif -#include +#include +#include #include #include #include #include +#include #include 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 ) ) ); diff --git a/test/test_matcher.cpp b/test/test_matcher.cpp index c28648e..916f20b 100644 --- a/test/test_matcher.cpp +++ b/test/test_matcher.cpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include 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 diff --git a/test/test_max_args.cpp b/test/test_max_args.cpp index 970a25f..7d74943 100644 --- a/test/test_max_args.cpp +++ b/test/test_max_args.cpp @@ -8,7 +8,7 @@ #include "mock_error.hpp" #include -#include +#include #include #define IDENTITY(z, n, d) d diff --git a/test/test_mock.cpp b/test/test_mock.cpp index 2e4f41c..aecaa9a 100644 --- a/test/test_mock.cpp +++ b/test/test_mock.cpp @@ -8,9 +8,8 @@ #include "mock_error.hpp" #include -#include -#include -#include +#include +#include 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 ) }; diff --git a/test/test_object.cpp b/test/test_object.cpp index 84e1094..bd11dc3 100644 --- a/test/test_object.cpp +++ b/test/test_object.cpp @@ -10,8 +10,8 @@ #include #include #include -#include -#include +#include +#include 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(); 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 ) ), diff --git a/test/test_sequence.cpp b/test/test_sequence.cpp index d14de02..2a7b584 100644 --- a/test/test_sequence.cpp +++ b/test/test_sequence.cpp @@ -9,7 +9,7 @@ #include "mock_error.hpp" #include #include -#include +#include BOOST_FIXTURE_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_throws, mock_error_fixture ) {