Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
1f5b880
refactor: extract MockSettings construction from MIMICPP_DETAIL_MAKE_…
DNKpp Sep 8, 2025
bf0b3d3
refactor: extract some of the internal interface-mocking complexity i…
DNKpp Sep 9, 2025
5dd80f1
feat: signature_prepend_param trait
DNKpp Sep 9, 2025
7b720bd
feat: add (MIMICPP_)MOCK_(OVERLOADED_)METHOD_WITH_THIS convenience ma…
DNKpp Sep 9, 2025
f0107e0
chore: add example for MOCK_METHOD_WITH_THIS
DNKpp Sep 9, 2025
ab143d3
refactor: extract function header construction and mock invocation fr…
DNKpp Sep 10, 2025
5068c37
refactor: merge previously extracted macros and slightly tweak other …
DNKpp Sep 18, 2025
61fdd61
test: the limit is the sky!
DNKpp Sep 18, 2025
c0b2ce9
fix: lower limit test to 32 cases
DNKpp Sep 19, 2025
507907d
fix: correct internal macro name
DNKpp Sep 19, 2025
5e55e8e
chore: try different expansion strategy for is_overload_set trait
DNKpp Sep 19, 2025
5eedc6c
chore: experiment with yet another approach
DNKpp Sep 19, 2025
383c2a6
Revert "fix: lower limit test to 32 cases"
DNKpp Sep 19, 2025
d1c4737
cleanup: remove obsolete detail traits
DNKpp Sep 19, 2025
954e2c2
feat: add linkage param to detail facade factory macros
DNKpp Sep 20, 2025
2da078e
feat: introduce optional is_member boolean-member for facade-traits
DNKpp Oct 3, 2025
6f5e890
feat: add signature_add_lvalue_ref_qualifier trait
DNKpp Oct 4, 2025
36b6159
feat: add signature_add_rvalue_ref_qualifier trait
DNKpp Oct 4, 2025
cc143d9
feat: add util::StaticString
DNKpp Oct 4, 2025
dc55c72
chore: add detail::apply_normalized_specs which omits override and fi…
DNKpp Oct 4, 2025
afa5888
refactor: replace several manual return types with decltype(auto)
DNKpp Oct 4, 2025
374e2d6
refactor: simplify MIMICPP_DETAIL_MAKE_FACADE_FUNCTION
DNKpp Oct 4, 2025
96dcb93
docs: correct MIMICPP_DETAIL_MAKE_FACADE_FUNCTION documentation
DNKpp Oct 4, 2025
4388a07
fix: add missing utilities/StaticString.hpp include
DNKpp Oct 4, 2025
dcbc4a7
refactor: util::StaticString does not store the null-terminator
DNKpp Oct 4, 2025
67e1fe4
test: extend util::StaticString test-cases
DNKpp Oct 4, 2025
1630136
refactor: make apply_normalized_specs more efficient
DNKpp Oct 4, 2025
2ee371d
fix: please clang
DNKpp Oct 4, 2025
b732d59
refactor: slightly adjust apply_normalized_specs again
DNKpp Oct 4, 2025
832fd6a
fix: please msvc
DNKpp Oct 4, 2025
6d76ff8
feat: add MIMICPP_MAKE_OVERLOADED_FACADE_EXT and MIMICPP_MAKE_FACADE_EXT
DNKpp Oct 5, 2025
d5d2504
refactor: move facade related symbols to Facade.hpp and introduce ns …
DNKpp Oct 5, 2025
3b99dc2
refactor: extract general purpose internal macros into macros/Common.hpp
DNKpp Oct 5, 2025
8bc0589
refactor: extract MIMICPP_DETAIL_MAKE_SIGNATURE and MIMICPP_DETAIL_MA…
DNKpp Oct 5, 2025
4bc9546
refactor: move MIMICPP_DETAIL_MAKE_FACADE_TARGET to macros/FacadeHelp…
DNKpp Oct 5, 2025
22b511a
refactor: move MIMICPP_DETAIL_MAKE_PARAM and MIMICPP_DETAIL_MAKE_PARA…
DNKpp Oct 5, 2025
0bf7b2a
refactor: move MIMICPP_DETAIL_FORWARD_ARG_AS_TUPLE and MIMICPP_DETAIL…
DNKpp Oct 5, 2025
62fad05
refactor: move MIMICPP_DETAIL_MAKE_OVERLOAD_INFOS_ALL and related mac…
DNKpp Oct 5, 2025
bc26969
refactor: move MIMICPP_ADD_OVERLOAD, MIMICPP_DETAIL_MAKE_FACADE_FUNCT…
DNKpp Oct 5, 2025
5a3fb00
refactor: rename several internal MAKE macros to GENERATE
DNKpp Oct 5, 2025
8e411f4
refactor: move MIMICPP_MAKE_OVERLOADED_FACADE_EXT and MIMICPP_MAKE_FA…
DNKpp Oct 5, 2025
5af23de
feat: add MAKE_FACADE_EXT and MAKE_OVERLOADED_FACADE_EXT
DNKpp Oct 5, 2025
0d649f2
refactor: move ADD_OVERLOAD shorthand macro into macros/FacadeHelper.hpp
DNKpp Oct 5, 2025
a9b063c
refactor: rework limitation test in terms of MIMICPP_MAKE_OVERLOADED_…
DNKpp Oct 5, 2025
62cf804
fix: add missing macros/InterfaceMocking.hpp include
DNKpp Oct 6, 2025
b05d5bd
fix: make sure facade::detail::is_member_v is exported from module
DNKpp Oct 12, 2025
8641a41
fix: mark member functions as constexpr
DNKpp Oct 12, 2025
0ed7767
refactor: rename macros/FacadeHelper.hpp to macros/Facade.hpp
DNKpp Oct 12, 2025
b4be299
fix: correct cmake target-source
DNKpp Oct 12, 2025
2f29143
fix: add missing explicit `template` keyword into MIMICPP_DETAIL_GENE…
DNKpp Oct 12, 2025
53cdaa6
test: add stacktrace-skip related tests for facade::mock_as_member an…
DNKpp Oct 12, 2025
12886b6
refactor: split Facade.cpp into several source-files inside `facade` …
DNKpp Oct 12, 2025
df879a6
test: re-add a previously removed stacktrace-entry-related test for M…
DNKpp Oct 12, 2025
b09c91d
test: add target name-related tests for existing facade traits
DNKpp Oct 12, 2025
395835a
refactor: rename MIMICPP_MAKE_OVERLOADED_MEMBER_FACADE to MIMICPP_MAK…
DNKpp Oct 12, 2025
520e811
feat: add shorthand variants for MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK …
DNKpp Oct 12, 2025
1d239e0
test: add cases for MIMICPP_MAKE_OVERLOADED_MEMBER_MOCK and MIMICPP_M…
DNKpp Oct 12, 2025
cfdee09
refactor: rename MIMICPP_MOCK_OVERLOADED_METHOD_WITH_THIS to MIMICPP_…
DNKpp Oct 12, 2025
c2a2482
chore: deprecate (MIMICPP_)MOCK_(OVERLOADED_)METHOD macros
DNKpp Oct 12, 2025
6caed3b
chore: move manual facade mocking example to examples/FacadeMock.cpp
DNKpp Oct 12, 2025
2c3a3d1
docs: add documentation for the facade section and mark interfaces se…
DNKpp Oct 12, 2025
d0df783
chore: remove InterfaceMock.hpp
DNKpp Oct 12, 2025
5152486
fix: mark potentially unused arguments as [[maybe_unused]]
DNKpp Oct 12, 2025
9533c46
fix: replace old interface macros with new facade macros in Vectorcal…
DNKpp Oct 12, 2025
e291c38
fix: replace non-existing header include with mimic++/Facade.hpp
DNKpp Oct 12, 2025
230fbe1
fix: replace MIMICPP_MOCK_METHOD usage with MIMICPP_MAKE_MEMBER_MOCK
DNKpp Oct 12, 2025
5796cb6
docs: enhance facade documentation
DNKpp Oct 12, 2025
1613161
docs: use \deprecated for interface-mocking related symbols
DNKpp Oct 12, 2025
de94eac
fix: splitup facade::detail::apply_normalized_specs::evaluate_specs f…
DNKpp Oct 12, 2025
3924c27
fix: use MIMICPP_DETAIL_CONSTEXPR_STRING to mark make_settings function
DNKpp Oct 12, 2025
69be5a8
fix: make facade::detail::apply_normalized_specs compiling
DNKpp Oct 12, 2025
e557795
fix: remove unnecessary macros/InterfaceMocking.hpp include
DNKpp Oct 12, 2025
81f4b85
fix: add missing mimic++/macros/InterfaceMocking.hpp include
DNKpp Oct 14, 2025
819ba85
fix: add missing includes into all-in-one header
DNKpp Oct 14, 2025
3da5c4f
feat: add examples for MAKE_OVERLOADED_MEMBER_MOCK and MAKE_MEMBER_MOCK
DNKpp Oct 14, 2025
7522dd4
docs: update examples in README.md
DNKpp Oct 14, 2025
c6aefc8
chore: mark interface-mock examples as deprecated
DNKpp Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ TEST_CASE("Interfaces can be mocked.")
~Derived() override = default;

// This generates the override method and a mock object named `get_`.
MOCK_METHOD(get, int, (), const);
MAKE_MEMBER_MOCK(get, int, (), const override);
};

Derived mock{};
Expand Down Expand Up @@ -342,7 +342,7 @@ TEST_CASE("Interface overload-sets are directly supported.")
~Derived() override = default;

// This generates two overloads of `get` and a single mock object named `get_`.
MOCK_OVERLOADED_METHOD(
MAKE_OVERLOADED_MEMBER_MOCK(
get, // The name of the overload set.
ADD_OVERLOAD(int&, ()), // This enables `int& operator ()()`...
ADD_OVERLOAD(const int&, (), const)); // ... and this the `const int& operator ()() const` on the mock.
Expand Down
3 changes: 2 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ add_executable(${TARGET_NAME}
"CustomMatcher.cpp"
"CustomPrinter.cpp"
"CustomString.cpp"
"Deprecated_InterfaceMock.cpp"
"FacadeMock.cpp"
"Finalizers.cpp"
"InterfaceMock.cpp"
"Mock.cpp"
"Requirements.cpp"
"Sequences.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,14 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)

#include "mimic++/InterfaceMock.hpp"
#include "mimic++/Facade.hpp"
#include "mimic++/macros/InterfaceMocking.hpp"
#include "mimic++/policies/FinalizerPolicies.hpp"

TEST_CASE(
"Mocking interface methods by hand.",
"[example][example::mock][example::mock::interface]")
{
//! [interface mock manual]
class Interface
{
public:
virtual ~Interface() = default;
virtual void foo() = 0;
};

class Derived
: public Interface
{
public:
~Derived() override = default;
#include "../test/unit-tests/SuppressionMacros.hpp" // needs to disable the deprecations

// Begin boilerplate

// we build our mock object by hand
mimicpp::Mock<void()> foo_{};

// and forward the incoming call from the interface function to the mock object.
void foo() override
{
return foo_();
}

// End boilerplate
};

// this may be a function from somewhere else, working with an interface.
constexpr auto my_function = [](Interface& obj) {
obj.foo();
};

Derived mock{};
SCOPED_EXP mock.foo_.expect_call();

my_function(mock);
//! [interface mock manual]
}
START_WARNING_SUPPRESSION
SUPPRESS_DEPRECATION

TEST_CASE(
"Interfaces methods can be mocked.",
Expand Down Expand Up @@ -189,3 +151,5 @@ TEST_CASE(
use_interfaceB(mock); // calls foo() and the const bar()
//! [interface mock multiple inheritance]
}

STOP_WARNING_SUPPRESSION
235 changes: 235 additions & 0 deletions examples/FacadeMock.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)

#include "mimic++/Facade.hpp"
#include "mimic++/policies/FinalizerPolicies.hpp"

TEST_CASE(
"Mocking a polymorphic type by hand.",
"[example][example::mock][example::mock::facade]")
{
//! [facade mock manual]
class Interface
{
public:
virtual ~Interface() = default;
virtual void foo() = 0;
};

class Derived
: public Interface
{
public:
~Derived() override = default;

// Begin boilerplate

// we build our mock object by hand
mimicpp::Mock<void()> foo_{};

// and forward the incoming call from the interface function to the mock object.
void foo() override
{
return foo_();
}

// End boilerplate
};

// this may be a function from somewhere else, working with an interface.
constexpr auto my_function = [](Interface& obj) {
obj.foo();
};

Derived mock{};
SCOPED_EXP mock.foo_.expect_call();

my_function(mock);
//! [facade mock manual]
}

TEST_CASE(
"Virtual functions can be mocked.",
"[example][example::mock][example::mock::facade]")
{
//! [facade interface mock simple]
class Interface
{
public:
virtual ~Interface() = default;
virtual void foo() = 0;
};

class Derived
: public Interface
{
public:
~Derived() override = default;

// this generates the override method and a mock object named `foo_`
MAKE_MEMBER_MOCK(foo, void, (), override);
};

// this may be a function from somewhere else, working with an interface.
constexpr auto my_function = [](Interface& obj) {
obj.foo();
};

Derived mock{};
SCOPED_EXP mock.foo_.expect_call(); // note the `_` suffix. That's the name of the mock object.

my_function(mock);
//! [facade interface mock]
}

TEST_CASE(
"Overloaded virtual functions can be mocked.",
"[example][example::mock][example::mock::facade]")
{
//! [facade interface mock overloaded]
class Interface
{
public:
virtual ~Interface() = default;
virtual void foo() = 0;
virtual void foo() const noexcept = 0;
};

class Derived
: public Interface
{
public:
~Derived() override = default;

// this generates both overrides and a mock object named `foo_`
MAKE_OVERLOADED_MEMBER_MOCK(
foo,
ADD_OVERLOAD(void, (), override),
ADD_OVERLOAD(void, (), const noexcept override)); // note the `const noexcept` specifications as third argument
};

// this may be a function from somewhere else, working with an immutable interface.
constexpr auto my_function = [](Interface const& obj) {
obj.foo();
};

Derived mock{};
SCOPED_EXP std::as_const(mock).foo_.expect_call(); // We explicitly require the const overload to be called.

my_function(mock);
//! [facade interface mock overloaded]
}

TEST_CASE(
"Facade-Mocks can have an explicit *this* param.",
"[example][example::mock][example::mock::facade]")
{
//! [facade mock with this]
namespace finally = mimicpp::finally;

class Base
{
public:
virtual ~Base() = default;

virtual int foo() const
{
return 42;
}
};

class Derived
: public Base
{
public:
~Derived() override = default;

// This alias is required because the `..._WITH_THIS` macros are not able to determine the current type by themselves.
using self_type = Derived;

// This generates the override method and a mock object named foo_, which expects an explicit *this* param.
// => `Mock<int(Derived const*) const>`
MAKE_MEMBER_MOCK_WITH_THIS(foo, int, (), const override);
};

Derived object{};

// The first param behaves like an actual *this* pointer.
SCOPED_EXP object.foo_.expect_call(&object)
// Let's redirect the call to the actual `Base::foo` implementation.
and finally::returns_apply_all_result_of([](auto* self) { return self->Base::foo(); });

CHECK(42 == object.foo());
//! [facade mock with this]
}

TEST_CASE(
"Multiple-inheritance is supported.",
"[example][example::mock][example::mock::facade]")
{
//! [facade mock multiple inheritance]
namespace expect = mimicpp::expect;
namespace finally = mimicpp::finally;

class InterfaceA
{
public:
virtual ~InterfaceA() = default;
virtual void foo() = 0;

virtual void bar() = 0;
};

class InterfaceB
{
public:
virtual ~InterfaceB() = default;
virtual void foo() = 0;

virtual int bar() const noexcept = 0;
};

class Derived
: public InterfaceA,
public InterfaceB
{
public:
~Derived() override = default;

// Both interfaces have a foo() method with the same signature, so we do not need to overload.
MAKE_MEMBER_MOCK(foo, void, (), override); // mocks both foo() methods from InterfaceA and InterfaceB

// Both interfaces have a bar() method, but with different signature. So, let's work on that overload-set.
MAKE_OVERLOADED_MEMBER_MOCK(
bar,
ADD_OVERLOAD(void, (), override), // from InterfaceA
ADD_OVERLOAD(int, (), const noexcept override)); // from InterfaceB
};

// let's build a function, which requires the InterfaceA
constexpr auto use_interfaceA = [](InterfaceA& obj) {
obj.foo();
obj.bar();
};

// and another, which requires the InterfaceB
constexpr auto use_interfaceB = [](InterfaceB& obj) {
obj.foo();
std::ignore = obj.bar(); // InterfaceB::bar returns an int, just explicitly ignore it here
};

// setting up the expectations isn't any different from the previous examples
Derived mock{};
SCOPED_EXP mock.foo_.expect_call()
and expect::twice();
SCOPED_EXP mock.bar_.expect_call(); // selects the non-const overload of bar()
SCOPED_EXP std::as_const(mock).bar_.expect_call() // selects the const overload of bar()
and finally::returns(42);

use_interfaceA(mock); // calls foo() and the non-const bar()
use_interfaceB(mock); // calls foo() and the const bar()

//! [facade mock multiple inheritance]
}
4 changes: 2 additions & 2 deletions examples/RegisterCallConvention.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// https://www.boost.org/LICENSE_1_0.txt)

#include "mimic++/CallConvention.hpp"
#include "mimic++/InterfaceMock.hpp"
#include "mimic++/Facade.hpp"

//! [register __stdcall]
MIMICPP_REGISTER_CALL_CONVENTION(__stdcall, detail::stdcall_convention);
Expand Down Expand Up @@ -37,7 +37,7 @@ TEST_CASE(
struct derived
: public interface
{
MIMICPP_MOCK_METHOD(foo, void, (), const, __stdcall); // the call-convention goes last
MIMICPP_MAKE_MEMBER_MOCK(foo, void, (), const override, __stdcall); // the call-convention goes last
};

derived mock{};
Expand Down
10 changes: 5 additions & 5 deletions examples/VariadicMocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)

#include "mimic++/InterfaceMock.hpp"
#include "mimic++/Facade.hpp"
#include "mimic++/Mock.hpp"
#include "mimic++/matchers/RangeMatchers.hpp"
#include "mimic++/policies/FinalizerPolicies.hpp"
Expand Down Expand Up @@ -54,11 +54,11 @@ namespace
: public VariadicInterface<Args...>
{
public:
MOCK_METHOD(foo, void, (Args...));
MOCK_OVERLOADED_METHOD(
MAKE_MEMBER_MOCK(foo, void, (Args...), override);
MAKE_OVERLOADED_MEMBER_MOCK(
bar,
ADD_OVERLOAD(int, (int, Args...)),
ADD_OVERLOAD(std::string, (Args..., int, Args...), const));
ADD_OVERLOAD(int, (int, Args...), override),
ADD_OVERLOAD(std::string, (Args..., int, Args...), const override));
};

//! [variadic interface def]
Expand Down
Loading
Loading