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