From ff338c289a6ea84a980f50f9e0a12b7a49febb66 Mon Sep 17 00:00:00 2001 From: FranckRJ Date: Sun, 21 Apr 2024 11:59:23 +0200 Subject: [PATCH] dnk --- include/fakeit/StubbingProgress.hpp | 6 +- tests/referece_types_tests.cpp | 254 +++++++++++++++++----------- 2 files changed, 161 insertions(+), 99 deletions(-) diff --git a/include/fakeit/StubbingProgress.hpp b/include/fakeit/StubbingProgress.hpp index 519ba622..09da555b 100644 --- a/include/fakeit/StubbingProgress.hpp +++ b/include/fakeit/StubbingProgress.hpp @@ -88,7 +88,11 @@ namespace fakeit { template MethodStubbingProgress& ReturnCapture(T&& r) { - auto store = std::make_shared::type>(std::forward(r)); + static_assert(std::is_constructible< + typename std::remove_cv::type>::type&, + typename std::remove_cv::type>::type&>::value, + "The type captured by ReturnCapture() (named T) must be compatible with the return type of the function (named R), i.e. T t{...}; R& r = t; must compile without creating temporaries."); + auto store = std::make_shared::type>::type>(std::forward(r)); return Do([store](const typename fakeit::test_arg::type...) mutable -> R { return std::forward(*store); }); diff --git a/tests/referece_types_tests.cpp b/tests/referece_types_tests.cpp index a7f2d0c6..8fc4c86a 100644 --- a/tests/referece_types_tests.cpp +++ b/tests/referece_types_tests.cpp @@ -18,20 +18,29 @@ struct ReferenceTypesTests: tpunit::TestFixture { class AbstractType { public: - virtual void foo() = 0; + virtual const std::string& getContent() = 0; + + // Return true if object was sliced, false otherwise. + virtual bool wasObjectSliced() { + return true; + } }; class ConcreteType: public AbstractType { public: - int state; - ConcreteType(int value = 10) : - state(value) { + std::string content; + ConcreteType(const std::string& newContent = "defaultContent") : + content{newContent} { + } + const std::string& getContent() override { + return content; } - void foo() override { + bool wasObjectSliced() override { + return false; } bool operator==(const ConcreteType& other) const { - return (other.state == this->state); + return (other.content == this->content); } }; @@ -42,6 +51,8 @@ struct ReferenceTypesTests: tpunit::TestFixture { virtual ConcreteType& returnConcreteTypeByRef() = 0; virtual const std::string& returnStringByConstRef() = 0; virtual std::string& returnStringByRef() = 0; + virtual const std::unique_ptr& returnMoveOnlyByConstRef() = 0; + virtual std::unique_ptr& returnMoveOnlyByRef() = 0; }; ReferenceTypesTests() : @@ -49,14 +60,15 @@ struct ReferenceTypesTests: tpunit::TestFixture { // TEST(ReferenceTypesTests::implicitStubbingDefaultReturnValues), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues), - TEST(ReferenceTypesTests::explicitStubbingReturnCopyValuesForRef), - TEST(ReferenceTypesTests::explicitStubbingReturnValuesCopyForRRef), + TEST(ReferenceTypesTests::explicitStubbingReturnValues), TEST(ReferenceTypesTests::explicitStubbingDefaultReturnValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_with_AlwaysReturn), - TEST(ReferenceTypesTests::explicitStubbingReturnCopyValuesForRef_with_AlwaysReturn), - TEST(ReferenceTypesTests::explicitStubbingReturnCopyValues_with_AlwaysReturn), TEST(ReferenceTypesTests::explicitStubbingReturnValues_by_assignment), - TEST(ReferenceTypesTests::explicitStubbingReturnValues) + TEST(ReferenceTypesTests::explicitStubbingReturnCaptureByCopy), + TEST(ReferenceTypesTests::explicitStubbingReturnCaptureByMove), + TEST(ReferenceTypesTests::explicitStubbingReturnCaptureByTemporary), + TEST(ReferenceTypesTests::explicitStubbingReturnCaptureForRef_with_AlwaysReturn), + TEST(ReferenceTypesTests::explicitStubbingReturnCaptureForRValRef_with_AlwaysReturn) // ) { } @@ -140,66 +152,6 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } - void explicitStubbingReturnCopyValuesForRef() { - Mock mock; - - // add scope so we know we are copying - { - std::string a_string{"myString"}; - int num{ 1 }; - - // explicit copy here - When(Method(mock, returnStringByConstRef)).ReturnCapture(a_string); - When(Method(mock, returnIntByRef)).ReturnCapture(num); - - // modify now so know whether or not is was copied - a_string = "modified"; - num = 2; - } - - ReferenceInterface& i = mock.get(); - - // Fundamental types are initiated to 0. - EXPECT_EQUAL("myString", i.returnStringByConstRef()); - EXPECT_EQUAL(1, i.returnIntByRef()); - } - - void explicitStubbingReturnValuesCopyForRRef() { - Mock mock; - - { - When(Method(mock, returnStringByConstRef)).ReturnCapture(std::string{ "myConstRefString" }); - When(Method(mock, returnStringByRef)).ReturnCapture(std::string{ "myRefString" }); - When(Method(mock, returnConcreteTypeByRef)).ReturnCapture(ConcreteType(20)); - When(Method(mock, returnIntByRef)).ReturnCapture(1); - } - - ReferenceInterface& i = mock.get(); - - EXPECT_EQUAL("myConstRefString", i.returnStringByConstRef()); - EXPECT_EQUAL("myRefString", i.returnStringByRef()); - EXPECT_EQUAL(ConcreteType(20), i.returnConcreteTypeByRef()); - EXPECT_EQUAL(1, i.returnIntByRef()); - } - - void explicitStubbingReturnCopyValuesForRef_with_AlwaysReturn() { - Mock mock; - - { - When(Method(mock, returnStringByConstRef)).AlwaysReturnCapture(std::string{ "myConstRefString" }); - When(Method(mock, returnStringByRef)).AlwaysReturnCapture(std::string{ "myRefString" }); - When(Method(mock, returnConcreteTypeByRef)).AlwaysReturnCapture(ConcreteType(20)); - When(Method(mock, returnIntByRef)).AlwaysReturnCapture(1); - } - - ReferenceInterface& i = mock.get(); - - EXPECT_EQUAL("myConstRefString", i.returnStringByConstRef()); - EXPECT_EQUAL("myRefString", i.returnStringByRef()); - EXPECT_EQUAL(ConcreteType(20), i.returnConcreteTypeByRef()); - EXPECT_EQUAL(1, i.returnIntByRef()); - } - void explicitStubbingReturnValues_with_AlwaysReturn() { Mock mock; // @@ -224,33 +176,6 @@ struct ReferenceTypesTests: tpunit::TestFixture { ASSERT_EQUAL(&c, &i.returnAbstractTypeByRef()); } - void explicitStubbingReturnCopyValues_with_AlwaysReturn() { - Mock mock; - - // add scope so we know we are copying - { - std::string a_string{ "myString" }; - int num{ 1 }; - - // explicit copy here - When(Method(mock, returnStringByConstRef)).AlwaysReturnCapture(a_string); - When(Method(mock, returnIntByRef)).AlwaysReturnCapture(num); - - // modify now so know whether or not is was copied - a_string = "modified"; - num = 2; - } - - ReferenceInterface& i = mock.get(); - - // Fundamental types are initiated to 0. - EXPECT_EQUAL("myString", i.returnStringByConstRef()); - EXPECT_EQUAL("myString", i.returnStringByConstRef()); - - EXPECT_EQUAL(1, i.returnIntByRef()); - EXPECT_EQUAL(1, i.returnIntByRef()); - } - void explicitStubbingReturnValues_by_assignment() { Mock mock; // @@ -299,4 +224,137 @@ struct ReferenceTypesTests: tpunit::TestFixture { #endif } + void explicitStubbingReturnCaptureByCopy() { + Mock mock; + + // add scope so we know we are copying + { + std::string aString{"myString"}; + int num = 1; + ConcreteType concrete{"myConcreteType"}; + + // explicit copy here + When(Method(mock, returnStringByConstRef)).ReturnCapture(aString); + When(Method(mock, returnIntByRef)).ReturnCapture(num); + When(Method(mock, returnAbstractTypeByRef)).ReturnCapture(concrete); + + // modify now so know whether or not is was copied + aString = "modified"; + num = 2; + concrete.content = "modified"; + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + AbstractType& abstract = i.returnAbstractTypeByRef(); + EXPECT_FALSE(abstract.wasObjectSliced()); + EXPECT_EQUAL("myConcreteType", abstract.getContent()); + } + + void explicitStubbingReturnCaptureByMove() { + Mock mock; + + // add scope so we know we are moving + { + std::string aString{"aString"}; + std::string bString{"bString"}; + std::unique_ptr aPtrString{new std::string{"aPtrString"}}; + std::unique_ptr bPtrString{new std::string{"bPtrString"}}; + ConcreteType concrete{"myConcreteType"}; + + // explicit move here + When(Method(mock, returnStringByConstRef)).ReturnCapture(std::move(aString)); + When(Method(mock, returnStringByRef)).ReturnCapture(std::move(bString)); + When(Method(mock, returnMoveOnlyByConstRef)).ReturnCapture(std::move(aPtrString)); + When(Method(mock, returnMoveOnlyByRef)).ReturnCapture(std::move(bPtrString)); + When(Method(mock, returnAbstractTypeByRef)).ReturnCapture(std::move(concrete)); + + // Verify objects were moved. + EXPECT_TRUE(aString.empty()); + EXPECT_TRUE(bString.empty()); + EXPECT_EQUAL(aPtrString, nullptr); + EXPECT_EQUAL(bPtrString, nullptr); + EXPECT_TRUE(concrete.content.empty()); + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("aString", i.returnStringByConstRef()); + EXPECT_EQUAL("bString", i.returnStringByRef()); + EXPECT_EQUAL("aPtrString", *i.returnMoveOnlyByConstRef()); + EXPECT_EQUAL("bPtrString", *i.returnMoveOnlyByRef()); + AbstractType& abstract = i.returnAbstractTypeByRef(); + EXPECT_FALSE(abstract.wasObjectSliced()); + EXPECT_EQUAL("myConcreteType", abstract.getContent()); + } + + void explicitStubbingReturnCaptureByTemporary() { + Mock mock; + + { + When(Method(mock, returnStringByConstRef)).ReturnCapture(std::string{"aString"}); + When(Method(mock, returnStringByRef)).ReturnCapture(std::string{"bString"}); + When(Method(mock, returnMoveOnlyByConstRef)).ReturnCapture(std::unique_ptr(new std::string{"aPtrString"})); + When(Method(mock, returnMoveOnlyByRef)).ReturnCapture(std::unique_ptr(new std::string{"bPtrString"})); + When(Method(mock, returnAbstractTypeByRef)).ReturnCapture(ConcreteType{"myConcreteType"}); + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("aString", i.returnStringByConstRef()); + EXPECT_EQUAL("bString", i.returnStringByRef()); + EXPECT_EQUAL("aPtrString", *i.returnMoveOnlyByConstRef()); + EXPECT_EQUAL("bPtrString", *i.returnMoveOnlyByRef()); + AbstractType& abstract = i.returnAbstractTypeByRef(); + EXPECT_FALSE(abstract.wasObjectSliced()); + EXPECT_EQUAL("myConcreteType", abstract.getContent()); + } + + void explicitStubbingReturnCaptureForRef_with_AlwaysReturn() { + Mock mock; + + // add scope so we know we are copying + { + std::string a_string{ "myString" }; + int num{ 1 }; + + // explicit copy here + When(Method(mock, returnStringByConstRef)).AlwaysReturnCapture(a_string); + When(Method(mock, returnIntByRef)).AlwaysReturnCapture(num); + + // modify now so know whether or not is was copied + a_string = "modified"; + num = 2; + } + + ReferenceInterface& i = mock.get(); + + // Fundamental types are initiated to 0. + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + EXPECT_EQUAL("myString", i.returnStringByConstRef()); + + EXPECT_EQUAL(1, i.returnIntByRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + } + + void explicitStubbingReturnCaptureForRValRef_with_AlwaysReturn() { + Mock mock; + + { + When(Method(mock, returnStringByConstRef)).AlwaysReturnCapture(std::string{ "myConstRefString" }); + When(Method(mock, returnStringByRef)).AlwaysReturnCapture(std::string{ "myRefString" }); + When(Method(mock, returnConcreteTypeByRef)).AlwaysReturnCapture(ConcreteType("myConcreteType")); + When(Method(mock, returnIntByRef)).AlwaysReturnCapture(1); + } + + ReferenceInterface& i = mock.get(); + + EXPECT_EQUAL("myConstRefString", i.returnStringByConstRef()); + EXPECT_EQUAL("myRefString", i.returnStringByRef()); + EXPECT_EQUAL(ConcreteType("myConcreteType"), i.returnConcreteTypeByRef()); + EXPECT_EQUAL(1, i.returnIntByRef()); + } + } __ReferenceTypesTests;