1 #ifndef DALI_TEST_SUITE_UTILS_H
2 #define DALI_TEST_SUITE_UTILS_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <dali/public-api/dali-core.h>
30 #include <test-compare-types.h>
34 void tet_infoline(const char* str);
35 void tet_printf(const char* format, ...);
38 #include "test-actor-utils.h"
39 #include "test-application.h"
40 #include "test-gesture-generator.h"
44 #define STRINGIZE_I(text) #text
45 #define STRINGIZE(text) STRINGIZE_I(text)
48 * Inspired by https://stackoverflow.com/questions/1706346/file-macro-manipulation-handling-at-compile-time
49 * answer by Chetan Reddy
51 constexpr int32_t basenameIndex(const char* const path, const int32_t index = 0, const int32_t slashIndex = -1)
55 ? basenameIndex(path, index + 1, index)
56 : basenameIndex(path, index + 1, slashIndex))
60 #define __FILELINE__ ({ static const int32_t basenameIdx = basenameIndex( __FILE__ ); \
61 static_assert (basenameIdx >= 0, "compile-time basename" ); \
62 __FILE__ ":" STRINGIZE(__LINE__) + basenameIdx ; })
64 #define TEST_LOCATION __FILELINE__
65 #define TEST_INNER_LOCATION(x) (std::string(x) + " (" + STRINGIZE(__LINE__) + ")").c_str()
71 extern int32_t test_return_value;
73 void tet_result(int32_t value);
76 return ((test_return_value > 0) ? 1 : 0)
78 void tet_infoline(const char* str);
79 void tet_printf(const char* format, ...);
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
86 #define DALI_TEST_CHECK(condition) \
89 tet_result(TET_PASS); \
93 fprintf(stderr, "Test failed in %s, condition: %s\n", __FILELINE__, #condition); \
94 tet_result(TET_FAIL); \
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);
104 * Test whether two values are equal.
105 * @param[in] value1 The first value
106 * @param[in] value2 The second value
107 * @param[in] location The TEST_LOCATION macro should be used here
109 template<typename Type>
110 inline void DALI_TEST_EQUALS(Type value1, Type value2, const char* location)
112 if(!CompareType<Type>(value1, value2, 0.01f))
114 std::ostringstream o;
115 o << value1 << " == " << value2 << std::endl;
116 fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
117 tet_result(TET_FAIL);
122 tet_result(TET_PASS);
127 * Test whether two values are equal.
128 * @param[in] value1 The first value
129 * @param[in] value2 The second value
131 #define DALI_TEST_EQUAL(v1, v2) DALI_TEST_EQUALS(v1, v2, __FILELINE__)
133 template<typename Type>
134 inline void DALI_TEST_EQUALS(Type value1, Type value2, float epsilon, const char* location)
136 if(!CompareType<Type>(value1, value2, epsilon))
138 std::ostringstream o;
139 o << value1 << " == " << value2 << std::endl;
140 fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
141 tet_result(TET_FAIL);
146 tet_result(TET_PASS);
150 template<typename Type>
151 inline void DALI_TEST_NOT_EQUALS(Type value1, Type value2, float epsilon, const char* location)
153 if(CompareType<Type>(value1, value2, epsilon))
155 std::ostringstream o;
156 o << value1 << " != " << value2 << std::endl;
157 fprintf(stderr, "Test failed in %s, checking %s", location, o.str().c_str());
158 tet_result(TET_FAIL);
163 tet_result(TET_PASS);
168 * Test whether two TimePeriods are within a certain distance of each other.
169 * @param[in] value1 The first value
170 * @param[in] value2 The second value
171 * @param[in] epsilon The values must be within this distance of each other
172 * @param[in] location The TEST_LOCATION macro should be used here
175 inline void DALI_TEST_EQUALS<TimePeriod>(TimePeriod value1, TimePeriod value2, float epsilon, const char* location)
177 if((fabs(value1.durationSeconds - value2.durationSeconds) > epsilon))
179 fprintf(stderr, "Test failed in %s, checking durations %f == %f, epsilon %f\n", location, value1.durationSeconds, value2.durationSeconds, epsilon);
180 tet_result(TET_FAIL);
183 else if((fabs(value1.delaySeconds - value2.delaySeconds) > epsilon))
185 fprintf(stderr, "Test failed in %s, checking delays %f == %f, epsilon %f\n", location, value1.delaySeconds, value2.delaySeconds, epsilon);
186 tet_result(TET_FAIL);
191 tet_result(TET_PASS);
196 * Test whether two base handles are equal.
197 * @param[in] baseHandle1 The first value
198 * @param[in] baseHandle2 The second value
199 * @param[in] location The TEST_LOCATION macro should be used here
201 void DALI_TEST_EQUALS(const BaseHandle& baseHandle1, const BaseHandle& baseHandle2, const char* location);
204 * Test whether a size_t value and an uint32_t are equal.
205 * @param[in] value1 The first value
206 * @param[in] value2 The second value
207 * @param[in] location The TEST_LOCATION macro should be used here
209 void DALI_TEST_EQUALS(const size_t value1, const uint32_t value2, const char* location);
212 * Test whether an uint32_t and a size_t value and are equal.
213 * @param[in] value1 The first value
214 * @param[in] value2 The second value
215 * @param[in] location The TEST_LOCATION macro should be used here
217 void DALI_TEST_EQUALS(const uint32_t value1, const size_t value2, const char* location);
220 * Test whether two Matrix3 objects are equal.
221 * @param[in] matrix1 The first object
222 * @param[in] matrix2 The second object
223 * @param[in] location The TEST_LOCATION macro should be used here
225 void DALI_TEST_EQUALS(const Matrix3& matrix1, const Matrix3& matrix2, const char* location);
227 /** Test whether two Matrix3 objects are equal (fuzzy compare).
228 * @param[in] matrix1 The first object
229 * @param[in] matrix2 The second object
230 * @param[in] epsilon The epsilon to use for comparison
231 * @param[in] location The TEST_LOCATION macro should be used here
233 void DALI_TEST_EQUALS(const Matrix3& matrix1, const Matrix3& matrix2, float epsilon, const char* location);
236 * Test whether two Matrix objects are equal.
237 * @param[in] matrix1 The first object
238 * @param[in] matrix2 The second object
239 * @param[in] location The TEST_LOCATION macro should be used here
241 void DALI_TEST_EQUALS(const Matrix& matrix1, const Matrix& matrix2, const char* location);
244 * Test whether two Matrix objects are equal (fuzzy-compare).
245 * @param[in] matrix1 The first object
246 * @param[in] matrix2 The second object
247 * @param[in] location The TEST_LOCATION macro should be used here
249 void DALI_TEST_EQUALS(const Matrix& matrix1, const Matrix& matrix2, float epsilon, const char* location);
252 * Test whether two strings are equal.
253 * @param[in] str1 The first string
254 * @param[in] str2 The second string
255 * @param[in] location The TEST_LOCATION macro should be used here
258 inline void DALI_TEST_EQUALS<const char*>(const char* str1, const char* str2, const char* location)
260 if(strcmp(str1, str2))
262 fprintf(stderr, "Test failed in %s, checking '%s' == '%s'\n", location, str1, str2);
263 tet_result(TET_FAIL);
268 tet_result(TET_PASS);
273 * Test whether two strings are equal.
274 * @param[in] str1 The first string
275 * @param[in] str2 The second string
276 * @param[in] location The TEST_LOCATION macro should be used here
279 inline void DALI_TEST_EQUALS<const std::string&>(const std::string& str1, const std::string& str2, const char* location)
281 DALI_TEST_EQUALS(str1.c_str(), str2.c_str(), location);
285 * Test whether two strings are equal.
286 * @param[in] str1 The first string
287 * @param[in] str2 The second string
288 * @param[in] location The TEST_LOCATION macro should be used here
290 void DALI_TEST_EQUALS(Property::Value& str1, const char* str2, const char* location);
293 * Test whether two strings are equal.
294 * @param[in] str1 The first string
295 * @param[in] str2 The second string
296 * @param[in] location The TEST_LOCATION macro should be used here
298 void DALI_TEST_EQUALS(const std::string& str1, const char* str2, const char* location);
301 * Test whether two strings are equal.
302 * @param[in] str1 The first string
303 * @param[in] str2 The second string
304 * @param[in] location The TEST_LOCATION macro should be used here
306 void DALI_TEST_EQUALS(const char* str1, const std::string& str2, const char* location);
309 * Test whether two strings are equal.
310 * @param[in] str1 The first string
311 * @param[in] str2 The second string
312 * @param[in] location The TEST_LOCATION macro should be used here
315 inline void DALI_TEST_EQUALS<const std::string_view>(std::string_view str1, std::string_view str2, const char* location)
317 DALI_TEST_EQUALS(str1.data(), str2.data(), location);
320 inline void DALI_TEST_EQUALS(std::string_view str1, const char* str2, const char* location)
322 DALI_TEST_EQUALS(str1.data(), str2, location);
325 inline void DALI_TEST_EQUALS(std::string_view str1, const std::string& str2, const char* location)
327 DALI_TEST_EQUALS(str1.data(), str2.c_str(), location);
330 inline void DALI_TEST_EQUALS(const std::string& str2, std::string_view str1, const char* location)
332 DALI_TEST_EQUALS(str2.c_str(), str1.data(), location);
335 inline void DALI_TEST_EQUALS(const char* str1, std::string_view str2, const char* location)
337 DALI_TEST_EQUALS(str1, str2.data(), location);
341 * Test if a property value type is equal to a trivial type.
343 template<typename Type>
344 inline void DALI_TEST_VALUE_EQUALS(Property::Value&& value1, Type value2, float epsilon, const char* location)
346 Property::Value value2b(value2);
347 DALI_TEST_EQUALS(value1, value2b, epsilon, location);
351 * Test whether one unsigned integer value is greater than another.
352 * Test succeeds if value1 > value2
353 * @param[in] value1 The first value
354 * @param[in] value2 The second value
355 * @param[in] location The TEST_LOCATION macro should be used here
358 void DALI_TEST_GREATER(T value1, T value2, const char* location)
360 if(!(value1 > value2))
362 std::cerr << "Test failed in " << location << ", checking " << value1 << " > " << value2 << "\n";
363 tet_result(TET_FAIL);
368 tet_result(TET_PASS);
373 * Test whether the assertion condition that failed and thus triggered the
374 * exception \b e contained a given substring.
375 * @param[in] e The exception that we expect was fired by a runtime assertion failure.
376 * @param[in] conditionSubString The text that we expect to be present in an
377 * assertion which triggered the exception.
378 * @param[in] location The TEST_LOCATION macro should be used here.
380 void DALI_TEST_ASSERT(DaliException& e, std::string conditionSubString, const char* location);
384 * @param[in] e The exception that we expect was fired by a runtime assertion failure.
386 inline void DALI_TEST_PRINT_ASSERT(DaliException& e)
388 tet_printf("Assertion %s failed at %s\n", e.condition, e.location);
392 * Test that given piece of code triggers the right assertion
393 * Fails the test if the assert didn't occur.
394 * Turns off logging during the execution of the code to avoid excessive false positive log output from the assertions
395 * @param expressions code to execute
396 * @param assertstring the substring expected in the assert
398 #define DALI_TEST_ASSERTION(expressions, assertstring) \
401 TestApplication::EnableLogging(false); \
403 TestApplication::EnableLogging(true); \
404 fprintf(stderr, "Test failed in %s, expected assert: '%s' didn't occur\n", __FILELINE__, assertstring); \
405 tet_result(TET_FAIL); \
408 catch(Dali::DaliException & e) \
410 DALI_TEST_ASSERT(e, assertstring, TEST_LOCATION); \
414 * Test that given piece of code triggers an exception
415 * Fails the test if the exception didn't occur.
416 * Turns off logging during the execution of the code to avoid excessive false positive log output from the assertions
417 * @param expressions code to execute
418 * @param except the exception expected in the assert
420 #define DALI_TEST_THROWS(expressions, except) \
423 TestApplication::EnableLogging(false); \
425 TestApplication::EnableLogging(true); \
426 fprintf(stderr, "Test failed in %s, expected exception: '%s' didn't occur\n", __FILELINE__, #except); \
427 tet_result(TET_FAIL); \
432 tet_result(TET_PASS); \
436 fprintf(stderr, "Test failed in %s, unexpected exception\n", __FILELINE__); \
437 tet_result(TET_FAIL); \
441 // Functor to test whether an Applied signal is emitted
442 struct ConstraintAppliedCheck
444 ConstraintAppliedCheck(bool& signalReceived);
445 void operator()(Constraint& constraint);
447 void CheckSignalReceived();
448 void CheckSignalNotReceived();
449 bool& mSignalReceived; // owned by individual tests
453 * A Helper to test default functions
456 struct DefaultFunctionCoverage
458 DefaultFunctionCoverage()
468 // Test namespace to prevent pollution of Dali namespace, add Test helper functions here
474 * Helper to check object destruction occurred
475 * 1) In main part of code create an ObjectDestructionTracker
476 * 2) Within sub section of main create object Actor test and call Start with Actor to test for destruction
477 * 3) Perform code which is expected to destroy Actor
478 * 4) Back in main part of code use IsDestroyed() to test if Actor was destroyed
480 class ObjectDestructionTracker : public ConnectionTracker
484 * @brief Call in main part of code
485 * @param[in] objectRegistry The object Registry being used
487 ObjectDestructionTracker(ObjectRegistry objectRegistry);
490 * @brief Call in sub bock of code where the Actor being checked is still alive.
492 * @param[in] actor Actor to be checked for destruction
494 void Start(Actor actor);
497 * @brief Call to check if Actor alive or destroyed.
499 * @return bool true if Actor was destroyed
504 ObjectRegistry mObjectRegistry;
505 bool mRefObjectDestroyed;
510 #endif // DALI_TEST_SUITE_UTILS_H