diff --git a/tests/QTestExtensions.hpp b/tests/QTestExtensions.hpp index 1bb0dfe111..2ff213906d 100644 --- a/tests/QTestExtensions.hpp +++ b/tests/QTestExtensions.hpp @@ -17,18 +17,19 @@ #include // Adds some additional functionality to QtTest (eg. explicitely defined fuzzy comparison -// of float and custom data types), and some extension mechanisms to provide other new -// functionality as needed. +// of float and custom data types), and some extension mechanisms to provide other +// test functionality as needed. - -// Generic function that reimplements the debugging output of a QCOMPARE failure via QFAIL. -// Use this to implement your own QCOMPARE-ish macros (see QEXPLICIT_FUZZY_COMPARE for -// more info). -template -void QTest_failWithMessage (const T & actual, const T & expected, const char * actual_expr, const char * expected_expr, int line, const char * file) -{ - -} +// QFUZZY_COMPARE (actual_expr, expected_expr, epsilon / error tolerance): +// Requires that you have two functions defined: +// +// V fuzzyCompare (const T & a, const T & b) +// QTextStream & operator << (const T & v) +// +// fuzzyCompare should take a data type, T, and return the difference between two +// such values / objects in terms of a second type, V (which should match the error +// value type). For glm::vec3, T = glm::vec3, V = float, for example +// // Generic function that reimplements the debugging output of a QCOMPARE failure via QFAIL. // Use this to implement your own QCOMPARE-ish macros (see QEXPLICIT_FUZZY_COMPARE for @@ -61,19 +62,42 @@ inline QString QTest_generateCompareFailureMessage (const char * failMessage, co int pad1_ = qMax(s2.length() - s1.length(), 0); int pad2_ = qMax(s1.length() - s2.length(), 0); - QString pad1 = QString(")").rightJustified(pad1_, ' '); - QString pad2 = QString(")").rightJustified(pad2_, ' '); + QString pad1 = QString("): ").rightJustified(pad1_, ' '); + QString pad2 = QString("): ").rightJustified(pad2_, ' '); QString msg; QTextStream stream (&msg); stream << failMessage << "\n\t" - "Actual: (" << actual_expr << pad1 << ": " << actual << "\n\t" - "Expected: (" << expected_expr << pad2 << ": " << expected; + "Actual: (" << actual_expr << pad1 << actual << "\n\t" + "Expected: (" << expected_expr << pad2 << expected; return msg; } +// Generates a QCOMPARE style failure message with custom arguments. +// This is expected to be wrapped in a macro (see QFUZZY_COMPARE), and it must +// actually return on failure (unless other functionality is desired). +template +inline void QTest_failWithMessage(const char * failMessage, const T & actual, const T & expected, const char * actualExpr, const char * expectedExpr, int line, const char * file) +{ + QTest::qFail(qPrintable(QTest_generateCompareFailureMessage(failMessage, actual, expected, actualExpr, expectedExpr)), file, line); +} + +// Generates a QCOMPARE style failure message with custom arguments. +// Writing additional lines (eg:) +// Actual (): +// Expected (): +// +// Loc: [()] +// is provided via a lamdbda / closure that can write to the textstream. +// Be aware that newlines are actually "\n\t" (with this impl), so use that to get +// proper indenting (and add extra '\t's to get additional indentation). +template +inline void QTest_failWithMessage(const char * failMessage, const T & actual, const T & expected, const char * actualExpr, const char * expectedExpr, int line, const char * file, std::function writeAdditionalMessageLines) { + QTest::qFail(qPrintable(QTest_generateCompareFailureMessage(failMessage, actual, expected, actualExpr, expectedExpr, writeAdditionalMessageLines)), file, line); +} + template -inline bool QTest_fuzzyCompare(const T & actual, const T & expected, const char * actual_expr, const char * expected_expr, int line, const char * file, const V & epsilon) +inline auto QTest_fuzzyCompare(const T & actual, const T & expected, const char * actual_expr, const char * expected_expr, int line, const char * file, const V & epsilon) -> decltype(fuzzyCompare(actual, expected)) { if (fuzzyCompare(actual, expected) > epsilon) { QTest::qFail(qPrintable(QTest_generateCompareFailureMessage("Compared values are not the same (fuzzy compare)", actual, expected, actual_expr, expected_expr, @@ -91,18 +115,4 @@ do { \ return; \ } while(0) -// Note: this generates a message that looks something like the following: -// FAIL! : BulletUtilTests::fooTest() Compared values are not the same (fuzzy compare) -// Actual (foo * 3): glm::vec3 { 1, 0, 3 } -// Expected (bar + baz): glm::vec3 { 2, 0, 5 } -// Error Tolerance: 2.23607 > 1 -// Loc: [/Users/semery/hifi/tests/physics/src/BulletUtilTests.cpp(68)] -// -// The last line (and the FAIL! message up to "Compared values...") are generated automatically by -// QFAIL. It is possible to generate these manually via __FILE__ and __LINE__, but QFAIL does this -// already so there's no point in reimplementing it. However, since we are using QFAIL to generate -// our line number for us, it's important that it's actually invoked on the same line as the thing -// that calls it -- hence the elaborate macro(s) above (since the result is *technically* one line) -// - #endif diff --git a/tests/physics/src/BulletUtilTests.cpp b/tests/physics/src/BulletUtilTests.cpp index 4d92d6f7b7..e31618255d 100644 --- a/tests/physics/src/BulletUtilTests.cpp +++ b/tests/physics/src/BulletUtilTests.cpp @@ -11,12 +11,18 @@ #include -#include "PhysicsTestUtil.h" +//#include "PhysicsTestUtil.h" #include #include #include "BulletUtilTests.h" +// Constants +const glm::vec3 origin(0.0f); +const glm::vec3 xAxis(1.0f, 0.0f, 0.0f); +const glm::vec3 yAxis(0.0f, 1.0f, 0.0f); +const glm::vec3 zAxis(0.0f, 0.0f, 1.0f); + QTEST_MAIN(BulletUtilTests) diff --git a/tests/physics/src/BulletUtilTests.h b/tests/physics/src/BulletUtilTests.h index df61de8216..804b91bb8a 100644 --- a/tests/physics/src/BulletUtilTests.h +++ b/tests/physics/src/BulletUtilTests.h @@ -13,6 +13,8 @@ #define hifi_BulletUtilTests_h #include +#include +#include class BulletUtilTests : public QObject { Q_OBJECT @@ -23,4 +25,16 @@ private slots: void fooTest (); }; +// Define comparison + printing functions for the data types we need + +inline float fuzzyCompare (const glm::vec3 & a, const glm::vec3 & b) { + return glm::distance(a, b); +} +inline QTextStream & operator << (QTextStream & stream, const glm::vec3 & v) { + return stream << "glm::vec3 { " << v.x << ", " << v.y << ", " << v.z << " }"; +} + +// These hook into this (and must be defined first...) +#include "../QTestExtensions.hpp" + #endif // hifi_BulletUtilTests_h diff --git a/tests/physics/src/CollisionInfoTests.h b/tests/physics/src/CollisionInfoTests.h index 10c27fd551..a53386e726 100644 --- a/tests/physics/src/CollisionInfoTests.h +++ b/tests/physics/src/CollisionInfoTests.h @@ -12,6 +12,8 @@ #ifndef hifi_CollisionInfoTests_h #define hifi_CollisionInfoTests_h +#include +#include #include class CollisionInfoTests : public QObject { @@ -22,4 +24,16 @@ private slots: // void translateThenRotate(); }; + +// Define comparison + printing functions for the data types we need +inline float fuzzyCompare (const glm::vec3 & a, const glm::vec3 & b) { + return glm::distance(a, b); +} +inline QTextStream & operator << (QTextStream & stream, const glm::vec3 & v) { + return stream << "glm::vec3 { " << v.x << ", " << v.y << ", " << v.z << " }"; +} + +// These hook into this (and must be defined first...) +#include "../QTestExtensions.hpp" + #endif // hifi_CollisionInfoTests_h diff --git a/tests/physics/src/MeshMassPropertiesTests.cpp b/tests/physics/src/MeshMassPropertiesTests.cpp index 69c7330e09..d4d1a6768b 100644 --- a/tests/physics/src/MeshMassPropertiesTests.cpp +++ b/tests/physics/src/MeshMassPropertiesTests.cpp @@ -9,7 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "PhysicsTestUtil.h" #include #include #include @@ -74,22 +73,28 @@ void MeshMassPropertiesTests::testParallelAxisTheorem() { btMatrix3x3 twoSmallBoxesInertia = smallBoxShiftedRight + smallBoxShiftedLeft; // verify bigBox same as twoSmallBoxes - btScalar error; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - QFUZZY_COMPARE(bitBoxInertia[i][j], twoSmallBoxesInertia[i][j], acceptableAbsoluteError); -// error = bitBoxInertia[i][j] - twoSmallBoxesInertia[i][j]; -// if (fabsf(error) > acceptableAbsoluteError) { -// std::cout << __FILE__ << ":" << __LINE__ << " ERROR : box inertia[" << i << "][" << j << "] off by = " -// << error << std::endl; -// } - } - } - -#ifdef VERBOSE_UNIT_TESTS - printMatrix("expected inertia", bitBoxInertia); - printMatrix("computed inertia", twoSmallBoxesInertia); -#endif // VERBOSE_UNIT_TESTS +// btScalar error; +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 3; ++j) { +// QFUZZY_COMPARE(bitBoxInertia[i][j], twoSmallBoxesInertia[i][j], acceptableAbsoluteError); +//// error = bitBoxInertia[i][j] - twoSmallBoxesInertia[i][j]; +//// if (fabsf(error) > acceptableAbsoluteError) { +//// std::cout << __FILE__ << ":" << __LINE__ << " ERROR : box inertia[" << i << "][" << j << "] off by = " +//// << error << std::endl; +//// } +// } +// } + + // Try commenting this out to see what happens when the test fails + twoSmallBoxesInertia[0][2] += 10; + + // This now does the same as the above (using the maxDiff fuzzyCompare impl for two btMatrices) + QFUZZY_COMPARE(bitBoxInertia, twoSmallBoxesInertia, acceptableAbsoluteError); + +//#ifdef VERBOSE_UNIT_TESTS +// printMatrix("expected inertia", bitBoxInertia); +// printMatrix("computed inertia", twoSmallBoxesInertia); +//#endif // VERBOSE_UNIT_TESTS //#endif // EXPOSE_HELPER_FUNCTIONS_FOR_UNIT_TEST } diff --git a/tests/physics/src/MeshMassPropertiesTests.h b/tests/physics/src/MeshMassPropertiesTests.h index ce56d3f8c7..6d0b2bae4b 100644 --- a/tests/physics/src/MeshMassPropertiesTests.h +++ b/tests/physics/src/MeshMassPropertiesTests.h @@ -12,7 +12,12 @@ #ifndef hifi_MeshMassPropertiesTests_h #define hifi_MeshMassPropertiesTests_h +#include +#include +#include + #include +#include class MeshMassPropertiesTests : public QObject { Q_OBJECT @@ -23,6 +28,51 @@ private slots: void testOpenTetrahedonMesh(); void testClosedTetrahedronMesh(); void testBoxAsMesh(); -// void runAllTests(); }; + +// Define comparison + printing functions for the data types we need + +inline float fuzzyCompare (const glm::vec3 & a, const glm::vec3 & b) { + return glm::distance(a, b); +} +inline QTextStream & operator << (QTextStream & stream, const glm::vec3 & v) { + return stream << "glm::vec3 { " << v.x << ", " << v.y << ", " << v.z << " }"; +} +inline btScalar fuzzyCompare (const btScalar & a, const btScalar & b) { + return fabs(a - b); +} +// uh... how do we compare matrices? +// Guess we'll just do this element-wise for the time being +inline btScalar fuzzyCompare (const btMatrix3x3 & a, const btMatrix3x3 & b) { + btScalar totalDiff = 0; + btScalar maxDiff = 0; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + btScalar diff = fabs(a[i][j] - b[i][j]); + totalDiff += diff; + maxDiff = qMax(diff, maxDiff); + } + } +// return totalDiff; + return maxDiff; +} +inline QTextStream & operator << (QTextStream & stream, const btMatrix3x3 & matrix) { + stream << "[\n\t\t"; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + stream << " " << matrix[i][j]; + } + stream << "\n\t\t"; + } + stream << "]\n\t"; // hacky as hell, but this should work... + return stream; +} + + + + +// These hook into this (and must be defined first...) +#include "../QTestExtensions.hpp" + + #endif // hifi_MeshMassPropertiesTests_h