Make OwnerPointer Movable & add test cases
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-OwnerPointer.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // EXTERNAL INCLUDES
19 #include <utility>
20
21 // INTERNAL INCLUDES
22 #include <dali-test-suite-utils.h>
23 #include <dali/internal/common/owner-pointer.h>
24
25 using namespace Dali::Internal;
26
27 void utc_dali_internal_owner_pointer_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_internal_owner_pointer_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37 ///////////////////////////////////////////////////////////////////////////////
38 namespace
39 {
40
41 /// Takes in a reference to a bool which is set to true when the destructor is called
42 class OwnedClass
43 {
44 public:
45
46   OwnedClass( bool& destructorCalled )
47   : mDestructorCalled( destructorCalled )
48   {
49     mDestructorCalled = false;
50   }
51
52   ~OwnedClass()
53   {
54     mDestructorCalled = true;
55   }
56
57 private:
58
59   bool& mDestructorCalled;
60 };
61
62 /// Just a simple class with a function that marks a member boolean to true if that function is called
63 class ClassWithFunction
64 {
65 public:
66   ClassWithFunction() = default;
67
68   void MyFunction()
69   {
70     functionCalled = true;
71   }
72
73   bool functionCalled{ false };
74 };
75
76 } // anon namespace
77
78 ///////////////////////////////////////////////////////////////////////////////
79
80 int UtcDaliOwnerPointerEnsureDeletion(void)
81 {
82   // Ensure that the object owned by the owner-pointer is deleted.
83
84   bool deleted = false;
85
86   {
87     OwnerPointer< OwnedClass > pointer( new OwnedClass( deleted ) );
88     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
89   }
90
91   // OwnerPointer out-of-scope, object should be deleted.
92
93   DALI_TEST_EQUALS( deleted, true, TEST_LOCATION );
94
95   END_TEST;
96 }
97
98 int UtcDaliOwnerPointerDefaultConstructor(void)
99 {
100   // Ensure the default constructor is created as expected.
101
102   OwnerPointer< OwnedClass > pointer;
103   DALI_TEST_CHECK( pointer.Get() == nullptr );
104
105   END_TEST;
106 }
107
108 int UtcDaliOwnerPointerCopy(void)
109 {
110   // Call copy constructor and assignment operator
111
112   bool deleted = false;
113   OwnedClass* owned = new OwnedClass( deleted );
114
115   OwnerPointer< OwnedClass > first( owned );
116   DALI_TEST_CHECK( first.Get() == owned );
117
118   {
119     // Copy constructor, first should have a nullptr now, no object deletion
120     OwnerPointer< OwnedClass > second( first );
121     DALI_TEST_CHECK( first.Get() == nullptr );
122     DALI_TEST_CHECK( second.Get() == owned);
123     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
124
125     // Self assignment, nothing should change or be deleted.
126     first = first;
127     second = second;
128     DALI_TEST_CHECK( first.Get() == nullptr );
129     DALI_TEST_CHECK( second.Get() == owned );
130     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
131
132     // Assign second to first, no deletion, second should have a nullptr now
133     first = second;
134     DALI_TEST_CHECK( first.Get() == owned );
135     DALI_TEST_CHECK( second.Get() == nullptr );
136     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
137   }
138
139   // second is out-of-scope now, no object deletion
140   DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
141
142   // Assign to an empty pointer, owned object should be deleted
143   OwnerPointer< OwnedClass > empty;
144   first = empty;
145   DALI_TEST_EQUALS( deleted, true, TEST_LOCATION );
146   DALI_TEST_CHECK( first.Get() == nullptr );
147   DALI_TEST_CHECK( empty.Get() == nullptr );
148
149   END_TEST;
150 }
151
152 int UtcDaliOwnerPointerMove(void)
153 {
154   // Call move constructor and move assignment operator
155
156   bool deleted = false;
157   OwnedClass* owned = new OwnedClass( deleted );
158
159   OwnerPointer< OwnedClass > first( owned );
160   DALI_TEST_CHECK( first.Get() == owned );
161
162   {
163     // Move constructor, first should have a nullptr now, no object deletion
164     OwnerPointer< OwnedClass > second( std::move( first ) );
165     DALI_TEST_CHECK( first.Get() == nullptr );
166     DALI_TEST_CHECK( second.Get() == owned);
167     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
168
169     // Self assignment, nothing should change or be deleted.
170     first = std::move( first );
171     second = std::move( second );
172     DALI_TEST_CHECK( first.Get() == nullptr );
173     DALI_TEST_CHECK( second.Get() == owned );
174     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
175
176     // Assign second to first, no deletion, second should have a nullptr now
177     first = std::move( second );
178     DALI_TEST_CHECK( first.Get() == owned );
179     DALI_TEST_CHECK( second.Get() == nullptr );
180     DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
181   }
182
183   // second is out-of-scope now, no object deletion
184   DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
185
186   // Assign to an empty pointer, owned object should be deleted
187   OwnerPointer< OwnedClass > empty;
188   first = std::move( empty );
189   DALI_TEST_EQUALS( deleted, true, TEST_LOCATION );
190   DALI_TEST_CHECK( first.Get() == nullptr );
191   DALI_TEST_CHECK( empty.Get() == nullptr );
192
193   END_TEST;
194 }
195
196 int UtcDaliOwnerPointerIndirection(void)
197 {
198   // Check the indirection operators
199
200   using Ptr = OwnerPointer< int >;
201
202   {
203     int* rawIntPtr( new int( 200 ) );
204     Ptr nonConstPtr( rawIntPtr );
205     DALI_TEST_CHECK( rawIntPtr == &( *nonConstPtr ) );
206     DALI_TEST_EQUALS( *nonConstPtr, 200, TEST_LOCATION );
207   }
208
209   {
210     int* rawIntPtr2( new int( 300 ) );
211     const Ptr constPtr( rawIntPtr2 );
212     DALI_TEST_CHECK( rawIntPtr2 == &( *constPtr ) );
213     DALI_TEST_EQUALS( *constPtr, 300, TEST_LOCATION );
214   }
215
216   END_TEST;
217 }
218
219 int UtcDaliOwnerPointerPointerOperator(void)
220 {
221   // Check the pointer operators
222
223   using Ptr = OwnerPointer< ClassWithFunction >;
224
225   // Check if function is called as expected when using a const OwnerPointer
226   {
227     ClassWithFunction* rawPtr( new ClassWithFunction );
228     Ptr nonConstPtr( rawPtr );
229     DALI_TEST_EQUALS( rawPtr->functionCalled, false, TEST_LOCATION );
230     nonConstPtr->MyFunction();
231     DALI_TEST_EQUALS( rawPtr->functionCalled, true, TEST_LOCATION );
232   }
233
234
235   // Check if function is called as expected when using a const OwnerPointer
236   {
237     ClassWithFunction* rawPtr2( new ClassWithFunction );
238     const Ptr constPtr( rawPtr2 );
239     DALI_TEST_EQUALS( rawPtr2->functionCalled, false, TEST_LOCATION );
240     constPtr->MyFunction();
241     DALI_TEST_EQUALS( rawPtr2->functionCalled, true, TEST_LOCATION );
242   }
243   END_TEST;
244 }
245
246 int UtcDaliOwnerPointerComparisonOperator(void)
247 {
248   // Check the comparison operator
249
250   using Ptr = OwnerPointer< int >;
251
252   int* rawIntPtr( new int( 200 ) );
253   Ptr ownerPtr( rawIntPtr );
254   DALI_TEST_CHECK( ownerPtr == rawIntPtr );
255   DALI_TEST_CHECK( ! ( ownerPtr == nullptr ) );
256
257   END_TEST;
258 }
259
260 int UtcDaliOwnerPointerReset(void)
261 {
262   // Ensure that calling Reset deletes the object and sets the owner-pointer to NULL
263
264   bool deleted = false;
265
266   OwnerPointer< OwnedClass > pointer( new OwnedClass( deleted ) );
267   DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
268   pointer.Reset();
269   DALI_TEST_EQUALS( deleted, true, TEST_LOCATION );
270   DALI_TEST_CHECK( pointer.Get() == nullptr );
271
272   // Reset the empty pointer, should have no effect but there shouldn't be any crash
273   pointer.Reset();
274   DALI_TEST_CHECK( pointer.Get() == nullptr );
275
276   END_TEST;
277 }
278
279 int UtcDaliOwnerPointerRelease(void)
280 {
281   // Ensure that calling Release does NOT delete the object but still sets the owner-pointer to NULL
282
283   bool deleted = false;
284
285   OwnedClass* rawPtr = new OwnedClass( deleted );
286   OwnerPointer< OwnedClass > pointer( rawPtr );
287
288   DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
289   DALI_TEST_CHECK( pointer.Release() == rawPtr );
290   DALI_TEST_EQUALS( deleted, false, TEST_LOCATION );
291   DALI_TEST_CHECK( pointer.Get() == nullptr );
292
293   // Release the empty pointer, should have no effect but there shouldn't be any crash
294   DALI_TEST_CHECK( pointer.Release() == nullptr );
295   DALI_TEST_CHECK( pointer.Get() == nullptr );
296
297   END_TEST;
298 }
299
300 int UtcDaliOwnerPointerGet(void)
301 {
302   // Check the Get method
303
304   using Ptr = OwnerPointer< int >;
305
306   int* rawIntPtr( new int( 200 ) );
307   Ptr ownerPtr( rawIntPtr );
308   DALI_TEST_CHECK( ownerPtr.Get() == rawIntPtr );
309
310   END_TEST;
311 }
312
313 int UtcDaliOwnerPointerSwap(void)
314 {
315   // Ensure the Swap method swaps the pointers and doesn't delete any objects
316
317   using Ptr = OwnerPointer< OwnedClass >;
318
319   bool firstObjectDeleted = false;
320   bool secondObjectDeleted = false;
321
322   OwnedClass* firstRawPtr = new OwnedClass( firstObjectDeleted );
323   OwnedClass* secondRawPtr = new OwnedClass( secondObjectDeleted );
324
325   Ptr firstPtr( firstRawPtr );
326   Ptr secondPtr( secondRawPtr );
327
328   // Check initial values
329   DALI_TEST_EQUALS( firstObjectDeleted, false, TEST_LOCATION );
330   DALI_TEST_EQUALS( secondObjectDeleted, false, TEST_LOCATION );
331   DALI_TEST_CHECK( firstPtr == firstRawPtr );
332   DALI_TEST_CHECK( secondPtr == secondRawPtr );
333
334   // Call Swap on first and ensure swap is done and there's no deletion
335   firstPtr.Swap( secondPtr );
336   DALI_TEST_EQUALS( firstObjectDeleted, false, TEST_LOCATION );
337   DALI_TEST_EQUALS( secondObjectDeleted, false, TEST_LOCATION );
338   DALI_TEST_CHECK( firstPtr == secondRawPtr );
339   DALI_TEST_CHECK( secondPtr == firstRawPtr );
340
341   // Swap back using second, again no deletion
342   secondPtr.Swap( firstPtr );
343   DALI_TEST_EQUALS( firstObjectDeleted, false, TEST_LOCATION );
344   DALI_TEST_EQUALS( secondObjectDeleted, false, TEST_LOCATION );
345   DALI_TEST_CHECK( firstPtr == firstRawPtr );
346   DALI_TEST_CHECK( secondPtr == secondRawPtr );
347
348   // Swap with self, nothing should change or be deleted
349   firstPtr.Swap( firstPtr );
350   DALI_TEST_EQUALS( firstObjectDeleted, false, TEST_LOCATION );
351   DALI_TEST_CHECK( firstPtr == firstRawPtr );
352
353   // Swap with an empty OwnerPointer, no deletion but firstPtr should be empty now
354   Ptr emptyPtr;
355   firstPtr.Swap( emptyPtr );
356   DALI_TEST_EQUALS( firstObjectDeleted, false, TEST_LOCATION );
357   DALI_TEST_CHECK( firstPtr == nullptr );
358   DALI_TEST_CHECK( emptyPtr == firstRawPtr );
359
360   END_TEST;
361 }