Skip to content

Commit cb6bd99

Browse files
committed
Added back .(Always)Return<ref-type>(val) to force capture value as reference (in a deprecated manner), and other minor fixes.
1 parent a4fa679 commit cb6bd99

File tree

2 files changed

+177
-10
lines changed

2 files changed

+177
-10
lines changed

include/fakeit/StubbingProgress.hpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ namespace fakeit {
8080
}
8181

8282
void AlwaysReturn(const R &r) {
83-
return AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
83+
AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
8484
}
8585

8686
// The std::enable_if is only there to disambiguate with the deprecated version of .AlwaysReturn<type>(val), and
@@ -113,7 +113,7 @@ namespace fakeit {
113113
fk_remove_cvref_t<T>,
114114
fk_remove_cvref_t<R>>::type;
115115
auto store = std::make_shared<StoredType>(std::forward<T>(r));
116-
return AlwaysDo([store](const typename fakeit::test_arg<arglist>::type...) mutable -> R {
116+
AlwaysDo([store](const typename fakeit::test_arg<arglist>::type...) mutable -> R {
117117
return std::forward<R>(*store);
118118
});
119119
}
@@ -124,8 +124,8 @@ namespace fakeit {
124124
}
125125

126126
template<typename T>
127-
MethodStubbingProgress<R, arglist...>& AlwaysReturnRefCapt(T&& r) {
128-
return AlwaysReturn(std::forward<T>(r));
127+
void AlwaysReturnRefCapt(T&& r) {
128+
AlwaysReturn(std::forward<T>(r));
129129
}
130130
};
131131

@@ -147,7 +147,7 @@ namespace fakeit {
147147
}
148148

149149
void AlwaysReturn(const R &r) {
150-
return AlwaysDo([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
150+
AlwaysDo([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
151151
}
152152

153153
MethodStubbingProgress<R, arglist...>& ReturnValCapt(const R& r) {
@@ -159,7 +159,7 @@ namespace fakeit {
159159
}
160160

161161
void AlwaysReturnValCapt(const R &r) {
162-
return AlwaysReturn(r);
162+
AlwaysReturn(r);
163163
}
164164

165165
template<typename T>
@@ -169,9 +169,9 @@ namespace fakeit {
169169
}
170170

171171
template<typename T>
172-
MethodStubbingProgress<R, arglist...>& AlwaysReturnRefCapt(T&& r) {
172+
void AlwaysReturnRefCapt(T&& r) {
173173
static_assert(std::is_lvalue_reference<T>::value, "AlwaysReturnRefCapt() cannot take an rvalue references because it would make it dangling, use AlwaysReturnValCapt() instead.");
174-
return AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
174+
AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
175175
}
176176
};
177177

@@ -205,7 +205,23 @@ namespace fakeit {
205205
// to errors (because you have to specify the type). .AlwaysReturnValCapt("ok") is superior and should be used instead.
206206
template<typename TypeUsedToForceCapture, typename RealType, typename std::enable_if<!std::is_reference<TypeUsedToForceCapture>::value, bool>::type = true>
207207
void AlwaysReturn(RealType&& ret) {
208-
return this->AlwaysReturnValCapt(TypeUsedToForceCapture(std::forward<RealType>(ret)));
208+
this->AlwaysReturnValCapt(TypeUsedToForceCapture(std::forward<RealType>(ret)));
209+
}
210+
211+
// DEPRECATED: This should ideally be removed, it allows writing .Return<std::string&>(str) when a function
212+
// returns "std::string" (for example) to have the same behavior has .ReturnRefCapt(str). But it is prone
213+
// to errors (because you have to specify the type). .ReturnRefCapt(str) is superior and should be used instead.
214+
template<typename TypeUsedToForceCapture, typename RealType, typename std::enable_if<std::is_reference<TypeUsedToForceCapture>::value, bool>::type = true>
215+
MethodStubbingProgress<R, arglist...>& Return(RealType&& ret) {
216+
return this->ReturnRefCapt(std::forward<RealType>(ret));
217+
}
218+
219+
// DEPRECATED: This should ideally be removed, it allows writing .AlwaysReturn<std::string&>(str) when a function
220+
// returns "std::string" (for example) to have the same behavior has .AlwaysReturnRefCapt(str). But it is prone
221+
// to errors (because you have to specify the type). .AlwaysReturnRefCapt(str) is superior and should be used instead.
222+
template<typename TypeUsedToForceCapture, typename RealType, typename std::enable_if<std::is_reference<TypeUsedToForceCapture>::value, bool>::type = true>
223+
void AlwaysReturn(RealType&& ret) {
224+
this->AlwaysReturnRefCapt(std::forward<RealType>(ret));
209225
}
210226

211227
MethodStubbingProgress<R, arglist...> &

tests/return_template_specialization.cpp

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
2323
TEST(ReturnTemplateSpecializationTests::return_valcapt_from_other_type_temp),
2424
TEST(ReturnTemplateSpecializationTests::return_default_from_same_type_variable),
2525
TEST(ReturnTemplateSpecializationTests::return_valspecialization_from_same_type_variable),
26+
TEST(ReturnTemplateSpecializationTests::return_refspecialization_from_same_type_variable),
2627
TEST(ReturnTemplateSpecializationTests::return_valcapt_from_same_type_variable),
2728
TEST(ReturnTemplateSpecializationTests::return_refcapt_from_same_type_variable),
2829
TEST(ReturnTemplateSpecializationTests::return_default_from_other_type_variable),
2930
TEST(ReturnTemplateSpecializationTests::return_valspecialization_from_other_type_variable),
31+
TEST(ReturnTemplateSpecializationTests::return_refspecialization_from_other_type_variable),
3032
TEST(ReturnTemplateSpecializationTests::return_valcapt_from_other_type_variable),
3133
TEST(ReturnTemplateSpecializationTests::return_refcapt_from_other_type_variable),
3234
TEST(ReturnTemplateSpecializationTests::always_return_default_from_same_type_temp),
@@ -37,10 +39,14 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
3739
TEST(ReturnTemplateSpecializationTests::always_return_valcapt_from_other_type_temp),
3840
TEST(ReturnTemplateSpecializationTests::always_return_default_from_same_type_variable),
3941
TEST(ReturnTemplateSpecializationTests::always_return_valspecialization_from_same_type_variable),
42+
TEST(ReturnTemplateSpecializationTests::always_return_refspecialization_from_same_type_variable),
4043
TEST(ReturnTemplateSpecializationTests::always_return_valcapt_from_same_type_variable),
44+
TEST(ReturnTemplateSpecializationTests::always_return_refcapt_from_same_type_variable),
4145
TEST(ReturnTemplateSpecializationTests::always_return_default_from_other_type_variable),
4246
TEST(ReturnTemplateSpecializationTests::always_return_valspecialization_from_other_type_variable),
43-
TEST(ReturnTemplateSpecializationTests::always_return_valcapt_from_other_type_variable)
47+
TEST(ReturnTemplateSpecializationTests::always_return_refspecialization_from_other_type_variable),
48+
TEST(ReturnTemplateSpecializationTests::always_return_valcapt_from_other_type_variable),
49+
TEST(ReturnTemplateSpecializationTests::always_return_refcapt_from_other_type_variable)
4450
) {
4551
}
4652

@@ -235,6 +241,34 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
235241
}
236242
}
237243

244+
void return_refspecialization_from_same_type_variable() {
245+
Mock<SomeStruct> mock;
246+
247+
{
248+
std::string something = "something";
249+
MoveOnly mo = 5;
250+
251+
When(Method(mock, returnRef)).Return<std::string&>(something);
252+
something = "a different thing";
253+
ASSERT_EQUAL(mock.get().returnRef(), "a different thing");
254+
Verify(Method(mock, returnRef)).Once();
255+
256+
When(Method(mock, returnRefMo)).Return<MoveOnly&&>(mo);
257+
mo.i = 10;
258+
ASSERT_EQUAL(mock.get().returnRefMo().i, 10);
259+
Verify(Method(mock, returnRefMo)).Once();
260+
}
261+
262+
{
263+
std::string something = "something";
264+
265+
When(Method(mock, returnVal)).Return<std::string&>(something);
266+
something = "a different thing";
267+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
268+
Verify(Method(mock, returnVal)).Once();
269+
}
270+
}
271+
238272
void return_valcapt_from_same_type_variable() {
239273
Mock<SomeStruct> mock;
240274

@@ -350,6 +384,25 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
350384
}
351385
}
352386

387+
void return_refspecialization_from_other_type_variable() {
388+
Mock<SomeStruct> mock;
389+
390+
{
391+
const char* something = "something";
392+
int num = 5;
393+
394+
When(Method(mock, returnVal)).Return<std::string&>(something);
395+
something = "a different thing";
396+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
397+
Verify(Method(mock, returnVal)).Once();
398+
399+
When(Method(mock, returnValMo)).Return<MoveOnly&&>(num);
400+
num = 10;
401+
ASSERT_EQUAL(mock.get().returnValMo().i, 10);
402+
Verify(Method(mock, returnValMo)).Once();
403+
}
404+
}
405+
353406
void return_valcapt_from_other_type_variable() {
354407
Mock<SomeStruct> mock;
355408

@@ -565,6 +618,40 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
565618
}
566619
}
567620

621+
void always_return_refspecialization_from_same_type_variable() {
622+
Mock<SomeStruct> mock;
623+
624+
{
625+
std::string something = "something";
626+
MoveOnly mo = 5;
627+
628+
When(Method(mock, returnRef)).AlwaysReturn<std::string&>(something);
629+
something = "a different thing";
630+
ASSERT_EQUAL(mock.get().returnRef(), "a different thing");
631+
something = "another different thing";
632+
ASSERT_EQUAL(mock.get().returnRef(), "another different thing");
633+
Verify(Method(mock, returnRef)).Exactly(2);
634+
635+
When(Method(mock, returnRefMo)).AlwaysReturn<MoveOnly&&>(mo);
636+
mo.i = 10;
637+
ASSERT_EQUAL(mock.get().returnRefMo().i, 10);
638+
mo.i = 50;
639+
ASSERT_EQUAL(mock.get().returnRefMo().i, 50);
640+
Verify(Method(mock, returnRefMo)).Exactly(2);
641+
}
642+
643+
{
644+
std::string something = "something";
645+
646+
When(Method(mock, returnVal)).AlwaysReturn<std::string&>(something);
647+
something = "a different thing";
648+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
649+
something = "another different thing";
650+
ASSERT_EQUAL(mock.get().returnVal(), "another different thing");
651+
Verify(Method(mock, returnVal)).Exactly(2);
652+
}
653+
}
654+
568655
void always_return_valcapt_from_same_type_variable() {
569656
Mock<SomeStruct> mock;
570657

@@ -599,6 +686,40 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
599686
}
600687
}
601688

689+
void always_return_refcapt_from_same_type_variable() {
690+
Mock<SomeStruct> mock;
691+
692+
{
693+
std::string something = "something";
694+
MoveOnly mo = 5;
695+
696+
When(Method(mock, returnRef)).AlwaysReturnRefCapt(something);
697+
something = "a different thing";
698+
ASSERT_EQUAL(mock.get().returnRef(), "a different thing");
699+
something = "another different thing";
700+
ASSERT_EQUAL(mock.get().returnRef(), "another different thing");
701+
Verify(Method(mock, returnRef)).Exactly(2);
702+
703+
When(Method(mock, returnRefMo)).AlwaysReturnRefCapt(mo);
704+
mo.i = 10;
705+
ASSERT_EQUAL(mock.get().returnRefMo().i, 10);
706+
mo.i = 50;
707+
ASSERT_EQUAL(mock.get().returnRefMo().i, 50);
708+
Verify(Method(mock, returnRefMo)).Exactly(2);
709+
}
710+
711+
{
712+
std::string something = "something";
713+
714+
When(Method(mock, returnVal)).AlwaysReturnRefCapt(something);
715+
something = "a different thing";
716+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
717+
something = "another different thing";
718+
ASSERT_EQUAL(mock.get().returnVal(), "another different thing");
719+
Verify(Method(mock, returnVal)).Exactly(2);
720+
}
721+
}
722+
602723
void always_return_default_from_other_type_variable() {
603724
Mock<SomeStruct> mock;
604725

@@ -648,6 +769,21 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
648769
}
649770
}
650771

772+
void always_return_refspecialization_from_other_type_variable() {
773+
Mock<SomeStruct> mock;
774+
775+
{
776+
const char* something = "something";
777+
778+
When(Method(mock, returnVal)).AlwaysReturn<std::string&>(something);
779+
something = "a different thing";
780+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
781+
something = "another different thing";
782+
ASSERT_EQUAL(mock.get().returnVal(), "another different thing");
783+
Verify(Method(mock, returnVal)).Exactly(2);
784+
}
785+
}
786+
651787
void always_return_valcapt_from_other_type_variable() {
652788
Mock<SomeStruct> mock;
653789

@@ -682,4 +818,19 @@ struct ReturnTemplateSpecializationTests : tpunit::TestFixture {
682818
}
683819
}
684820

821+
void always_return_refcapt_from_other_type_variable() {
822+
Mock<SomeStruct> mock;
823+
824+
{
825+
const char* something = "something";
826+
827+
When(Method(mock, returnVal)).AlwaysReturnRefCapt(something);
828+
something = "a different thing";
829+
ASSERT_EQUAL(mock.get().returnVal(), "a different thing");
830+
something = "another different thing";
831+
ASSERT_EQUAL(mock.get().returnVal(), "another different thing");
832+
Verify(Method(mock, returnVal)).Exactly(2);
833+
}
834+
}
835+
685836
} __ReturnTemplateSpecializationTests;

0 commit comments

Comments
 (0)