void TypeTraitsTest::isIterable() { /* Non-iterable types */ CORRADE_VERIFY(!IsIterable<int>{}); /* STL types with begin()/end() members */ CORRADE_VERIFY(IsIterable<std::vector<int>>{}); CORRADE_VERIFY(IsIterable<std::string>{}); /* STL types with std::begin()/std::end() only */ CORRADE_VERIFY(IsIterable<std::valarray<int>>{}); /* Types with out-of-class begin()/end() */ { #ifdef CORRADE_GCC47_COMPATIBILITY CORRADE_EXPECT_FAIL("GCC 4.7 has broken SFINAE in this case (results in compile error when not present)"); #endif CORRADE_VERIFY(IsIterable<Type>{}); } /* Corrade types */ CORRADE_VERIFY(IsIterable<Containers::Array<int>>{}); { #ifdef CORRADE_GCC47_COMPATIBILITY CORRADE_EXPECT_FAIL("GCC 4.7 has broken SFINAE in this case (results in compile error when not present)"); #endif CORRADE_VERIFY(IsIterable<Containers::LinkedList<LinkedListItem>>{}); } }
void ArrayTest::pointerConversion() { Array a(2); int* b = a; CORRADE_COMPARE(b, a.begin()); const Array c(3); const int* d = c; CORRADE_COMPARE(d, c.begin()); /* Pointer arithmetic */ const Array e(3); const int* f = e + 2; CORRADE_COMPARE(f, &e[2]); /* Verify that we can't convert rvalues */ CORRADE_VERIFY((std::is_convertible<Array&, int*>::value)); CORRADE_VERIFY((std::is_convertible<const Array&, 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<Array, int*>::value)); CORRADE_VERIFY(!(std::is_convertible<Array&&, 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 Array, const int*>::value)); CORRADE_VERIFY(!(std::is_convertible<const Array&&, const int*>::value)); } }
void DirectoryTest::list() { /* All */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR), (std::vector<std::string>{".", "..", "dir", "file"}), TestSuite::Compare::SortedContainer); { #ifdef TRAVIS_CI_HAS_CRAZY_FILESYSTEM_ON_LINUX CORRADE_EXPECT_FAIL("Travis CI has crazy filesystem on Linux."); #endif /* Skip special */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SkipSpecial), (std::vector<std::string>{".", "..", "dir", "file"}), TestSuite::Compare::SortedContainer); } /* All, sorted ascending */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SortAscending), (std::vector<std::string>{".", "..", "dir", "file"}), TestSuite::Compare::Container); /* All, sorted descending */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SortDescending), (std::vector<std::string>{"file", "dir", "..", "."}), TestSuite::Compare::Container); /* Skip . and .. */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SkipDotAndDotDot), (std::vector<std::string>{"dir", "file"}), TestSuite::Compare::SortedContainer); { #ifdef TRAVIS_CI_HAS_CRAZY_FILESYSTEM_ON_LINUX CORRADE_EXPECT_FAIL("Travis CI has crazy filesystem on Linux."); #endif /* Skip directories */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SkipDirectories), std::vector<std::string>{"file"}, TestSuite::Compare::SortedContainer); /* Skip files */ CORRADE_COMPARE_AS(Directory::list(DIRECTORY_TEST_DIR, Directory::Flag::SkipFiles), (std::vector<std::string>{".", "..", "dir"}), TestSuite::Compare::SortedContainer); } }
void DirectoryTest::home() { const std::string home = Directory::home(); Debug() << "Home dir found as:" << home; /* On OSX verify that the home dir contains `Desktop` directory. Hopefully that's true on all language mutations. */ #ifdef CORRADE_TARGET_APPLE CORRADE_VERIFY(Directory::fileExists(Directory::join(home, "Desktop"))); /* On other Unixes verify that the home dir contains `.local` directory. Ugly and hacky, but it's the best I came up with. Can't test for e.g. `/home/` substring, as that can be overriden. */ #elif defined(CORRADE_TARGET_UNIX) CORRADE_VERIFY(Directory::fileExists(Directory::join(home, ".local"))); /* On Windows verify that the home dir contains `desktop.ini` file. Ugly and hacky, but it's the best I came up with. Can't test for e.g. `/Users/` substring, as that can be overriden. */ #elif defined(CORRADE_TARGET_WINDOWS) CORRADE_VERIFY(Directory::fileExists(Directory::join(home, "desktop.ini"))); /* No idea elsewhere */ #else CORRADE_EXPECT_FAIL("Not implemented yet."); CORRADE_COMPARE(home, "(not implemented)"); #endif }
void BufferTextureGLTest::bind() { if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_buffer_object>()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); BufferTexture texture; if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) { CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it"); Buffer buffer; constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; buffer.setData(data, BufferUsage::StaticDraw); texture.setBuffer(BufferTextureFormat::R8UI, buffer); CORRADE_VERIFY(false); } texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); AbstractTexture::unbind(15); MAGNUM_VERIFY_NO_ERROR(); AbstractTexture::bind(7, {&texture, nullptr, &texture}); MAGNUM_VERIFY_NO_ERROR(); }
void DirectoryTest::configurationDir() { const std::string dir = Directory::configurationDir("Corrade"); Debug() << "Configuration dir found as:" << dir; /* On Linux verify that the parent dir contains `autostart` directory, something from GTK or something from Qt. Ugly and hacky, but it's the best I could come up with. Can't test for e.g. `/home/` substring, as that can be overriden. */ #if __linux__ CORRADE_COMPARE(dir.substr(dir.size()-7), "corrade"); CORRADE_VERIFY(Directory::fileExists(Directory::join(Directory::path(dir), "autostart")) || Directory::fileExists(Directory::join(Directory::path(dir), "dconf")) || Directory::fileExists(Directory::join(Directory::path(dir), "Trolltech.conf"))); /* On Windows verify that the parent dir contains `Microsoft` subdirectory. Ugly and hacky, but it's the best I came up with. Can't test for e.g. `/Users/` substring, as that can be overriden. */ #elif defined(CORRADE_TARGET_WINDOWS) CORRADE_COMPARE(dir.substr(dir.size()-7), "Corrade"); CORRADE_VERIFY(Directory::fileExists(Directory::join(Directory::path(dir), "Microsoft"))); /* No idea elsewhere */ #else CORRADE_EXPECT_FAIL("Not implemented yet."); CORRADE_COMPARE(dir, "(not implemented)"); #endif }
void AbstractQueryGLTest::label() { #ifdef MAGNUM_TARGET_GLES2 if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::occlusion_query_boolean>()) CORRADE_SKIP(Extensions::GL::EXT::occlusion_query_boolean::string() + std::string(" is not supported.")); #endif /* No-Op version is tested in AbstractObjectGLTest */ if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() && !Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>()) CORRADE_SKIP("Required extension is not available"); { /** @todo Is this even legal optimization? */ CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label."); CORRADE_VERIFY(false); } SampleQuery query; query.begin(SampleQuery::Target::AnySamplesPassed); query.end(); CORRADE_COMPARE(query.label(), ""); query.setLabel("MyQuery"); CORRADE_COMPARE(query.label(), "MyQuery"); MAGNUM_VERIFY_NO_ERROR(); }
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 }
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 StringTest::uppercase() { /* Lowecase */ CORRADE_COMPARE(String::uppercase("hello"), "HELLO"); /* Uppercase */ CORRADE_COMPARE(String::uppercase("QWERTZUIOP"), "QWERTZUIOP"); /* Special chars */ CORRADE_COMPARE(String::uppercase(".,?- \"!/(98765%"), ".,?- \"!/(98765%"); /* UTF-8 */ CORRADE_EXPECT_FAIL("UTF-8 uppercasing is not supported."); CORRADE_COMPARE(String::uppercase("ěščřžýáíéúůďťň"), "ĚŠČŘŽÝÁÍÉÚŮĎŤŇ"); }
void StaticArrayViewTest::constructDerived() { struct A { int i; }; struct B: A {}; /* See ArrayViewTest for comments */ CORRADE_VERIFY((std::is_convertible<B(&)[5], 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; }; /* See ArrayViewTest for comments */ CORRADE_VERIFY(!(std::is_convertible<C(&)[5], Containers::StaticArrayView<5, A>>::value)); } }
void ImageDataTest::toReference() { auto data = new unsigned char[3]; const Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); ImageReference2D b = a; CORRADE_COMPARE(b.format(), ColorFormat::Red); CORRADE_COMPARE(b.type(), ColorType::UnsignedByte); CORRADE_COMPARE(b.size(), Vector2i(1, 3)); CORRADE_COMPARE(b.data(), data); CORRADE_VERIFY((std::is_convertible<const Trade::ImageData2D&, ImageReference2D>::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<const Trade::ImageData2D, ImageReference2D>::value)); CORRADE_VERIFY(!(std::is_convertible<const Trade::ImageData2D&&, ImageReference2D>::value)); } }
void ShapeTest::collision() { Scene3D scene; ShapeGroup3D shapes; Object3D a(&scene); Shape<Shapes::Sphere3D> aShape(a, {{1.0f, -2.0f, 3.0f}, 1.5f}, &shapes); { /* Collision with point inside the sphere */ Shape<Shapes::Point3D> aShape2(a, {{1.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); const Collision3D collision = aShape.collision(aShape2); CORRADE_VERIFY(collision); CORRADE_COMPARE(collision.position(), Vector3(1.0f, -2.0f, 3.0f)); } { /* No collision with point inside the sphere, but not in the same group */ ShapeGroup3D shapes2; Shape<Shapes::Point3D> aShape3(a, {{1.0f, -2.0f, 3.0f}}, &shapes2); shapes2.setClean(); CORRADE_VERIFY(!aShape.collision(aShape3)); } { CORRADE_EXPECT_FAIL("Should cross-scene collision work or not?"); /* No collision with point inside the sphere, but not in the same scene */ Scene3D scene2; Object3D c(&scene2); Shape<Shapes::Point3D> cShape(c, {{1.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); CORRADE_VERIFY(!aShape.collision(cShape)); } { /* No collision with point outside of the sphere */ Object3D b(&scene); Shape<Shapes::Point3D> bShape(b, {{3.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); CORRADE_VERIFY(!aShape.collision(bShape)); /* Move point inside the sphere -- collision */ b.translate(Vector3::xAxis(-1.0f)); shapes.setClean(); const Collision3D collision = aShape.collision(bShape); CORRADE_VERIFY(collision); CORRADE_COMPARE(collision.position(), Vector3(2.0f, -2.0f, 3.0f)); } }
void StbTrueTypeFontGLTest::properties() { StbTrueTypeFont font; CORRADE_VERIFY(font.openFile(Utility::Directory::join(FREETYPEFONT_TEST_DIR, "Oxygen.ttf"), 16.0f)); CORRADE_COMPARE(font.size(), 16.0f); CORRADE_COMPARE(font.glyphId(U'W'), 58); { CORRADE_EXPECT_FAIL("Font properties don't match FreeType with the same font size."); CORRADE_COMPARE(font.ascent(), 15.0f); CORRADE_COMPARE(font.descent(), -4.0f); CORRADE_COMPARE(font.lineHeight(), 19.0f); CORRADE_COMPARE(font.glyphAdvance(58), Vector2(17.0f, 0.0f)); } { /* Test that we are at least consistently wrong */ CORRADE_COMPARE(font.ascent(), 17.0112f); CORRADE_COMPARE(font.descent(), -4.32215f); CORRADE_COMPARE(font.lineHeight(), 21.3333f); CORRADE_COMPARE(font.glyphAdvance(58), Vector2(19.0694f, 0.0f)); } }
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 StbTrueTypeFontGLTest::layout() { StbTrueTypeFont font; CORRADE_VERIFY(font.openFile(Utility::Directory::join(FREETYPEFONT_TEST_DIR, "Oxygen.ttf"), 16.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}}); std::unique_ptr<AbstractLayouter> layouter = font.layout(cache, 0.5f, "Wave"); CORRADE_VERIFY(layouter); CORRADE_COMPARE(layouter->glyphCount(), 4); Vector2 cursorPosition; Range2D rectangle, position, textureCoordinates; /* 'W' */ 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_EXPECT_FAIL("Font properties don't match FreeType with the same font size."); CORRADE_COMPARE(cursorPosition, Vector2(0.53125f, 0.0f)); } { /* Test that we are at least consistently wrong */ CORRADE_COMPARE(cursorPosition, Vector2(0.595917f, 0.0f)); } /* 'a' (not in cache) */ std::tie(position, textureCoordinates) = layouter->renderGlyph(1, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D()); CORRADE_COMPARE(textureCoordinates, Range2D()); { CORRADE_EXPECT_FAIL("Font properties don't match FreeType with the same font size."); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); } { /* Test that we are at least consistently wrong */ CORRADE_COMPARE(cursorPosition, Vector2(0.295582f, 0.0f)); } /* 'v' (not in cache) */ std::tie(position, textureCoordinates) = layouter->renderGlyph(2, cursorPosition = {}, rectangle); CORRADE_COMPARE(position, Range2D()); CORRADE_COMPARE(textureCoordinates, Range2D()); { CORRADE_EXPECT_FAIL("Font properties don't match FreeType with the same font size."); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); } { /* Test that we are at least consistently wrong */ CORRADE_COMPARE(cursorPosition, Vector2(0.289709f, 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_EXPECT_FAIL("Font properties don't match FreeType with the same font size."); CORRADE_COMPARE(cursorPosition, Vector2(0.28125f, 0.0f)); } { /* Test that we are at least consistently wrong */ CORRADE_COMPARE(cursorPosition, Vector2(0.298658f, 0.0f)); } }
void Test::unexpectedPassEqual() { CORRADE_EXPECT_FAIL("Cannot get it right."); CORRADE_COMPARE(2 + 2, 4); // #9 }
void Test::unexpectedPassExpression() { CORRADE_EXPECT_FAIL("Not yet implemented."); CORRADE_VERIFY(true == true); // #8 }