Skip to content

Commit ded6e47

Browse files
committed
Merge branch 'dev-2.2.0'
2 parents 081fd91 + eedd7eb commit ded6e47

28 files changed

+6086
-4222
lines changed

build/sources.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CPP_SRCS += \
1313
miscellaneous_tests.cpp \
1414
msc_stubbing_multiple_values_tests.cpp \
1515
msc_type_info_tests.cpp \
16+
overloadded_methods_tests.cpp \
1617
referece_types_tests.cpp \
1718
remove_const_volatile_tests.cpp \
1819
rvalue_arguments_tests.cpp \

include/fakeit/MatchersCollector.hpp

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ namespace fakeit {
3434
template<std::size_t N>
3535
using NakedArgType = typename naked_type<ArgType<index>>::type;
3636

37-
template<std::size_t N>
38-
using ArgMatcherCreatorType = decltype(std::declval<TypedMatcherCreator<NakedArgType<N>>>());
39-
4037
MatchersCollector(std::vector<Destructible *> &matchers)
4138
: _matchers(matchers) {
4239
}
@@ -46,56 +43,34 @@ namespace fakeit {
4643

4744
template<typename Head>
4845
typename std::enable_if< //
49-
std::is_constructible<NakedArgType<index>, Head>::value, void> //
50-
::type CollectMatchers(const Head &value) {
46+
std::is_constructible<NakedArgType<index>, Head&&>::value, void> //
47+
::type CollectMatchers(Head &&value) {
5148

52-
TypedMatcher<NakedArgType<index>> *d = Eq<NakedArgType<index>>(value).createMatcher();
49+
TypedMatcher<NakedArgType<index>> *d = Eq(std::forward<Head>(value)).template createMatcher<NakedArgType<index>>();
5350
_matchers.push_back(d);
5451
}
5552

56-
template<typename Head, typename ...Tail>
57-
typename std::enable_if< //
58-
std::is_constructible<NakedArgType<index>, Head>::value //
59-
, void> //
60-
::type CollectMatchers(const Head &head, const Tail &... tail) {
61-
CollectMatchers(head);
62-
MatchersCollector<index + 1, arglist...> c(_matchers);
63-
c.CollectMatchers(tail...);
64-
}
65-
6653
template<typename Head>
6754
typename std::enable_if< //
68-
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> //
69-
::type CollectMatchers(const Head &creator) {
70-
TypedMatcher<NakedArgType<index>> *d = creator.createMatcher();
55+
naked_type<Head>::type::template IsTypeCompatible<NakedArgType<index>>::value, void> //
56+
::type CollectMatchers(Head &&creator) {
57+
TypedMatcher<NakedArgType<index>> *d = creator.template createMatcher<NakedArgType<index>>();
7158
_matchers.push_back(d);
7259
}
7360

74-
template<typename Head, typename ...Tail>
75-
//
76-
typename std::enable_if< //
77-
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> //
78-
::type CollectMatchers(const Head &head, const Tail &... tail) {
79-
CollectMatchers(head);
80-
MatchersCollector<index + 1, arglist...> c(_matchers);
81-
c.CollectMatchers(tail...);
82-
}
83-
8461
template<typename Head>
8562
typename std::enable_if<//
86-
std::is_same<AnyMatcher, Head>::value, void> //
87-
::type CollectMatchers(const Head &) {
88-
TypedMatcher<NakedArgType<index>> *d = Any<NakedArgType<index>>().createMatcher();
63+
std::is_same<AnyMatcher, typename naked_type<Head>::type>::value, void> //
64+
::type CollectMatchers(Head &&) {
65+
TypedMatcher<NakedArgType<index>> *d = Any().template createMatcher<NakedArgType<index>>();
8966
_matchers.push_back(d);
9067
}
9168

9269
template<typename Head, typename ...Tail>
93-
typename std::enable_if< //
94-
std::is_same<AnyMatcher, Head>::value, void> //
95-
::type CollectMatchers(const Head &head, const Tail &... tail) {
96-
CollectMatchers(head);
70+
void CollectMatchers(Head &&head, Tail &&... tail) {
71+
CollectMatchers(std::forward<Head>(head));
9772
MatchersCollector<index + 1, arglist...> c(_matchers);
98-
c.CollectMatchers(tail...);
73+
c.CollectMatchers(std::forward<Tail>(tail)...);
9974
}
10075

10176
};

include/fakeit/MethodMockingContext.hpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ namespace fakeit {
5252
/**
5353
* Return the original method. not the mock.
5454
*/
55-
virtual typename std::function<R(arglist&...)> getOriginalMethod() = 0;
55+
virtual typename std::function<R(arglist&...)> getOriginalMethodCopyArgs() = 0;
56+
virtual typename std::function<R(arglist&...)> getOriginalMethodForwardArgs() = 0;
5657

5758
virtual std::string getMethodName() = 0;
5859

@@ -153,8 +154,12 @@ namespace fakeit {
153154
into.push_back(&getStubbingContext().getInvolvedMock());
154155
}
155156

156-
typename std::function<R(arglist &...)> getOriginalMethod() {
157-
return getStubbingContext().getOriginalMethod();
157+
typename std::function<R(arglist &...)> getOriginalMethodCopyArgs() {
158+
return getStubbingContext().getOriginalMethodCopyArgs();
159+
}
160+
161+
typename std::function<R(arglist &...)> getOriginalMethodForwardArgs() {
162+
return getStubbingContext().getOriginalMethodForwardArgs();
158163
}
159164

160165
void setInvocationMatcher(typename ActualInvocation<arglist...>::Matcher *matcher) {
@@ -222,13 +227,13 @@ namespace fakeit {
222227
_impl->setMethodDetails(mockName, methodName);
223228
}
224229

225-
void setMatchingCriteria(std::function<bool(arglist &...)> predicate) {
230+
void setMatchingCriteria(const std::function<bool(arglist &...)>& predicate) {
226231
typename ActualInvocation<arglist...>::Matcher *matcher{
227232
new UserDefinedInvocationMatcher<arglist...>(predicate)};
228233
_impl->setInvocationMatcher(matcher);
229234
}
230235

231-
void setMatchingCriteria(const std::vector<Destructible *> &matchers) {
236+
void setMatchingCriteria(std::vector<Destructible *> &matchers) {
232237
typename ActualInvocation<arglist...>::Matcher *matcher{
233238
new ArgumentsMatcherInvocationMatcher<arglist...>(matchers)};
234239
_impl->setInvocationMatcher(matcher);
@@ -245,21 +250,26 @@ namespace fakeit {
245250
_impl->setMethodBodyByAssignment(method);
246251
}
247252

248-
template<class ...matcherCreators, class = typename std::enable_if<
249-
sizeof...(matcherCreators) == sizeof...(arglist)>::type>
250-
void setMatchingCriteria(const matcherCreators &... matcherCreator) {
253+
template<class ...matcherCreators>
254+
typename std::enable_if< //
255+
sizeof...(matcherCreators) == sizeof...(arglist), void> //
256+
::type setMatchingCriteria(matcherCreators &&... matcherCreator) {
251257
std::vector<Destructible *> matchers;
252258

253259
MatchersCollector<0, arglist...> c(matchers);
254-
c.CollectMatchers(matcherCreator...);
260+
c.CollectMatchers(std::forward<matcherCreators>(matcherCreator)...);
255261

256262
MethodMockingContext<R, arglist...>::setMatchingCriteria(matchers);
257263
}
258264

259265
private:
260266

261-
typename std::function<R(arglist&...)> getOriginalMethod() override {
262-
return _impl->getOriginalMethod();
267+
typename std::function<R(arglist&...)> getOriginalMethodCopyArgs() override {
268+
return _impl->getOriginalMethodCopyArgs();
269+
}
270+
271+
typename std::function<R(arglist&...)> getOriginalMethodForwardArgs() override {
272+
return _impl->getOriginalMethodForwardArgs();
263273
}
264274

265275
std::shared_ptr<Implementation> _impl;
@@ -287,18 +297,13 @@ namespace fakeit {
287297
return *this;
288298
}
289299

290-
MockingContext<R, arglist...> &Using(const arglist &... args) {
291-
MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
292-
return *this;
293-
}
294-
295300
template<class ...arg_matcher>
296-
MockingContext<R, arglist...> &Using(const arg_matcher &... arg_matchers) {
297-
MethodMockingContext<R, arglist...>::setMatchingCriteria(arg_matchers...);
301+
MockingContext<R, arglist...> &Using(arg_matcher &&... arg_matchers) {
302+
MethodMockingContext<R, arglist...>::setMatchingCriteria(std::forward<arg_matcher>(arg_matchers)...);
298303
return *this;
299304
}
300305

301-
MockingContext<R, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
306+
MockingContext<R, arglist...> &Matching(const std::function<bool(arglist &...)>& matcher) {
302307
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
303308
return *this;
304309
}
@@ -308,7 +313,7 @@ namespace fakeit {
308313
return *this;
309314
}
310315

311-
MockingContext<R, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
316+
MockingContext<R, arglist...> &operator()(const std::function<bool(arglist &...)>& matcher) {
312317
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
313318
return *this;
314319
}
@@ -352,18 +357,13 @@ namespace fakeit {
352357
return *this;
353358
}
354359

355-
MockingContext<void, arglist...> &Using(const arglist &... args) {
356-
MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
357-
return *this;
358-
}
359-
360360
template<class ...arg_matcher>
361-
MockingContext<void, arglist...> &Using(const arg_matcher &... arg_matchers) {
362-
MethodMockingContext<void, arglist...>::setMatchingCriteria(arg_matchers...);
361+
MockingContext<void, arglist...> &Using(arg_matcher &&... arg_matchers) {
362+
MethodMockingContext<void, arglist...>::setMatchingCriteria(std::forward<arg_matcher>(arg_matchers)...);
363363
return *this;
364364
}
365365

366-
MockingContext<void, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
366+
MockingContext<void, arglist...> &Matching(const std::function<bool(arglist &...)>& matcher) {
367367
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
368368
return *this;
369369
}
@@ -373,7 +373,7 @@ namespace fakeit {
373373
return *this;
374374
}
375375

376-
MockingContext<void, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
376+
MockingContext<void, arglist...> &operator()(const std::function<bool(arglist &...)>& matcher) {
377377
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
378378
return *this;
379379
}

include/fakeit/MockImpl.hpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,28 @@ namespace fakeit {
180180
: MethodMockingContextBase<R, arglist...>(mock), _vMethod(vMethod) {
181181
}
182182

183-
184-
virtual std::function<R(arglist&...)> getOriginalMethod() override {
183+
template<typename ... T, typename std::enable_if<all_true<std::is_copy_constructible<T>::value...>::value, int>::type = 0>
184+
std::function<R(arglist&...)> getOriginalMethodCopyArgsInternal(int) {
185+
void *mPtr = MethodMockingContextBase<R, arglist...>::_mock.getOriginalMethod(_vMethod);
186+
C * instance = &(MethodMockingContextBase<R, arglist...>::_mock.get());
187+
return [=](arglist&... args) -> R {
188+
auto m = union_cast<typename VTableMethodType<R,arglist...>::type>(mPtr);
189+
return m(instance, args...);
190+
};
191+
}
192+
193+
/* LCOV_EXCL_START */
194+
template<typename ... T>
195+
[[noreturn]] std::function<R(arglist&...)> getOriginalMethodCopyArgsInternal(long) {
196+
std::abort(); // Shouldn't ever be called, Spy() should static_assert an error before.
197+
}
198+
/* LCOV_EXCL_STOP */
199+
200+
std::function<R(arglist&...)> getOriginalMethodCopyArgs() override {
201+
return getOriginalMethodCopyArgsInternal<arglist...>(0);
202+
}
203+
204+
std::function<R(arglist&...)> getOriginalMethodForwardArgs() override {
185205
void *mPtr = MethodMockingContextBase<R, arglist...>::_mock.getOriginalMethod(_vMethod);
186206
C * instance = &(MethodMockingContextBase<R, arglist...>::_mock.get());
187207
return [=](arglist&... args) -> R {
@@ -225,7 +245,12 @@ namespace fakeit {
225245
: MethodMockingContextBase<void>(mock) {
226246
}
227247

228-
virtual std::function<void()> getOriginalMethod() override {
248+
std::function<void()> getOriginalMethodCopyArgs() override {
249+
return [=]() -> void {
250+
};
251+
}
252+
253+
std::function<void()> getOriginalMethodForwardArgs() override {
229254
return [=]() -> void {
230255
};
231256
}
@@ -316,4 +341,4 @@ namespace fakeit {
316341
* the stubbed method (if exists).
317342
* This way we can also do extra work in the default implementation like mark the instance as deleted so the mock
318343
* will know not to delete it if already deleted!!!
319-
*/
344+
*/

include/fakeit/SpyFunctor.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,39 @@
77
*/
88
#pragma once
99

10+
#include <type_traits>
11+
1012
#include "fakeit/StubbingProgress.hpp"
1113
#include "fakeit/StubbingImpl.hpp"
1214
#include "fakeit/SpyingContext.hpp"
15+
#include "mockutils/type_utils.hpp"
1316

1417
namespace fakeit {
1518

1619
class SpyFunctor {
1720
private:
1821

19-
template<typename R, typename ... arglist>
20-
void spy(const SpyingContext<R, arglist...> &root) {
22+
template<typename R, typename ... arglist, typename std::enable_if<all_true<std::is_copy_constructible<arglist>::value...>::value, int>::type = 0>
23+
void spy(const SpyingContext<R, arglist...> &root, int) {
2124
SpyingContext<R, arglist...> &rootWithoutConst = const_cast<SpyingContext<R, arglist...> &>(root);
22-
auto methodFromOriginalVT = rootWithoutConst.getOriginalMethod();
25+
auto methodFromOriginalVT = rootWithoutConst.getOriginalMethodCopyArgs();
2326
rootWithoutConst.appendAction(new ReturnDelegateValue<R, arglist...>(methodFromOriginalVT));
2427
rootWithoutConst.commit();
2528
}
2629

30+
template<typename R, typename ... arglist>
31+
void spy(const SpyingContext<R, arglist...> &, long) {
32+
static_assert(!std::is_same<R, R>::value, "Spy() cannot accept move-only args, use SpyWithoutVerify() instead which is able to forward these args but then they won't be available for Verify().");
33+
}
34+
2735
void operator()() {
2836
}
2937

3038
public:
3139

3240
template<typename H, typename ... M>
3341
void operator()(const H &head, const M &... tail) {
34-
spy(head);
42+
spy(head, 0);
3543
this->operator()(tail...);
3644
}
3745

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
3+
#include "fakeit/StubbingProgress.hpp"
4+
#include "fakeit/StubbingImpl.hpp"
5+
#include "fakeit/SpyingContext.hpp"
6+
7+
namespace fakeit {
8+
9+
class SpyWithoutVerifyFunctor {
10+
private:
11+
12+
template<typename R, typename ... arglist>
13+
void spy(const SpyingContext<R, arglist...> &root) {
14+
SpyingContext<R, arglist...> &rootWithoutConst = const_cast<SpyingContext<R, arglist...> &>(root);
15+
auto methodFromOriginalVT = rootWithoutConst.getOriginalMethodForwardArgs();
16+
rootWithoutConst.appendAction(new ReturnDelegateValue<R, arglist...>(methodFromOriginalVT));
17+
rootWithoutConst.commit();
18+
}
19+
20+
void operator()() {
21+
}
22+
23+
public:
24+
25+
template<typename H, typename ... M>
26+
void operator()(const H &head, const M &... tail) {
27+
spy(head);
28+
this->operator()(tail...);
29+
}
30+
31+
};
32+
33+
}

include/fakeit/SpyingContext.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace fakeit {
1818
struct SpyingContext : Xaction {
1919
virtual void appendAction(Action<R, arglist...> *action) = 0;
2020

21-
virtual std::function<R(arglist&...)> getOriginalMethod() = 0;
21+
virtual std::function<R(arglist&...)> getOriginalMethodCopyArgs() = 0;
22+
virtual std::function<R(arglist&...)> getOriginalMethodForwardArgs() = 0;
2223
};
2324
}

include/fakeit/api_functors.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "fakeit/VerifyFunctor.hpp"
55
#include "fakeit/VerifyNoOtherInvocationsFunctor.hpp"
66
#include "fakeit/SpyFunctor.hpp"
7+
#include "fakeit/SpyWithoutVerifyFunctor.hpp"
78
#include "fakeit/FakeFunctor.hpp"
89
#include "fakeit/WhenFunctor.hpp"
910
#include "fakeit/UnverifiedFunctor.hpp"
@@ -15,6 +16,7 @@ namespace fakeit {
1516
static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit);
1617
static UnverifiedFunctor Unverified(Fakeit);
1718
static SpyFunctor Spy;
19+
static SpyWithoutVerifyFunctor SpyWithoutVerify;
1820
static FakeFunctor Fake;
1921
static WhenFunctor When;
2022

@@ -28,6 +30,7 @@ namespace fakeit {
2830
use(&Fake);
2931
use(&When);
3032
use(&Spy);
33+
use(&SpyWithoutVerify);
3134
use(&Using);
3235
use(&Verify);
3336
use(&VerifyNoOtherInvocations);

include/fakeit/api_macros.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
std::remove_reference<decltype((mock).get())>::type
99

1010
#define OVERLOADED_METHOD_PTR(mock, method, prototype) \
11-
fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::get(&MOCK_TYPE(mock)::method)
11+
fakeit::Prototype<prototype>::MemberType<typename MOCK_TYPE(mock)>::get(&MOCK_TYPE(mock)::method)
1212

1313
#define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \
14-
fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::getconst(&MOCK_TYPE(mock)::method)
14+
fakeit::Prototype<prototype>::MemberType<typename MOCK_TYPE(mock)>::getconst(&MOCK_TYPE(mock)::method)
1515

1616
#define Dtor(mock) \
1717
(mock).dtor().setMethodDetails(#mock,"destructor")

0 commit comments

Comments
 (0)