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);
102 std::ostream& operator<<(std::ostream& ostream, BaseHandle handle);
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
110 template<typename Type>
111 inline void DALI_TEST_EQUALS(Type value1, Type value2, const char* location)
113 if(!CompareType<Type>(value1, value2, 0.01f))
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);
123 tet_result(TET_PASS);
128 * Test whether two values are equal.
129 * @param[in] value1 The first value
130 * @param[in] value2 The second value
132 #define DALI_TEST_EQUAL(v1, v2) DALI_TEST_EQUALS(v1, v2, __FILELINE__)
134 template<typename Type>
135 inline void DALI_TEST_EQUALS(Type value1, Type value2, float epsilon, const char* location)
137 if(!CompareType<Type>(value1, value2, epsilon))
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);
147 tet_result(TET_PASS);
151 template<typename Type>
152 inline void DALI_TEST_NOT_EQUALS(Type value1, Type value2, float epsilon, const char* location)
154 if(CompareType<Type>(value1, value2, epsilon))
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);
164 tet_result(TET_PASS);
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
176 inline void DALI_TEST_EQUALS<TimePeriod>(TimePeriod value1, TimePeriod value2, float epsilon, const char* location)
178 if((fabs(value1.durationSeconds - value2.durationSeconds) > epsilon))
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);
184 else if((fabs(value1.delaySeconds - value2.delaySeconds) > epsilon))
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);
192 tet_result(TET_PASS);
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
202 void DALI_TEST_EQUALS(const BaseHandle& baseHandle1, const BaseHandle& baseHandle2, const char* location);
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
210 void DALI_TEST_EQUALS(const size_t value1, const uint32_t value2, const char* location);
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
218 void DALI_TEST_EQUALS(const uint32_t value1, const size_t value2, const char* location);
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
226 void DALI_TEST_EQUALS(const Matrix3& matrix1, const Matrix3& matrix2, const char* location);
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
234 void DALI_TEST_EQUALS(const Matrix3& matrix1, const Matrix3& matrix2, float epsilon, const char* location);
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
242 void DALI_TEST_EQUALS(const Matrix& matrix1, const Matrix& matrix2, const char* location);
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
250 void DALI_TEST_EQUALS(const Matrix& matrix1, const Matrix& matrix2, float epsilon, const char* location);
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
259 inline void DALI_TEST_EQUALS<const char*>(const char* str1, const char* str2, const char* location)
261 if(strcmp(str1, str2))
263 fprintf(stderr, "Test failed in %s, checking '%s' == '%s'\n", location, str1, str2);
264 tet_result(TET_FAIL);
269 tet_result(TET_PASS);
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
280 inline void DALI_TEST_EQUALS<const std::string&>(const std::string& str1, const std::string& str2, const char* location)
282 DALI_TEST_EQUALS(str1.c_str(), str2.c_str(), location);
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
291 void DALI_TEST_EQUALS(Property::Value& str1, const char* str2, const char* location);
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
299 void DALI_TEST_EQUALS(const std::string& str1, const char* str2, const char* location);
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
307 void DALI_TEST_EQUALS(const char* str1, const std::string& str2, const char* location);
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
316 inline void DALI_TEST_EQUALS<const std::string_view>(std::string_view str1, std::string_view str2, const char* location)
318 DALI_TEST_EQUALS(str1.data(), str2.data(), location);
321 inline void DALI_TEST_EQUALS(std::string_view str1, const char* str2, const char* location)
323 DALI_TEST_EQUALS(str1.data(), str2, location);
326 inline void DALI_TEST_EQUALS(std::string_view str1, const std::string& str2, const char* location)
328 DALI_TEST_EQUALS(str1.data(), str2.c_str(), location);
331 inline void DALI_TEST_EQUALS(const std::string& str2, std::string_view str1, const char* location)
333 DALI_TEST_EQUALS(str2.c_str(), str1.data(), location);
336 inline void DALI_TEST_EQUALS(const char* str1, std::string_view str2, const char* location)
338 DALI_TEST_EQUALS(str1, str2.data(), location);
342 * Test if a property value type is equal to a trivial type.
344 template<typename Type>
345 inline void DALI_TEST_VALUE_EQUALS(Property::Value&& value1, Type value2, float epsilon, const char* location)
347 Property::Value value2b(value2);
348 DALI_TEST_EQUALS(value1, value2b, epsilon, location);
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
359 void DALI_TEST_GREATER(T value1, T value2, const char* location)
361 if(!(value1 > value2))
363 std::cerr << "Test failed in " << location << ", checking " << value1 << " > " << value2 << "\n";
364 tet_result(TET_FAIL);
369 tet_result(TET_PASS);
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.
381 void DALI_TEST_ASSERT(DaliException& e, std::string conditionSubString, const char* location);
385 * @param[in] e The exception that we expect was fired by a runtime assertion failure.
387 inline void DALI_TEST_PRINT_ASSERT(DaliException& e)
389 tet_printf("Assertion %s failed at %s\n", e.condition, e.location);
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
399 #define DALI_TEST_ASSERTION(expressions, assertstring) \
402 TestApplication::EnableLogging(false); \
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); \
409 catch(Dali::DaliException & e) \
411 DALI_TEST_ASSERT(e, assertstring, TEST_LOCATION); \
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
421 #define DALI_TEST_THROWS(expressions, except) \
424 TestApplication::EnableLogging(false); \
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); \
433 tet_result(TET_PASS); \
437 fprintf(stderr, "Test failed in %s, unexpected exception\n", __FILELINE__); \
438 tet_result(TET_FAIL); \
442 // Functor to test whether an Applied signal is emitted
443 struct ConstraintAppliedCheck
445 ConstraintAppliedCheck(bool& signalReceived);
446 void operator()(Constraint& constraint);
448 void CheckSignalReceived();
449 void CheckSignalNotReceived();
450 bool& mSignalReceived; // owned by individual tests
454 * A Helper to test default functions
457 struct DefaultFunctionCoverage
459 DefaultFunctionCoverage()
469 // Test namespace to prevent pollution of Dali namespace, add Test helper functions here
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
481 class ObjectDestructionTracker : public ConnectionTracker
485 * @brief Call in main part of code
486 * @param[in] objectRegistry The object Registry being used
488 ObjectDestructionTracker(ObjectRegistry objectRegistry);
491 * @brief Call in sub bock of code where the Actor being checked is still alive.
493 * @param[in] actor Actor to be checked for destruction
495 void Start(Actor actor);
498 * @brief Call to check if Actor alive or destroyed.
500 * @return bool true if Actor was destroyed
505 ObjectRegistry mObjectRegistry;
506 bool mRefObjectDestroyed;
511 #endif // DALI_TEST_SUITE_UTILS_H