From 7067ed91c8ae8cf50a6be72264d299b871f5e52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 27 Sep 2022 16:06:54 +0200 Subject: [PATCH] {scene,image}converter: split implementation and executable tests. They're each a totally different beast and putting them into the same test file doesn't really make sense: - We want to link certain plugins statically on static builds to test certain code paths in the implementation. However this is counter-productive for the executable tests because there we are checking for plugin presence from the test with the assumption that the executable and the test have the exact same set of plugins available (or linked statically). - The executable tests are implemented on Unix only at the moment, thus it's wasteful to try to build it on any other platforms. Having it in a separate file makes it much easier to deal with. --- src/Magnum/SceneTools/Test/CMakeLists.txt | 142 +- .../Test/SceneConverterImplementationTest.cpp | 1231 +++++++++++++++++ .../info-animations.txt | 0 .../info-cameras.txt | 0 .../info-images.txt | 0 .../info-lights.txt | 0 .../info-materials.txt | 0 .../info-meshes-bounds.txt | 0 .../info-meshes.txt | 0 .../info-objects.txt | 0 .../info-references.txt | 0 .../info-scenes-objects.txt | 0 .../info-scenes.txt | 0 .../info-skins.txt | 0 .../info-textures.txt | 0 .../SceneTools/Test/SceneConverterTest.cpp | 1213 +--------------- src/Magnum/Trade/Test/CMakeLists.txt | 6 +- ...p => ImageConverterImplementationTest.cpp} | 22 +- .../info.txt | 0 19 files changed, 1327 insertions(+), 1287 deletions(-) create mode 100644 src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-animations.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-cameras.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-images.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-lights.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-materials.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-meshes-bounds.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-meshes.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-objects.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-references.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-scenes-objects.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-scenes.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-skins.txt (100%) rename src/Magnum/SceneTools/Test/{SceneConverterTestFiles => SceneConverterImplementationTestFiles}/info-textures.txt (100%) rename src/Magnum/Trade/Test/{ImageConverterTest.cpp => ImageConverterImplementationTest.cpp} (93%) rename src/Magnum/Trade/Test/{ImageConverterTestFiles => ImageConverterImplementationTestFiles}/info.txt (100%) diff --git a/src/Magnum/SceneTools/Test/CMakeLists.txt b/src/Magnum/SceneTools/Test/CMakeLists.txt index f6fbce27f..208885c27 100644 --- a/src/Magnum/SceneTools/Test/CMakeLists.txt +++ b/src/Magnum/SceneTools/Test/CMakeLists.txt @@ -52,72 +52,80 @@ corrade_add_test(SceneToolsConvertToSingleFun___Test ConvertToSingleFunctionObje corrade_add_test(SceneToolsFlattenMeshHierarchyTest FlattenMeshHierarchyTest.cpp LIBRARIES MagnumSceneToolsTestLib) corrade_add_test(SceneToolsOrderClusterParentsTest OrderClusterParentsTest.cpp LIBRARIES MagnumSceneToolsTestLib) -corrade_add_test(SceneToolsSceneConverterTest SceneConverterTest.cpp - LIBRARIES - MagnumSceneTools - # Link the same static plugins as for the magnum-sceneconverter - # executable so plugin existence checks are consistent between the two - ${MAGNUM_SCENECONVERTER_STATIC_PLUGINS} +corrade_add_test(SceneToolsSceneConverterImple___Test SceneConverterImplementationTest.cpp + LIBRARIES MagnumSceneTools FILES - SceneConverterTestFiles/blue4x4.png - # magnum-imageconverter --layers blue4x4.png --array blue4x4x1.ktx2 -c writerName= - SceneConverterTestFiles/blue4x4x1.ktx2 - SceneConverterTestFiles/broken-image-2d.gltf - SceneConverterTestFiles/broken-image-3d.gltf - SceneConverterTestFiles/broken-mesh.obj - SceneConverterTestFiles/broken-scene.gltf - SceneConverterTestFiles/dxt1.dds - SceneConverterTestFiles/empty.gltf - SceneConverterTestFiles/image-dds.gltf - SceneConverterTestFiles/images-2d.gltf - SceneConverterTestFiles/images-2d-1x1.bin - SceneConverterTestFiles/images-2d-1x1.gltf - SceneConverterTestFiles/images-3d.gltf - SceneConverterTestFiles/images-3d-1x1x1.bin - SceneConverterTestFiles/images-3d-1x1x1.gltf - SceneConverterTestFiles/info-data.txt - SceneConverterTestFiles/info-data-ignored-output.txt - SceneConverterTestFiles/info-animations.txt - SceneConverterTestFiles/info-cameras.txt - SceneConverterTestFiles/info-images.txt - SceneConverterTestFiles/info-lights.txt - SceneConverterTestFiles/info-materials.txt - SceneConverterTestFiles/info-meshes-bounds.txt - SceneConverterTestFiles/info-meshes.txt - SceneConverterTestFiles/info-objects.txt - SceneConverterTestFiles/info-references.txt - SceneConverterTestFiles/info-scenes-objects.txt - SceneConverterTestFiles/info-scenes.txt - SceneConverterTestFiles/info-skins.txt - SceneConverterTestFiles/info-textures.txt - SceneConverterTestFiles/point.obj - SceneConverterTestFiles/quad-duplicates-fuzzy.obj - SceneConverterTestFiles/quad-duplicates.obj - SceneConverterTestFiles/quad-duplicates.ply - SceneConverterTestFiles/quad-name-custom-attributes-duplicates.bin - SceneConverterTestFiles/quad-name-custom-attributes-duplicates.gltf - SceneConverterTestFiles/quad-name-custom-attributes.bin - SceneConverterTestFiles/quad-name-custom-attributes.gltf - SceneConverterTestFiles/quad-normals-texcoords.obj - SceneConverterTestFiles/quad-strip.bin - SceneConverterTestFiles/quad-strip.gltf - SceneConverterTestFiles/quad.bin - SceneConverterTestFiles/quad.gltf - SceneConverterTestFiles/quad.obj - SceneConverterTestFiles/quad.ply - SceneConverterTestFiles/red2x2.png - # magnum-imageconverter --layers red2x2.png --array red2x2x1.ktx2 -c writerName= - SceneConverterTestFiles/red2x2x1.ktx2 - SceneConverterTestFiles/two-quads-duplicates-fuzzy.bin - SceneConverterTestFiles/two-quads-duplicates-fuzzy.gltf - SceneConverterTestFiles/two-quads-duplicates.bin - SceneConverterTestFiles/two-quads-duplicates.gltf - SceneConverterTestFiles/two-quads.bin - SceneConverterTestFiles/two-quads.gltf - SceneConverterTestFiles/two-triangles-transformed.bin - SceneConverterTestFiles/two-triangles-transformed.gltf - SceneConverterTestFiles/two-triangles.obj) -target_include_directories(SceneToolsSceneConverterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/$) -if(MAGNUM_WITH_SCENECONVERTER AND CORRADE_TARGET_UNIX) - add_dependencies(SceneToolsSceneConverterTest magnum-sceneconverter) + SceneConverterImplementationTestFiles/info-animations.txt + SceneConverterImplementationTestFiles/info-cameras.txt + SceneConverterImplementationTestFiles/info-images.txt + SceneConverterImplementationTestFiles/info-lights.txt + SceneConverterImplementationTestFiles/info-materials.txt + SceneConverterImplementationTestFiles/info-meshes-bounds.txt + SceneConverterImplementationTestFiles/info-meshes.txt + SceneConverterImplementationTestFiles/info-objects.txt + SceneConverterImplementationTestFiles/info-references.txt + SceneConverterImplementationTestFiles/info-scenes-objects.txt + SceneConverterImplementationTestFiles/info-scenes.txt + SceneConverterImplementationTestFiles/info-skins.txt + SceneConverterImplementationTestFiles/info-textures.txt) +target_include_directories(SceneToolsSceneConverterImple___Test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/$) + +# Executable testing is implemented on Unix platforms only at the moment +if(CORRADE_TARGET_UNIX AND NOT CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT) + corrade_add_test(SceneToolsSceneConverterTest SceneConverterTest.cpp + LIBRARIES + MagnumSceneTools + # Link the same static plugins as for the magnum-sceneconverter + # executable so plugin existence checks are consistent between the two + ${MAGNUM_SCENECONVERTER_STATIC_PLUGINS} + FILES + SceneConverterTestFiles/blue4x4.png + # magnum-imageconverter --layers blue4x4.png --array blue4x4x1.ktx2 -c writerName= + SceneConverterTestFiles/blue4x4x1.ktx2 + SceneConverterTestFiles/broken-image-2d.gltf + SceneConverterTestFiles/broken-image-3d.gltf + SceneConverterTestFiles/broken-mesh.obj + SceneConverterTestFiles/broken-scene.gltf + SceneConverterTestFiles/dxt1.dds + SceneConverterTestFiles/empty.gltf + SceneConverterTestFiles/image-dds.gltf + SceneConverterTestFiles/images-2d.gltf + SceneConverterTestFiles/images-2d-1x1.bin + SceneConverterTestFiles/images-2d-1x1.gltf + SceneConverterTestFiles/images-3d.gltf + SceneConverterTestFiles/images-3d-1x1x1.bin + SceneConverterTestFiles/images-3d-1x1x1.gltf + SceneConverterTestFiles/info-data.txt + SceneConverterTestFiles/info-data-ignored-output.txt + SceneConverterTestFiles/point.obj + SceneConverterTestFiles/quad-duplicates-fuzzy.obj + SceneConverterTestFiles/quad-duplicates.obj + SceneConverterTestFiles/quad-duplicates.ply + SceneConverterTestFiles/quad-name-custom-attributes-duplicates.bin + SceneConverterTestFiles/quad-name-custom-attributes-duplicates.gltf + SceneConverterTestFiles/quad-name-custom-attributes.bin + SceneConverterTestFiles/quad-name-custom-attributes.gltf + SceneConverterTestFiles/quad-normals-texcoords.obj + SceneConverterTestFiles/quad-strip.bin + SceneConverterTestFiles/quad-strip.gltf + SceneConverterTestFiles/quad.bin + SceneConverterTestFiles/quad.gltf + SceneConverterTestFiles/quad.obj + SceneConverterTestFiles/quad.ply + SceneConverterTestFiles/red2x2.png + # magnum-imageconverter --layers red2x2.png --array red2x2x1.ktx2 -c writerName= + SceneConverterTestFiles/red2x2x1.ktx2 + SceneConverterTestFiles/two-quads-duplicates-fuzzy.bin + SceneConverterTestFiles/two-quads-duplicates-fuzzy.gltf + SceneConverterTestFiles/two-quads-duplicates.bin + SceneConverterTestFiles/two-quads-duplicates.gltf + SceneConverterTestFiles/two-quads.bin + SceneConverterTestFiles/two-quads.gltf + SceneConverterTestFiles/two-triangles-transformed.bin + SceneConverterTestFiles/two-triangles-transformed.gltf + SceneConverterTestFiles/two-triangles.obj) + target_include_directories(SceneToolsSceneConverterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/$) + if(MAGNUM_WITH_SCENECONVERTER) + add_dependencies(SceneToolsSceneConverterTest magnum-sceneconverter) + endif() endif() diff --git a/src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp b/src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp new file mode 100644 index 000000000..cbc2b36c5 --- /dev/null +++ b/src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp @@ -0,0 +1,1231 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "Magnum/Math/CubicHermite.h" +#include "Magnum/Math/Matrix3.h" +#include "Magnum/Math/Matrix4.h" + +#include "Magnum/SceneTools/Implementation/sceneConverterUtilities.h" + +#include "configure.h" + +namespace Magnum { namespace SceneTools { namespace Test { namespace { + +struct SceneConverterImplementationTest: TestSuite::Tester { + explicit SceneConverterImplementationTest(); + + void infoEmpty(); + void infoScenesObjects(); + void infoAnimations(); + void infoSkins(); + void infoLights(); + void infoCameras(); + void infoMaterials(); + void infoMeshes(); + void infoMeshesBounds(); + void infoTextures(); + void infoImages(); + /* Image info further tested in ImageConverterImplementationTest */ + void infoReferenceCount(); + void infoError(); + + Utility::Arguments _infoArgs; +}; + +using namespace Containers::Literals; +using namespace Math::Literals; + +const struct { + const char* name; + const char* arg; + const char* expected; + bool printVisualCheck; +} InfoScenesObjectsData[]{ + {"", "--info", "info-scenes-objects.txt", true}, + {"only scenes", "--info-scenes", "info-scenes.txt", false}, + {"only objects", "--info-objects", "info-objects.txt", false}, +}; + +const struct { + const char* name; + bool oneOrAll; + bool printVisualCheck; +} InfoOneOrAllData[]{ + {"", true, true}, + {"--info", false, false}, +}; + +SceneConverterImplementationTest::SceneConverterImplementationTest() { + addTests({&SceneConverterImplementationTest::infoEmpty}); + + addInstancedTests({&SceneConverterImplementationTest::infoScenesObjects}, + Containers::arraySize(InfoScenesObjectsData)); + + addInstancedTests({&SceneConverterImplementationTest::infoAnimations, + &SceneConverterImplementationTest::infoSkins, + &SceneConverterImplementationTest::infoLights, + &SceneConverterImplementationTest::infoCameras, + &SceneConverterImplementationTest::infoMaterials, + &SceneConverterImplementationTest::infoMeshes}, + Containers::arraySize(InfoOneOrAllData)); + + addTests({&SceneConverterImplementationTest::infoMeshesBounds}); + + addInstancedTests({&SceneConverterImplementationTest::infoTextures, + &SceneConverterImplementationTest::infoImages}, + Containers::arraySize(InfoOneOrAllData)); + + addTests({&SceneConverterImplementationTest::infoReferenceCount, + &SceneConverterImplementationTest::infoError}); + + /* A subset of arguments needed by the info printing code */ + _infoArgs.addBooleanOption("info") + .addBooleanOption("info-scenes") + .addBooleanOption("info-objects") + .addBooleanOption("info-animations") + .addBooleanOption("info-skins") + .addBooleanOption("info-lights") + .addBooleanOption("info-cameras") + .addBooleanOption("info-materials") + .addBooleanOption("info-meshes") + .addBooleanOption("info-textures") + .addBooleanOption("info-images") + .addBooleanOption("bounds"); +} + +void SceneConverterImplementationTest::infoEmpty() { + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + } importer; + + const char* argv[]{"", "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); + CORRADE_COMPARE(out.str(), ""); +} + +void SceneConverterImplementationTest::infoScenesObjects() { + auto&& data = InfoScenesObjectsData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + /* First scene has 4, second 7, the last three are not in any scene and + thus not listed. Object 5 has no fields and thus not listed either. */ + UnsignedLong doObjectCount() const override { return 10; } + UnsignedInt doSceneCount() const override { return 2; } + Containers::String doSceneName(UnsignedInt id) override { + return id == 0 ? "A simple scene" : ""; + } + Containers::String doObjectName(UnsignedLong id) override { + if(id == 0) return "Parent-less mesh"; + if(id == 2) return "Two meshes, shared among two scenes"; + if(id == 4) return "Two custom arrays"; + if(id == 6) return "Only in the second scene, but no fields, thus same as unreferenced"; + if(id == 8) return "Not in any scene"; + return ""; + } + Containers::String doSceneFieldName(UnsignedInt name) override { + if(name == 1337) return "DirectionVector"; + return ""; + } + Containers::Optional doScene(UnsignedInt id) override { + /* Builtin fields, some duplicated, one marked as ordered */ + if(id == 0) { + Containers::ArrayView parentMapping; + Containers::ArrayView parents; + Containers::ArrayView meshMapping; + Containers::ArrayView meshes; + Containers::ArrayTuple data{ + {NoInit, 3, parentMapping}, + {ValueInit, 3, parents}, + {NoInit, 4, meshMapping}, + {ValueInit, 4, meshes}, + }; + Utility::copy({1, 3, 2}, parentMapping); + Utility::copy({2, 0, 2, 1}, meshMapping); + /* No need to fill the data, zero-init is fine */ + return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 4, std::move(data), { + Trade::SceneFieldData{Trade::SceneField::Parent, parentMapping, parents}, + Trade::SceneFieldData{Trade::SceneField::Mesh, meshMapping, meshes, Trade::SceneFieldFlag::OrderedMapping}, + }}; + } + + /* Two custom fields, one array. Stored as an external memory. */ + if(id == 1) { + return Trade::SceneData{Trade::SceneMappingType::UnsignedByte, 8, Trade::DataFlag::ExternallyOwned|Trade::DataFlag::Mutable, scene2Data, { + Trade::SceneFieldData{Trade::sceneFieldCustom(42), Containers::arrayView(scene2Data->customMapping), Containers::arrayView(scene2Data->custom)}, + Trade::SceneFieldData{Trade::sceneFieldCustom(1337), Trade::SceneMappingType::UnsignedByte, scene2Data->customArrayMapping, Trade::SceneFieldType::Short, scene2Data->customArray, 3}, + }}; + } + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + struct { + UnsignedByte customMapping[2]; + Double custom[2]; + UnsignedByte customArrayMapping[3]; + Vector3s customArray[3]; + } scene2Data[1]{{ + /* No need to fill the data, zero-init is fine */ + {7, 3}, {}, {2, 4, 4}, {} + }}; + } importer; + + const char* argv[]{"", data.arg}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join({SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles", data.expected}), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoAnimations() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doAnimationCount() const override { return 2; } + Containers::String doAnimationName(UnsignedInt id) override { + return id == 1 ? "Custom track duration and interpolator function" : ""; + } + Containers::Optional doAnimation(UnsignedInt id) override { + /* First has two tracks with a shared time and implicit duration, + one with a different result type. */ + if(id == 0) { + Containers::ArrayView time; + Containers::ArrayView translation; + Containers::ArrayView rotation; + Containers::ArrayTuple data{ + {ValueInit, 3, time}, + {ValueInit, 3, translation}, + {ValueInit, 3, rotation} + }; + Utility::copy({0.5f, 1.0f, 1.25f}, time); + return Trade::AnimationData{std::move(data), { + /** @todo cleanup once AnimationTrackData has sane + constructors */ + Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Translation2D, 17, Animation::TrackView{time, translation, Animation::Interpolation::Linear, Animation::Extrapolation::DefaultConstructed, Animation::Extrapolation::Constant}}, + Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Rotation2D, 17, Animation::TrackView{time, rotation, Animation::Interpolation::Constant, Animation::Extrapolation::Extrapolated}}, + }}; + } + + /* Second has track duration different from animation duration and + a custom interpolator. Stored as an external memory. */ + if(id == 1) { + return Trade::AnimationData{Trade::DataFlag::ExternallyOwned, animation2Data, { + /** @todo cleanup once AnimationTrackData has sane + constructors */ + Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Scaling3D, 666, Animation::TrackView{animation2Data->time, animation2Data->scaling, Math::lerp, Animation::Extrapolation::DefaultConstructed, Animation::Extrapolation::Constant}}, + }, {0.1f, 1.3f}}; + } + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + struct { + Float time[5]; + Vector3 scaling[5]; + } animation2Data[1]{{ + {0.75f, 0.75f, 1.0f, 1.0f, 1.25f}, + {} + }}; + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-animations" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-animations.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoSkins() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doSkin2DCount() const override { return 2; } + Containers::String doSkin2DName(UnsignedInt id) override { + return id == 1 ? "Second 2D skin, external data" : ""; + } + Containers::Optional doSkin2D(UnsignedInt id) override { + /* First a regular skin, second externally owned */ + if(id == 0) return Trade::SkinData2D{ + {3, 6, 7, 12, 22}, + {{}, {}, {}, {}, {}} + }; + + if(id == 1) return Trade::SkinData2D{Trade::DataFlag::ExternallyOwned, skin2JointData, Trade::DataFlag::ExternallyOwned, skin2MatrixData}; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doSkin3DCount() const override { return 3; } + Containers::String doSkin3DName(UnsignedInt id) override { + return id == 0 ? "First 3D skin, external data" : ""; + } + Containers::Optional doSkin3D(UnsignedInt id) override { + /* Reverse order in 3D, plus one more to ensure the count isn't + mismatched between 2D and 3D */ + if(id == 0) return Trade::SkinData3D{Trade::DataFlag::ExternallyOwned, skin3JointData, Trade::DataFlag::ExternallyOwned, skin3MatrixData}; + + if(id == 1) return Trade::SkinData3D{ + {3, 22}, + {{}, {}} + }; + + if(id == 2) return Trade::SkinData3D{ + {3}, + {{}} + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt skin2JointData[15]; + Matrix3 skin2MatrixData[15]; + UnsignedInt skin3JointData[12]; + Matrix4 skin3MatrixData[12]; + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-skins" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-skins.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoLights() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doLightCount() const override { return 2; } + Containers::String doLightName(UnsignedInt id) override { + return id == 1 ? "Directional light with always-implicit attenuation and range" : ""; + } + Containers::Optional doLight(UnsignedInt id) override { + /* First a blue spot light */ + if(id == 0) return Trade::LightData{ + Trade::LightData::Type::Spot, + 0x3457ff_rgbf, + 15.0f, + {1.2f, 0.3f, 0.04f}, + 100.0f, + 55.0_degf, + 85.0_degf + }; + + /* Second a yellow directional light with infinite range */ + if(id == 1) return Trade::LightData{ + Trade::LightData::Type::Directional, + 0xff5734_rgbf, + 5.0f + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-lights" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-lights.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoCameras() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doCameraCount() const override { return 3; } + Containers::String doCameraName(UnsignedInt id) override { + return id == 0 ? "Orthographic 2D" : ""; + } + Containers::Optional doCamera(UnsignedInt id) override { + /* First 2D ortho camera, where near/far will get omited */ + if(id == 0) return Trade::CameraData{ + Trade::CameraType::Orthographic2D, + {5.0f, 6.0f}, + 0.0f, 0.0f + }; + + /* 3D ortho camera */ + if(id == 1) return Trade::CameraData{ + Trade::CameraType::Orthographic3D, + {2.0f, 3.0f}, + -1.0f, 0.5f + }; + + /* Third a perspective camera, specified with size, but printed + with FoV */ + if(id == 2) return Trade::CameraData{ + Trade::CameraType::Perspective3D, + 35.0_degf, 4.0f/3.0f, 0.01f, 100.0f + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-cameras" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-cameras.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoMaterials() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doMaterialCount() const override { return 2; } + Containers::String doMaterialName(UnsignedInt id) override { + return id == 1 ? "Lots o' laierz" : ""; + } + Containers::Optional doMaterial(UnsignedInt id) override { + /* First has custom attributes */ + if(id == 0) return Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, { + {Trade::MaterialAttribute::BaseColor, 0x3bd26799_rgbaf}, + {Trade::MaterialAttribute::DoubleSided, true}, + {Trade::MaterialAttribute::EmissiveColor, 0xe9eca_rgbf}, + {Trade::MaterialAttribute::RoughnessTexture, 67u}, + {Trade::MaterialAttribute::RoughnessTextureMatrix, Matrix3::translation({0.25f, 0.75f})}, + {Trade::MaterialAttribute::RoughnessTextureSwizzle, Trade::MaterialTextureSwizzle::B}, + {"reflectionAngle", 35.0_degf}, + /* These shouldn't have a color swatch rendered */ + {"notAColour4", Vector4{0.1f, 0.2f, 0.3f, 0.4f}}, + {"notAColour3", Vector3{0.2f, 0.3f, 0.4f}}, + {"data", Containers::ArrayView{"0123456789abcdef", 17}}, + {"deadBeef", reinterpret_cast(0xdeadbeef)}, + {"undeadBeef", reinterpret_cast(0xbeefbeef)}, + }}; + + /* Second has layers, custom layers, unnamed layers and a name */ + if(id == 1) return Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Phong, { + {Trade::MaterialAttribute::DiffuseColor, 0xc7cf2f99_rgbaf}, + {Trade::MaterialLayer::ClearCoat}, + {Trade::MaterialAttribute::LayerFactor, 0.5f}, + {Trade::MaterialAttribute::LayerFactorTexture, 3u}, + {Trade::MaterialAttribute::LayerName, "anEmptyLayer"}, + {Trade::MaterialAttribute::LayerFactor, 0.25f}, + {Trade::MaterialAttribute::LayerFactorTexture, 2u}, + {"yes", "a string"}, + }, {1, 4, 5, 8}}; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-materials" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-materials.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoMeshes() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doMeshCount() const override { return 3; } + UnsignedInt doMeshLevelCount(UnsignedInt id) override { + return id == 1 ? 2 : 1; + } + Containers::String doMeshName(UnsignedInt id) override { + return id == 1 ? "LODs? No, meshets." : ""; + } + Containers::String doMeshAttributeName(UnsignedShort name) override { + if(name == 25) return "vertices"; + if(name == 26) return "triangles"; + /* 37 (triangleCount) deliberately not named */ + if(name == 116) return "vertexCount"; + + return ""; + } + Containers::Optional doMesh(UnsignedInt id, UnsignedInt level) override { + /* First is indexed & externally owned */ + if(id == 0 && level == 0) return Trade::MeshData{MeshPrimitive::Points, + Trade::DataFlag::ExternallyOwned, indices, + Trade::MeshIndexData{indices}, + Trade::DataFlag::ExternallyOwned|Trade::DataFlag::Mutable, points, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(points)} + }}; + + /* Second is multi-level, with second level being indexed meshlets + with custom (array) attributes */ + if(id == 1 && level == 0) { + Containers::ArrayView positions; + Containers::ArrayView tangents; + Containers::ArrayTuple data{ + {NoInit, 250, positions}, + {NoInit, 250, tangents}, + }; + return Trade::MeshData{MeshPrimitive::Triangles, std::move(data), { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions}, + Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, tangents}, + }}; + } + if(id == 1 && level == 1) { + Containers::StridedArrayView2D vertices; + Containers::StridedArrayView2D indices; + Containers::ArrayView triangleCount; + Containers::ArrayView vertexCount; + Containers::ArrayTuple data{ + {NoInit, {135, 64}, vertices}, + {NoInit, {135, 126}, indices}, + {NoInit, 135, triangleCount}, + {NoInit, 135, vertexCount}, + }; + return Trade::MeshData{MeshPrimitive::Meshlets, std::move(data), { + Trade::MeshAttributeData{Trade::meshAttributeCustom(25), vertices}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(26), indices}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(37), triangleCount}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(116), vertexCount}, + }}; + } + + /* Third is an empty instance mesh */ + if(id == 2 && level == 0) return Trade::MeshData{MeshPrimitive::Instances, 15}; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedShort indices[70]; + Vector3 points[50]; + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-meshes" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-meshes.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoMeshesBounds() { + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doMeshCount() const override { return 1; } + Containers::Optional doMesh(UnsignedInt, UnsignedInt) override { + return Trade::MeshData{MeshPrimitive::Lines, + {}, indexData, Trade::MeshIndexData{indexData}, + {}, vertexData, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(vertexData->positions)}, + Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, Containers::arrayView(vertexData->tangent)}, + Trade::MeshAttributeData{Trade::MeshAttribute::Bitangent, Containers::arrayView(vertexData->bitangent)}, + Trade::MeshAttributeData{Trade::MeshAttribute::ObjectId, Containers::arrayView(vertexData->objectId)}, + Trade::MeshAttributeData{Trade::MeshAttribute::Normal, Containers::arrayView(vertexData->normal)}, + Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, Containers::arrayView(vertexData->textureCoordinates)}, + Trade::MeshAttributeData{Trade::MeshAttribute::Color, Containers::arrayView(vertexData->color)}, + Trade::MeshAttributeData{Trade::MeshAttribute::ObjectId, Containers::arrayView(vertexData->objectIdSecondary)}, + }}; + } + + UnsignedByte indexData[3]{15, 3, 176}; + + struct { + Vector3 positions[2]; + Vector3 tangent[2]; + Vector3 bitangent[2]; + UnsignedShort objectId[2]; + Vector3 normal[2]; + Vector2 textureCoordinates[2]; + Vector4 color[2]; + UnsignedInt objectIdSecondary[2]; + } vertexData[1]{{ + {{0.1f, -0.1f, 0.2f}, {0.2f, 0.0f, -0.2f}}, + {{0.2f, -0.2f, 0.8f}, {0.3f, 0.8f, 0.2f}}, + {{0.4f, 0.2f, 1.0f}, {0.3f, 0.9f, 0.0f}}, + {155, 12}, + {{0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 1.0f}}, + {{0.5f, 0.5f}, {1.5f, 0.5f}}, + {0x99336600_rgbaf, 0xff663333_rgbaf}, + {15, 337}, + }}; + } importer; + + const char* argv[]{"", "--info-meshes", "--bounds"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-meshes-bounds.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoTextures() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doTextureCount() const override { return 2; } + Containers::String doTextureName(UnsignedInt id) override { + return id == 1 ? "Name!" : ""; + } + Containers::Optional doTexture(UnsignedInt id) override { + /* First a 1D texture */ + if(id == 0) return Trade::TextureData{ + Trade::TextureType::Texture1D, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 666 + }; + + /* Second a 2D array texture */ + if(id == 1) return Trade::TextureData{ + Trade::TextureType::Texture2DArray, + SamplerFilter::Linear, + SamplerFilter::Nearest, + SamplerMipmap::Linear, + {SamplerWrapping::MirroredRepeat, SamplerWrapping::ClampToEdge, SamplerWrapping::MirrorClampToEdge}, + 3 + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-textures" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-textures.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoImages() { + auto&& data = InfoOneOrAllData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + /* Just the very basics to ensure image info *is* printed. Tested in full + in ImageConverterTest. */ + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage1DCount() const override { return 1; } + Containers::Optional doImage1D(UnsignedInt, UnsignedInt) override { + return Trade::ImageData1D{PixelFormat::R32F, 1024, Containers::Array{NoInit, 4096}}; + } + } importer; + + const char* argv[]{"", data.oneOrAll ? "--info-images" : "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + if(data.printVisualCheck) { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-images.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoReferenceCount() { + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + /* One data of each kind should be always referenced twice+, one once, + one not at all, and one reference should be OOB */ + + UnsignedLong doObjectCount() const override { return 4; } + Containers::String doObjectName(UnsignedLong id) override { + return id == 2 ? "Not referenced" : ""; + } + UnsignedInt doSceneCount() const override { return 2; } + Containers::Optional doScene(UnsignedInt id) override { + if(id == 0) return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 2, {}, sceneData3D, { + /* To mark the scene as 3D */ + Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix4x4, nullptr}, + Trade::SceneFieldData{Trade::SceneField::Mesh, + Containers::arrayView(sceneData3D->mapping), + Containers::arrayView(sceneData3D->meshes)}, + Trade::SceneFieldData{Trade::SceneField::MeshMaterial, + Containers::arrayView(sceneData3D->mapping), + Containers::arrayView(sceneData3D->materials)}, + Trade::SceneFieldData{Trade::SceneField::Light, + Containers::arrayView(sceneData3D->mapping), + Containers::arrayView(sceneData3D->lights)}, + Trade::SceneFieldData{Trade::SceneField::Camera, + Containers::arrayView(sceneData3D->mapping), + Containers::arrayView(sceneData3D->cameras)}, + Trade::SceneFieldData{Trade::SceneField::Skin, + Containers::arrayView(sceneData3D->mapping), + Containers::arrayView(sceneData3D->skins)}, + }}; + if(id == 1) return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 4, {}, sceneData2D, { + /* To mark the scene as 2D */ + Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix3x3, nullptr}, + Trade::SceneFieldData{Trade::SceneField::Mesh, + Containers::arrayView(sceneData2D->mapping), + Containers::arrayView(sceneData2D->meshes)}, + Trade::SceneFieldData{Trade::SceneField::Skin, + Containers::arrayView(sceneData2D->mapping), + Containers::arrayView(sceneData2D->skins)}, + }}; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doSkin2DCount() const override { return 3; } + Containers::String doSkin2DName(UnsignedInt id) override { + return id == 2 ? "Not referenced" : ""; + } + Containers::Optional doSkin2D(UnsignedInt id) override { + if(id == 0) return Trade::SkinData2D{ + {35, 22}, + {{}, {}} + }; + if(id == 1) return Trade::SkinData2D{ + {33, 10, 100}, + {{}, {}, {}} + }; + if(id == 2) return Trade::SkinData2D{ + {66}, + {{}} + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doSkin3DCount() const override { return 3; } + Containers::String doSkin3DName(UnsignedInt id) override { + return id == 0 ? "Not referenced" : ""; + } + Containers::Optional doSkin3D(UnsignedInt id) override { + if(id == 0) return Trade::SkinData3D{ + {35, 22}, + {{}, {}} + }; + if(id == 1) return Trade::SkinData3D{ + {37}, + {{}} + }; + if(id == 2) return Trade::SkinData3D{ + {300, 10, 1000}, + {{}, {}, {}} + }; + + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doLightCount() const override { return 3; } + Containers::String doLightName(UnsignedInt id) override { + return id == 1 ? "Not referenced" : ""; + } + Containers::Optional doLight(UnsignedInt id) override { + if(id == 0) return Trade::LightData{ + Trade::LightData::Type::Directional, + 0x57ff34_rgbf, + 5.0f + }; + if(id == 1) return Trade::LightData{ + Trade::LightData::Type::Ambient, + 0xff5734_rgbf, + 0.1f + }; + if(id == 2) return Trade::LightData{ + Trade::LightData::Type::Directional, + 0x3457ff_rgbf, + 1.0f + }; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doCameraCount() const override { return 3; } + Containers::String doCameraName(UnsignedInt id) override { + return id == 0 ? "Not referenced" : ""; + } + Containers::Optional doCamera(UnsignedInt id) override { + if(id == 0) return Trade::CameraData{ + Trade::CameraType::Orthographic3D, + {2.0f, 3.0f}, + -1.0f, 0.5f + }; + if(id == 1) return Trade::CameraData{ + Trade::CameraType::Orthographic3D, + {2.0f, 2.0f}, + 0.0f, 1.0f + }; + if(id == 2) return Trade::CameraData{ + Trade::CameraType::Orthographic2D, + {2.0f, 2.0f}, + 0.0f, 0.0f + }; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doMaterialCount() const override { return 3; } + Containers::String doMaterialName(UnsignedInt id) override { + return id == 2 ? "Not referenced" : ""; + } + Containers::Optional doMaterial(UnsignedInt id) override { + if(id == 0) return Trade::MaterialData{{}, { + {Trade::MaterialAttribute::DiffuseTexture, 2u}, + {Trade::MaterialAttribute::BaseColorTexture, 2u}, + }}; + if(id == 1) return Trade::MaterialData{{}, { + {"lookupTexture", 0u}, + {"volumeTexture", 3u}, + {Trade::MaterialAttribute::NormalTexture, 17u}, + {Trade::MaterialAttribute::EmissiveTexture, 4u}, + }}; + if(id == 2) return Trade::MaterialData{{}, {}}; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doMeshCount() const override { return 3; } + Containers::String doMeshName(UnsignedInt id) override { + return id == 1 ? "Not referenced" : ""; + } + Containers::Optional doMesh(UnsignedInt id, UnsignedInt) override { + if(id == 0) return Trade::MeshData{MeshPrimitive::Points, 5}; + if(id == 1) return Trade::MeshData{MeshPrimitive::Lines, 4}; + if(id == 2) return Trade::MeshData{MeshPrimitive::TriangleFan, 4}; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doTextureCount() const override { return 5; } + Containers::String doTextureName(UnsignedInt id) override { + return id == 1 ? "Not referenced" : ""; + } + Containers::Optional doTexture(UnsignedInt id) override { + if(id == 0) return Trade::TextureData{ + Trade::TextureType::Texture1D, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 1 + }; + if(id == 1) return Trade::TextureData{ + Trade::TextureType::Texture1DArray, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 225 + }; + if(id == 2) return Trade::TextureData{ + Trade::TextureType::Texture2D, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 0 + }; + if(id == 3) return Trade::TextureData{ + Trade::TextureType::Texture3D, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 1 + }; + if(id == 4) return Trade::TextureData{ + Trade::TextureType::Texture2D, + SamplerFilter::Nearest, + SamplerFilter::Linear, + SamplerMipmap::Nearest, + SamplerWrapping::Repeat, + 0 + }; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doImage1DCount() const override { return 2; } + Containers::String doImage1DName(UnsignedInt id) override { + return id == 0 ? "Not referenced" : ""; + } + Containers::Optional doImage1D(UnsignedInt id, UnsignedInt) override { + if(id == 0) + return Trade::ImageData1D{PixelFormat::RGBA8I, 1, Containers::Array{NoInit, 4}}; + if(id == 1) + return Trade::ImageData1D{PixelFormat::R8I, 4, Containers::Array{NoInit, 4}}; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doImage2DCount() const override { return 2; } + Containers::String doImage2DName(UnsignedInt id) override { + return id == 1 ? "Not referenced" : ""; + } + Containers::Optional doImage2D(UnsignedInt id, UnsignedInt) override { + if(id == 0) + return Trade::ImageData2D{PixelFormat::RGBA8I, {1, 2}, Containers::Array{NoInit, 8}}; + if(id == 1) + return Trade::ImageData2D{PixelFormat::R8I, {4, 1}, Containers::Array{NoInit, 4}}; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + UnsignedInt doImage3DCount() const override { return 2; } + Containers::String doImage3DName(UnsignedInt id) override { + return id == 0 ? "Not referenced" : ""; + } + Containers::Optional doImage3D(UnsignedInt id, UnsignedInt) override { + if(id == 0) + return Trade::ImageData3D{PixelFormat::RGBA8I, {1, 2, 1}, Containers::Array{NoInit, 8}}; + if(id == 1) + return Trade::ImageData3D{PixelFormat::R8I, {4, 1, 1}, Containers::Array{NoInit, 4}}; + CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + + struct { + UnsignedInt mapping[4]; + UnsignedInt meshes[4]; + Int materials[4]; + UnsignedInt lights[4]; + UnsignedInt cameras[4]; + UnsignedInt skins[4]; + } sceneData3D[1]{{ + {0, 1, 1, 25}, + {2, 0, 2, 67}, + {0, 1, 23, 0}, + {0, 17, 0, 2}, + {166, 1, 2, 1}, + {1, 1, 22, 2} + }}; + + struct { + UnsignedInt mapping[3]; + UnsignedInt meshes[3]; + UnsignedInt skins[3]; + } sceneData2D[1]{{ + {3, 116, 1}, + {2, 0, 23}, + {177, 0, 1} + }}; + } importer; + + const char* argv[]{"", "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + /* Print to visually verify coloring */ + { + Debug{} << "======================== visual color verification start ======================="; + Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); + Debug{} << "======================== visual color verification end ========================="; + } + + std::ostringstream out; + Debug redirectOutput{&out}; + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); + CORRADE_COMPARE_AS(out.str(), + Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterImplementationTestFiles/info-references.txt"), + TestSuite::Compare::StringToFile); +} + +void SceneConverterImplementationTest::infoError() { + struct Importer: Trade::AbstractImporter { + Trade::ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + /* The one single object is named, and that name should be printed + after all error messages */ + UnsignedLong doObjectCount() const override { return 1; } + Containers::String doObjectName(UnsignedLong) override { return "A name"; } + + UnsignedInt doSceneCount() const override { return 2; } + Containers::Optional doScene(UnsignedInt id) override { + Error{} << "Scene" << id << "error!"; + return {}; + } + + UnsignedInt doAnimationCount() const override { return 2; } + Containers::Optional doAnimation(UnsignedInt id) override { + Error{} << "Animation" << id << "error!"; + return {}; + } + + UnsignedInt doSkin2DCount() const override { return 2; } + Containers::Optional doSkin2D(UnsignedInt id) override { + Error{} << "2D skin" << id << "error!"; + return {}; + } + + UnsignedInt doSkin3DCount() const override { return 2; } + Containers::Optional doSkin3D(UnsignedInt id) override { + Error{} << "3D skin" << id << "error!"; + return {}; + } + + UnsignedInt doLightCount() const override { return 2; } + Containers::Optional doLight(UnsignedInt id) override { + Error{} << "Light" << id << "error!"; + return {}; + } + + UnsignedInt doCameraCount() const override { return 2; } + Containers::Optional doCamera(UnsignedInt id) override { + Error{} << "Camera" << id << "error!"; + return {}; + } + + UnsignedInt doMaterialCount() const override { return 2; } + Containers::Optional doMaterial(UnsignedInt id) override { + Error{} << "Material" << id << "error!"; + return {}; + } + + UnsignedInt doMeshCount() const override { return 2; } + Containers::Optional doMesh(UnsignedInt id, UnsignedInt) override { + Error{} << "Mesh" << id << "error!"; + return {}; + } + + UnsignedInt doTextureCount() const override { return 2; } + Containers::Optional doTexture(UnsignedInt id) override { + Error{} << "Texture" << id << "error!"; + return {}; + } + + /* Errors for all image types tested in ImageConverterTest */ + UnsignedInt doImage2DCount() const override { return 2; } + Containers::Optional doImage2D(UnsignedInt id, UnsignedInt) override { + Error{} << "Image" << id << "error!"; + return {}; + } + } importer; + + const char* argv[]{"", "--info"}; + CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); + + std::chrono::high_resolution_clock::duration time; + + std::ostringstream out; + Debug redirectOutput{&out}; + Error redirectError{&out}; + /* It should return a failure */ + CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == true); + CORRADE_COMPARE(out.str(), + /* It should not exit after first error... */ + "Scene 0 error!\n" + "Scene 1 error!\n" + "Animation 0 error!\n" + "Animation 1 error!\n" + "2D skin 0 error!\n" + "2D skin 1 error!\n" + "3D skin 0 error!\n" + "3D skin 1 error!\n" + "Light 0 error!\n" + "Light 1 error!\n" + "Camera 0 error!\n" + "Camera 1 error!\n" + "Material 0 error!\n" + "Material 1 error!\n" + "Mesh 0 error!\n" + "Mesh 1 error!\n" + "Texture 0 error!\n" + "Texture 1 error!\n" + "Image 0 error!\n" + "Image 1 error!\n" + /* ... and it should print all info output after the errors */ + "Object 0: A name\n"); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::SceneTools::Test::SceneConverterImplementationTest) diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-animations.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-animations.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-animations.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-animations.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-cameras.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-cameras.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-cameras.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-cameras.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-images.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-images.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-images.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-images.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-lights.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-lights.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-lights.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-lights.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-materials.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-materials.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-materials.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-materials.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-meshes-bounds.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-meshes-bounds.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-meshes-bounds.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-meshes-bounds.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-meshes.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-meshes.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-meshes.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-meshes.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-objects.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-objects.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-objects.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-objects.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-references.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-references.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-references.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-references.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-scenes-objects.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-objects.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-scenes-objects.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-objects.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-scenes.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-scenes.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-skins.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-skins.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-skins.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-skins.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-textures.txt b/src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-textures.txt similarity index 100% rename from src/Magnum/SceneTools/Test/SceneConverterTestFiles/info-textures.txt rename to src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-textures.txt diff --git a/src/Magnum/SceneTools/Test/SceneConverterTest.cpp b/src/Magnum/SceneTools/Test/SceneConverterTest.cpp index 9613406ec..676dca78e 100644 --- a/src/Magnum/SceneTools/Test/SceneConverterTest.cpp +++ b/src/Magnum/SceneTools/Test/SceneConverterTest.cpp @@ -23,24 +23,22 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include +#include #include -#include "Magnum/Math/CubicHermite.h" -#include "Magnum/Math/Matrix3.h" -#include "Magnum/Math/Matrix4.h" #include "Magnum/Trade/AbstractImageConverter.h" +#include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/AbstractSceneConverter.h" -#include "Magnum/SceneTools/Implementation/sceneConverterUtilities.h" - #include "configure.h" namespace Magnum { namespace SceneTools { namespace Test { namespace { @@ -48,54 +46,13 @@ namespace Magnum { namespace SceneTools { namespace Test { namespace { struct SceneConverterTest: TestSuite::Tester { explicit SceneConverterTest(); - void infoImplementationEmpty(); - void infoImplementationScenesObjects(); - void infoImplementationAnimations(); - void infoImplementationSkins(); - void infoImplementationLights(); - void infoImplementationCameras(); - void infoImplementationMaterials(); - void infoImplementationMeshes(); - void infoImplementationMeshesBounds(); - void infoImplementationTextures(); - void infoImplementationImages(); - /* Image info further tested in ImageConverterTest */ - void infoImplementationReferenceCount(); - void infoImplementationError(); - - #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT void info(); void convert(); void error(); - #endif - - Utility::Arguments _infoArgs; }; using namespace Containers::Literals; -using namespace Math::Literals; - -const struct { - const char* name; - const char* arg; - const char* expected; - bool printVisualCheck; -} InfoImplementationScenesObjectsData[]{ - {"", "--info", "info-scenes-objects.txt", true}, - {"only scenes", "--info-scenes", "info-scenes.txt", false}, - {"only objects", "--info-objects", "info-objects.txt", false}, -}; - -const struct { - const char* name; - bool oneOrAll; - bool printVisualCheck; -} InfoImplementationOneOrAllData[]{ - {"", true, true}, - {"--info", false, false}, -}; -#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT const struct { const char* name; Containers::Array args; @@ -768,32 +725,8 @@ const struct { "Trade::GltfSceneConverter::add(): can't load NonexistentImageConverter for image conversion\n" "Cannot add 3D image 0\n"}, }; -#endif SceneConverterTest::SceneConverterTest() { - addTests({&SceneConverterTest::infoImplementationEmpty}); - - addInstancedTests({&SceneConverterTest::infoImplementationScenesObjects}, - Containers::arraySize(InfoImplementationScenesObjectsData)); - - addInstancedTests({&SceneConverterTest::infoImplementationAnimations, - &SceneConverterTest::infoImplementationSkins, - &SceneConverterTest::infoImplementationLights, - &SceneConverterTest::infoImplementationCameras, - &SceneConverterTest::infoImplementationMaterials, - &SceneConverterTest::infoImplementationMeshes}, - Containers::arraySize(InfoImplementationOneOrAllData)); - - addTests({&SceneConverterTest::infoImplementationMeshesBounds}); - - addInstancedTests({&SceneConverterTest::infoImplementationTextures, - &SceneConverterTest::infoImplementationImages}, - Containers::arraySize(InfoImplementationOneOrAllData)); - - addTests({&SceneConverterTest::infoImplementationReferenceCount, - &SceneConverterTest::infoImplementationError}); - - #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT addInstancedTests({&SceneConverterTest::info}, Containers::arraySize(InfoData)); @@ -802,1130 +735,11 @@ SceneConverterTest::SceneConverterTest() { addInstancedTests({&SceneConverterTest::error}, Containers::arraySize(ErrorData)); - #endif - - /* A subset of arguments needed by the info printing code */ - _infoArgs.addBooleanOption("info") - .addBooleanOption("info-scenes") - .addBooleanOption("info-objects") - .addBooleanOption("info-animations") - .addBooleanOption("info-skins") - .addBooleanOption("info-lights") - .addBooleanOption("info-cameras") - .addBooleanOption("info-materials") - .addBooleanOption("info-meshes") - .addBooleanOption("info-textures") - .addBooleanOption("info-images") - .addBooleanOption("bounds"); /* Create output dir, if doesn't already exist */ Utility::Path::make(Utility::Path::join(SCENETOOLS_TEST_OUTPUT_DIR, "SceneConverterTestFiles")); } -void SceneConverterTest::infoImplementationEmpty() { - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - } importer; - - const char* argv[]{"", "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); - CORRADE_COMPARE(out.str(), ""); -} - -void SceneConverterTest::infoImplementationScenesObjects() { - auto&& data = InfoImplementationScenesObjectsData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - /* First scene has 4, second 7, the last three are not in any scene and - thus not listed. Object 5 has no fields and thus not listed either. */ - UnsignedLong doObjectCount() const override { return 10; } - UnsignedInt doSceneCount() const override { return 2; } - Containers::String doSceneName(UnsignedInt id) override { - return id == 0 ? "A simple scene" : ""; - } - Containers::String doObjectName(UnsignedLong id) override { - if(id == 0) return "Parent-less mesh"; - if(id == 2) return "Two meshes, shared among two scenes"; - if(id == 4) return "Two custom arrays"; - if(id == 6) return "Only in the second scene, but no fields, thus same as unreferenced"; - if(id == 8) return "Not in any scene"; - return ""; - } - Containers::String doSceneFieldName(UnsignedInt name) override { - if(name == 1337) return "DirectionVector"; - return ""; - } - Containers::Optional doScene(UnsignedInt id) override { - /* Builtin fields, some duplicated, one marked as ordered */ - if(id == 0) { - Containers::ArrayView parentMapping; - Containers::ArrayView parents; - Containers::ArrayView meshMapping; - Containers::ArrayView meshes; - Containers::ArrayTuple data{ - {NoInit, 3, parentMapping}, - {ValueInit, 3, parents}, - {NoInit, 4, meshMapping}, - {ValueInit, 4, meshes}, - }; - Utility::copy({1, 3, 2}, parentMapping); - Utility::copy({2, 0, 2, 1}, meshMapping); - /* No need to fill the data, zero-init is fine */ - return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 4, std::move(data), { - Trade::SceneFieldData{Trade::SceneField::Parent, parentMapping, parents}, - Trade::SceneFieldData{Trade::SceneField::Mesh, meshMapping, meshes, Trade::SceneFieldFlag::OrderedMapping}, - }}; - } - - /* Two custom fields, one array. Stored as an external memory. */ - if(id == 1) { - return Trade::SceneData{Trade::SceneMappingType::UnsignedByte, 8, Trade::DataFlag::ExternallyOwned|Trade::DataFlag::Mutable, scene2Data, { - Trade::SceneFieldData{Trade::sceneFieldCustom(42), Containers::arrayView(scene2Data->customMapping), Containers::arrayView(scene2Data->custom)}, - Trade::SceneFieldData{Trade::sceneFieldCustom(1337), Trade::SceneMappingType::UnsignedByte, scene2Data->customArrayMapping, Trade::SceneFieldType::Short, scene2Data->customArray, 3}, - }}; - } - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - struct { - UnsignedByte customMapping[2]; - Double custom[2]; - UnsignedByte customArrayMapping[3]; - Vector3s customArray[3]; - } scene2Data[1]{{ - /* No need to fill the data, zero-init is fine */ - {7, 3}, {}, {2, 4, 4}, {} - }}; - } importer; - - const char* argv[]{"", data.arg}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join({SCENETOOLS_TEST_DIR, "SceneConverterTestFiles", data.expected}), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationAnimations() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doAnimationCount() const override { return 2; } - Containers::String doAnimationName(UnsignedInt id) override { - return id == 1 ? "Custom track duration and interpolator function" : ""; - } - Containers::Optional doAnimation(UnsignedInt id) override { - /* First has two tracks with a shared time and implicit duration, - one with a different result type. */ - if(id == 0) { - Containers::ArrayView time; - Containers::ArrayView translation; - Containers::ArrayView rotation; - Containers::ArrayTuple data{ - {ValueInit, 3, time}, - {ValueInit, 3, translation}, - {ValueInit, 3, rotation} - }; - Utility::copy({0.5f, 1.0f, 1.25f}, time); - return Trade::AnimationData{std::move(data), { - /** @todo cleanup once AnimationTrackData has sane - constructors */ - Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Translation2D, 17, Animation::TrackView{time, translation, Animation::Interpolation::Linear, Animation::Extrapolation::DefaultConstructed, Animation::Extrapolation::Constant}}, - Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Rotation2D, 17, Animation::TrackView{time, rotation, Animation::Interpolation::Constant, Animation::Extrapolation::Extrapolated}}, - }}; - } - - /* Second has track duration different from animation duration and - a custom interpolator. Stored as an external memory. */ - if(id == 1) { - return Trade::AnimationData{Trade::DataFlag::ExternallyOwned, animation2Data, { - /** @todo cleanup once AnimationTrackData has sane - constructors */ - Trade::AnimationTrackData{Trade::AnimationTrackTargetType::Scaling3D, 666, Animation::TrackView{animation2Data->time, animation2Data->scaling, Math::lerp, Animation::Extrapolation::DefaultConstructed, Animation::Extrapolation::Constant}}, - }, {0.1f, 1.3f}}; - } - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - struct { - Float time[5]; - Vector3 scaling[5]; - } animation2Data[1]{{ - {0.75f, 0.75f, 1.0f, 1.0f, 1.25f}, - {} - }}; - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-animations" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-animations.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationSkins() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doSkin2DCount() const override { return 2; } - Containers::String doSkin2DName(UnsignedInt id) override { - return id == 1 ? "Second 2D skin, external data" : ""; - } - Containers::Optional doSkin2D(UnsignedInt id) override { - /* First a regular skin, second externally owned */ - if(id == 0) return Trade::SkinData2D{ - {3, 6, 7, 12, 22}, - {{}, {}, {}, {}, {}} - }; - - if(id == 1) return Trade::SkinData2D{Trade::DataFlag::ExternallyOwned, skin2JointData, Trade::DataFlag::ExternallyOwned, skin2MatrixData}; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doSkin3DCount() const override { return 3; } - Containers::String doSkin3DName(UnsignedInt id) override { - return id == 0 ? "First 3D skin, external data" : ""; - } - Containers::Optional doSkin3D(UnsignedInt id) override { - /* Reverse order in 3D, plus one more to ensure the count isn't - mismatched between 2D and 3D */ - if(id == 0) return Trade::SkinData3D{Trade::DataFlag::ExternallyOwned, skin3JointData, Trade::DataFlag::ExternallyOwned, skin3MatrixData}; - - if(id == 1) return Trade::SkinData3D{ - {3, 22}, - {{}, {}} - }; - - if(id == 2) return Trade::SkinData3D{ - {3}, - {{}} - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt skin2JointData[15]; - Matrix3 skin2MatrixData[15]; - UnsignedInt skin3JointData[12]; - Matrix4 skin3MatrixData[12]; - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-skins" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-skins.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationLights() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doLightCount() const override { return 2; } - Containers::String doLightName(UnsignedInt id) override { - return id == 1 ? "Directional light with always-implicit attenuation and range" : ""; - } - Containers::Optional doLight(UnsignedInt id) override { - /* First a blue spot light */ - if(id == 0) return Trade::LightData{ - Trade::LightData::Type::Spot, - 0x3457ff_rgbf, - 15.0f, - {1.2f, 0.3f, 0.04f}, - 100.0f, - 55.0_degf, - 85.0_degf - }; - - /* Second a yellow directional light with infinite range */ - if(id == 1) return Trade::LightData{ - Trade::LightData::Type::Directional, - 0xff5734_rgbf, - 5.0f - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-lights" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-lights.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationCameras() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doCameraCount() const override { return 3; } - Containers::String doCameraName(UnsignedInt id) override { - return id == 0 ? "Orthographic 2D" : ""; - } - Containers::Optional doCamera(UnsignedInt id) override { - /* First 2D ortho camera, where near/far will get omited */ - if(id == 0) return Trade::CameraData{ - Trade::CameraType::Orthographic2D, - {5.0f, 6.0f}, - 0.0f, 0.0f - }; - - /* 3D ortho camera */ - if(id == 1) return Trade::CameraData{ - Trade::CameraType::Orthographic3D, - {2.0f, 3.0f}, - -1.0f, 0.5f - }; - - /* Third a perspective camera, specified with size, but printed - with FoV */ - if(id == 2) return Trade::CameraData{ - Trade::CameraType::Perspective3D, - 35.0_degf, 4.0f/3.0f, 0.01f, 100.0f - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-cameras" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-cameras.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationMaterials() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doMaterialCount() const override { return 2; } - Containers::String doMaterialName(UnsignedInt id) override { - return id == 1 ? "Lots o' laierz" : ""; - } - Containers::Optional doMaterial(UnsignedInt id) override { - /* First has custom attributes */ - if(id == 0) return Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, { - {Trade::MaterialAttribute::BaseColor, 0x3bd26799_rgbaf}, - {Trade::MaterialAttribute::DoubleSided, true}, - {Trade::MaterialAttribute::EmissiveColor, 0xe9eca_rgbf}, - {Trade::MaterialAttribute::RoughnessTexture, 67u}, - {Trade::MaterialAttribute::RoughnessTextureMatrix, Matrix3::translation({0.25f, 0.75f})}, - {Trade::MaterialAttribute::RoughnessTextureSwizzle, Trade::MaterialTextureSwizzle::B}, - {"reflectionAngle", 35.0_degf}, - /* These shouldn't have a color swatch rendered */ - {"notAColour4", Vector4{0.1f, 0.2f, 0.3f, 0.4f}}, - {"notAColour3", Vector3{0.2f, 0.3f, 0.4f}}, - {"data", Containers::ArrayView{"0123456789abcdef", 17}}, - {"deadBeef", reinterpret_cast(0xdeadbeef)}, - {"undeadBeef", reinterpret_cast(0xbeefbeef)}, - }}; - - /* Second has layers, custom layers, unnamed layers and a name */ - if(id == 1) return Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Phong, { - {Trade::MaterialAttribute::DiffuseColor, 0xc7cf2f99_rgbaf}, - {Trade::MaterialLayer::ClearCoat}, - {Trade::MaterialAttribute::LayerFactor, 0.5f}, - {Trade::MaterialAttribute::LayerFactorTexture, 3u}, - {Trade::MaterialAttribute::LayerName, "anEmptyLayer"}, - {Trade::MaterialAttribute::LayerFactor, 0.25f}, - {Trade::MaterialAttribute::LayerFactorTexture, 2u}, - {"yes", "a string"}, - }, {1, 4, 5, 8}}; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-materials" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-materials.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationMeshes() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doMeshCount() const override { return 3; } - UnsignedInt doMeshLevelCount(UnsignedInt id) override { - return id == 1 ? 2 : 1; - } - Containers::String doMeshName(UnsignedInt id) override { - return id == 1 ? "LODs? No, meshets." : ""; - } - Containers::String doMeshAttributeName(UnsignedShort name) override { - if(name == 25) return "vertices"; - if(name == 26) return "triangles"; - /* 37 (triangleCount) deliberately not named */ - if(name == 116) return "vertexCount"; - - return ""; - } - Containers::Optional doMesh(UnsignedInt id, UnsignedInt level) override { - /* First is indexed & externally owned */ - if(id == 0 && level == 0) return Trade::MeshData{MeshPrimitive::Points, - Trade::DataFlag::ExternallyOwned, indices, - Trade::MeshIndexData{indices}, - Trade::DataFlag::ExternallyOwned|Trade::DataFlag::Mutable, points, { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(points)} - }}; - - /* Second is multi-level, with second level being indexed meshlets - with custom (array) attributes */ - if(id == 1 && level == 0) { - Containers::ArrayView positions; - Containers::ArrayView tangents; - Containers::ArrayTuple data{ - {NoInit, 250, positions}, - {NoInit, 250, tangents}, - }; - return Trade::MeshData{MeshPrimitive::Triangles, std::move(data), { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions}, - Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, tangents}, - }}; - } - if(id == 1 && level == 1) { - Containers::StridedArrayView2D vertices; - Containers::StridedArrayView2D indices; - Containers::ArrayView triangleCount; - Containers::ArrayView vertexCount; - Containers::ArrayTuple data{ - {NoInit, {135, 64}, vertices}, - {NoInit, {135, 126}, indices}, - {NoInit, 135, triangleCount}, - {NoInit, 135, vertexCount}, - }; - return Trade::MeshData{MeshPrimitive::Meshlets, std::move(data), { - Trade::MeshAttributeData{Trade::meshAttributeCustom(25), vertices}, - Trade::MeshAttributeData{Trade::meshAttributeCustom(26), indices}, - Trade::MeshAttributeData{Trade::meshAttributeCustom(37), triangleCount}, - Trade::MeshAttributeData{Trade::meshAttributeCustom(116), vertexCount}, - }}; - } - - /* Third is an empty instance mesh */ - if(id == 2 && level == 0) return Trade::MeshData{MeshPrimitive::Instances, 15}; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedShort indices[70]; - Vector3 points[50]; - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-meshes" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-meshes.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationMeshesBounds() { - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doMeshCount() const override { return 1; } - Containers::Optional doMesh(UnsignedInt, UnsignedInt) override { - return Trade::MeshData{MeshPrimitive::Lines, - {}, indexData, Trade::MeshIndexData{indexData}, - {}, vertexData, { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(vertexData->positions)}, - Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, Containers::arrayView(vertexData->tangent)}, - Trade::MeshAttributeData{Trade::MeshAttribute::Bitangent, Containers::arrayView(vertexData->bitangent)}, - Trade::MeshAttributeData{Trade::MeshAttribute::ObjectId, Containers::arrayView(vertexData->objectId)}, - Trade::MeshAttributeData{Trade::MeshAttribute::Normal, Containers::arrayView(vertexData->normal)}, - Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, Containers::arrayView(vertexData->textureCoordinates)}, - Trade::MeshAttributeData{Trade::MeshAttribute::Color, Containers::arrayView(vertexData->color)}, - Trade::MeshAttributeData{Trade::MeshAttribute::ObjectId, Containers::arrayView(vertexData->objectIdSecondary)}, - }}; - } - - UnsignedByte indexData[3]{15, 3, 176}; - - struct { - Vector3 positions[2]; - Vector3 tangent[2]; - Vector3 bitangent[2]; - UnsignedShort objectId[2]; - Vector3 normal[2]; - Vector2 textureCoordinates[2]; - Vector4 color[2]; - UnsignedInt objectIdSecondary[2]; - } vertexData[1]{{ - {{0.1f, -0.1f, 0.2f}, {0.2f, 0.0f, -0.2f}}, - {{0.2f, -0.2f, 0.8f}, {0.3f, 0.8f, 0.2f}}, - {{0.4f, 0.2f, 1.0f}, {0.3f, 0.9f, 0.0f}}, - {155, 12}, - {{0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 1.0f}}, - {{0.5f, 0.5f}, {1.5f, 0.5f}}, - {0x99336600_rgbaf, 0xff663333_rgbaf}, - {15, 337}, - }}; - } importer; - - const char* argv[]{"", "--info-meshes", "--bounds"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-meshes-bounds.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationTextures() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doTextureCount() const override { return 2; } - Containers::String doTextureName(UnsignedInt id) override { - return id == 1 ? "Name!" : ""; - } - Containers::Optional doTexture(UnsignedInt id) override { - /* First a 1D texture */ - if(id == 0) return Trade::TextureData{ - Trade::TextureType::Texture1D, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 666 - }; - - /* Second a 2D array texture */ - if(id == 1) return Trade::TextureData{ - Trade::TextureType::Texture2DArray, - SamplerFilter::Linear, - SamplerFilter::Nearest, - SamplerMipmap::Linear, - {SamplerWrapping::MirroredRepeat, SamplerWrapping::ClampToEdge, SamplerWrapping::MirrorClampToEdge}, - 3 - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-textures" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-textures.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationImages() { - auto&& data = InfoImplementationOneOrAllData[testCaseInstanceId()]; - setTestCaseDescription(data.name); - - /* Just the very basics to ensure image info *is* printed. Tested in full - in ImageConverterTest. */ - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - UnsignedInt doImage1DCount() const override { return 1; } - Containers::Optional doImage1D(UnsignedInt, UnsignedInt) override { - return Trade::ImageData1D{PixelFormat::R32F, 1024, Containers::Array{NoInit, 4096}}; - } - } importer; - - const char* argv[]{"", data.oneOrAll ? "--info-images" : "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - if(data.printVisualCheck) { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-images.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationReferenceCount() { - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - /* One data of each kind should be always referenced twice+, one once, - one not at all, and one reference should be OOB */ - - UnsignedLong doObjectCount() const override { return 4; } - Containers::String doObjectName(UnsignedLong id) override { - return id == 2 ? "Not referenced" : ""; - } - UnsignedInt doSceneCount() const override { return 2; } - Containers::Optional doScene(UnsignedInt id) override { - if(id == 0) return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 2, {}, sceneData3D, { - /* To mark the scene as 3D */ - Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix4x4, nullptr}, - Trade::SceneFieldData{Trade::SceneField::Mesh, - Containers::arrayView(sceneData3D->mapping), - Containers::arrayView(sceneData3D->meshes)}, - Trade::SceneFieldData{Trade::SceneField::MeshMaterial, - Containers::arrayView(sceneData3D->mapping), - Containers::arrayView(sceneData3D->materials)}, - Trade::SceneFieldData{Trade::SceneField::Light, - Containers::arrayView(sceneData3D->mapping), - Containers::arrayView(sceneData3D->lights)}, - Trade::SceneFieldData{Trade::SceneField::Camera, - Containers::arrayView(sceneData3D->mapping), - Containers::arrayView(sceneData3D->cameras)}, - Trade::SceneFieldData{Trade::SceneField::Skin, - Containers::arrayView(sceneData3D->mapping), - Containers::arrayView(sceneData3D->skins)}, - }}; - if(id == 1) return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 4, {}, sceneData2D, { - /* To mark the scene as 2D */ - Trade::SceneFieldData{Trade::SceneField::Transformation, Trade::SceneMappingType::UnsignedInt, nullptr, Trade::SceneFieldType::Matrix3x3, nullptr}, - Trade::SceneFieldData{Trade::SceneField::Mesh, - Containers::arrayView(sceneData2D->mapping), - Containers::arrayView(sceneData2D->meshes)}, - Trade::SceneFieldData{Trade::SceneField::Skin, - Containers::arrayView(sceneData2D->mapping), - Containers::arrayView(sceneData2D->skins)}, - }}; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doSkin2DCount() const override { return 3; } - Containers::String doSkin2DName(UnsignedInt id) override { - return id == 2 ? "Not referenced" : ""; - } - Containers::Optional doSkin2D(UnsignedInt id) override { - if(id == 0) return Trade::SkinData2D{ - {35, 22}, - {{}, {}} - }; - if(id == 1) return Trade::SkinData2D{ - {33, 10, 100}, - {{}, {}, {}} - }; - if(id == 2) return Trade::SkinData2D{ - {66}, - {{}} - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doSkin3DCount() const override { return 3; } - Containers::String doSkin3DName(UnsignedInt id) override { - return id == 0 ? "Not referenced" : ""; - } - Containers::Optional doSkin3D(UnsignedInt id) override { - if(id == 0) return Trade::SkinData3D{ - {35, 22}, - {{}, {}} - }; - if(id == 1) return Trade::SkinData3D{ - {37}, - {{}} - }; - if(id == 2) return Trade::SkinData3D{ - {300, 10, 1000}, - {{}, {}, {}} - }; - - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doLightCount() const override { return 3; } - Containers::String doLightName(UnsignedInt id) override { - return id == 1 ? "Not referenced" : ""; - } - Containers::Optional doLight(UnsignedInt id) override { - if(id == 0) return Trade::LightData{ - Trade::LightData::Type::Directional, - 0x57ff34_rgbf, - 5.0f - }; - if(id == 1) return Trade::LightData{ - Trade::LightData::Type::Ambient, - 0xff5734_rgbf, - 0.1f - }; - if(id == 2) return Trade::LightData{ - Trade::LightData::Type::Directional, - 0x3457ff_rgbf, - 1.0f - }; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doCameraCount() const override { return 3; } - Containers::String doCameraName(UnsignedInt id) override { - return id == 0 ? "Not referenced" : ""; - } - Containers::Optional doCamera(UnsignedInt id) override { - if(id == 0) return Trade::CameraData{ - Trade::CameraType::Orthographic3D, - {2.0f, 3.0f}, - -1.0f, 0.5f - }; - if(id == 1) return Trade::CameraData{ - Trade::CameraType::Orthographic3D, - {2.0f, 2.0f}, - 0.0f, 1.0f - }; - if(id == 2) return Trade::CameraData{ - Trade::CameraType::Orthographic2D, - {2.0f, 2.0f}, - 0.0f, 0.0f - }; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doMaterialCount() const override { return 3; } - Containers::String doMaterialName(UnsignedInt id) override { - return id == 2 ? "Not referenced" : ""; - } - Containers::Optional doMaterial(UnsignedInt id) override { - if(id == 0) return Trade::MaterialData{{}, { - {Trade::MaterialAttribute::DiffuseTexture, 2u}, - {Trade::MaterialAttribute::BaseColorTexture, 2u}, - }}; - if(id == 1) return Trade::MaterialData{{}, { - {"lookupTexture", 0u}, - {"volumeTexture", 3u}, - {Trade::MaterialAttribute::NormalTexture, 17u}, - {Trade::MaterialAttribute::EmissiveTexture, 4u}, - }}; - if(id == 2) return Trade::MaterialData{{}, {}}; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doMeshCount() const override { return 3; } - Containers::String doMeshName(UnsignedInt id) override { - return id == 1 ? "Not referenced" : ""; - } - Containers::Optional doMesh(UnsignedInt id, UnsignedInt) override { - if(id == 0) return Trade::MeshData{MeshPrimitive::Points, 5}; - if(id == 1) return Trade::MeshData{MeshPrimitive::Lines, 4}; - if(id == 2) return Trade::MeshData{MeshPrimitive::TriangleFan, 4}; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doTextureCount() const override { return 5; } - Containers::String doTextureName(UnsignedInt id) override { - return id == 1 ? "Not referenced" : ""; - } - Containers::Optional doTexture(UnsignedInt id) override { - if(id == 0) return Trade::TextureData{ - Trade::TextureType::Texture1D, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 1 - }; - if(id == 1) return Trade::TextureData{ - Trade::TextureType::Texture1DArray, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 225 - }; - if(id == 2) return Trade::TextureData{ - Trade::TextureType::Texture2D, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 0 - }; - if(id == 3) return Trade::TextureData{ - Trade::TextureType::Texture3D, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 1 - }; - if(id == 4) return Trade::TextureData{ - Trade::TextureType::Texture2D, - SamplerFilter::Nearest, - SamplerFilter::Linear, - SamplerMipmap::Nearest, - SamplerWrapping::Repeat, - 0 - }; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doImage1DCount() const override { return 2; } - Containers::String doImage1DName(UnsignedInt id) override { - return id == 0 ? "Not referenced" : ""; - } - Containers::Optional doImage1D(UnsignedInt id, UnsignedInt) override { - if(id == 0) - return Trade::ImageData1D{PixelFormat::RGBA8I, 1, Containers::Array{NoInit, 4}}; - if(id == 1) - return Trade::ImageData1D{PixelFormat::R8I, 4, Containers::Array{NoInit, 4}}; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doImage2DCount() const override { return 2; } - Containers::String doImage2DName(UnsignedInt id) override { - return id == 1 ? "Not referenced" : ""; - } - Containers::Optional doImage2D(UnsignedInt id, UnsignedInt) override { - if(id == 0) - return Trade::ImageData2D{PixelFormat::RGBA8I, {1, 2}, Containers::Array{NoInit, 8}}; - if(id == 1) - return Trade::ImageData2D{PixelFormat::R8I, {4, 1}, Containers::Array{NoInit, 4}}; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - UnsignedInt doImage3DCount() const override { return 2; } - Containers::String doImage3DName(UnsignedInt id) override { - return id == 0 ? "Not referenced" : ""; - } - Containers::Optional doImage3D(UnsignedInt id, UnsignedInt) override { - if(id == 0) - return Trade::ImageData3D{PixelFormat::RGBA8I, {1, 2, 1}, Containers::Array{NoInit, 8}}; - if(id == 1) - return Trade::ImageData3D{PixelFormat::R8I, {4, 1, 1}, Containers::Array{NoInit, 4}}; - CORRADE_INTERNAL_ASSERT_UNREACHABLE(); - } - - struct { - UnsignedInt mapping[4]; - UnsignedInt meshes[4]; - Int materials[4]; - UnsignedInt lights[4]; - UnsignedInt cameras[4]; - UnsignedInt skins[4]; - } sceneData3D[1]{{ - {0, 1, 1, 25}, - {2, 0, 2, 67}, - {0, 1, 23, 0}, - {0, 17, 0, 2}, - {166, 1, 2, 1}, - {1, 1, 22, 2} - }}; - - struct { - UnsignedInt mapping[3]; - UnsignedInt meshes[3]; - UnsignedInt skins[3]; - } sceneData2D[1]{{ - {3, 116, 1}, - {2, 0, 23}, - {177, 0, 1} - }}; - } importer; - - const char* argv[]{"", "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - /* Print to visually verify coloring */ - { - Debug{} << "======================== visual color verification start ======================="; - Implementation::printInfo(Debug::isTty() ? Debug::Flags{} : Debug::Flag::DisableColors, Debug::isTty(), _infoArgs, importer, time); - Debug{} << "======================== visual color verification end ========================="; - } - - std::ostringstream out; - Debug redirectOutput{&out}; - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, false, _infoArgs, importer, time) == false); - CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(SCENETOOLS_TEST_DIR, "SceneConverterTestFiles/info-references.txt"), - TestSuite::Compare::StringToFile); -} - -void SceneConverterTest::infoImplementationError() { - struct Importer: Trade::AbstractImporter { - Trade::ImporterFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } - void doClose() override {} - - /* The one single object is named, and that name should be printed - after all error messages */ - UnsignedLong doObjectCount() const override { return 1; } - Containers::String doObjectName(UnsignedLong) override { return "A name"; } - - UnsignedInt doSceneCount() const override { return 2; } - Containers::Optional doScene(UnsignedInt id) override { - Error{} << "Scene" << id << "error!"; - return {}; - } - - UnsignedInt doAnimationCount() const override { return 2; } - Containers::Optional doAnimation(UnsignedInt id) override { - Error{} << "Animation" << id << "error!"; - return {}; - } - - UnsignedInt doSkin2DCount() const override { return 2; } - Containers::Optional doSkin2D(UnsignedInt id) override { - Error{} << "2D skin" << id << "error!"; - return {}; - } - - UnsignedInt doSkin3DCount() const override { return 2; } - Containers::Optional doSkin3D(UnsignedInt id) override { - Error{} << "3D skin" << id << "error!"; - return {}; - } - - UnsignedInt doLightCount() const override { return 2; } - Containers::Optional doLight(UnsignedInt id) override { - Error{} << "Light" << id << "error!"; - return {}; - } - - UnsignedInt doCameraCount() const override { return 2; } - Containers::Optional doCamera(UnsignedInt id) override { - Error{} << "Camera" << id << "error!"; - return {}; - } - - UnsignedInt doMaterialCount() const override { return 2; } - Containers::Optional doMaterial(UnsignedInt id) override { - Error{} << "Material" << id << "error!"; - return {}; - } - - UnsignedInt doMeshCount() const override { return 2; } - Containers::Optional doMesh(UnsignedInt id, UnsignedInt) override { - Error{} << "Mesh" << id << "error!"; - return {}; - } - - UnsignedInt doTextureCount() const override { return 2; } - Containers::Optional doTexture(UnsignedInt id) override { - Error{} << "Texture" << id << "error!"; - return {}; - } - - /* Errors for all image types tested in ImageConverterTest */ - UnsignedInt doImage2DCount() const override { return 2; } - Containers::Optional doImage2D(UnsignedInt id, UnsignedInt) override { - Error{} << "Image" << id << "error!"; - return {}; - } - } importer; - - const char* argv[]{"", "--info"}; - CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv)); - - std::chrono::high_resolution_clock::duration time; - - std::ostringstream out; - Debug redirectOutput{&out}; - Error redirectError{&out}; - /* It should return a failure */ - CORRADE_VERIFY(Implementation::printInfo(Debug::Flag::DisableColors, {}, _infoArgs, importer, time) == true); - CORRADE_COMPARE(out.str(), - /* It should not exit after first error... */ - "Scene 0 error!\n" - "Scene 1 error!\n" - "Animation 0 error!\n" - "Animation 1 error!\n" - "2D skin 0 error!\n" - "2D skin 1 error!\n" - "3D skin 0 error!\n" - "3D skin 1 error!\n" - "Light 0 error!\n" - "Light 1 error!\n" - "Camera 0 error!\n" - "Camera 1 error!\n" - "Material 0 error!\n" - "Material 1 error!\n" - "Mesh 0 error!\n" - "Mesh 1 error!\n" - "Texture 0 error!\n" - "Texture 1 error!\n" - "Image 0 error!\n" - "Image 1 error!\n" - /* ... and it should print all info output after the errors */ - "Object 0: A name\n"); -} - -#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT namespace { #ifdef SCENECONVERTER_EXECUTABLE_FILENAME @@ -1964,12 +778,8 @@ void SceneConverterTest::info() { setTestCaseDescription(data.name); #ifndef SCENECONVERTER_EXECUTABLE_FILENAME - #ifdef CORRADE_TARGET_UNIX CORRADE_SKIP("magnum-sceneconverter not built, can't test"); #else - CORRADE_SKIP("Executable testing implemented only on Unix platforms"); - #endif - #else /* Check if required plugins can be loaded. Catches also ABI and interface mismatch errors. */ PluginManager::Manager importerManager{MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}; @@ -1991,12 +801,8 @@ void SceneConverterTest::convert() { setTestCaseDescription(data.name); #ifndef SCENECONVERTER_EXECUTABLE_FILENAME - #ifdef CORRADE_TARGET_UNIX CORRADE_SKIP("magnum-sceneconverter not built, can't test"); #else - CORRADE_SKIP("Executable testing implemented only on Unix platforms"); - #endif - #else /* Check if required plugins can be loaded. Catches also ABI and interface mismatch errors. */ PluginManager::Manager importerManager{MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}; @@ -2043,12 +849,8 @@ void SceneConverterTest::error() { setTestCaseDescription(data.name); #ifndef SCENECONVERTER_EXECUTABLE_FILENAME - #ifdef CORRADE_TARGET_UNIX CORRADE_SKIP("magnum-sceneconverter not built, can't test"); #else - CORRADE_SKIP("Executable testing implemented only on Unix platforms"); - #endif - #else /* Check if required plugins can be loaded. Catches also ABI and interface mismatch errors. */ PluginManager::Manager importerManager{MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}; @@ -2087,7 +889,6 @@ void SceneConverterTest::error() { CORRADE_VERIFY(!output.first()); #endif } -#endif }}}} diff --git a/src/Magnum/Trade/Test/CMakeLists.txt b/src/Magnum/Trade/Test/CMakeLists.txt index 3360dd59c..7364ecc3f 100644 --- a/src/Magnum/Trade/Test/CMakeLists.txt +++ b/src/Magnum/Trade/Test/CMakeLists.txt @@ -55,11 +55,11 @@ corrade_add_test(TradeCameraDataTest CameraDataTest.cpp LIBRARIES MagnumTradeTes corrade_add_test(TradeDataTest DataTest.cpp LIBRARIES MagnumTrade) corrade_add_test(TradeFlatMaterialDataTest FlatMaterialDataTest.cpp LIBRARIES MagnumTradeTestLib) -corrade_add_test(TradeImageConverterTest ImageConverterTest.cpp +corrade_add_test(TradeImageConverterImplementa___Test ImageConverterImplementationTest.cpp LIBRARIES MagnumTrade FILES - ImageConverterTestFiles/info.txt) -target_include_directories(TradeImageConverterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + ImageConverterImplementationTestFiles/info.txt) +target_include_directories(TradeImageConverterImplementa___Test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) corrade_add_test(TradeImageDataTest ImageDataTest.cpp LIBRARIES MagnumTradeTestLib) corrade_add_test(TradeLightDataTest LightDataTest.cpp LIBRARIES MagnumTradeTestLib) diff --git a/src/Magnum/Trade/Test/ImageConverterTest.cpp b/src/Magnum/Trade/Test/ImageConverterImplementationTest.cpp similarity index 93% rename from src/Magnum/Trade/Test/ImageConverterTest.cpp rename to src/Magnum/Trade/Test/ImageConverterImplementationTest.cpp index 812caf3aa..be66e56ea 100644 --- a/src/Magnum/Trade/Test/ImageConverterTest.cpp +++ b/src/Magnum/Trade/Test/ImageConverterImplementationTest.cpp @@ -36,19 +36,19 @@ namespace Magnum { namespace Trade { namespace Test { namespace { -struct ImageConverterTest: TestSuite::Tester { - explicit ImageConverterTest(); +struct ImageConverterImplementationTest: TestSuite::Tester { + explicit ImageConverterImplementationTest(); - void infoImplementation(); - void infoImplementationError(); + void info(); + void infoError(); }; -ImageConverterTest::ImageConverterTest() { - addTests({&ImageConverterTest::infoImplementation, - &ImageConverterTest::infoImplementationError}); +ImageConverterImplementationTest::ImageConverterImplementationTest() { + addTests({&ImageConverterImplementationTest::info, + &ImageConverterImplementationTest::infoError}); } -void ImageConverterTest::infoImplementation() { +void ImageConverterImplementationTest::info() { struct Importer: Trade::AbstractImporter { Trade::ImporterFeatures doFeatures() const override { return {}; } bool doIsOpened() const override { return true; } @@ -139,11 +139,11 @@ void ImageConverterTest::infoImplementation() { Debug redirectOutput{&out}; Implementation::printImageInfo(Debug::Flag::DisableColors, infos, nullptr, nullptr, nullptr); CORRADE_COMPARE_AS(out.str(), - Utility::Path::join(TRADE_TEST_DIR, "ImageConverterTestFiles/info.txt"), + Utility::Path::join(TRADE_TEST_DIR, "ImageConverterImplementationTestFiles/info.txt"), TestSuite::Compare::StringToFile); } -void ImageConverterTest::infoImplementationError() { +void ImageConverterImplementationTest::infoError() { struct Importer: Trade::AbstractImporter { Trade::ImporterFeatures doFeatures() const override { return {}; } bool doIsOpened() const override { return true; } @@ -189,4 +189,4 @@ void ImageConverterTest::infoImplementationError() { }}}} -CORRADE_TEST_MAIN(Magnum::Trade::Test::ImageConverterTest) +CORRADE_TEST_MAIN(Magnum::Trade::Test::ImageConverterImplementationTest) diff --git a/src/Magnum/Trade/Test/ImageConverterTestFiles/info.txt b/src/Magnum/Trade/Test/ImageConverterImplementationTestFiles/info.txt similarity index 100% rename from src/Magnum/Trade/Test/ImageConverterTestFiles/info.txt rename to src/Magnum/Trade/Test/ImageConverterImplementationTestFiles/info.txt