diff --git a/src/Magnum/Primitives/CMakeLists.txt b/src/Magnum/Primitives/CMakeLists.txt index 3dc919cf6..31871b2bb 100644 --- a/src/Magnum/Primitives/CMakeLists.txt +++ b/src/Magnum/Primitives/CMakeLists.txt @@ -30,23 +30,25 @@ set(CMAKE_FOLDER "Magnum/Primitives") set(MagnumPrimitives_SRCS Axis.cpp - Capsule.cpp - Circle.cpp Crosshair.cpp - Cone.cpp Cube.cpp - Cylinder.cpp Gradient.cpp Grid.cpp Icosphere.cpp Line.cpp Plane.cpp Square.cpp - UVSphere.cpp Implementation/Spheroid.cpp Implementation/WireframeSpheroid.cpp) +set(MagnumPrimitives_GracefulAssert_SRCS + Capsule.cpp + Circle.cpp + Cone.cpp + Cylinder.cpp + UVSphere.cpp) + set(MagnumPrimitives_HEADERS Axis.h Capsule.h @@ -70,11 +72,23 @@ set(MagnumPrimitives_PRIVATE_HEADERS Implementation/Spheroid.h Implementation/WireframeSpheroid.h) -# Primitives library -add_library(MagnumPrimitives ${SHARED_OR_STATIC} +# Objects shared between main and test library +add_library(MagnumPrimitivesObjects OBJECT ${MagnumPrimitives_SRCS} ${MagnumPrimitives_HEADERS} ${MagnumPrimitives_PRIVATE_HEADERS}) +target_include_directories(MagnumPrimitivesObjects PUBLIC $) +if(NOT MAGNUM_BUILD_STATIC) + target_compile_definitions(MagnumPrimitivesObjects PRIVATE "MagnumPrimitivesObjects_EXPORTS") +endif() +if(NOT MAGNUM_BUILD_STATIC OR MAGNUM_BUILD_STATIC_PIC) + set_target_properties(MagnumPrimitivesObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + +# Primitives library +add_library(MagnumPrimitives ${SHARED_OR_STATIC} + $ + ${MagnumPrimitives_GracefulAssert_SRCS}) set_target_properties(MagnumPrimitives PROPERTIES DEBUG_POSTFIX "-d") if(NOT MAGNUM_BUILD_STATIC) @@ -94,6 +108,21 @@ install(TARGETS MagnumPrimitives install(FILES ${MagnumPrimitives_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Primitives) if(MAGNUM_BUILD_TESTS) + # Library with graceful assert for testing + add_library(MagnumPrimitivesTestLib ${SHARED_OR_STATIC} ${EXCLUDE_FROM_ALL_IF_TEST_TARGET} + $ + ${MagnumPrimitives_GracefulAssert_SRCS}) + set_target_properties(MagnumPrimitivesTestLib PROPERTIES DEBUG_POSTFIX "-d") + target_compile_definitions(MagnumPrimitivesTestLib PRIVATE + "CORRADE_GRACEFUL_ASSERT" "MagnumPrimitives_EXPORTS") + if(MAGNUM_BUILD_STATIC_PIC) + set_target_properties(MagnumPrimitivesTestLib PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + target_link_libraries(MagnumPrimitivesTestLib PUBLIC + Magnum + MagnumMeshTools + MagnumTrade) + add_subdirectory(Test ${EXCLUDE_FROM_ALL_IF_TEST_TARGET}) endif() diff --git a/src/Magnum/Primitives/Capsule.cpp b/src/Magnum/Primitives/Capsule.cpp index 9bfd1a232..db10e26f5 100644 --- a/src/Magnum/Primitives/Capsule.cpp +++ b/src/Magnum/Primitives/Capsule.cpp @@ -38,7 +38,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const Float halfLength) { CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1, - "Primitives::capsule2DWireframe(): at least one hemisphere ring and one cylinder ring expected", + "Primitives::capsule2DWireframe(): expected at least one hemisphere ring and one cylinder ring but got" << hemisphereRings << "and" << cylinderRings, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Containers::Array vertexData; @@ -109,7 +109,7 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi Trade::MeshData capsule3DSolid(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const UnsignedInt segments, const Float halfLength, const CapsuleFlags flags) { CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, - "Primitives::capsule3DSolid(): at least one hemisphere ring, one cylinder ring and three segments expected", + "Primitives::capsule3DSolid(): expected at least one hemisphere ring, one cylinder ring and three segments but got" << hemisphereRings << Debug::nospace << "," << cylinderRings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::Spheroid capsule{segments, Implementation::Spheroid::Flag(UnsignedByte(flags))}; @@ -153,7 +153,7 @@ CORRADE_IGNORE_DEPRECATED_POP Trade::MeshData capsule3DWireframe(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const UnsignedInt segments, const Float halfLength) { CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 4 && segments%4 == 0, - "Primitives::capsule3DWireframe(): at least one hemisphere and cylinder ring and multiples of 4 segments expected", + "Primitives::capsule3DWireframe(): expected at least one hemisphere ring, one cylinder ring and multiples of 4 segments but got" << hemisphereRings << Debug::nospace << "," << cylinderRings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::WireframeSpheroid capsule(segments/4); diff --git a/src/Magnum/Primitives/Circle.cpp b/src/Magnum/Primitives/Circle.cpp index e9461d558..6459a046a 100644 --- a/src/Magnum/Primitives/Circle.cpp +++ b/src/Magnum/Primitives/Circle.cpp @@ -50,7 +50,7 @@ constexpr Trade::MeshAttributeData AttributeData2DTextureCoords[]{ } Trade::MeshData circle2DSolid(const UnsignedInt segments, const Circle2DFlags flags) { - CORRADE_ASSERT(segments >= 3, "Primitives::circle2DSolid(): segments must be >= 3", + CORRADE_ASSERT(segments >= 3, "Primitives::circle2DSolid(): expected at least three segments but got" << segments, (Trade::MeshData{MeshPrimitive::TriangleFan, 0})); /* Allocate interleaved array for all vertex data */ @@ -98,7 +98,7 @@ CORRADE_IGNORE_DEPRECATED_POP #endif Trade::MeshData circle2DWireframe(const UnsignedInt segments) { - CORRADE_ASSERT(segments >= 3, "Primitives::circle2DWireframe(): segments must be >= 3", + CORRADE_ASSERT(segments >= 3, "Primitives::circle2DWireframe(): expected at least three segments but got" << segments, (Trade::MeshData{MeshPrimitive::LineLoop, 0})); Containers::Array vertexData{segments*sizeof(Vector2)}; @@ -117,7 +117,7 @@ Trade::MeshData circle2DWireframe(const UnsignedInt segments) { } Trade::MeshData circle3DSolid(const UnsignedInt segments, const Circle3DFlags flags) { - CORRADE_ASSERT(segments >= 3, "Primitives::circle3DSolid(): segments must be >= 3", + CORRADE_ASSERT(segments >= 3, "Primitives::circle3DSolid(): expected at least three segments but got" << segments, (Trade::MeshData{MeshPrimitive::TriangleFan, 0})); /* Calculate attribute count and vertex size */ @@ -219,7 +219,7 @@ constexpr Trade::MeshAttributeData AttributeData3DWireframe[]{ } Trade::MeshData circle3DWireframe(const UnsignedInt segments) { - CORRADE_ASSERT(segments >= 3, "Primitives::circle3DWireframe(): segments must be >= 3", + CORRADE_ASSERT(segments >= 3, "Primitives::circle3DWireframe(): expected at least three segments but got" << segments, (Trade::MeshData{MeshPrimitive::LineLoop, 0})); Containers::Array vertexData{segments*sizeof(Vector3)}; diff --git a/src/Magnum/Primitives/Cone.cpp b/src/Magnum/Primitives/Cone.cpp index 91b5bd94c..76a2ed175 100644 --- a/src/Magnum/Primitives/Cone.cpp +++ b/src/Magnum/Primitives/Cone.cpp @@ -36,7 +36,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData coneSolid(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength, const ConeFlags flags) { CORRADE_ASSERT(rings >= 1 && segments >= 3, - "Primitives::coneSolid(): at least one ring and three segments expected", + "Primitives::coneSolid(): expected at least one ring and three segments but got" << rings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::Spheroid cone{segments, Implementation::Spheroid::Flag(UnsignedByte(flags))}; @@ -67,7 +67,7 @@ Trade::MeshData coneSolid(const UnsignedInt rings, const UnsignedInt segments, c Trade::MeshData coneWireframe(const UnsignedInt segments, const Float halfLength) { CORRADE_ASSERT(segments >= 4 && segments%4 == 0, - "Primitives::coneWireframe(): multiples of 4 segments expected", + "Primitives::coneWireframe(): expected multiples of 4 segments but got" << segments, (Trade::MeshData{MeshPrimitive::Lines, 0})); Implementation::WireframeSpheroid cone{segments/4}; diff --git a/src/Magnum/Primitives/Cylinder.cpp b/src/Magnum/Primitives/Cylinder.cpp index 968d4cc0b..1c3f0d3e6 100644 --- a/src/Magnum/Primitives/Cylinder.cpp +++ b/src/Magnum/Primitives/Cylinder.cpp @@ -36,7 +36,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData cylinderSolid(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength, const CylinderFlags flags) { CORRADE_ASSERT(rings >= 1 && segments >= 3, - "Primitives::cylinderSolid(): at least one ring and three segments expected", + "Primitives::cylinderSolid(): expected at least one ring and three segments but got" << rings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::Spheroid cylinder{segments, Implementation::Spheroid::Flag(UnsignedByte(flags))}; @@ -74,7 +74,7 @@ Trade::MeshData cylinderSolid(const UnsignedInt rings, const UnsignedInt segment Trade::MeshData cylinderWireframe(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength) { CORRADE_ASSERT(rings >= 1 && segments >= 4 && segments%4 == 0, - "Primitives::cylinderWireframe(): at least one ring and multiples of 4 segments expected", + "Primitives::cylinderWireframe(): expected at least one ring and multiples of 4 segments but got" << rings << "and" << segments, (Trade::MeshData{MeshPrimitive::Lines, 0})); Implementation::WireframeSpheroid cylinder(segments/4); diff --git a/src/Magnum/Primitives/Test/CMakeLists.txt b/src/Magnum/Primitives/Test/CMakeLists.txt index e4f9eac40..d2713afc1 100644 --- a/src/Magnum/Primitives/Test/CMakeLists.txt +++ b/src/Magnum/Primitives/Test/CMakeLists.txt @@ -29,16 +29,16 @@ set(CMAKE_FOLDER "Magnum/Primitives/Test") corrade_add_test(PrimitivesAxisTest AxisTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesCircleTest CircleTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test(PrimitivesCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPrimitivesTestLib) +corrade_add_test(PrimitivesCircleTest CircleTest.cpp LIBRARIES MagnumPrimitivesTestLib) corrade_add_test(PrimitivesCrosshairTest CrosshairTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesCubeTest CubeTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesConeTest ConeTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesCylinderTest CylinderTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test(PrimitivesConeTest ConeTest.cpp LIBRARIES MagnumPrimitivesTestLib) +corrade_add_test(PrimitivesCylinderTest CylinderTest.cpp LIBRARIES MagnumPrimitivesTestLib) corrade_add_test(PrimitivesGradientTest GradientTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesGridTest GridTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesIcosphereTest IcosphereTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesLineTest LineTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesPlaneTest PlaneTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesSquareTest SquareTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitivesTestLib) diff --git a/src/Magnum/Primitives/Test/CapsuleTest.cpp b/src/Magnum/Primitives/Test/CapsuleTest.cpp index bea5ae40d..a74dd4295 100644 --- a/src/Magnum/Primitives/Test/CapsuleTest.cpp +++ b/src/Magnum/Primitives/Test/CapsuleTest.cpp @@ -24,8 +24,10 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include +#include #include "Magnum/Math/Vector4.h" #include "Magnum/Trade/MeshData.h" @@ -37,10 +39,14 @@ struct CapsuleTest: TestSuite::Tester { explicit CapsuleTest(); void wireframe2D(); + void wireframe2DInvalid(); void solid3DWithoutTextureCoordinates(); void solid3DWithTextureCoordinatesOrTangents(); + void solid3DInvalid(); + void wireframe3D(); + void wireframe3DInvalid(); }; constexpr struct { @@ -54,12 +60,15 @@ constexpr struct { CapsuleTest::CapsuleTest() { addTests({&CapsuleTest::wireframe2D, + &CapsuleTest::wireframe2DInvalid, &CapsuleTest::solid3DWithoutTextureCoordinates}); addInstancedTests({&CapsuleTest::solid3DWithTextureCoordinatesOrTangents}, Containers::arraySize(TextureCoordinatesOrTangentsData)); - addTests({&CapsuleTest::wireframe3D}); + addTests({&CapsuleTest::solid3DInvalid, + &CapsuleTest::wireframe3D, + &CapsuleTest::wireframe3DInvalid}); } void CapsuleTest::wireframe2D() { @@ -110,6 +119,22 @@ void CapsuleTest::wireframe2D() { }), TestSuite::Compare::Container); } +void CapsuleTest::wireframe2DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::capsule2DWireframe(1, 1, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::capsule2DWireframe(0, 1, 1.0f); + Primitives::capsule2DWireframe(1, 0, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::capsule2DWireframe(): expected at least one hemisphere ring and one cylinder ring but got 0 and 1\n" + "Primitives::capsule2DWireframe(): expected at least one hemisphere ring and one cylinder ring but got 1 and 0\n", + TestSuite::Compare::String); +} + void CapsuleTest::solid3DWithoutTextureCoordinates() { Trade::MeshData capsule = capsule3DSolid(2, 4, 3, 0.5f); @@ -197,6 +222,24 @@ void CapsuleTest::solid3DWithoutTextureCoordinates() { }), TestSuite::Compare::Container); } +void CapsuleTest::solid3DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::capsule3DSolid(1, 1, 3, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::capsule3DSolid(0, 1, 3, 1.0f); + Primitives::capsule3DSolid(1, 0, 3, 1.0f); + Primitives::capsule3DSolid(1, 1, 2, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::capsule3DSolid(): expected at least one hemisphere ring, one cylinder ring and three segments but got 0, 1 and 3\n" + "Primitives::capsule3DSolid(): expected at least one hemisphere ring, one cylinder ring and three segments but got 1, 0 and 3\n" + "Primitives::capsule3DSolid(): expected at least one hemisphere ring, one cylinder ring and three segments but got 1, 1 and 2\n", + TestSuite::Compare::String); +} + void CapsuleTest::solid3DWithTextureCoordinatesOrTangents() { auto&& data = TextureCoordinatesOrTangentsData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -396,6 +439,27 @@ void CapsuleTest::wireframe3D() { }), TestSuite::Compare::Container); } +void CapsuleTest::wireframe3DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::capsule3DWireframe(1, 1, 4, 1.0f); + Primitives::capsule3DWireframe(1, 1, 16, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::capsule3DWireframe(0, 1, 4, 1.0f); + Primitives::capsule3DWireframe(1, 0, 4, 1.0f); + Primitives::capsule3DWireframe(1, 1, 9, 1.0f); + Primitives::capsule3DWireframe(1, 1, 0, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::capsule3DWireframe(): expected at least one hemisphere ring, one cylinder ring and multiples of 4 segments but got 0, 1 and 4\n" + "Primitives::capsule3DWireframe(): expected at least one hemisphere ring, one cylinder ring and multiples of 4 segments but got 1, 0 and 4\n" + "Primitives::capsule3DWireframe(): expected at least one hemisphere ring, one cylinder ring and multiples of 4 segments but got 1, 1 and 9\n" + "Primitives::capsule3DWireframe(): expected at least one hemisphere ring, one cylinder ring and multiples of 4 segments but got 1, 1 and 0\n", + TestSuite::Compare::String); +} + }}}} CORRADE_TEST_MAIN(Magnum::Primitives::Test::CapsuleTest) diff --git a/src/Magnum/Primitives/Test/CircleTest.cpp b/src/Magnum/Primitives/Test/CircleTest.cpp index 34ead240d..ee996fbef 100644 --- a/src/Magnum/Primitives/Test/CircleTest.cpp +++ b/src/Magnum/Primitives/Test/CircleTest.cpp @@ -24,6 +24,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include @@ -38,10 +39,14 @@ struct CircleTest: TestSuite::Tester { explicit CircleTest(); void solid2D(); + void solid2DInvalid(); void solid3D(); + void solid3DInvalid(); void wireframe2D(); + void wireframe2DInvalid(); void wireframe3D(); + void wireframe3DInvalid(); }; constexpr struct { @@ -66,11 +71,17 @@ CircleTest::CircleTest() { addInstancedTests({&CircleTest::solid2D}, Containers::arraySize(Solid2DData)); + addTests({&CircleTest::solid2DInvalid}); + addInstancedTests({&CircleTest::solid3D}, Containers::arraySize(Solid3DData)); + addTests({&CircleTest::solid3DInvalid}); + addTests({&CircleTest::wireframe2D, - &CircleTest::wireframe3D}); + &CircleTest::wireframe2DInvalid, + &CircleTest::wireframe3D, + &CircleTest::wireframe3DInvalid}); } void CircleTest::solid2D() { @@ -102,6 +113,18 @@ void CircleTest::solid2D() { } else CORRADE_VERIFY(!circle.hasAttribute(Trade::MeshAttribute::TextureCoordinates)); } +void CircleTest::solid2DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::circle2DSolid(3); + + Containers::String out; + Error redirectError{&out}; + Primitives::circle2DSolid(2); + CORRADE_COMPARE(out, "Primitives::circle2DSolid(): expected at least three segments but got 2\n"); +} + void CircleTest::solid3D() { auto&& data = Solid3DData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -172,6 +195,18 @@ void CircleTest::solid3D() { } } +void CircleTest::solid3DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::circle3DSolid(3); + + Containers::String out; + Error redirectError{&out}; + Primitives::circle3DSolid(2); + CORRADE_COMPARE(out, "Primitives::circle3DSolid(): expected at least three segments but got 2\n"); +} + void CircleTest::wireframe2D() { Trade::MeshData circle = Primitives::circle2DWireframe(8); @@ -186,6 +221,18 @@ void CircleTest::wireframe2D() { }), TestSuite::Compare::Container); } +void CircleTest::wireframe2DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::circle2DWireframe(3); + + Containers::String out; + Error redirectError{&out}; + Primitives::circle2DWireframe(2); + CORRADE_COMPARE(out, "Primitives::circle2DWireframe(): expected at least three segments but got 2\n"); +} + void CircleTest::wireframe3D() { Trade::MeshData circle = Primitives::circle3DWireframe(8); @@ -200,6 +247,18 @@ void CircleTest::wireframe3D() { }), TestSuite::Compare::Container); } +void CircleTest::wireframe3DInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::circle3DWireframe(3); + + Containers::String out; + Error redirectError{&out}; + Primitives::circle3DWireframe(2); + CORRADE_COMPARE(out, "Primitives::circle3DWireframe(): expected at least three segments but got 2\n"); +} + }}}} CORRADE_TEST_MAIN(Magnum::Primitives::Test::CircleTest) diff --git a/src/Magnum/Primitives/Test/ConeTest.cpp b/src/Magnum/Primitives/Test/ConeTest.cpp index 8310e8f6e..7ac5cc1d5 100644 --- a/src/Magnum/Primitives/Test/ConeTest.cpp +++ b/src/Magnum/Primitives/Test/ConeTest.cpp @@ -24,8 +24,10 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include +#include #include "Magnum/Math/Vector4.h" #include "Magnum/Primitives/Cone.h" @@ -40,7 +42,10 @@ struct ConeTest: TestSuite::Tester { void solidWithCaps(); void solidWithTextureCoordinatesOrTangents(); void solidWithTextureCoordinatesOrTangentsAndCaps(); + void solidInvalid(); + void wireframe(); + void wireframeInvalid(); }; constexpr struct { @@ -61,7 +66,10 @@ ConeTest::ConeTest() { &ConeTest::solidWithTextureCoordinatesOrTangentsAndCaps}, Containers::arraySize(TextureCoordinatesOrTangentsData)); - addTests({&ConeTest::wireframe}); + addTests({&ConeTest::solidInvalid, + + &ConeTest::wireframe, + &ConeTest::wireframeInvalid}); } void ConeTest::solidWithoutAnything() { @@ -399,6 +407,22 @@ void ConeTest::solidWithTextureCoordinatesOrTangentsAndCaps() { }), TestSuite::Compare::Container); } +void ConeTest::solidInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::coneSolid(1, 3, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::coneSolid(0, 3, 1.0f); + Primitives::coneSolid(1, 2, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::coneSolid(): expected at least one ring and three segments but got 0 and 3\n" + "Primitives::coneSolid(): expected at least one ring and three segments but got 1 and 2\n", + TestSuite::Compare::String); +} + void ConeTest::wireframe() { Trade::MeshData cone = coneWireframe(8, 1.5f); @@ -427,6 +451,23 @@ void ConeTest::wireframe() { }), TestSuite::Compare::Container); } +void ConeTest::wireframeInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::coneWireframe(4, 1.0f); + Primitives::coneWireframe(16, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::coneWireframe(9, 1.0f); + Primitives::coneWireframe(0, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::coneWireframe(): expected multiples of 4 segments but got 9\n" + "Primitives::coneWireframe(): expected multiples of 4 segments but got 0\n", + TestSuite::Compare::String); +} + }}}} CORRADE_TEST_MAIN(Magnum::Primitives::Test::ConeTest) diff --git a/src/Magnum/Primitives/Test/CylinderTest.cpp b/src/Magnum/Primitives/Test/CylinderTest.cpp index a8bfeba5a..eee3e5969 100644 --- a/src/Magnum/Primitives/Test/CylinderTest.cpp +++ b/src/Magnum/Primitives/Test/CylinderTest.cpp @@ -24,8 +24,10 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include +#include #include "Magnum/Math/Vector4.h" #include "Magnum/Primitives/Cylinder.h" @@ -40,7 +42,10 @@ struct CylinderTest: TestSuite::Tester { void solidWithCaps(); void solidWithTextureCoordinatesOrTangents(); void solidWithTextureCoordinatesOrTangentsAndCaps(); + void solidInvalid(); + void wireframe(); + void wireframeInvalid(); }; constexpr struct { @@ -61,7 +66,10 @@ CylinderTest::CylinderTest() { &CylinderTest::solidWithTextureCoordinatesOrTangentsAndCaps}, Containers::arraySize(TextureCoordinatesOrTangentsData)); - addTests({&CylinderTest::wireframe}); + addTests({&CylinderTest::solidInvalid, + + &CylinderTest::wireframe, + &CylinderTest::wireframeInvalid}); } void CylinderTest::solidWithoutAnything() { @@ -441,6 +449,22 @@ void CylinderTest::solidWithTextureCoordinatesOrTangentsAndCaps() { }), TestSuite::Compare::Container); } +void CylinderTest::solidInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::cylinderSolid(1, 3, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::cylinderSolid(0, 3, 1.0f); + Primitives::cylinderSolid(1, 2, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::cylinderSolid(): expected at least one ring and three segments but got 0 and 3\n" + "Primitives::cylinderSolid(): expected at least one ring and three segments but got 1 and 2\n", + TestSuite::Compare::String); +} + void CylinderTest::wireframe() { Trade::MeshData cylinder = cylinderWireframe(2, 8, 0.5f); @@ -493,6 +517,25 @@ void CylinderTest::wireframe() { }), TestSuite::Compare::Container); } +void CylinderTest::wireframeInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::cylinderWireframe(1, 4, 1.0f); + Primitives::cylinderWireframe(1, 16, 1.0f); + + Containers::String out; + Error redirectError{&out}; + Primitives::cylinderWireframe(0, 4, 1.0f); + Primitives::cylinderWireframe(1, 9, 1.0f); + Primitives::cylinderWireframe(1, 0, 1.0f); + CORRADE_COMPARE_AS(out, + "Primitives::cylinderWireframe(): expected at least one ring and multiples of 4 segments but got 0 and 4\n" + "Primitives::cylinderWireframe(): expected at least one ring and multiples of 4 segments but got 1 and 9\n" + "Primitives::cylinderWireframe(): expected at least one ring and multiples of 4 segments but got 1 and 0\n", + TestSuite::Compare::String); +} + }}}} CORRADE_TEST_MAIN(Magnum::Primitives::Test::CylinderTest) diff --git a/src/Magnum/Primitives/Test/UVSphereTest.cpp b/src/Magnum/Primitives/Test/UVSphereTest.cpp index c570c9b85..735b5d294 100644 --- a/src/Magnum/Primitives/Test/UVSphereTest.cpp +++ b/src/Magnum/Primitives/Test/UVSphereTest.cpp @@ -24,8 +24,10 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include +#include #include "Magnum/Math/Vector4.h" #include "Magnum/Primitives/UVSphere.h" @@ -38,7 +40,10 @@ struct UVSphereTest: TestSuite::Tester { void solidWithoutTextureCoordinates(); void solidWithTextureCoordinatesOrTangents(); + void solidInvalid(); + void wireframe(); + void wireframeInvalid(); }; constexpr struct { @@ -56,7 +61,10 @@ UVSphereTest::UVSphereTest() { addInstancedTests({&UVSphereTest::solidWithTextureCoordinatesOrTangents}, Containers::arraySize(TextureCoordinatesOrTangentsData)); - addTests({&UVSphereTest::wireframe}); + addTests({&UVSphereTest::solidInvalid, + + &UVSphereTest::wireframe, + &UVSphereTest::wireframeInvalid}); } void UVSphereTest::solidWithoutTextureCoordinates() { @@ -182,6 +190,22 @@ void UVSphereTest::solidWithTextureCoordinatesOrTangents() { }), TestSuite::Compare::Container); } +void UVSphereTest::solidInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::uvSphereSolid(2, 3); + + Containers::String out; + Error redirectError{&out}; + Primitives::uvSphereSolid(1, 3); + Primitives::uvSphereSolid(2, 2); + CORRADE_COMPARE_AS(out, + "Primitives::uvSphereSolid(): expected at least two rings and three segments but got 1 and 3\n" + "Primitives::uvSphereSolid(): expected at least two rings and three segments but got 2 and 2\n", + TestSuite::Compare::String); +} + void UVSphereTest::wireframe() { Trade::MeshData sphere = uvSphereWireframe(6, 8); @@ -242,6 +266,27 @@ void UVSphereTest::wireframe() { }), TestSuite::Compare::Container); } +void UVSphereTest::wireframeInvalid() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This is fine */ + Primitives::uvSphereWireframe(2, 4); + Primitives::uvSphereWireframe(4, 16); + + Containers::String out; + Error redirectError{&out}; + Primitives::uvSphereWireframe(3, 4); + Primitives::uvSphereWireframe(0, 4); + Primitives::uvSphereWireframe(2, 9); + Primitives::uvSphereWireframe(2, 0); + CORRADE_COMPARE_AS(out, + "Primitives::uvSphereWireframe(): expected multiples of 2 rings and multiples of 4 segments but got 3 and 4\n" + "Primitives::uvSphereWireframe(): expected multiples of 2 rings and multiples of 4 segments but got 0 and 4\n" + "Primitives::uvSphereWireframe(): expected multiples of 2 rings and multiples of 4 segments but got 2 and 9\n" + "Primitives::uvSphereWireframe(): expected multiples of 2 rings and multiples of 4 segments but got 2 and 0\n", + TestSuite::Compare::String); +} + }}}} CORRADE_TEST_MAIN(Magnum::Primitives::Test::UVSphereTest) diff --git a/src/Magnum/Primitives/UVSphere.cpp b/src/Magnum/Primitives/UVSphere.cpp index f915f6695..d394b37f0 100644 --- a/src/Magnum/Primitives/UVSphere.cpp +++ b/src/Magnum/Primitives/UVSphere.cpp @@ -36,7 +36,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData uvSphereSolid(const UnsignedInt rings, const UnsignedInt segments, const UVSphereFlags flags) { CORRADE_ASSERT(rings >= 2 && segments >= 3, - "Primitives::uvSphereSolid(): at least two rings and three segments expected", + "Primitives::uvSphereSolid(): expected at least two rings and three segments but got" << rings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::Spheroid sphere(segments, Implementation::Spheroid::Flag(UnsignedByte(flags))); @@ -71,7 +71,7 @@ CORRADE_IGNORE_DEPRECATED_POP Trade::MeshData uvSphereWireframe(const UnsignedInt rings, const UnsignedInt segments) { CORRADE_ASSERT(rings >= 2 && rings%2 == 0 && segments >= 4 && segments%4 == 0, - "Primitives::uvSphereWireframe(): multiples of 2 rings and multiples of 4 segments expected", + "Primitives::uvSphereWireframe(): expected multiples of 2 rings and multiples of 4 segments but got" << rings << "and" << segments, (Trade::MeshData{MeshPrimitive::Triangles, 0})); Implementation::WireframeSpheroid sphere(segments/4); diff --git a/src/Magnum/Primitives/visibility.h b/src/Magnum/Primitives/visibility.h index 69a9cb546..a60977a8e 100644 --- a/src/Magnum/Primitives/visibility.h +++ b/src/Magnum/Primitives/visibility.h @@ -32,7 +32,7 @@ #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_BUILD_STATIC - #ifdef MagnumPrimitives_EXPORTS + #if defined(MagnumPrimitives_EXPORTS) || defined(MagnumPrimitivesObjects_EXPORTS) #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_EXPORT #else #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_IMPORT