ff22fb75c3cec58c669c6fda587548f5031eb3de
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-IntrusivePtr.cpp
1 /*
2  * Copyright (c) 2015 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
19 #include <iostream>
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
23
24 using namespace Dali;
25
26 namespace
27 {
28
29 const int REPEAT = 1000;
30
31 size_t g_creationCount = 0;
32 size_t g_destructionCount = 0;
33 size_t g_creationCountSubclass = 0;
34 size_t g_destructionCountSubclass = 0;
35 size_t g_creationCountUnrelated = 0;
36 size_t g_destructionCountUnrelated = 0;
37
38 class Counted : public RefObject
39 {
40 public:
41   Counted()
42   {
43     ++g_creationCount;
44   }
45   ~Counted()
46   {
47     ++g_destructionCount;
48   }
49 };
50
51 class CountedSubclass : public Counted
52 {
53 public:
54   CountedSubclass()
55   {
56     ++g_creationCountSubclass;
57   }
58   ~CountedSubclass()
59   {
60     ++g_destructionCountSubclass;
61   }
62 };
63
64 class UnrelatedCounted : public RefObject
65 {
66 public:
67   UnrelatedCounted()
68   {
69     ++g_creationCountUnrelated;
70   }
71   ~UnrelatedCounted()
72   {
73     ++g_destructionCountUnrelated;
74   }
75 };
76
77 class TestObject : public RefObject
78 {
79 public:
80   TestObject()
81   : data(201)
82   {
83   }
84
85   TestObject(const TestObject& testObject)
86   : RefObject(testObject),
87     data(testObject.data)
88   {
89   }
90
91   TestObject& Assign(const TestObject& testObject)
92   {
93     RefObject::operator=(testObject);
94     data = testObject.data;
95     return *this;
96   }
97
98   int data;
99 };
100
101
102 } // Anonymous namespace
103
104 /**
105  * Test that a default constructed pointer is null and harmless.
106  */
107 int UtcDaliIntrusivePtrIntrusivePtr(void)
108 {
109   tet_infoline( "Testing Dali::IntrusivePtr::IntrusivePtr()" );
110
111   g_creationCount = g_destructionCount = 0;
112
113   IntrusivePtr<Counted> counted;
114   DALI_TEST_EQUALS( g_creationCount, 0u, TEST_LOCATION );
115   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
116   // Test the pointer is null
117   DALI_TEST_EQUALS( counted.Get(), (Counted*) 0, TEST_LOCATION );
118   DALI_TEST_EQUALS( &(*counted), (Counted*) 0, TEST_LOCATION );
119   // Check destruction of the null smart pointer does nothing:
120   counted = IntrusivePtr<Counted>();
121   DALI_TEST_EQUALS( g_creationCount, 0u, TEST_LOCATION );
122   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
123
124   END_TEST;
125 }
126
127 int UtcDaliIntrusivePtrIntrusivePtrTP(void)
128 {
129   tet_infoline( "Testing Dali::IntrusivePtr::IntrusivePtr(T*)" );
130
131   g_creationCount = g_destructionCount = 0;
132
133   IntrusivePtr<Counted> counted( new Counted );
134   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
135   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
136   counted = 0;
137   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
138   DALI_TEST_EQUALS( g_destructionCount, 1u, TEST_LOCATION );
139
140   END_TEST;
141 }
142
143 // Class is too simple for a negative case to be created: int UtcDaliIntrusiveIntrusivePtrTN(void)
144
145 int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrUP(void)
146 {
147   tet_infoline( "Testing Dali::IntrusivePtr::IntrusivePtr(IntrusivePtr<U> const &)" );
148
149   g_creationCount = g_destructionCount = g_creationCountSubclass = g_destructionCountSubclass = 0;
150
151   IntrusivePtr<CountedSubclass> countedSubclass( new CountedSubclass );
152   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
153   DALI_TEST_EQUALS( g_creationCountSubclass, 1u, TEST_LOCATION );
154   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
155   DALI_TEST_EQUALS( g_destructionCountSubclass, 0u, TEST_LOCATION );
156
157   IntrusivePtr<Counted> counted( countedSubclass );
158   DALI_TEST_EQUALS( counted->ReferenceCount(), 2, TEST_LOCATION );
159
160   // Make loads more references:
161   std::vector< IntrusivePtr<Counted> > intrusivePtrs;
162   for( int i = 0; i < REPEAT; ++i )
163   {
164     intrusivePtrs.push_back( IntrusivePtr<Counted>( countedSubclass ) );
165   }
166   DALI_TEST_EQUALS( counted->ReferenceCount(), 2 + REPEAT, TEST_LOCATION );
167
168   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
169   DALI_TEST_EQUALS( g_creationCountSubclass, 1u, TEST_LOCATION );
170   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
171
172   END_TEST;
173 }
174
175 // The negative version of this test would fail at compile time:
176 // int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrUN(void)
177
178 int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrP(void)
179 {
180   tet_infoline( "Testing Dali::IntrusivePtr::IntrusivePtr(IntrusivePtr const &)" );
181
182   // Pass a pointer to a constructed second object:
183   // Pass a pointer to null:
184
185   g_creationCount = g_destructionCount = 0;
186
187   IntrusivePtr<Counted> counted( new Counted );
188   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
189   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
190   DALI_TEST_EQUALS( counted->ReferenceCount(), 1, TEST_LOCATION );
191
192   IntrusivePtr<Counted> counted2( counted );
193   DALI_TEST_EQUALS( counted->ReferenceCount(), 2, TEST_LOCATION );
194   DALI_TEST_EQUALS( counted.Get(), counted2.Get(), TEST_LOCATION );
195
196   // Make loads more references:
197   std::vector< IntrusivePtr<Counted> > intrusivePtrs;
198   for( int i = 0; i < REPEAT; ++i )
199   {
200     intrusivePtrs.push_back( IntrusivePtr<Counted>( counted ) );
201   }
202   DALI_TEST_EQUALS( counted->ReferenceCount(), 2 + REPEAT, TEST_LOCATION );
203
204   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
205   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
206
207   intrusivePtrs.clear();
208
209   DALI_TEST_EQUALS( counted->ReferenceCount(), 2, TEST_LOCATION );
210
211   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
212   DALI_TEST_EQUALS( g_destructionCount, 0u, TEST_LOCATION );
213
214   counted.Reset();
215   DALI_TEST_EQUALS( counted2->ReferenceCount(), 1, TEST_LOCATION );
216   counted2.Reset();
217
218   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
219   DALI_TEST_EQUALS( g_destructionCount, 1u, TEST_LOCATION );
220
221   END_TEST;
222 }
223
224 int UtcDaliIntrusivePtrGetP(void)
225 {
226   tet_infoline( "Testing Dali::IntrusivePtr::Get()" );
227
228   IntrusivePtr<Counted> counted( new Counted );
229   DALI_TEST_CHECK( counted.Get() != 0 );
230   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
231   DALI_TEST_EQUALS( counted->ReferenceCount(), 1, TEST_LOCATION );
232
233   END_TEST;
234 }
235
236 int UtcDaliIntrusivePtrGetN(void)
237 {
238   tet_infoline( "Testing Dali::IntrusivePtr::Get()" );
239
240   g_creationCount = 0;
241
242   IntrusivePtr<Counted> counted( 0 );
243   DALI_TEST_CHECK( counted.Get() == 0 );
244   DALI_TEST_EQUALS( g_creationCount, 0u, TEST_LOCATION );
245
246   END_TEST;
247 }
248
249 int UtcDaliIntrusivePtrArrowOperatorP(void)
250 {
251   tet_infoline( "Positive Test for Dali::IntrusivePtr::operator->()" );
252
253   IntrusivePtr<Counted> counted( new Counted );
254   DALI_TEST_CHECK( (counted.operator->()) != 0 );
255   DALI_TEST_EQUALS( counted->ReferenceCount(), 1, TEST_LOCATION );
256
257   END_TEST;
258 }
259
260 int UtcDaliIntrusivePtrArrowOperatorN(void)
261 {
262   tet_infoline( "Negative Test for Dali::IntrusivePtr::operator->()" );
263
264   IntrusivePtr<Counted> counted;
265   DALI_TEST_CHECK( (counted.operator->()) == 0 );
266
267   END_TEST;
268 }
269
270 int UtcDaliIntrusivePtrIndirectionOperatorP(void)
271 {
272   tet_infoline( "Positive Test for Dali::IntrusivePtr::operator*()" );
273
274   IntrusivePtr<Counted> counted( new Counted );
275   DALI_TEST_CHECK( &(counted.operator*()) != 0 );
276   DALI_TEST_EQUALS( (*counted).ReferenceCount(), 1, TEST_LOCATION );
277
278   END_TEST;
279 }
280
281 int UtcDaliIntrusivePtrIndirectionOperatorN(void)
282 {
283   tet_infoline( "Negative Test for Dali::IntrusivePtr::operator*()" );
284
285   IntrusivePtr<Counted> counted;
286   DALI_TEST_CHECK( &(counted.operator*()) == 0 );
287
288   END_TEST;
289 }
290
291 int UtcDaliIntrusivePtrResetP(void)
292 {
293   tet_infoline( "Positive Test for Dali::IntrusivePtr::Reset()" );
294
295   IntrusivePtr<Counted> counted( new Counted );
296   DALI_TEST_CHECK( counted.Get() != 0 );
297   counted.Reset();
298   DALI_TEST_CHECK( counted.Get() == 0 );
299
300   END_TEST;
301 }
302
303 int UtcDaliIntrusivePtrResetN(void)
304 {
305   tet_infoline( "Negative Test for Dali::IntrusivePtr::Reset()" );
306
307   IntrusivePtr<Counted> counted;
308   Counted* firstGet = counted.Get();
309   counted.Reset();
310   DALI_TEST_EQUALS( counted.Get(), firstGet, TEST_LOCATION );
311
312   END_TEST;
313 }
314
315 int UtcDaliIntrusivePtrResetTP(void)
316 {
317   tet_infoline( "Positive Test for Dali::IntrusivePtr::Reset(T*)" );
318
319   g_creationCount = g_destructionCount = 0;
320
321   IntrusivePtr<Counted> counted( new Counted );
322
323   IntrusivePtr<Counted> counted2( new Counted );
324
325   DALI_TEST_EQUALS( counted->ReferenceCount(), 1, TEST_LOCATION );
326   DALI_TEST_EQUALS( counted2->ReferenceCount(), 1, TEST_LOCATION );
327
328   counted.Reset( counted2.Get() );
329
330   DALI_TEST_EQUALS( counted->ReferenceCount(), 2, TEST_LOCATION );
331   DALI_TEST_EQUALS( counted2->ReferenceCount(), 2, TEST_LOCATION );
332
333   DALI_TEST_EQUALS( counted.Get(), counted2.Get(), TEST_LOCATION );
334
335   DALI_TEST_EQUALS( g_creationCount, 2u, TEST_LOCATION );
336   DALI_TEST_EQUALS( g_destructionCount, 1u, TEST_LOCATION );
337
338   counted2.Reset( (Counted*) 0 );
339   counted.Reset( counted2.Get() );
340   DALI_TEST_EQUALS( g_destructionCount, 2u, TEST_LOCATION );
341
342   // Check that reseting nulls is harmless:
343   counted2.Reset( counted.Get() );
344   counted.Reset( counted2.Get() );
345
346   DALI_TEST_EQUALS( g_destructionCount, 2u, TEST_LOCATION );
347
348   END_TEST;
349 }
350
351
352 int UtcDaliIntrusivePtrResetTN(void)
353 {
354   tet_infoline( "Negative Test for Dali::IntrusivePtr::Reset(T*)" );
355
356   g_creationCount = g_destructionCount = 0;
357
358   IntrusivePtr<Counted> counted( new Counted );
359
360   counted.Reset( (Counted*) 0 );
361
362   DALI_TEST_EQUALS( counted.Get(), (Counted*) 0, TEST_LOCATION );
363   DALI_TEST_EQUALS( g_creationCount, 1u, TEST_LOCATION );
364   DALI_TEST_EQUALS( g_destructionCount, 1u, TEST_LOCATION );
365
366   END_TEST;
367 }
368
369
370
371 int UtcDaliIntrusivePtrOperatorBooleanTypeP(void)
372 {
373   tet_infoline( "Positive Test for Dali::IntrusivePtr::operator Booleantype()" );
374
375   IntrusivePtr<Counted> counted( new Counted );
376   DALI_TEST_CHECK( counted.operator BooleanType() != 0 );
377   DALI_TEST_CHECK( counted );
378
379   typedef void (IntrusivePtr<Counted>::*BoolIdiomFunc)() const;
380   BoolIdiomFunc func = static_cast<BoolIdiomFunc>( counted.operator BooleanType() );
381   ((counted).*func)(); // purely for test coverage
382
383   counted.Reset();
384   DALI_TEST_CHECK( counted.operator BooleanType() == 0 );
385
386   END_TEST;
387 }
388
389 int UtcDaliIntrusivePtrOperatorBooleanTypeN(void)
390 {
391   tet_infoline( "Negative Test for Dali::IntrusivePtr::operator Booleantype()" );
392
393   IntrusivePtr<Counted> counted;
394   DALI_TEST_CHECK( counted.operator BooleanType() == 0 );
395   DALI_TEST_CHECK( !counted );
396   END_TEST;
397 }
398
399 /** Equality of two different types*/
400 int UtcDaliIntrusivePtrOperatorEqualTU(void)
401 {
402   tet_infoline( "Test for Dali::IntrusivePtr::operator ==(T, U)" );
403
404   IntrusivePtr<Counted> counted1( new Counted );
405   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
406   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
407   IntrusivePtr<Counted> counted2( countedSubclass2 );
408
409   DALI_TEST_EQUALS( operator==( counted1, countedSubclass1 ), false, TEST_LOCATION );
410   DALI_TEST_EQUALS( operator==( counted2, countedSubclass2 ), true, TEST_LOCATION );
411   END_TEST;
412 }
413
414 /** Inequality of two different types*/
415 int UtcDaliIntrusivePtrOperatorNotEqualTU(void)
416 {
417   tet_infoline( "Test for Dali::IntrusivePtr::operator !=(T, U)" );
418
419   IntrusivePtr<Counted> counted1( new Counted );
420   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
421   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
422   IntrusivePtr<Counted> counted2( countedSubclass2 );
423
424   DALI_TEST_EQUALS( operator!=( counted1, countedSubclass1 ), true, TEST_LOCATION );
425   DALI_TEST_EQUALS( operator!=( counted2, countedSubclass2 ), false, TEST_LOCATION );
426   END_TEST;
427 }
428
429 /** Equality of two different types where right hand side is a raw pointer */
430 int UtcDaliIntrusivePtrOperatorEqualRightPointerTU(void)
431 {
432   tet_infoline( "Test for Dali::IntrusivePtr::operator ==(T, U*)" );
433
434   IntrusivePtr<Counted> counted1( new Counted );
435   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
436   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
437   IntrusivePtr<Counted> counted2( countedSubclass2 );
438
439   DALI_TEST_EQUALS( operator==( counted1, countedSubclass1.Get() ), false, TEST_LOCATION );
440   DALI_TEST_EQUALS( operator==( counted2, countedSubclass2.Get() ), true, TEST_LOCATION );
441   END_TEST;
442 }
443
444 /** Inequality of two different types where the right hand side is a raw pointer */
445 int UtcDaliIntrusivePtrOperatorNotEqualRightPointerTU(void)
446 {
447   tet_infoline( "Test for Dali::IntrusivePtr::operator !=(T, U*)" );
448
449   IntrusivePtr<Counted> counted1( new Counted );
450   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
451   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
452   IntrusivePtr<Counted> counted2( countedSubclass2 );
453
454   DALI_TEST_EQUALS( operator!=( counted1, countedSubclass1.Get() ), true, TEST_LOCATION );
455   DALI_TEST_EQUALS( operator!=( counted2, countedSubclass2.Get() ), false, TEST_LOCATION );
456   END_TEST;
457 }
458
459 /** Equality of two different types where left hand side is a raw pointer */
460 int UtcDaliIntrusivePtrOperatorEqualLeftPointerTU(void)
461 {
462   tet_infoline( "Test for Dali::IntrusivePtr::operator ==(T*, U)" );
463
464   IntrusivePtr<Counted> counted1( new Counted );
465   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
466   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
467   IntrusivePtr<Counted> counted2( countedSubclass2 );
468
469   DALI_TEST_EQUALS( operator==( counted1.Get(), countedSubclass1 ), false, TEST_LOCATION );
470   DALI_TEST_EQUALS( operator==( counted2.Get(), countedSubclass2 ), true, TEST_LOCATION );
471   END_TEST;
472 }
473
474 /** Inequality of two different types where the left hand side is a raw pointer */
475 int UtcDaliIntrusivePtrOperatorNotEqualLeftPointerTU(void)
476 {
477   tet_infoline( "Test for Dali::IntrusivePtr::operator !=(T*, U)" );
478
479   IntrusivePtr<Counted> counted1( new Counted );
480   IntrusivePtr<CountedSubclass> countedSubclass1( new CountedSubclass );
481   IntrusivePtr<CountedSubclass> countedSubclass2( new CountedSubclass );
482   IntrusivePtr<Counted> counted2( countedSubclass2 );
483
484   DALI_TEST_EQUALS( operator!=( counted1.Get(), countedSubclass1 ), true, TEST_LOCATION );
485   DALI_TEST_EQUALS( operator!=( counted2.Get(), countedSubclass2 ), false, TEST_LOCATION );
486   END_TEST;
487 }
488
489 int UtcDaliRefObjectCopyConstructor(void)
490 {
491   tet_infoline("Test for Dali::RefObject(const RefObject&)");
492
493   {
494     IntrusivePtr<TestObject> testPtr( new TestObject );
495     DALI_TEST_EQUALS( testPtr->ReferenceCount(), 1, TEST_LOCATION );
496
497     const TestObject& testObject=*testPtr.Get();
498     {
499       IntrusivePtr<TestObject> testPtr2( new TestObject(testObject) );
500       DALI_TEST_EQUALS( testPtr2->ReferenceCount(), 1, TEST_LOCATION );
501     }
502     DALI_TEST_EQUALS( testPtr->ReferenceCount(), 1, TEST_LOCATION );
503   }
504   END_TEST;
505 }
506
507
508 int UtcDaliRefObjectAssignmentOperator(void)
509 {
510   tet_infoline("Test for Dali::RefObject::operator=(const RefObject&)");
511
512   {
513     IntrusivePtr<TestObject> testPtr( new TestObject );
514     DALI_TEST_EQUALS( testPtr->ReferenceCount(), 1, TEST_LOCATION );
515
516     const TestObject& testObject=*testPtr.Get();
517     {
518       IntrusivePtr<TestObject> testPtr2( new TestObject() );
519       testPtr->data = 33;
520       IntrusivePtr<TestObject> testPtr3 = testPtr2;
521       DALI_TEST_EQUALS( testPtr2->ReferenceCount(), 2, TEST_LOCATION );
522       DALI_TEST_EQUALS( testPtr2->data, 201, TEST_LOCATION );
523
524       TestObject& testObject2 = *testPtr2.Get();
525       testObject2 = testObject;
526
527       DALI_TEST_EQUALS( testPtr->ReferenceCount(), 1, TEST_LOCATION );
528       DALI_TEST_EQUALS( testPtr2->ReferenceCount(), 2, TEST_LOCATION );
529     }
530     DALI_TEST_EQUALS( testPtr->ReferenceCount(), 1, TEST_LOCATION );
531   }
532   END_TEST;
533 }