diff --git a/doc/coding-style.dox b/doc/coding-style.dox index 28e892516..8c686005d 100644 --- a/doc/coding-style.dox +++ b/doc/coding-style.dox @@ -185,5 +185,49 @@ requirements. All classes and functions using those commands are cross-referenced in page @ref required-extensions. +@section unit-tests Unit tests + +All unit tests use Corrade's @ref Corrade::TestSuite "TestSuite". + +Don't forget to test all `constexpr` methods -- many compilers don't implicitly +check whether the `constexpr` keyword can be used but then complain when you +force the expression to be constant. It's better not to have given method +marked as `constexpr` than have it marked it errorneously. It's usually not +desirable to have special test case for `constexpr` behaviors, add `constexpr` +keywords to existing test cases to avoid duplicated testing of the same thing. +Example (testing copy constructor): +@code +constexpr Vector3 a(1.5f, 2.0f, 0.4f); +constexpr Vector3 b(a); +CORRADE_COMPARE(b, Vector3(1.5f, 2.0f, 0.4f)); +@endcode + +Don't forget to test implicit/explicit constructors and conversion operators +where it matters (i.e. all low-level and frequently used types like vectors, +matrices etc.). If the constructor/operator is implicit, test it in the context +where explicit one would fail to compile, if it is explicit, test its +explicitness with `std::is_convertible` (it should return `false`). These tests +might catch various ambiguous call errors which would otherwise be unnoticed: +@code +Vector2 a = {1.5f, 0.5f}; // Explicit constructor would fail to compile here +CORRADE_COMPARE(a, Vector2(1.5f, 0.5f)); + +Vector2i b(a); // Implicit conversion operator would return true in 2nd check +CORRADE_COMPARE(b, Vector2(1, 0)); +CORRADE_VERIFY(!(std::is_convertible::value)); +@endcode + +If some type should be constructible also from base type (additionaly to copy +constructor), don't forget to test that too. The test is also usually needed +only for low-level frequently used types (vectors, matrices) where such error +would do largest harm. Depending on how copy constructor is implemented, you +probably don't need to test classic copy construction, as it would be handled +by the already tested one. Example (copy construction from base type): +@code +Vector<3, Float> a(1.5f, 2.0f, 0.4f); +Vector3 b(a); +CORRADE_COMPARE(b, Vector3(1.5f, 2.0f, 0.4f)); +@endcode + */ } diff --git a/src/Math/DualComplex.h b/src/Math/DualComplex.h index 9ee19f2e9..5cde5f0ad 100644 --- a/src/Math/DualComplex.h +++ b/src/Math/DualComplex.h @@ -126,6 +126,9 @@ template class DualComplex: public Dual> { constexpr explicit DualComplex(const Vector2& vector): Dual>({}, Complex(vector)) {} #endif + /** @brief Copy constructor */ + constexpr DualComplex(const Dual>& other): Dual>(other) {} + /** * @brief Whether the dual complex number is normalized * @@ -320,9 +323,6 @@ template class DualComplex: public Dual> { #endif private: - /* Used by Dual operators and dualConjugated() */ - constexpr DualComplex(const Dual>& other): Dual>(other) {} - /* Just to be sure nobody uses this, as it wouldn't probably work with our operator*() */ using Dual>::operator*; diff --git a/src/Math/DualQuaternion.h b/src/Math/DualQuaternion.h index cead7637a..a1fd0526b 100644 --- a/src/Math/DualQuaternion.h +++ b/src/Math/DualQuaternion.h @@ -132,6 +132,9 @@ template class DualQuaternion: public Dual> { constexpr explicit DualQuaternion(const Vector3& vector): Dual>({}, {vector, T(0)}) {} #endif + /** @brief Copy constructor */ + constexpr DualQuaternion(const Dual>& other): Dual>(other) {} + /** * @brief Whether the dual quaternion is normalized * @@ -309,10 +312,6 @@ template class DualQuaternion: public Dual> { } MAGNUM_DUAL_SUBCLASS_IMPLEMENTATION(DualQuaternion, Quaternion) - - private: - /* Used by Dual operators and dualConjugated() */ - constexpr DualQuaternion(const Dual>& other): Dual>(other) {} }; /** @debugoperator{Magnum::Math::DualQuaternion} */ diff --git a/src/Math/Test/BoolVectorTest.cpp b/src/Math/Test/BoolVectorTest.cpp index 1063726e6..06b7a42e3 100644 --- a/src/Math/Test/BoolVectorTest.cpp +++ b/src/Math/Test/BoolVectorTest.cpp @@ -33,13 +33,13 @@ class BoolVectorTest: public Corrade::TestSuite::Tester { public: explicit BoolVectorTest(); + void construct(); void constructDefault(); void constructOneValue(); void constructOneElement(); + void constructCopy(); void data(); - void constExpressions(); - void compare(); void compareUndefined(); void all(); @@ -59,13 +59,13 @@ static_assert(BoolVector<17>::DataSize == 3, "Improper DataSize"); typedef Math::BoolVector<19> BoolVector19; BoolVectorTest::BoolVectorTest() { - addTests({&BoolVectorTest::constructDefault, + addTests({&BoolVectorTest::construct, + &BoolVectorTest::constructDefault, &BoolVectorTest::constructOneValue, &BoolVectorTest::constructOneElement, + &BoolVectorTest::constructCopy, &BoolVectorTest::data, - &BoolVectorTest::constExpressions, - &BoolVectorTest::compare, &BoolVectorTest::compareUndefined, &BoolVectorTest::all, @@ -78,24 +78,49 @@ BoolVectorTest::BoolVectorTest() { &BoolVectorTest::debug}); } +void BoolVectorTest::construct() { + constexpr BoolVector19 a = {0xa5, 0x5f, 0x07}; + CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07)); +} + void BoolVectorTest::constructDefault() { - CORRADE_COMPARE(BoolVector19(), BoolVector19(0x00, 0x00, 0x00)); + constexpr BoolVector19 a; + CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00)); } void BoolVectorTest::constructOneValue() { - CORRADE_COMPARE(BoolVector19(false), BoolVector19(0x00, 0x00, 0x00)); - CORRADE_COMPARE(BoolVector19(true), BoolVector19(0xff, 0xff, 0x07)); + #ifndef CORRADE_GCC46_COMPATIBILITY + constexpr BoolVector19 a(false); + #else + BoolVector19 a(false); /* not constexpr under GCC < 4.7 */ + #endif + CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00)); + + #ifndef CORRADE_GCC46_COMPATIBILITY + constexpr BoolVector19 b(true); + #else + BoolVector19 b(true); /* not constexpr under GCC < 4.7 */ + #endif + CORRADE_COMPARE(b, BoolVector19(0xff, 0xff, 0x07)); + + CORRADE_VERIFY(!(std::is_convertible::value)); } void BoolVectorTest::constructOneElement() { typedef BoolVector<1> BoolVector1; - BoolVector1 a = 0x01; + constexpr BoolVector1 a = 0x01; CORRADE_COMPARE(a, BoolVector1(0x01)); } +void BoolVectorTest::constructCopy() { + constexpr BoolVector19 a = {0xa5, 0x5f, 0x07}; + constexpr BoolVector19 b(a); + CORRADE_COMPARE(b, BoolVector19(0xa5, 0x5f, 0x07)); +} + void BoolVectorTest::data() { - BoolVector19 a(0x08, 0x03, 0x04); + constexpr BoolVector19 a(0x08, 0x03, 0x04); CORRADE_VERIFY(!a[0] && !a[1] && !a[2]); CORRADE_VERIFY(a[3]); @@ -105,36 +130,16 @@ void BoolVectorTest::data() { CORRADE_VERIFY(!a[10] && !a[11] && !a[12] && !a[13] && !a[14] && !a[15] && !a[16] && !a[17]); CORRADE_VERIFY(a[18]); - a.set(15, true); - CORRADE_VERIFY(a[15]); - - CORRADE_COMPARE(a, BoolVector19(0x08, 0x83, 0x04)); -} - -void BoolVectorTest::constExpressions() { - /* Default constructor */ - constexpr BoolVector19 a; - CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00)); - - /* Value constructor */ - constexpr BoolVector19 b(0xa5, 0x5f, 0x07); - CORRADE_COMPARE(b, BoolVector19(0xa5, 0x5f, 0x07)); - - /* One-value constructor, not constexpr under GCC < 4.7 */ - #ifndef CORRADE_GCC46_COMPATIBILITY - constexpr BoolVector19 c(true); - CORRADE_COMPARE(c, BoolVector19(0xff, 0xff, 0x07)); - #endif + constexpr bool b = a[9]; + CORRADE_COMPARE(b, true); - /* Copy constructor */ - constexpr BoolVector19 d(b); - CORRADE_COMPARE(d, BoolVector19(0xa5, 0x5f, 0x07)); + constexpr UnsignedByte c = *a.data(); + CORRADE_COMPARE(c, 0x08); - /* Data access, pointer chasings, i.e. *(b.data()[3]), are not possible */ - constexpr bool e = b[2]; - constexpr UnsignedByte f = *b.data(); - CORRADE_COMPARE(e, true); - CORRADE_COMPARE(f, 0xa5); + BoolVector19 d(0x08, 0x03, 0x04); + d.set(15, true); + CORRADE_VERIFY(d[15]); + CORRADE_COMPARE(d, BoolVector19(0x08, 0x83, 0x04)); } void BoolVectorTest::compare() { diff --git a/src/Math/Test/DualComplexTest.cpp b/src/Math/Test/DualComplexTest.cpp index bd34f77b4..6e6c5d554 100644 --- a/src/Math/Test/DualComplexTest.cpp +++ b/src/Math/Test/DualComplexTest.cpp @@ -127,7 +127,7 @@ void DualComplexTest::constructFromVector() { } void DualComplexTest::constructCopy() { - constexpr DualComplex a({-1.0f, 2.5f}, {3.0f, -7.5f}); + constexpr Math::Dual a({-1.0f, 2.5f}, {3.0f, -7.5f}); constexpr DualComplex b(a); CORRADE_COMPARE(b, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f})); } diff --git a/src/Math/Test/DualQuaternionTest.cpp b/src/Math/Test/DualQuaternionTest.cpp index 93e364e94..db7a7e653 100644 --- a/src/Math/Test/DualQuaternionTest.cpp +++ b/src/Math/Test/DualQuaternionTest.cpp @@ -125,7 +125,7 @@ void DualQuaternionTest::constructFromVector() { } void DualQuaternionTest::constructCopy() { - constexpr DualQuaternion a({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f}); + constexpr Math::Dual a({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f}); constexpr DualQuaternion b(a); CORRADE_COMPARE(b, DualQuaternion({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f})); } diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index 2b2baa996..6daafea13 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -122,9 +122,9 @@ Matrix3Test::Matrix3Test() { } void Matrix3Test::construct() { - constexpr Matrix3 a({3.0f, 5.0f, 8.0f}, - {4.5f, 4.0f, 7.0f}, - {7.9f, -1.0f, 8.0f}); + constexpr Matrix3 a = {{3.0f, 5.0f, 8.0f}, + {4.5f, 4.0f, 7.0f}, + {7.9f, -1.0f, 8.0f}}; CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f}, {4.5f, 4.0f, 7.0f}, {7.9f, -1.0f, 8.0f})); @@ -173,9 +173,9 @@ void Matrix3Test::constructConversion() { } void Matrix3Test::constructCopy() { - constexpr Matrix3 a({3.0f, 5.0f, 8.0f}, - {4.5f, 4.0f, 7.0f}, - {7.9f, -1.0f, 8.0f}); + constexpr RectangularMatrix<3, 3, Float> a(Vector<3, Float>(3.0f, 5.0f, 8.0f), + Vector<3, Float>(4.5f, 4.0f, 7.0f), + Vector<3, Float>(7.9f, -1.0f, 8.0f)); constexpr Matrix3 b(a); CORRADE_COMPARE(b, Matrix3({3.0f, 5.0f, 8.0f}, {4.5f, 4.0f, 7.0f}, diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index d983114b1..c311b6c24 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -134,10 +134,10 @@ Matrix4Test::Matrix4Test() { } void Matrix4Test::construct() { - constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f}, - {4.5f, 4.0f, 7.0f, 2.0f}, - {1.0f, 2.0f, 3.0f, -1.0f}, - {7.9f, -1.0f, 8.0f, -1.5f}); + constexpr Matrix4 a = {{3.0f, 5.0f, 8.0f, -3.0f}, + {4.5f, 4.0f, 7.0f, 2.0f}, + {1.0f, 2.0f, 3.0f, -1.0f}, + {7.9f, -1.0f, 8.0f, -1.5f}}; CORRADE_COMPARE(a, Matrix4({3.0f, 5.0f, 8.0f, -3.0f}, {4.5f, 4.0f, 7.0f, 2.0f}, {1.0f, 2.0f, 3.0f, -1.0f}, @@ -193,10 +193,10 @@ void Matrix4Test::constructConversion() { } void Matrix4Test::constructCopy() { - constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f}, - {4.5f, 4.0f, 7.0f, 2.0f}, - {1.0f, 2.0f, 3.0f, -1.0f}, - {7.9f, -1.0f, 8.0f, -1.5f}); + constexpr Matrix<4, Float> a(Vector<4, Float>(3.0f, 5.0f, 8.0f, -3.0f), + Vector<4, Float>(4.5f, 4.0f, 7.0f, 2.0f), + Vector<4, Float>(1.0f, 2.0f, 3.0f, -1.0f), + Vector<4, Float>(7.9f, -1.0f, 8.0f, -1.5f)); constexpr Matrix4 b(a); CORRADE_COMPARE(b, Matrix4({3.0f, 5.0f, 8.0f, -3.0f}, {4.5f, 4.0f, 7.0f, 2.0f}, diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 91f19195a..ad5054d11 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -108,11 +108,10 @@ MatrixTest::MatrixTest() { } void MatrixTest::construct() { - /* Value constructor */ - constexpr Matrix4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f), - Vector4(4.5f, 4.0f, 7.0f, 2.0f), - Vector4(1.0f, 2.0f, 3.0f, -1.0f), - Vector4(7.9f, -1.0f, 8.0f, -1.5f)); + constexpr Matrix4 a = {Vector4(3.0f, 5.0f, 8.0f, -3.0f), + Vector4(4.5f, 4.0f, 7.0f, 2.0f), + Vector4(1.0f, 2.0f, 3.0f, -1.0f), + Vector4(7.9f, -1.0f, 8.0f, -1.5f)}; CORRADE_COMPARE(a, Matrix4(Vector4(3.0f, 5.0f, 8.0f, -3.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f), Vector4(1.0f, 2.0f, 3.0f, -1.0f), @@ -167,10 +166,10 @@ void MatrixTest::constructConversion() { } void MatrixTest::constructCopy() { - constexpr Matrix4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f), - Vector4(4.5f, 4.0f, 7.0f, 2.0f), - Vector4(1.0f, 2.0f, 3.0f, -1.0f), - Vector4(7.9f, -1.0f, 8.0f, -1.5f)); + constexpr RectangularMatrix<4, 4, Float> a(Vector4(3.0f, 5.0f, 8.0f, -3.0f), + Vector4(4.5f, 4.0f, 7.0f, 2.0f), + Vector4(1.0f, 2.0f, 3.0f, -1.0f), + Vector4(7.9f, -1.0f, 8.0f, -1.5f)); constexpr Matrix4 b(a); CORRADE_COMPARE(b, Matrix4(Vector4(3.0f, 5.0f, 8.0f, -3.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f), diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 62fd58395..fb686d222 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -122,9 +122,9 @@ RectangularMatrixTest::RectangularMatrixTest() { } void RectangularMatrixTest::construct() { - constexpr Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f), - Vector4(5.0f, 6.0f, 7.0f, 8.0f), - Vector4(9.0f, 10.0f, 11.0f, 12.0f)); + constexpr Matrix3x4 a = {Vector4(1.0f, 2.0f, 3.0f, 4.0f), + Vector4(5.0f, 6.0f, 7.0f, 8.0f), + Vector4(9.0f, 10.0f, 11.0f, 12.0f)}; CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f), Vector4(5.0f, 6.0f, 7.0f, 8.0f), Vector4(9.0f, 10.0f, 11.0f, 12.0f))); diff --git a/src/Math/Test/Vector2Test.cpp b/src/Math/Test/Vector2Test.cpp index 5dd0ee28d..7cdf9e3dc 100644 --- a/src/Math/Test/Vector2Test.cpp +++ b/src/Math/Test/Vector2Test.cpp @@ -96,7 +96,7 @@ Vector2Test::Vector2Test() { } void Vector2Test::construct() { - constexpr Vector2 a(1.5f, 2.5f); + constexpr Vector2 a = {1.5f, 2.5f}; CORRADE_COMPARE(a, (Vector<2, Float>(1.5f, 2.5f))); } @@ -131,7 +131,7 @@ void Vector2Test::constructConversion() { } void Vector2Test::constructCopy() { - constexpr Vector2 a(1.5f, 2.5f); + constexpr Vector<2, Float> a(1.5f, 2.5f); constexpr Vector2 b(a); CORRADE_COMPARE(b, Vector2(1.5f, 2.5f)); } diff --git a/src/Math/Test/Vector3Test.cpp b/src/Math/Test/Vector3Test.cpp index fdd68abb0..7a1373575 100644 --- a/src/Math/Test/Vector3Test.cpp +++ b/src/Math/Test/Vector3Test.cpp @@ -98,7 +98,7 @@ Vector3Test::Vector3Test() { } void Vector3Test::construct() { - constexpr Vector3 a(1.0f, 2.5f, -3.0f); + constexpr Vector3 a = {1.0f, 2.5f, -3.0f}; CORRADE_COMPARE(a, (Vector<3, Float>(1.0f, 2.5f, -3.0f))); } @@ -139,7 +139,7 @@ void Vector3Test::constructConversion() { } void Vector3Test::constructCopy() { - constexpr Vector3 a(1.0f, 2.5f, -3.0f); + constexpr Vector<3, Float> a(1.0f, 2.5f, -3.0f); constexpr Vector3 b(a); CORRADE_COMPARE(b, Vector3(1.0f, 2.5f, -3.0f)); } diff --git a/src/Math/Test/Vector4Test.cpp b/src/Math/Test/Vector4Test.cpp index 059e936d1..d3ee2778d 100644 --- a/src/Math/Test/Vector4Test.cpp +++ b/src/Math/Test/Vector4Test.cpp @@ -95,7 +95,7 @@ Vector4Test::Vector4Test() { } void Vector4Test::construct() { - constexpr Vector4 a(1.0f, -2.5f, 3.0f, 4.1f); + constexpr Vector4 a = {1.0f, -2.5f, 3.0f, 4.1f}; CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f))); } @@ -136,7 +136,7 @@ void Vector4Test::constructConversion() { } void Vector4Test::constructCopy() { - constexpr Vector4 a(1.0f, -2.5f, 3.0f, 4.1f); + constexpr Vector<4, Float> a(1.0f, -2.5f, 3.0f, 4.1f); constexpr Vector4 b(a); CORRADE_COMPARE(b, Vector4(1.0f, -2.5f, 3.0f, 4.1f)); } diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 9feddec5b..63869ef00 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -143,20 +143,20 @@ VectorTest::VectorTest() { } void VectorTest::construct() { - constexpr Vector4 a(1.0f, 2.0f, -3.0f, 4.5f); + constexpr Vector4 a = {1.0f, 2.0f, -3.0f, 4.5f}; CORRADE_COMPARE(a, Vector4(1.0f, 2.0f, -3.0f, 4.5f)); } -void VectorTest::constructDefault() { - constexpr Vector4 a; - CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); -} - void VectorTest::constructFromData() { Float data[] = { 1.0f, 2.0f, 3.0f, 4.0f }; CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f)); } +void VectorTest::constructDefault() { + constexpr Vector4 a; + CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); +} + void VectorTest::constructOneValue() { #ifndef CORRADE_GCC46_COMPATIBILITY constexpr Vector4 a(7.25f); diff --git a/src/Trade/TextureData.h b/src/Trade/TextureData.h index a93740b14..531b6972b 100644 --- a/src/Trade/TextureData.h +++ b/src/Trade/TextureData.h @@ -48,7 +48,7 @@ class TextureData { Texture1D, /**< One-dimensional texture */ Texture2D, /**< Two-dimensional texture */ Texture3D, /**< Three-dimensional texture */ - Cube, /**< Cube map texture */ + Cube /**< Cube map texture */ }; /**