0c5efa35615eb5a91a2735ad2c7a243b29847884
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / dali-test-suite-utils.h
1 #ifndef DALI_TEST_SUITE_UTILS_H
2 #define DALI_TEST_SUITE_UTILS_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdarg>
23 #include <cstdio>
24 #include <iostream>
25 #include <cstring>
26 #include <string>
27
28 // INTERNAL INCLUDES
29 #include <dali/public-api/dali-core.h>
30 #include <test-compare-types.h>
31
32 void tet_infoline(const char*str);
33 void tet_printf(const char *format, ...);
34
35 #include "test-application.h"
36 #include "test-actor-utils.h"
37 #include "test-gesture-generator.h"
38
39 using namespace Dali;
40
41 #define STRINGIZE_I(text) #text
42 #define STRINGIZE(text) STRINGIZE_I(text)
43
44 /**
45  * Inspired by https://stackoverflow.com/questions/1706346/file-macro-manipulation-handling-at-compile-time
46  * answer by Chetan Reddy
47  */
48 constexpr int32_t basenameIndex( const char * const path, const int32_t index = 0, const int32_t slashIndex = -1 )
49 {
50    return path[ index ]
51        ? ( path[ index ] == '/'
52            ? basenameIndex( path, index + 1, index )
53            : basenameIndex( path, index + 1, slashIndex ) )
54        : ( slashIndex + 1 );
55 }
56
57 #define __FILELINE__ ( { static const int32_t basenameIdx = basenameIndex( __FILE__ ); \
58                          static_assert (basenameIdx >= 0, "compile-time basename" );   \
59                          __FILE__ ":" STRINGIZE(__LINE__) + basenameIdx ; } )
60
61 #define TEST_LOCATION __FILELINE__
62 #define TEST_INNER_LOCATION(x) ( std::string(x) + " (" + STRINGIZE(__LINE__) + ")" ).c_str()
63
64 #define TET_UNDEF 2
65 #define TET_FAIL 1
66 #define TET_PASS 0
67
68 extern int32_t test_return_value;
69
70 void tet_result(int32_t value);
71
72 #define END_TEST \
73   return ((test_return_value>0)?1:0)
74
75 void tet_infoline(const char* str);
76 void tet_printf(const char *format, ...);
77
78 /**
79  * DALI_TEST_CHECK is a wrapper for tet_result.
80  * If the condition evaluates to false, the test is stopped.
81  * @param[in] The boolean expression to check
82  */
83 #define DALI_TEST_CHECK(condition)                                                        \
84 if ( (condition) )                                                                        \
85 {                                                                                         \
86   tet_result(TET_PASS);                                                                   \
87 }                                                                                         \
88 else                                                                                      \
89 {                                                                                         \
90   fprintf(stderr, "Test failed in %s, condition: %s\n", __FILELINE__, #condition );       \
91   tet_result(TET_FAIL);                                                                   \
92   throw("TET_FAIL");                                                                      \
93 }
94
95
96 bool operator==(TimePeriod a, TimePeriod b);
97 std::ostream& operator<<( std::ostream& ostream, TimePeriod value );
98 std::ostream& operator<<( std::ostream& ostream, Radian angle );
99 std::ostream& operator<<( std::ostream& ostream, Degree angle );
100
101 /**
102  * Test whether two values are equal.
103  * @param[in] value1 The first value
104  * @param[in] value2 The second value
105  * @param[in] location The TEST_LOCATION macro should be used here
106  */
107 template<typename Type>
108 inline void DALI_TEST_EQUALS(Type value1, Type value2, const char* location)
109 {
110   if( !CompareType<Type>(value1, value2, 0.01f) )
111   {
112     std::ostringstream o;
113     o << value1 << " == " << value2 << std::endl;
114     fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
115     tet_result(TET_FAIL);
116     throw("TET_FAIL");                                                                      \
117   }
118   else
119   {
120     tet_result(TET_PASS);
121   }
122 }
123
124 /**
125  * Test whether two values are equal.
126  * @param[in] value1 The first value
127  * @param[in] value2 The second value
128  */
129 #define DALI_TEST_EQUAL( v1, v2 ) DALI_TEST_EQUALS( v1, v2, __FILELINE__ )
130
131 template<typename Type>
132 inline void DALI_TEST_EQUALS(Type value1, Type value2, float epsilon, const char* location)
133 {
134   if( !CompareType<Type>(value1, value2, epsilon) )
135   {
136     std::ostringstream o;
137     o << value1 << " == " << value2 << std::endl;
138     fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
139     tet_result(TET_FAIL);
140     throw("TET_FAIL");                                                                      \
141   }
142   else
143   {
144     tet_result(TET_PASS);
145   }
146 }
147
148 template<typename Type>
149 inline void DALI_TEST_NOT_EQUALS(Type value1, Type value2, float epsilon, const char* location)
150 {
151   if( CompareType<Type>(value1, value2, epsilon) )
152   {
153     std::ostringstream o;
154     o << value1 << " !=  " << value2 << std::endl;
155     fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
156     tet_result(TET_FAIL);
157     throw("TET_FAIL");                                                                      \
158   }
159   else
160   {
161     tet_result(TET_PASS);
162   }
163 }
164
165
166 /**
167  * Test whether two TimePeriods are within a certain distance of each other.
168  * @param[in] value1 The first value
169  * @param[in] value2 The second value
170  * @param[in] epsilon The values must be within this distance of each other
171  * @param[in] location The TEST_LOCATION macro should be used here
172  */
173 template<>
174 inline void DALI_TEST_EQUALS<TimePeriod>( TimePeriod value1, TimePeriod value2, float epsilon, const char* location)
175 {
176   if ((fabs(value1.durationSeconds - value2.durationSeconds) > epsilon))
177   {
178     fprintf(stderr, "Test failed in %s, checking durations %f == %f, epsilon %f\n", location, value1.durationSeconds, value2.durationSeconds, epsilon);
179     tet_result(TET_FAIL);
180     throw("TET_FAIL");                                                                      \
181   }
182   else if ((fabs(value1.delaySeconds - value2.delaySeconds) > epsilon))
183   {
184     fprintf(stderr, "Test failed in %s, checking delays %f == %f, epsilon %f\n", location, value1.delaySeconds, value2.delaySeconds, epsilon);
185     tet_result(TET_FAIL);
186     throw("TET_FAIL");                                                                      \
187   }
188   else
189   {
190     tet_result(TET_PASS);
191   }
192 }
193
194 /**
195  * Test whether two base handles are equal.
196  * @param[in] baseHandle1 The first value
197  * @param[in] baseHandle2 The second value
198  * @param[in] location The TEST_LOCATION macro should be used here
199  */
200 void DALI_TEST_EQUALS( const BaseHandle& baseHandle1, const BaseHandle& baseHandle2, const char* location );
201
202 /**
203  * Test whether a size_t value and an uint32_t are equal.
204  * @param[in] value1 The first value
205  * @param[in] value2 The second value
206  * @param[in] location The TEST_LOCATION macro should be used here
207  */
208 void DALI_TEST_EQUALS( const size_t value1, const uint32_t value2, const char* location );
209
210 /**
211  * Test whether an uint32_t and a size_t value and are equal.
212  * @param[in] value1 The first value
213  * @param[in] value2 The second value
214  * @param[in] location The TEST_LOCATION macro should be used here
215  */
216 void DALI_TEST_EQUALS( const uint32_t value1, const size_t value2, const char* location );
217
218 /**
219  * Test whether two Matrix3 objects are equal.
220  * @param[in] matrix1 The first object
221  * @param[in] matrix2 The second object
222  * @param[in] location The TEST_LOCATION macro should be used here
223  */
224 void DALI_TEST_EQUALS( const Matrix3& matrix1, const Matrix3& matrix2, const char* location);
225
226 /** Test whether two Matrix3 objects are equal (fuzzy compare).
227  * @param[in] matrix1 The first object
228  * @param[in] matrix2 The second object
229  * @param[in] epsilon The epsilon to use for comparison
230  * @param[in] location The TEST_LOCATION macro should be used here
231  */
232 void DALI_TEST_EQUALS( const Matrix3& matrix1, const Matrix3& matrix2, float epsilon, const char* location);
233
234 /**
235  * Test whether two Matrix objects are equal.
236  * @param[in] matrix1 The first object
237  * @param[in] matrix2 The second object
238  * @param[in] location The TEST_LOCATION macro should be used here
239  */
240 void DALI_TEST_EQUALS( const Matrix& matrix1, const Matrix& matrix2, const char* location);
241
242 /**
243  * Test whether two Matrix objects are equal (fuzzy-compare).
244  * @param[in] matrix1 The first object
245  * @param[in] matrix2 The second object
246  * @param[in] location The TEST_LOCATION macro should be used here
247  */
248 void DALI_TEST_EQUALS( const Matrix& matrix1, const Matrix& matrix2, float epsilon, const char* location);
249
250 /**
251  * Test whether two strings are equal.
252  * @param[in] str1 The first string
253  * @param[in] str2 The second string
254  * @param[in] location The TEST_LOCATION macro should be used here
255  */
256 template<>
257 inline void DALI_TEST_EQUALS<const char*>( const char* str1, const char* str2, const char* location)
258 {
259   if (strcmp(str1, str2))
260   {
261     fprintf(stderr, "Test failed in %s, checking '%s' == '%s'\n", location, str1, str2);
262     tet_result(TET_FAIL);
263     throw("TET_FAIL");                                                                      \
264   }
265   else
266   {
267     tet_result(TET_PASS);
268   }
269 }
270
271 /**
272  * Test whether two strings are equal.
273  * @param[in] str1 The first string
274  * @param[in] str2 The second string
275  * @param[in] location The TEST_LOCATION macro should be used here
276  */
277 template<>
278 inline void DALI_TEST_EQUALS<const std::string&>( const std::string &str1, const std::string &str2, const char* location)
279 {
280   DALI_TEST_EQUALS(str1.c_str(), str2.c_str(), location);
281 }
282
283 /**
284  * Test whether two strings are equal.
285  * @param[in] str1 The first string
286  * @param[in] str2 The second string
287  * @param[in] location The TEST_LOCATION macro should be used here
288  */
289 void DALI_TEST_EQUALS( Property::Value& str1, const char* str2, const char* location);
290
291 /**
292  * Test whether two strings are equal.
293  * @param[in] str1 The first string
294  * @param[in] str2 The second string
295  * @param[in] location The TEST_LOCATION macro should be used here
296  */
297 void DALI_TEST_EQUALS( const std::string &str1, const char* str2, const char* location);
298
299 /**
300  * Test whether two strings are equal.
301  * @param[in] str1 The first string
302  * @param[in] str2 The second string
303  * @param[in] location The TEST_LOCATION macro should be used here
304  */
305 void DALI_TEST_EQUALS( const char* str1, const std::string &str2, const char* location);
306
307 /**
308  * Test whether one unsigned integer value is greater than another.
309  * Test succeeds if value1 > value2
310  * @param[in] value1 The first value
311  * @param[in] value2 The second value
312  * @param[in] location The TEST_LOCATION macro should be used here
313  */
314 template< typename T >
315 void DALI_TEST_GREATER( T value1, T value2, const char* location)
316 {
317   if (!(value1 > value2))
318   {
319     std::cerr << "Test failed in " << location << ", checking " << value1 <<" > " << value2 << "\n";
320     tet_result(TET_FAIL);
321     throw("TET_FAIL");                                                                      \
322   }
323   else
324   {
325     tet_result(TET_PASS);
326   }
327 }
328
329 /**
330  * Test whether the assertion condition that failed and thus triggered the
331  * exception \b e contained a given substring.
332  * @param[in] e The exception that we expect was fired by a runtime assertion failure.
333  * @param[in] conditionSubString The text that we expect to be present in an
334  *                               assertion which triggered the exception.
335  * @param[in] location The TEST_LOCATION macro should be used here.
336  */
337 void DALI_TEST_ASSERT( DaliException& e, std::string conditionSubString, const char* location );
338
339 /**
340  * Print the assert
341  * @param[in] e The exception that we expect was fired by a runtime assertion failure.
342  */
343 inline void DALI_TEST_PRINT_ASSERT( DaliException& e )
344 {
345   tet_printf("Assertion %s failed at %s\n", e.condition, e.location );
346 }
347
348 /**
349  * Test that given piece of code triggers the right assertion
350  * Fails the test if the assert didn't occur.
351  * Turns off logging during the execution of the code to avoid excessive false positive log output from the assertions
352  * @param expressions code to execute
353  * @param assertstring the substring expected in the assert
354  */
355 #define DALI_TEST_ASSERTION( expressions, assertstring ) \
356 try \
357 { \
358   TestApplication::EnableLogging( false ); \
359   expressions; \
360   TestApplication::EnableLogging( true ); \
361   fprintf(stderr, "Test failed in %s, expected assert: '%s' didn't occur\n", __FILELINE__, assertstring ); \
362   tet_result(TET_FAIL); \
363   throw("TET_FAIL"); } \
364 catch( Dali::DaliException& e ) \
365 { \
366   DALI_TEST_ASSERT( e, assertstring, TEST_LOCATION ); \
367 }
368
369 // Functor to test whether an Applied signal is emitted
370 struct ConstraintAppliedCheck
371 {
372   ConstraintAppliedCheck( bool& signalReceived );
373   void operator()( Constraint& constraint );
374   void Reset();
375   void CheckSignalReceived();
376   void CheckSignalNotReceived();
377   bool& mSignalReceived; // owned by individual tests
378 };
379
380 /**
381  * A Helper to test default functions
382  */
383 template <typename T>
384 struct DefaultFunctionCoverage
385 {
386   DefaultFunctionCoverage()
387   {
388     T a;
389     T *b = new T(a);
390     DALI_TEST_CHECK(b);
391     a = *b;
392     delete b;
393   }
394 };
395
396 // Test namespace to prevent pollution of Dali namespace, add Test helper functions here
397 namespace Test
398 {
399 /**
400  *  @brief
401  *
402  *  Helper to check object destruction occurred
403  *  1) In main part of code create an ObjectDestructionTracker
404  *  2) Within sub section of main create object Actor test and call Start with Actor to test for destruction
405  *  3) Perform code which is expected to destroy Actor
406  *  4) Back in main part of code use IsDestroyed() to test if Actor was destroyed
407  */
408 class ObjectDestructionTracker : public ConnectionTracker
409 {
410 public:
411
412   /**
413    * @brief Call in main part of code
414    * @param[in] objectRegistry The object Registry being used
415    */
416   ObjectDestructionTracker( ObjectRegistry objectRegistry );
417
418   /**
419    * @brief Call in sub bock of code where the Actor being checked is still alive.
420    *
421    * @param[in] actor Actor to be checked for destruction
422    */
423   void Start( Actor actor );
424
425   /**
426    * @brief Call to check if Actor alive or destroyed.
427    *
428    * @return bool true if Actor was destroyed
429    */
430   bool IsDestroyed();
431
432 private:
433   ObjectRegistry mObjectRegistry;
434   bool mRefObjectDestroyed;
435 };
436
437 } // namespace Test
438
439 #endif // DALI_TEST_SUITE_UTILS_H