void TesterTest::compareNonCopyable() { /* Just to verify that there is no need to copy anything anywhere */ NonCopyable a, b; CORRADE_COMPARE(a, b); }
void Vector4Test::construct() { 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))); }
void Vector4Test::constructNoInit() { Vector4 a{1.0f, -2.5f, 3.0f, 4.1f}; new(&a) Vector4{NoInit}; CORRADE_COMPARE(a, (Vector4{1.0f, -2.5f, 3.0f, 4.1f})); }
void MagnumFontGLTest::layout() { MagnumFont font; CORRADE_VERIFY(font.openFile(Utility::Directory::join(MAGNUMFONT_TEST_DIR, "font.conf"), 0.0f)); /* Fill the cache with some fake glyphs */ GlyphCache cache(Vector2i(256)); cache.insert(font.glyphId(U'W'), {25, 34}, {{0, 8}, {16, 128}}); cache.insert(font.glyphId(U'e'), {25, 12}, {{16, 4}, {64, 32}}); auto layouter = font.layout(cache, 0.5f, "Wave"); CORRADE_VERIFY(layouter); CORRADE_COMPARE(layouter->glyphCount(), 4); Range2D rectangle; Range2D position; Range2D textureCoordinates; /* 'W' */ Vector2 cursorPosition; std::tie(position, textureCoordinates) = layouter->renderGlyph(0, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D({0.78125f, 1.0625f}, {1.28125f, 4.8125f})); CORRADE_COMPARE(textureCoordinates, Range2D({0, 0.03125f}, {0.0625f, 0.5f})); CORRADE_COMPARE(cursorPosition, Vector2(0.71875f, 0.0f)); /* 'a' (not found) */ std::tie(position, textureCoordinates) = layouter->renderGlyph(1, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D()); CORRADE_COMPARE(textureCoordinates, Range2D()); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); /* 'v' (not found) */ std::tie(position, textureCoordinates) = layouter->renderGlyph(2, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D()); CORRADE_COMPARE(textureCoordinates, Range2D()); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); /* 'e' */ std::tie(position, textureCoordinates) = layouter->renderGlyph(3, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D({0.78125f, 0.375f}, {2.28125f, 1.25f})); CORRADE_COMPARE(textureCoordinates, Range2D({0.0625f, 0.015625f}, {0.25f, 0.125f})); CORRADE_COMPARE(cursorPosition, Vector2(0.375f, 0.0f)); }
void ForceRendererTest::zero3D() { CORRADE_COMPARE(Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, Vector3()), Matrix4::translation({0.5f, -3.0f, 1.0f})*Matrix4::scaling(Vector3(0.0f))); }
void StaticArrayTest::slice() { StaticArray a{InPlaceInit, 1, 2, 3, 4, 5}; const StaticArray ac{InPlaceInit, 1, 2, 3, 4, 5}; ArrayView b = a.slice(1, 4); CORRADE_COMPARE(b.size(), 3); CORRADE_COMPARE(b[0], 2); CORRADE_COMPARE(b[1], 3); CORRADE_COMPARE(b[2], 4); ConstArrayView bc = ac.slice(1, 4); CORRADE_COMPARE(bc.size(), 3); CORRADE_COMPARE(bc[0], 2); CORRADE_COMPARE(bc[1], 3); CORRADE_COMPARE(bc[2], 4); ArrayView c = a.prefix(3); CORRADE_COMPARE(c.size(), 3); CORRADE_COMPARE(c[0], 1); CORRADE_COMPARE(c[1], 2); CORRADE_COMPARE(c[2], 3); ConstArrayView cc = ac.prefix(3); CORRADE_COMPARE(cc.size(), 3); CORRADE_COMPARE(cc[0], 1); CORRADE_COMPARE(cc[1], 2); CORRADE_COMPARE(cc[2], 3); ArrayView d = a.suffix(2); CORRADE_COMPARE(d.size(), 3); CORRADE_COMPARE(d[0], 3); CORRADE_COMPARE(d[1], 4); CORRADE_COMPARE(d[2], 5); ConstArrayView dc = ac.suffix(2); CORRADE_COMPARE(dc.size(), 3); CORRADE_COMPARE(dc[0], 3); CORRADE_COMPARE(dc[1], 4); CORRADE_COMPARE(dc[2], 5); }
void SwizzleTest::components() { constexpr auto a = swizzle<'z', 'x', 'w', 'y'>(Vector4i(2, 4, 5, 7)); CORRADE_COMPARE(a, Vector4i(5, 2, 7, 4)); }
void DistanceTest::lineSegmentPoint2D() { Vector2 a(0.0f); Vector2 b(1.0f); /* Point on the line segment */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, Vector2(0.25f)), 0.0f); /* Point on the line, outside the segment, closer to A */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, Vector2(-1.0f)), Constants::sqrt2()); /* Be sure that *Squared() works the same, as it has slightly different implementation */ CORRADE_COMPARE(Distance::lineSegmentPointSquared(a, b, Vector2(-1.0f)), 2.0f); /* Point on the line, outside the segment, closer to B */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, Vector2(1.0f + 1.0f/Constants::sqrt2())), 1.0f); CORRADE_COMPARE(Distance::lineSegmentPointSquared(a, b, Vector2(1.0f + 1.0f/Constants::sqrt2())), 1.0f); /* Point next to the line segment */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, {1.0f, 0.0f}), 1.0f/Constants::sqrt2()); CORRADE_COMPARE(Distance::lineSegmentPointSquared(a, b, {1.0f, 0.0f}), 0.5f); /* Point outside the line segment, closer to A */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, Vector2(1.0f, 0.0f) - Vector2(1.0f, 0.5f)), 0.5f); CORRADE_COMPARE(Distance::lineSegmentPointSquared(a, b, Vector2(1.0f, 0.0f) - Vector2(1.0f, 0.5f)), 0.25f); /* Point outside the line segment, closer to B */ CORRADE_COMPARE(Distance::lineSegmentPoint(a, b, Vector2(1.0f, 0.0f) + Vector2(0.5f, 1.0f)), 0.5f); CORRADE_COMPARE(Distance::lineSegmentPointSquared(a, b, Vector2(1.0f, 0.0f) + Vector2(0.5f, 1.0f)), 0.25f); }
void ComplexTest::constructDefault() { constexpr Complex a; CORRADE_COMPARE(a, Complex(1.0f, 0.0f)); CORRADE_COMPARE(a.length(), 1.0f); }
void UnitTest::constructDefault() { constexpr Sec b; CORRADE_COMPARE(b, Sec(0.0f)); }
void UnitTest::constructNoInit() { Sec a{25.0f}; new(&a) Sec{NoInit}; CORRADE_COMPARE(a, Sec{25.0f}); }
void UnitTest::negated() { constexpr Sec a(25.0f); constexpr Sec b(-a); CORRADE_COMPARE(b, Sec(-25.0f)); }
void PointTest::transformed() { const auto point = Shapes::Point3D({1.0f, 2.0f, 3.0f}) .transformed(Matrix4::translation({5.0f, 6.0f, 7.0f})); CORRADE_COMPARE(point.position(), Vector3(6.0f, 8.0f, 10.0f)); }
namespace Test { struct Test: Tester { Test(std::ostream* out); void noChecks(); void trueExpression(); void falseExpression(); void equal(); void nonEqual(); void expectFail(); void unexpectedPassExpression(); void unexpectedPassEqual(); void compareAs(); void compareAsFail(); void compareWith(); void compareWithFail(); void compareImplicitConversionFail(); void skip(); void testCaseName(); void testCaseNameNoChecks(); void testCaseDescription(); void setupTeardown(); void setupTeardownEmpty(); void setupTeardownFail(); void setupTeardownSkip(); void setup(); void teardown(); void instancedTest(); void repeatedTest(); void repeatedTestEmpty(); void repeatedTestFail(); void repeatedTestSkip(); void repeatedTestSetupTeardown(); void repeatedTestSetupTeardownEmpty(); void repeatedTestSetupTeardownFail(); void repeatedTestSetupTeardownSkip(); std::ostream* _out; int _i = 0; }; Test::Test(std::ostream* const out): _out{out} { addTests({&Test::noChecks, &Test::trueExpression, &Test::falseExpression, &Test::equal, &Test::nonEqual, &Test::expectFail, &Test::unexpectedPassExpression, &Test::unexpectedPassEqual, &Test::compareAs, &Test::compareAsFail, &Test::compareWith, &Test::compareWithFail, &Test::compareImplicitConversionFail, &Test::skip, &Test::testCaseName, &Test::testCaseNameNoChecks, &Test::testCaseDescription}); addTests({&Test::setupTeardown, &Test::setupTeardownEmpty, &Test::setupTeardownFail, &Test::setupTeardownSkip}, &Test::setup, &Test::teardown); addInstancedTests({&Test::instancedTest}, 5); addRepeatedTests({&Test::repeatedTest, &Test::repeatedTestEmpty, &Test::repeatedTestFail, &Test::repeatedTestSkip}, 50); addRepeatedTests({&Test::repeatedTestSetupTeardown, &Test::repeatedTestSetupTeardownEmpty, &Test::repeatedTestSetupTeardownFail, &Test::repeatedTestSetupTeardownSkip}, 2, &Test::setup, &Test::teardown); } void Test::noChecks() { return; } void Test::trueExpression() { CORRADE_VERIFY(true); // #1 } void Test::falseExpression() { CORRADE_VERIFY(5 != 5); // #2 } void Test::equal() { CORRADE_COMPARE(3, 3); // #3 } void Test::nonEqual() { int a = 5; int b = 3; CORRADE_COMPARE(a, b); // #4 } void Test::expectFail() { { CORRADE_EXPECT_FAIL("The world is not mad yet."); CORRADE_COMPARE(2 + 2, 5); // #5 CORRADE_VERIFY(false == true); // #6 } CORRADE_VERIFY(true); // #7 { CORRADE_EXPECT_FAIL_IF(6*7 == 49, "This is not our universe"); CORRADE_VERIFY(true); // #8 } } void Test::unexpectedPassExpression() { CORRADE_EXPECT_FAIL("Not yet implemented."); CORRADE_VERIFY(true == true); // #9 } void Test::unexpectedPassEqual() { CORRADE_EXPECT_FAIL("Cannot get it right."); CORRADE_COMPARE(2 + 2, 4); // #10 } void Test::compareAs() { CORRADE_COMPARE_AS("kill!", "hello", StringLength); // #11 } void Test::compareAsFail() { CORRADE_COMPARE_AS("meh", "hello", StringLength); // #12 } void Test::compareWith() { CORRADE_COMPARE_WITH("You rather GTFO", "hello", StringLength(10)); // #13 } void Test::compareWithFail() { CORRADE_COMPARE_WITH("You rather GTFO", "hello", StringLength(9)); // #14 } void Test::compareImplicitConversionFail() { std::string hello{"hello"}; CORRADE_COMPARE("holla", hello); // #15 } void Test::skip() { CORRADE_SKIP("This testcase is skipped."); CORRADE_VERIFY(false); // (not called) } void Test::testCaseName() { setTestCaseName("testCaseName<15>"); CORRADE_VERIFY(true); } void Test::testCaseNameNoChecks() { setTestCaseName("testCaseName<27>"); } void Test::testCaseDescription() { setTestCaseDescription("hello"); CORRADE_VERIFY(true); } void Test::setup() { Debug{_out} << " [" << Debug::nospace << testCaseId() << Debug::nospace << "] setting up..."; } void Test::teardown() { Debug{_out} << " [" << Debug::nospace << testCaseId() << Debug::nospace << "] tearing down..."; } void Test::setupTeardown() { CORRADE_VERIFY(true); } void Test::setupTeardownEmpty() {} void Test::setupTeardownFail() { CORRADE_VERIFY(false); } void Test::setupTeardownSkip() { CORRADE_SKIP("Skipped."); } namespace { constexpr struct { const char* desc; int value; int result; } InstanceData[] = { {"zero", 3, 27}, {nullptr, 1, 1}, {"two", 5, 122}, {nullptr, -6, -216}, {"last", 0, 0} }; } void Test::instancedTest() { const auto& data = InstanceData[testCaseInstanceId()]; if(data.desc) setTestCaseDescription(data.desc); CORRADE_COMPARE(data.value*data.value*data.value, data.result); } void Test::repeatedTest() { CORRADE_VERIFY(true); } void Test::repeatedTestEmpty() {} void Test::repeatedTestFail() { CORRADE_VERIFY(_i++ < 17); } void Test::repeatedTestSkip() { if(_i++ > 45) CORRADE_SKIP("Too late."); } void Test::repeatedTestSetupTeardown() { CORRADE_VERIFY(true); } void Test::repeatedTestSetupTeardownEmpty() {} void Test::repeatedTestSetupTeardownFail() { CORRADE_VERIFY(false); } void Test::repeatedTestSetupTeardownSkip() { CORRADE_SKIP("Skipped."); } struct TesterTest: Tester { explicit TesterTest(); void test(); void emptyTest(); void skipOnly(); void repeatEvery(); void repeatAll(); void compareNoCommonType(); void compareAsOverload(); void compareAsVarargs(); void compareNonCopyable(); void verifyExplicitBool(); void expectFailIfExplicitBool(); }; class EmptyTest: public Tester {}; TesterTest::TesterTest() { addTests({&TesterTest::test, &TesterTest::emptyTest, &TesterTest::skipOnly, &TesterTest::repeatEvery, &TesterTest::repeatAll, &TesterTest::compareNoCommonType, &TesterTest::compareAsOverload, &TesterTest::compareAsVarargs, &TesterTest::compareNonCopyable, &TesterTest::verifyExplicitBool, &TesterTest::expectFailIfExplicitBool}); } namespace { /* Disable automatic colors to ensure we have the same behavior everywhere */ const char* noColorArgv[] = { "", "--color", "off" }; const int noColorArgc = std::extent<decltype(noColorArgv)>(); } void TesterTest::test() { /* Print to visually verify coloring */ { Debug{} << "======================== visual color verification start ======================="; Test t{&std::cout}; t.registerTest("here.cpp", "TesterTest::Test"); t.exec(0, nullptr); Debug{} << "======================== visual color verification end ========================="; } std::stringstream out; Test t{&out}; t.registerTest("here.cpp", "TesterTest::Test"); int result = t.exec(noColorArgc, noColorArgv, &out, &out); CORRADE_VERIFY(result == 1); std::string expected = "Starting TesterTest::Test with 34 test cases...\n" " ? [01] <unknown>()\n" " OK [02] trueExpression()\n" " FAIL [03] falseExpression() at here.cpp on line 164\n" " Expression 5 != 5 failed.\n" " OK [04] equal()\n" " FAIL [05] nonEqual() at here.cpp on line 174\n" " Values a and b are not the same, actual is\n" " 5\n" " but expected\n" " 3\n" " XFAIL [06] expectFail() at here.cpp on line 180\n" " The world is not mad yet. 2 + 2 and 5 are not equal.\n" " XFAIL [06] expectFail() at here.cpp on line 181\n" " The world is not mad yet. Expression false == true failed.\n" " OK [06] expectFail()\n" " XPASS [07] unexpectedPassExpression() at here.cpp on line 194\n" " Expression true == true was expected to fail.\n" " XPASS [08] unexpectedPassEqual() at here.cpp on line 199\n" " 2 + 2 and 4 are not expected to be equal.\n" " OK [09] compareAs()\n" " FAIL [10] compareAsFail() at here.cpp on line 207\n" " Length of actual \"meh\" doesn't match length of expected \"hello\" with epsilon 0\n" " OK [11] compareWith()\n" " FAIL [12] compareWithFail() at here.cpp on line 215\n" " Length of actual \"You rather GTFO\" doesn't match length of expected \"hello\" with epsilon 9\n" " FAIL [13] compareImplicitConversionFail() at here.cpp on line 220\n" " Values \"holla\" and hello are not the same, actual is\n" " holla\n" " but expected\n" " hello\n" " SKIP [14] skip()\n" " This testcase is skipped.\n" " OK [15] testCaseName<15>()\n" " ? [16] testCaseName<27>()\n" " OK [17] testCaseDescription(hello)\n" " [18] setting up...\n" " [18] tearing down...\n" " OK [18] setupTeardown()\n" " [19] setting up...\n" " [19] tearing down...\n" " ? [19] <unknown>()\n" " [20] setting up...\n" " FAIL [20] setupTeardownFail() at here.cpp on line 257\n" " Expression false failed.\n" " [20] tearing down...\n" " [21] setting up...\n" " SKIP [21] setupTeardownSkip()\n" " Skipped.\n" " [21] tearing down...\n" " OK [22] instancedTest(zero)\n" " OK [23] instancedTest(1)\n" " FAIL [24] instancedTest(two) at here.cpp on line 282\n" " Values data.value*data.value*data.value and data.result are not the same, actual is\n" " 125\n" " but expected\n" " 122\n" " OK [25] instancedTest(3)\n" " OK [26] instancedTest(last)\n" " OK [27] repeatedTest()@50\n" " ? [28] <unknown>()@50\n" " FAIL [29] repeatedTestFail()@18 at here.cpp on line 292\n" " Expression _i++ < 17 failed.\n" " SKIP [30] repeatedTestSkip()@29\n" " Too late.\n" " [31] setting up...\n" " [31] tearing down...\n" " [31] setting up...\n" " [31] tearing down...\n" " OK [31] repeatedTestSetupTeardown()@2\n" " [32] setting up...\n" " [32] tearing down...\n" " [32] setting up...\n" " [32] tearing down...\n" " ? [32] <unknown>()@2\n" " [33] setting up...\n" " FAIL [33] repeatedTestSetupTeardownFail()@1 at here.cpp on line 306\n" " Expression false failed.\n" " [33] tearing down...\n" " [34] setting up...\n" " SKIP [34] repeatedTestSetupTeardownSkip()@1\n" " Skipped.\n" " [34] tearing down...\n" "Finished TesterTest::Test with 11 errors out of 95 checks. 5 test cases didn't contain any checks!\n"; //CORRADE_COMPARE(out.str().length(), expected.length()); CORRADE_COMPARE(out.str(), expected); } void TesterTest::emptyTest() { std::stringstream out; EmptyTest t; t.registerTest("here.cpp", "TesterTest::EmptyTest"); int result = t.exec(noColorArgc, noColorArgv, &out, &out); CORRADE_VERIFY(result == 2); CORRADE_COMPARE(out.str(), "No tests to run in TesterTest::EmptyTest!\n"); } void TesterTest::skipOnly() { std::stringstream out; const char* argv[] = { "", "--color", "off", "--only", "11 14 4 9", "--skip", "14" }; const int argc = std::extent<decltype(argv)>(); Test t{&out}; t.registerTest("here.cpp", "TesterTest::Test"); int result = t.exec(argc, argv, &out, &out); CORRADE_VERIFY(result == 0); std::string expected = "Starting TesterTest::Test with 3 test cases...\n" " OK [11] compareWith()\n" " OK [04] equal()\n" " OK [09] compareAs()\n" "Finished TesterTest::Test with 0 errors out of 3 checks.\n"; CORRADE_COMPARE(out.str(), expected); } void TesterTest::repeatEvery() { std::stringstream out; const char* argv[] = { "", "--color", "off", "--only", "27 4", "--repeat-every", "2" }; const int argc = std::extent<decltype(argv)>(); Test t{&out}; t.registerTest("here.cpp", "TesterTest::Test"); int result = t.exec(argc, argv, &out, &out); CORRADE_VERIFY(result == 0); std::string expected = "Starting TesterTest::Test with 2 test cases...\n" " OK [27] repeatedTest()@100\n" " OK [04] equal()@2\n" "Finished TesterTest::Test with 0 errors out of 102 checks.\n"; CORRADE_COMPARE(out.str(), expected); } void TesterTest::repeatAll() { std::stringstream out; const char* argv[] = { "", "--color", "off", "--only", "27 4", "--repeat-all", "2" }; const int argc = std::extent<decltype(argv)>(); Test t{&out}; t.registerTest("here.cpp", "TesterTest::Test"); int result = t.exec(argc, argv, &out, &out); CORRADE_VERIFY(result == 0); std::string expected = "Starting TesterTest::Test with 4 test cases...\n" " OK [27] repeatedTest()@50\n" " OK [04] equal()\n" " OK [27] repeatedTest()@50\n" " OK [04] equal()\n" "Finished TesterTest::Test with 0 errors out of 102 checks.\n"; CORRADE_COMPARE(out.str(), expected); } void TesterTest::compareNoCommonType() { /* Test that this compiles well */ struct A { /*implicit*/ A(int value): value(value) {} /*implicit*/ operator int() const { return value; } int value; }; CORRADE_COMPARE(A{5}, 5); } void TesterTest::compareAsOverload() { /* Just test that this compiles well */ float a = 3.0f; double b = 3.0f; CORRADE_COMPARE_AS(a, b, float); CORRADE_COMPARE_AS(a, b, double); } void TesterTest::compareAsVarargs() { const std::pair<int, int> a(3, 5); const std::pair<float, float> b(3.2f, 5.7f); CORRADE_COMPARE_AS(a, b, std::pair<int, int>); } namespace { struct NonCopyable { explicit NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; NonCopyable(NonCopyable&&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; NonCopyable& operator=(NonCopyable&&) = delete; }; inline bool operator==(const NonCopyable&, const NonCopyable&) { return true; } inline Utility::Debug& operator<<(Utility::Debug& debug, const NonCopyable&) { return debug << "NonCopyable"; } } void TesterTest::compareNonCopyable() { /* Just to verify that there is no need to copy anything anywhere */ NonCopyable a, b; CORRADE_COMPARE(a, b); } void TesterTest::verifyExplicitBool() { struct ExplicitTrue { explicit operator bool() const { return true; } }; ExplicitTrue t; CORRADE_VERIFY(t); CORRADE_VERIFY(ExplicitTrue()); struct ExplicitTrueNonConst { explicit operator bool() { return true; } }; ExplicitTrueNonConst tc; CORRADE_VERIFY(tc); CORRADE_VERIFY(ExplicitTrueNonConst()); struct ExplicitFalse { explicit operator bool() const { return false; } }; ExplicitFalse f; CORRADE_VERIFY(!f); } void TesterTest::expectFailIfExplicitBool() { struct ExplicitFalse { explicit operator bool() const { return false; } }; { ExplicitFalse t; CORRADE_EXPECT_FAIL_IF(t, ""); CORRADE_EXPECT_FAIL_IF(ExplicitFalse{}, ""); CORRADE_VERIFY(true); } struct ExplicitFalseNonConst { explicit operator bool() { return false; } }; { ExplicitFalseNonConst t; CORRADE_EXPECT_FAIL_IF(t, ""); CORRADE_EXPECT_FAIL_IF(ExplicitFalseNonConst{}, ""); CORRADE_VERIFY(true); } struct ExplicitTrue { explicit operator bool() const { return true; } }; { CORRADE_EXPECT_FAIL_IF(ExplicitTrue{}, ""); CORRADE_VERIFY(false); } } }}}
namespace Corrade { namespace Containers { namespace Test { struct StaticArrayTest: TestSuite::Tester { explicit StaticArrayTest(); void construct(); void constructDefaultInit(); void constructValueInit(); void constructNoInit(); void constructDirectInit(); void constructInPlaceInit(); void constructNonCopyable(); void constructNoImplicitConstructor(); void constructDirectReferences(); void convertBool(); void convertPointer(); void convertView(); void convertViewDerived(); void convertStaticView(); void convertStaticViewDerived(); void convertVoid(); void access(); void rvalueArrayAccess(); void rangeBasedFor(); void slice(); void sliceToStatic(); }; typedef Containers::StaticArray<5, int> StaticArray; typedef Containers::ArrayView<int> ArrayView; typedef Containers::ArrayView<const int> ConstArrayView; typedef Containers::ArrayView<const void> VoidArrayView; typedef Containers::StaticArrayView<5, int> StaticArrayView; typedef Containers::StaticArrayView<5, const int> ConstStaticArrayView; StaticArrayTest::StaticArrayTest() { addTests({&StaticArrayTest::construct, &StaticArrayTest::constructDefaultInit, &StaticArrayTest::constructValueInit, &StaticArrayTest::constructNoInit, &StaticArrayTest::constructDirectInit, &StaticArrayTest::constructInPlaceInit, &StaticArrayTest::constructNonCopyable, &StaticArrayTest::constructNoImplicitConstructor, &StaticArrayTest::constructDirectReferences, &StaticArrayTest::convertBool, &StaticArrayTest::convertPointer, &StaticArrayTest::convertView, &StaticArrayTest::convertViewDerived, &StaticArrayTest::convertStaticView, &StaticArrayTest::convertStaticViewDerived, &StaticArrayTest::convertVoid, &StaticArrayTest::access, &StaticArrayTest::rvalueArrayAccess, &StaticArrayTest::rangeBasedFor, &StaticArrayTest::slice, &StaticArrayTest::sliceToStatic}); } void StaticArrayTest::construct() { const StaticArray a; CORRADE_VERIFY(a); } void StaticArrayTest::constructDefaultInit() { const StaticArray a{DefaultInit}; CORRADE_VERIFY(a); } void StaticArrayTest::constructValueInit() { const StaticArray a{ValueInit}; CORRADE_VERIFY(a); CORRADE_COMPARE(a[0], 0); CORRADE_COMPARE(a[1], 0); CORRADE_COMPARE(a[2], 0); CORRADE_COMPARE(a[3], 0); CORRADE_COMPARE(a[4], 0); } namespace { struct Foo { static int constructorCallCount; static int destructorCallCount; Foo() { ++constructorCallCount; } ~Foo() { ++destructorCallCount; } }; int Foo::constructorCallCount = 0; int Foo::destructorCallCount = 0; } void StaticArrayTest::constructNoInit() { { const Containers::StaticArray<5, Foo> a{NoInit}; CORRADE_COMPARE(Foo::constructorCallCount, 0); const Containers::StaticArray<5, Foo> b{DefaultInit}; CORRADE_COMPARE(Foo::constructorCallCount, 5); } CORRADE_COMPARE(Foo::destructorCallCount, 10); } void StaticArrayTest::constructDirectInit() { const StaticArray a{DirectInit, -37}; CORRADE_COMPARE(a[0], -37); CORRADE_COMPARE(a[1], -37); CORRADE_COMPARE(a[2], -37); CORRADE_COMPARE(a[3], -37); CORRADE_COMPARE(a[4], -37); } void StaticArrayTest::constructInPlaceInit() { const StaticArray a{InPlaceInit, 1, 2, 3, 4, 5}; CORRADE_COMPARE(a[0], 1); CORRADE_COMPARE(a[1], 2); CORRADE_COMPARE(a[2], 3); CORRADE_COMPARE(a[3], 4); CORRADE_COMPARE(a[4], 5); } void StaticArrayTest::constructNonCopyable() { struct NonCopyable { NonCopyable(const NonCopyable&) = delete; NonCopyable(NonCopyable&&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; NonCopyable& operator=(NonCopyable&&) = delete; NonCopyable() {} /* to make it non-trivial to hit https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70395 */ ~NonCopyable() {} }; const Containers::StaticArray<5, NonCopyable> a; CORRADE_VERIFY(a); } void StaticArrayTest::constructNoImplicitConstructor() { struct NoImplicitConstructor { NoImplicitConstructor(int i): i{i} {} int i; }; const Containers::StaticArray<5, NoImplicitConstructor> a{Containers::DirectInit, 5}; CORRADE_VERIFY(a); CORRADE_COMPARE(a[0].i, 5); CORRADE_COMPARE(a[1].i, 5); CORRADE_COMPARE(a[2].i, 5); CORRADE_COMPARE(a[3].i, 5); CORRADE_COMPARE(a[4].i, 5); const Containers::StaticArray<5, NoImplicitConstructor> b{Containers::InPlaceInit, 1, 2, 3, 4, 5}; CORRADE_VERIFY(b); CORRADE_COMPARE(b[0].i, 1); CORRADE_COMPARE(b[1].i, 2); CORRADE_COMPARE(b[2].i, 3); CORRADE_COMPARE(b[3].i, 4); CORRADE_COMPARE(b[4].i, 5); } void StaticArrayTest::constructDirectReferences() { struct NonCopyable { NonCopyable(const NonCopyable&) = delete; NonCopyable(NonCopyable&&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; NonCopyable& operator=(NonCopyable&&) = delete; NonCopyable() = default; } a; struct Reference { Reference(NonCopyable&) {} }; const Containers::StaticArray<5, Reference> b{Containers::DirectInit, a}; CORRADE_VERIFY(b); } void StaticArrayTest::convertBool() { CORRADE_VERIFY(StaticArray{}); CORRADE_VERIFY(!(std::is_convertible<StaticArray, int>::value)); } void StaticArrayTest::convertPointer() { StaticArray a; int* b = a; CORRADE_COMPARE(b, a.begin()); const StaticArray c; const int* d = c; CORRADE_COMPARE(d, c.begin()); /* Pointer arithmetic */ const StaticArray e; const int* f = e + 2; CORRADE_COMPARE(f, &e[2]); /* Verify that we can't convert rvalues */ CORRADE_VERIFY((std::is_convertible<StaticArray&, int*>::value)); CORRADE_VERIFY((std::is_convertible<const StaticArray&, const int*>::value)); { #ifdef CORRADE_GCC47_COMPATIBILITY CORRADE_EXPECT_FAIL("Rvalue references for *this are not supported in GCC < 4.8.1."); #endif CORRADE_VERIFY(!(std::is_convertible<StaticArray, int*>::value)); CORRADE_VERIFY(!(std::is_convertible<StaticArray&&, int*>::value)); } /* Deleting const&& overload and leaving only const& one will not, in fact, disable conversion of const Array&& to pointer, but rather make the conversion ambiguous, which is not what we want, as it breaks e.g. rvalueArrayAccess() test. */ { CORRADE_EXPECT_FAIL("I don't know how to properly disable conversion of const Array&& to pointer."); CORRADE_VERIFY(!(std::is_convertible<const StaticArray, const int*>::value)); CORRADE_VERIFY(!(std::is_convertible<const StaticArray&&, const int*>::value)); } } void StaticArrayTest::convertView() { StaticArray a; const StaticArray ca; const ArrayView b = a; const ConstArrayView cb = ca; CORRADE_VERIFY(b.begin() == a.begin()); CORRADE_VERIFY(cb.begin() == ca.begin()); CORRADE_COMPARE(b.size(), 5); CORRADE_COMPARE(cb.size(), 5); } void StaticArrayTest::convertViewDerived() { struct A { int i; }; struct B: A {}; /* Valid use case: constructing Containers::ArrayView<Math::Vector<3, Float>> from Containers::ArrayView<Color3> because the data have the same size and data layout */ CORRADE_VERIFY((std::is_convertible<Containers::StaticArray<5, B>, Containers::ArrayView<A>>::value)); { CORRADE_EXPECT_FAIL("Intentionally not forbidding construction of base array from larger derived type to stay compatible with raw arrays"); struct C: A { int b; }; /* Array of 5 Cs has larger size than array of 5 As so it does not make sense to create the view from it, but we are keeping compatibility with raw arrays and thus allow the users to shoot themselves in a foot. */ CORRADE_VERIFY(!(std::is_convertible<Containers::StaticArray<5, C>, Containers::ArrayView<A>>::value)); } } void StaticArrayTest::convertStaticView() { StaticArray a; const StaticArray ca; const StaticArrayView b = a; const ConstStaticArrayView cb = ca; CORRADE_VERIFY(b.begin() == a.begin()); CORRADE_VERIFY(cb.begin() == ca.begin()); } void StaticArrayTest::convertStaticViewDerived() { struct A { int i; }; struct B: A {}; /* Valid use case: constructing Containers::ArrayView<Math::Vector<3, Float>> from Containers::ArrayView<Color3> because the data have the same size and data layout */ CORRADE_VERIFY((std::is_convertible<Containers::StaticArray<5, B>, Containers::StaticArrayView<5, A>>::value)); { CORRADE_EXPECT_FAIL("Intentionally not forbidding construction of base array from larger derived type to stay compatible with raw arrays"); struct C: A { int b; }; /* Array of 5 Cs has larger size than array of 5 As so it does not make sense to create the view from it, but we are keeping compatibility with raw arrays and thus allow the users to shoot themselves in a foot. */ CORRADE_VERIFY(!(std::is_convertible<Containers::StaticArray<5, C>, Containers::StaticArrayView<5, A>>::value)); } } void StaticArrayTest::convertVoid() { /* void reference to Array */ StaticArray a; VoidArrayView b = a; CORRADE_VERIFY(b == a); CORRADE_COMPARE(b.size(), 5*sizeof(int)); } void StaticArrayTest::access() { StaticArray a; for(std::size_t i = 0; i != 5; ++i) a[i] = i; CORRADE_COMPARE(a.data(), static_cast<int*>(a)); CORRADE_COMPARE(*(a.begin()+2), 2); CORRADE_COMPARE(a[4], 4); CORRADE_COMPARE(a.end()-a.begin(), 5); } void StaticArrayTest::rvalueArrayAccess() { CORRADE_COMPARE((StaticArray{DirectInit, 3})[2], 3); } void StaticArrayTest::rangeBasedFor() { StaticArray a; for(auto& i: a) i = 3; CORRADE_COMPARE(a[0], 3); CORRADE_COMPARE(a[1], 3); CORRADE_COMPARE(a[2], 3); CORRADE_COMPARE(a[3], 3); CORRADE_COMPARE(a[4], 3); } void StaticArrayTest::slice() { StaticArray a{InPlaceInit, 1, 2, 3, 4, 5}; const StaticArray ac{InPlaceInit, 1, 2, 3, 4, 5}; ArrayView b = a.slice(1, 4); CORRADE_COMPARE(b.size(), 3); CORRADE_COMPARE(b[0], 2); CORRADE_COMPARE(b[1], 3); CORRADE_COMPARE(b[2], 4); ConstArrayView bc = ac.slice(1, 4); CORRADE_COMPARE(bc.size(), 3); CORRADE_COMPARE(bc[0], 2); CORRADE_COMPARE(bc[1], 3); CORRADE_COMPARE(bc[2], 4); ArrayView c = a.prefix(3); CORRADE_COMPARE(c.size(), 3); CORRADE_COMPARE(c[0], 1); CORRADE_COMPARE(c[1], 2); CORRADE_COMPARE(c[2], 3); ConstArrayView cc = ac.prefix(3); CORRADE_COMPARE(cc.size(), 3); CORRADE_COMPARE(cc[0], 1); CORRADE_COMPARE(cc[1], 2); CORRADE_COMPARE(cc[2], 3); ArrayView d = a.suffix(2); CORRADE_COMPARE(d.size(), 3); CORRADE_COMPARE(d[0], 3); CORRADE_COMPARE(d[1], 4); CORRADE_COMPARE(d[2], 5); ConstArrayView dc = ac.suffix(2); CORRADE_COMPARE(dc.size(), 3); CORRADE_COMPARE(dc[0], 3); CORRADE_COMPARE(dc[1], 4); CORRADE_COMPARE(dc[2], 5); } void StaticArrayTest::sliceToStatic() { StaticArray a{InPlaceInit, 1, 2, 3, 4, 5}; const StaticArray ac{InPlaceInit, 1, 2, 3, 4, 5}; Containers::StaticArrayView<3, int> b = a.slice<3>(1); CORRADE_COMPARE(b[0], 2); CORRADE_COMPARE(b[1], 3); CORRADE_COMPARE(b[2], 4); Containers::StaticArrayView<3, const int> bc = ac.slice<3>(1); CORRADE_COMPARE(bc[0], 2); CORRADE_COMPARE(bc[1], 3); CORRADE_COMPARE(bc[2], 4); } }}}
void ComplexTest::constructCopy() { constexpr Complex a(2.5f, -5.0f); constexpr Complex b(a); CORRADE_COMPARE(b, Complex(2.5f, -5.0f)); }
void StaticArrayTest::rvalueArrayAccess() { CORRADE_COMPARE((StaticArray{DirectInit, 3})[2], 3); }
void ComplexTest::negated() { CORRADE_COMPARE(-Complex(2.5f, -7.4f), Complex(-2.5f, 7.4f)); }
void ContextTest::hrtfStatus() { std::ostringstream out; Debug(&out) << Context::HrtfStatus::Denied; CORRADE_COMPARE(out.str(), "Audio::Context::HrtfStatus::Denied\n"); }
void ComplexTest::dot() { Complex a(5.0f, 3.0f); Complex b(6.0f, -7.0f); CORRADE_COMPARE(Complex::dot(a, b), 9.0f); }
void SwizzleTest::constants() { constexpr auto a = swizzle<'1', 'w', '0', 'y'>(Vector4i(2, 4, 5, 7)); CORRADE_COMPARE(a, Vector4i(1, 7, 0, 4)); }
void ComplexTest::dotSelf() { CORRADE_COMPARE(Complex(-4.0f, 3.0f).dot(), 25.0f); }
void BufferGLTest::data() { Buffer buffer; /* Plain array */ constexpr Int data[] = {2, 7, 5, 13, 25}; buffer.setData({data, 5}, BufferUsage::StaticDraw); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /* STL vector */ std::vector<Int> data2{2, 7, 5, 13, 25}; buffer.setData(data2, BufferUsage::StaticDraw); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /* STL array */ std::array<Int, 5> data3{{2, 7, 5, 13, 25}}; buffer.setData(data3, BufferUsage::StaticDraw); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /** @todo How to verify the contents in ES? */ #ifndef MAGNUM_TARGET_GLES const Containers::Array<Int> contents = buffer.data<Int>(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(contents.size(), 5); CORRADE_COMPARE(contents[0], 2); CORRADE_COMPARE(contents[1], 7); CORRADE_COMPARE(contents[2], 5); CORRADE_COMPARE(contents[3], 13); CORRADE_COMPARE(contents[4], 25); #endif /* Plain array */ constexpr Int subData[] = {125, 3, 15}; buffer.setSubData(4, {subData, 3}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /* STL vector */ std::vector<Int> subData2{125, 3, 15}; buffer.setSubData(4, subData2); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /* STL array */ std::array<Int, 3> subData3{{125, 3, 15}}; buffer.setSubData(4, subData3); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(buffer.size(), 5*4); /** @todo How to verify the contents in ES? */ #ifndef MAGNUM_TARGET_GLES const Containers::Array<Int> subContents = buffer.subData<Int>(4, 3); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(subContents.size(), 3); CORRADE_COMPARE(subContents[0], 125); CORRADE_COMPARE(subContents[1], 3); CORRADE_COMPARE(subContents[2], 15); #endif }
void ComplexTest::length() { CORRADE_COMPARE(Complex(-4.0f, 3.0f).length(), 5.0f); }
void ForceRendererTest::antiParallel3D() { CORRADE_COMPARE(Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, Vector3::xAxis(-2.5f)), Matrix4::translation({0.5f, -3.0f, 1.0f})*Matrix4::scaling({-2.5f, 2.5f, 2.5f})); }
void ComplexTest::conjugated() { CORRADE_COMPARE(Complex(-3.0f, 4.5f).conjugated(), Complex(-3.0f, -4.5f)); }
void Vector4Test::constructDefault() { constexpr Vector4 a; constexpr Vector4 b{ZeroInit}; CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); }
void ComplexTest::debug() { std::ostringstream o; Debug(&o) << Complex(2.5f, -7.5f); CORRADE_COMPARE(o.str(), "Complex(2.5, -7.5)\n"); }
void Vector4Test::constructParts() { constexpr Vector3 a(1.0f, 2.0f, 3.0f); constexpr Vector4 b = {a, 4.0f}; CORRADE_COMPARE(b, Vector4(1.0f, 2.0f, 3.0f, 4.0f)); }
void TesterTest::test() { /* Print to visually verify coloring */ { Debug{} << "======================== visual color verification start ======================="; Test t{&std::cout}; t.registerTest("here.cpp", "TesterTest::Test"); t.exec(0, nullptr); Debug{} << "======================== visual color verification end ========================="; } std::stringstream out; Test t{&out}; t.registerTest("here.cpp", "TesterTest::Test"); int result = t.exec(noColorArgc, noColorArgv, &out, &out); CORRADE_VERIFY(result == 1); std::string expected = "Starting TesterTest::Test with 34 test cases...\n" " ? [01] <unknown>()\n" " OK [02] trueExpression()\n" " FAIL [03] falseExpression() at here.cpp on line 164\n" " Expression 5 != 5 failed.\n" " OK [04] equal()\n" " FAIL [05] nonEqual() at here.cpp on line 174\n" " Values a and b are not the same, actual is\n" " 5\n" " but expected\n" " 3\n" " XFAIL [06] expectFail() at here.cpp on line 180\n" " The world is not mad yet. 2 + 2 and 5 are not equal.\n" " XFAIL [06] expectFail() at here.cpp on line 181\n" " The world is not mad yet. Expression false == true failed.\n" " OK [06] expectFail()\n" " XPASS [07] unexpectedPassExpression() at here.cpp on line 194\n" " Expression true == true was expected to fail.\n" " XPASS [08] unexpectedPassEqual() at here.cpp on line 199\n" " 2 + 2 and 4 are not expected to be equal.\n" " OK [09] compareAs()\n" " FAIL [10] compareAsFail() at here.cpp on line 207\n" " Length of actual \"meh\" doesn't match length of expected \"hello\" with epsilon 0\n" " OK [11] compareWith()\n" " FAIL [12] compareWithFail() at here.cpp on line 215\n" " Length of actual \"You rather GTFO\" doesn't match length of expected \"hello\" with epsilon 9\n" " FAIL [13] compareImplicitConversionFail() at here.cpp on line 220\n" " Values \"holla\" and hello are not the same, actual is\n" " holla\n" " but expected\n" " hello\n" " SKIP [14] skip()\n" " This testcase is skipped.\n" " OK [15] testCaseName<15>()\n" " ? [16] testCaseName<27>()\n" " OK [17] testCaseDescription(hello)\n" " [18] setting up...\n" " [18] tearing down...\n" " OK [18] setupTeardown()\n" " [19] setting up...\n" " [19] tearing down...\n" " ? [19] <unknown>()\n" " [20] setting up...\n" " FAIL [20] setupTeardownFail() at here.cpp on line 257\n" " Expression false failed.\n" " [20] tearing down...\n" " [21] setting up...\n" " SKIP [21] setupTeardownSkip()\n" " Skipped.\n" " [21] tearing down...\n" " OK [22] instancedTest(zero)\n" " OK [23] instancedTest(1)\n" " FAIL [24] instancedTest(two) at here.cpp on line 282\n" " Values data.value*data.value*data.value and data.result are not the same, actual is\n" " 125\n" " but expected\n" " 122\n" " OK [25] instancedTest(3)\n" " OK [26] instancedTest(last)\n" " OK [27] repeatedTest()@50\n" " ? [28] <unknown>()@50\n" " FAIL [29] repeatedTestFail()@18 at here.cpp on line 292\n" " Expression _i++ < 17 failed.\n" " SKIP [30] repeatedTestSkip()@29\n" " Too late.\n" " [31] setting up...\n" " [31] tearing down...\n" " [31] setting up...\n" " [31] tearing down...\n" " OK [31] repeatedTestSetupTeardown()@2\n" " [32] setting up...\n" " [32] tearing down...\n" " [32] setting up...\n" " [32] tearing down...\n" " ? [32] <unknown>()@2\n" " [33] setting up...\n" " FAIL [33] repeatedTestSetupTeardownFail()@1 at here.cpp on line 306\n" " Expression false failed.\n" " [33] tearing down...\n" " [34] setting up...\n" " SKIP [34] repeatedTestSetupTeardownSkip()@1\n" " Skipped.\n" " [34] tearing down...\n" "Finished TesterTest::Test with 11 errors out of 95 checks. 5 test cases didn't contain any checks!\n"; //CORRADE_COMPARE(out.str().length(), expected.length()); CORRADE_COMPARE(out.str(), expected); }