From 66388912b702ced15e2b06c7ab95fbc60b17f3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 3 Jun 2026 23:32:12 +0200 Subject: [PATCH] ShaderTools,Text,Trade: thoroughly test operation failures. So far, even though code coverage says it's all fine, things like data conversion failures were not tested at all, or only by checking the return value, but without verifying that the implementation got actually called, and without checking that no superfluous message was printed by accident. The AbstractFontConverter interface is tested for failures as well even though most of it is scheduled for rework (STL removal, etc.), as otherwise it'd be likely that I forget to test the failure cases when simply porting the old test code to the new APIs. On the other hand, the Audio importer interface is not touched as it's scheduled for merging into Trade. --- .../Test/AbstractConverterTest.cpp | 125 +++ .../Text/Test/AbstractFontConverterTest.cpp | 343 +++++++- src/Magnum/Text/Test/AbstractFontTest.cpp | 333 +++++++- .../Trade/Test/AbstractImageConverterTest.cpp | 792 +++++++++++++++++- .../Trade/Test/AbstractImporterTest.cpp | 404 +++++++-- .../Trade/Test/AbstractSceneConverterTest.cpp | 331 +++++++- 6 files changed, 2227 insertions(+), 101 deletions(-) diff --git a/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp b/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp index 5b8f971d5..4ebde3294 100644 --- a/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp +++ b/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp @@ -80,6 +80,7 @@ struct AbstractConverterTest: TestSuite::Tester { void validateFileFailed(); void validateFileAsData(); void validateFileAsDataNotFound(); + void validateFileAsDataFailed(); void validateFileNotSupported(); void validateFileNotImplemented(); void validateFilePreprocessOnly(); @@ -109,6 +110,7 @@ struct AbstractConverterTest: TestSuite::Tester { void convertFileToDataFailed(); void convertFileToDataAsData(); void convertFileToDataAsDataNotFound(); + void convertFileToDataAsDataFailed(); void convertFileToDataNotSupported(); void convertFileToDataNotImplemented(); void convertFileToDataCustomDeleter(); @@ -143,6 +145,7 @@ struct AbstractConverterTest: TestSuite::Tester { void linkFilesToDataFailed(); void linkFilesToDataAsData(); void linkFilesToDataAsDataNotFound(); + void linkFilesToDataAsDataFailed(); void linkFilesToDataNotSupported(); void linkFilesToDataNotImplemented(); void linkFilesToDataPreprocessOnly(); @@ -232,6 +235,7 @@ AbstractConverterTest::AbstractConverterTest() { &AbstractConverterTest::validateFileFailed, &AbstractConverterTest::validateFileAsData, &AbstractConverterTest::validateFileAsDataNotFound, + &AbstractConverterTest::validateFileAsDataFailed, &AbstractConverterTest::validateFileNotSupported, &AbstractConverterTest::validateFileNotImplemented, &AbstractConverterTest::validateFilePreprocessOnly, @@ -261,6 +265,7 @@ AbstractConverterTest::AbstractConverterTest() { &AbstractConverterTest::convertFileToDataFailed, &AbstractConverterTest::convertFileToDataAsData, &AbstractConverterTest::convertFileToDataAsDataNotFound, + &AbstractConverterTest::convertFileToDataAsDataFailed, &AbstractConverterTest::convertFileToDataNotSupported, &AbstractConverterTest::convertFileToDataNotImplemented, &AbstractConverterTest::convertFileToDataCustomDeleter, @@ -295,6 +300,7 @@ AbstractConverterTest::AbstractConverterTest() { &AbstractConverterTest::linkFilesToDataFailed, &AbstractConverterTest::linkFilesToDataAsData, &AbstractConverterTest::linkFilesToDataAsDataNotFound, + &AbstractConverterTest::linkFilesToDataAsDataFailed, &AbstractConverterTest::linkFilesToDataNotSupported, &AbstractConverterTest::linkFilesToDataNotImplemented, &AbstractConverterTest::linkFilesToDataPreprocessOnly, @@ -705,14 +711,18 @@ void AbstractConverterTest::validateDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Pair doValidateData(Stage, Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.validateData(Stage::MeshTask, nullptr).first()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -818,14 +828,18 @@ void AbstractConverterTest::validateFileFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Pair doValidateFile(Stage, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.validateFile(Stage::MeshTask, {}).first()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -872,6 +886,30 @@ void AbstractConverterTest::validateFileAsDataNotFound() { TestSuite::Compare::StringHasSuffix); } +void AbstractConverterTest::validateFileAsDataFailed() { + struct: AbstractConverter { + ConverterFeatures doFeatures() const override { + return ConverterFeature::ValidateData; + } + void doSetInputFormat(Format, Containers::StringView) override {} + void doSetOutputFormat(Format, Containers::StringView) override {} + + Containers::Pair doValidateData(Stage, Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_COMPARE(converter.validateFile({}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat")), (Containers::Pair{})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractConverterTest::validateFileNotSupported() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -974,14 +1012,18 @@ void AbstractConverterTest::convertDataToDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertDataToData({}, nullptr)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1074,8 +1116,11 @@ void AbstractConverterTest::convertDataToFileThroughDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -1089,6 +1134,7 @@ void AbstractConverterTest::convertDataToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertDataToFile({}, {}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1183,14 +1229,18 @@ void AbstractConverterTest::convertFileToFileFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} bool doConvertFileToFile(Stage, Containers::StringView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertFileToFile({}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat"), Utility::Path::join(SHADERTOOLS_TEST_OUTPUT_DIR, "file.dat"))); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1249,8 +1299,11 @@ void AbstractConverterTest::convertFileToFileThroughDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -1264,6 +1317,7 @@ void AbstractConverterTest::convertFileToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertFileToFile({}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat"), filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1354,14 +1408,18 @@ void AbstractConverterTest::convertFileToDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doConvertFileToData(Stage, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertFileToData({}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat"))); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1407,6 +1465,30 @@ void AbstractConverterTest::convertFileToDataAsDataNotFound() { TestSuite::Compare::StringHasSuffix); } +void AbstractConverterTest::convertFileToDataAsDataFailed() { + struct: AbstractConverter { + ConverterFeatures doFeatures() const override { + return ConverterFeature::ConvertData; + } + void doSetInputFormat(Format, Containers::StringView) override {} + void doSetOutputFormat(Format, Containers::StringView) override {} + + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertFileToData({}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat"))); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractConverterTest::convertFileToDataNotSupported() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -1500,8 +1582,11 @@ void AbstractConverterTest::linkDataToDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -1509,6 +1594,7 @@ void AbstractConverterTest::linkDataToDataFailed() { Error redirectError{&out}; /* {{}} makes GCC 4.8 warn about zero as null pointer constant */ CORRADE_VERIFY(!converter.linkDataToData({Containers::Pair>{}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1643,8 +1729,11 @@ void AbstractConverterTest::linkDataToFileThroughDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -1659,6 +1748,7 @@ void AbstractConverterTest::linkDataToFileThroughDataFailed() { /* {{}} makes GCC 4.8 warn about zero as null pointer constant */ CORRADE_VERIFY(!converter.linkDataToFile({Containers::Pair>{}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1877,8 +1967,11 @@ void AbstractConverterTest::linkFilesToFileThroughDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -1894,6 +1987,7 @@ void AbstractConverterTest::linkFilesToFileThroughDataFailed() { {{}, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat")} }, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2031,8 +2125,11 @@ void AbstractConverterTest::linkFilesToDataFailed() { void doSetOutputFormat(Format, Containers::StringView) override {} Containers::Optional> doLinkFilesToData(Containers::ArrayView>) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -2041,6 +2138,7 @@ void AbstractConverterTest::linkFilesToDataFailed() { CORRADE_VERIFY(!converter.linkFilesToData({ {Stage::Vertex, Utility::Path::join(SHADERTOOLS_TEST_DIR, "another.dat")} })); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2099,6 +2197,33 @@ void AbstractConverterTest::linkFilesToDataAsDataNotFound() { TestSuite::Compare::StringHasSuffix); } +void AbstractConverterTest::linkFilesToDataAsDataFailed() { + struct: AbstractConverter { + ConverterFeatures doFeatures() const override { + return ConverterFeature::LinkData; + } + void doSetInputFormat(Format, Containers::StringView) override {} + void doSetOutputFormat(Format, Containers::StringView) override {} + + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + /* {{}} makes GCC 4.8 warn about zero as null pointer constant */ + CORRADE_VERIFY(!converter.linkFilesToData({ + {Stage::Fragment, Utility::Path::join(SHADERTOOLS_TEST_DIR, "file.dat")} + })); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractConverterTest::linkFilesToDataNotSupported() { CORRADE_SKIP_IF_NO_ASSERT(); diff --git a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp index 211f5b243..a1c790356 100644 --- a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp @@ -53,46 +53,57 @@ struct AbstractFontConverterTest: TestSuite::Tester { void thingNotSupported(); void exportFontToSingleData(); + void exportFontToSingleDataFailed(); void exportFontToSingleDataNotImplemented(); void exportFontToSingleDataCustomDeleter(); void exportFontToSingleDataNotSingleFile(); void exportFontToData(); + void exportFontToDataFailed(); void exportFontToDataNotImplemented(); void exportFontToDataCustomDeleter(); void exportFontToDataThroughSingleData(); void exportFontToDataThroughSingleDataFailed(); void exportFontToFile(); + void exportFontToFileFailed(); void exportFontToFileNotImplemented(); void exportFontToFileThroughData(); void exportFontToFileThroughDataFailed(); void exportFontToFileThroughDataNotWritable(); void exportGlyphCacheToSingleData(); + void exportGlyphCacheToSingleDataFailed(); void exportGlyphCacheToSingleDataNotImplemented(); void exportGlyphCacheToSingleDataCustomDeleter(); void exportGlyphCacheToSingleDataNotSingleFile(); void exportGlyphCacheToData(); + void exportGlyphCacheToDataFailed(); void exportGlyphCacheToDataNotImplemented(); void exportGlyphCacheToDataCustomDeleter(); void exportGlyphCacheToDataThroughSingleData(); void exportGlyphCacheToDataThroughSingleDataFailed(); void exportGlyphCacheToFile(); + void exportGlyphCacheToFileFailed(); void exportGlyphCacheToFileNotImplemented(); void exportGlyphCacheToFileThroughData(); void exportGlyphCacheToFileThroughDataFailed(); void exportGlyphCacheToFileThroughDataNotWritable(); void importGlyphCacheFromSingleData(); + void importGlyphCacheFromSingleDataFailed(); void importGlyphCacheFromSingleDataNotImplemented(); void importGlyphCacheFromSingleDataNotSingleFile(); void importGlyphCacheFromData(); + void importGlyphCacheFromDataFailed(); void importGlyphCacheFromDataNoData(); void importGlyphCacheFromDataNotImplemented(); void importGlyphCacheFromDataAsSingleData(); + void importGlyphCacheFromDataAsSingleDataFailed(); void importGlyphCacheFromFile(); + void importGlyphCacheFromFileFailed(); void importGlyphCacheFromFileNotImplemented(); void importGlyphCacheFromFileAsSingleData(); void importGlyphCacheFromFileAsSingleDataNotFound(); + void importGlyphCacheFromFileAsSingleDataFailed(); void debugFeature(); void debugFeaturePacked(); @@ -106,46 +117,57 @@ AbstractFontConverterTest::AbstractFontConverterTest() { &AbstractFontConverterTest::thingNotSupported, &AbstractFontConverterTest::exportFontToSingleData, + &AbstractFontConverterTest::exportFontToSingleDataFailed, &AbstractFontConverterTest::exportFontToSingleDataNotImplemented, &AbstractFontConverterTest::exportFontToSingleDataCustomDeleter, &AbstractFontConverterTest::exportFontToSingleDataNotSingleFile, &AbstractFontConverterTest::exportFontToData, + &AbstractFontConverterTest::exportFontToDataFailed, &AbstractFontConverterTest::exportFontToDataNotImplemented, &AbstractFontConverterTest::exportFontToDataCustomDeleter, &AbstractFontConverterTest::exportFontToDataThroughSingleData, &AbstractFontConverterTest::exportFontToDataThroughSingleDataFailed, &AbstractFontConverterTest::exportFontToFile, + &AbstractFontConverterTest::exportFontToFileFailed, &AbstractFontConverterTest::exportFontToFileNotImplemented, &AbstractFontConverterTest::exportFontToFileThroughData, &AbstractFontConverterTest::exportFontToFileThroughDataFailed, &AbstractFontConverterTest::exportFontToFileThroughDataNotWritable, &AbstractFontConverterTest::exportGlyphCacheToSingleData, + &AbstractFontConverterTest::exportGlyphCacheToSingleDataFailed, &AbstractFontConverterTest::exportGlyphCacheToSingleDataNotImplemented, &AbstractFontConverterTest::exportGlyphCacheToSingleDataCustomDeleter, &AbstractFontConverterTest::exportGlyphCacheToSingleDataNotSingleFile, &AbstractFontConverterTest::exportGlyphCacheToData, + &AbstractFontConverterTest::exportGlyphCacheToDataFailed, &AbstractFontConverterTest::exportGlyphCacheToDataNotImplemented, &AbstractFontConverterTest::exportGlyphCacheToDataCustomDeleter, &AbstractFontConverterTest::exportGlyphCacheToDataThroughSingleData, &AbstractFontConverterTest::exportGlyphCacheToDataThroughSingleDataFailed, &AbstractFontConverterTest::exportGlyphCacheToFile, + &AbstractFontConverterTest::exportGlyphCacheToFileFailed, &AbstractFontConverterTest::exportGlyphCacheToFileNotImplemented, &AbstractFontConverterTest::exportGlyphCacheToFileThroughData, &AbstractFontConverterTest::exportGlyphCacheToFileThroughDataFailed, &AbstractFontConverterTest::exportGlyphCacheToFileThroughDataNotWritable, &AbstractFontConverterTest::importGlyphCacheFromSingleData, + &AbstractFontConverterTest::importGlyphCacheFromSingleDataFailed, &AbstractFontConverterTest::importGlyphCacheFromSingleDataNotImplemented, &AbstractFontConverterTest::importGlyphCacheFromSingleDataNotSingleFile, &AbstractFontConverterTest::importGlyphCacheFromData, + &AbstractFontConverterTest::importGlyphCacheFromDataFailed, &AbstractFontConverterTest::importGlyphCacheFromDataNoData, &AbstractFontConverterTest::importGlyphCacheFromDataNotImplemented, &AbstractFontConverterTest::importGlyphCacheFromDataAsSingleData, + &AbstractFontConverterTest::importGlyphCacheFromDataAsSingleDataFailed, &AbstractFontConverterTest::importGlyphCacheFromFile, + &AbstractFontConverterTest::importGlyphCacheFromFileFailed, &AbstractFontConverterTest::importGlyphCacheFromFileNotImplemented, &AbstractFontConverterTest::importGlyphCacheFromFileAsSingleData, &AbstractFontConverterTest::importGlyphCacheFromFileAsSingleDataNotFound, + &AbstractFontConverterTest::importGlyphCacheFromFileAsSingleDataFailed, &AbstractFontConverterTest::debugFeature, &AbstractFontConverterTest::debugFeaturePacked, @@ -243,6 +265,30 @@ void AbstractFontConverterTest::exportFontToSingleData() { TestSuite::Compare::Container); } +void AbstractFontConverterTest::exportFontToSingleDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData|FontConverterFeature::ExportFont; + } + + Containers::Array doExportFontToSingleData(AbstractFont&, AbstractGlyphCache&, const std::u32string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.exportFontToSingleData(dummyFont, dummyGlyphCache, "euhh")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportFontToSingleDataNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -319,6 +365,30 @@ void AbstractFontConverterTest::exportFontToData() { TestSuite::Compare::Container); } +void AbstractFontConverterTest::exportFontToDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData|FontConverterFeature::ExportFont; + } + + std::vector>> doExportFontToData(AbstractFont&, AbstractGlyphCache&, const std::string&, const std::u32string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(converter.exportFontToData(dummyFont, dummyGlyphCache, "", "").empty()); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportFontToDataNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -384,12 +454,21 @@ void AbstractFontConverterTest::exportFontToDataThroughSingleDataFailed() { } Containers::Array doExportFontToSingleData(AbstractFont&, AbstractGlyphCache&, const std::u32string&) const override { + called = true; return {}; } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; } converter; - auto ret = converter.exportFontToData(dummyFont, dummyGlyphCache, "font.out", "ehh"); - CORRADE_VERIFY(ret.empty()); + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(converter.exportFontToData(dummyFont, dummyGlyphCache, "", "").empty()); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); } void AbstractFontConverterTest::exportFontToFile() { @@ -423,6 +502,30 @@ void AbstractFontConverterTest::exportFontToFile() { "\xfe\x02", TestSuite::Compare::FileToString); } +void AbstractFontConverterTest::exportFontToFileFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData|FontConverterFeature::ExportFont|FontConverterFeature::MultiFile; + } + + bool doExportFontToFile(AbstractFont&, AbstractGlyphCache&, const std::string&, const std::u32string&) const override { + called = true; + return false; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.exportFontToFile(dummyFont, dummyGlyphCache, "", "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportFontToFileNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -475,7 +578,14 @@ void AbstractFontConverterTest::exportFontToFileThroughDataFailed() { return FontConverterFeature::ConvertData|FontConverterFeature::ExportFont|FontConverterFeature::MultiFile; } - std::vector>> doExportFontToData(AbstractFont&, AbstractGlyphCache&, const std::string&, const std::u32string&) const override { return {}; } + std::vector>> doExportFontToData(AbstractFont&, AbstractGlyphCache&, const std::string&, const std::u32string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; } converter; Containers::String filename = Utility::Path::join(TEXT_TEST_OUTPUT_DIR, "font.out"); @@ -485,11 +595,13 @@ void AbstractFontConverterTest::exportFontToFileThroughDataFailed() { CORRADE_VERIFY(Utility::Path::remove(filename)); /* Function should fail, no file should get written and no error output - should be printed (the base implementation assumes the plugin does it) */ + should be printed (the base implementation assumes the plugin does + it) */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.exportFontToFile(dummyFont, dummyGlyphCache, filename, {})); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -529,6 +641,31 @@ void AbstractFontConverterTest::exportGlyphCacheToSingleData() { TestSuite::Compare::Container); } +void AbstractFontConverterTest::exportGlyphCacheToSingleDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ExportGlyphCache; + } + + Containers::Array doExportGlyphCacheToSingleData(AbstractGlyphCache&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.exportGlyphCacheToSingleData(dummyGlyphCache)); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportGlyphCacheToSingleDataNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -604,6 +741,31 @@ void AbstractFontConverterTest::exportGlyphCacheToData() { TestSuite::Compare::Container); } +void AbstractFontConverterTest::exportGlyphCacheToDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ExportGlyphCache; + } + + Containers::Array doExportGlyphCacheToSingleData(AbstractGlyphCache&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(converter.exportGlyphCacheToData(dummyGlyphCache, "").empty()); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportGlyphCacheToDataNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -670,12 +832,21 @@ void AbstractFontConverterTest::exportGlyphCacheToDataThroughSingleDataFailed() } Containers::Array doExportGlyphCacheToSingleData(AbstractGlyphCache&) const override { + called = true; return {}; } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; } converter; - auto ret = converter.exportGlyphCacheToData(dummyGlyphCache, "font.out"); - CORRADE_VERIFY(ret.empty()); + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(converter.exportGlyphCacheToData(dummyGlyphCache, "").empty()); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); } void AbstractFontConverterTest::exportGlyphCacheToFile() { @@ -709,6 +880,32 @@ void AbstractFontConverterTest::exportGlyphCacheToFile() { "\xfe\xed", TestSuite::Compare::FileToString); } +void AbstractFontConverterTest::exportGlyphCacheToFileFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ExportGlyphCache| + FontConverterFeature::MultiFile; + } + + bool doExportGlyphCacheToFile(AbstractGlyphCache&, const std::string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.exportGlyphCacheToFile(dummyGlyphCache, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::exportGlyphCacheToFileNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -759,7 +956,14 @@ void AbstractFontConverterTest::exportGlyphCacheToFileThroughDataFailed() { struct: AbstractFontConverter { FontConverterFeatures doFeatures() const override { return FontConverterFeature::ConvertData|FontConverterFeature::ExportGlyphCache|FontConverterFeature::MultiFile; } - std::vector>> doExportGlyphCacheToData(AbstractGlyphCache&, const std::string&) const override { return {}; } + std::vector>> doExportGlyphCacheToData(AbstractGlyphCache&, const std::string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; } converter; /* Remove previous file, if any */ @@ -773,6 +977,7 @@ void AbstractFontConverterTest::exportGlyphCacheToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.exportGlyphCacheToFile(dummyGlyphCache, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -814,6 +1019,31 @@ void AbstractFontConverterTest::importGlyphCacheFromSingleData() { CORRADE_COMPARE(cache->size(), (Vector3i{123, 345, 1})); } +void AbstractFontConverterTest::importGlyphCacheFromSingleDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ImportGlyphCache; + } + + Containers::Pointer doImportGlyphCacheFromSingleData(Containers::ArrayView) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.importGlyphCacheFromSingleData(nullptr)); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::importGlyphCacheFromSingleDataNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -863,6 +1093,31 @@ void AbstractFontConverterTest::importGlyphCacheFromData() { CORRADE_COMPARE(cache->size(), (Vector3i{123, 345, 1})); } +void AbstractFontConverterTest::importGlyphCacheFromDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ImportGlyphCache; + } + + Containers::Pointer doImportGlyphCacheFromData(const std::vector>>&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.importGlyphCacheFromData({{}, {{}, nullptr}})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::importGlyphCacheFromDataNoData() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -914,6 +1169,31 @@ void AbstractFontConverterTest::importGlyphCacheFromDataAsSingleData() { CORRADE_COMPARE(cache->size(), (Vector3i{123, 345, 1})); } +void AbstractFontConverterTest::importGlyphCacheFromDataAsSingleDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ImportGlyphCache; + } + + Containers::Pointer doImportGlyphCacheFromSingleData(const Containers::ArrayView) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.importGlyphCacheFromData({{{}, nullptr}})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::importGlyphCacheFromFile() { struct: AbstractFontConverter { FontConverterFeatures doFeatures() const override { @@ -935,6 +1215,30 @@ void AbstractFontConverterTest::importGlyphCacheFromFile() { CORRADE_COMPARE(cache->size(), (Vector3i{123, 345, 1})); } +void AbstractFontConverterTest::importGlyphCacheFromFileFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ImportGlyphCache; + } + + Containers::Pointer doImportGlyphCacheFromFile(const std::string&) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.importGlyphCacheFromFile(Utility::Path::join(TEXT_TEST_DIR, "data.bin"))); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::importGlyphCacheFromFileNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -990,6 +1294,31 @@ void AbstractFontConverterTest::importGlyphCacheFromFileAsSingleDataNotFound() { TestSuite::Compare::StringHasSuffix); } +void AbstractFontConverterTest::importGlyphCacheFromFileAsSingleDataFailed() { + struct: AbstractFontConverter { + FontConverterFeatures doFeatures() const override { + return FontConverterFeature::ConvertData| + FontConverterFeature::ImportGlyphCache; + } + + Containers::Pointer doImportGlyphCacheFromSingleData(const Containers::ArrayView) const override { + called = true; + return {}; + } + + /** @todo drop the mutable once the APIs are reworked and no longer + const (ugh) */ + mutable bool called = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.importGlyphCacheFromFile(Utility::Path::join(TEXT_TEST_DIR, "data.bin"))); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontConverterTest::debugFeature() { Containers::String out; diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index d0c3db92d..35f6721a1 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -58,9 +58,12 @@ struct AbstractFontTest: TestSuite::Tester { void construct(); void openData(); + void openDataFailed(); void openFile(); + void openFileFailed(); void openFileAsData(); void openFileAsDataNotFound(); + void openFileAsDataFailed(); void openFileNotImplemented(); void openDataNotSupported(); @@ -74,9 +77,12 @@ struct AbstractFontTest: TestSuite::Tester { void setFileCallbackNotImplemented(); void setFileCallbackNotSupported(); void setFileCallbackOpenFileDirectly(); + void setFileCallbackOpenFileDirectlyFailed(); void setFileCallbackOpenFileThroughBaseImplementation(); + void setFileCallbackOpenFileThroughBaseImplementationNotFound(); void setFileCallbackOpenFileThroughBaseImplementationFailed(); void setFileCallbackOpenFileAsData(); + void setFileCallbackOpenFileAsDataNotFound(); void setFileCallbackOpenFileAsDataFailed(); void properties(); @@ -133,9 +139,12 @@ AbstractFontTest::AbstractFontTest() { addTests({&AbstractFontTest::construct, &AbstractFontTest::openData, + &AbstractFontTest::openDataFailed, &AbstractFontTest::openFile, + &AbstractFontTest::openFileFailed, &AbstractFontTest::openFileAsData, &AbstractFontTest::openFileAsDataNotFound, + &AbstractFontTest::openFileAsDataFailed, &AbstractFontTest::openFileNotImplemented, &AbstractFontTest::openDataNotSupported, @@ -149,9 +158,12 @@ AbstractFontTest::AbstractFontTest() { &AbstractFontTest::setFileCallbackNotImplemented, &AbstractFontTest::setFileCallbackNotSupported, &AbstractFontTest::setFileCallbackOpenFileDirectly, + &AbstractFontTest::setFileCallbackOpenFileDirectlyFailed, &AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation, + &AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationNotFound, &AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed, &AbstractFontTest::setFileCallbackOpenFileAsData, + &AbstractFontTest::setFileCallbackOpenFileAsDataNotFound, &AbstractFontTest::setFileCallbackOpenFileAsDataFailed, &AbstractFontTest::properties, @@ -229,7 +241,10 @@ void AbstractFontTest::openData() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override {} + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } Properties doOpenData(Containers::ArrayView data, Float size) override { CORRADE_COMPARE_AS(data, @@ -257,13 +272,47 @@ void AbstractFontTest::openData() { CORRADE_COMPARE(font.descent(), 2.0f); CORRADE_COMPARE(font.lineHeight(), 3.0f); CORRADE_COMPARE(font.glyphCount(), 15); + + font.close(); + CORRADE_VERIFY(!font.isOpened()); +} + +void AbstractFontTest::openDataFailed() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenData(Containers::ArrayView, Float) override { + called = true; + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openData(nullptr, 1.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_COMPARE(out, ""); } void AbstractFontTest::openFile() { struct: AbstractFont { FontFeatures doFeatures() const override { return {}; } bool doIsOpened() const override { return _opened; } - void doClose() override {} + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } Properties doOpenFile(Containers::StringView filename, Float size) override { CORRADE_COMPARE(filename, "hello.ttf"); @@ -288,13 +337,47 @@ void AbstractFontTest::openFile() { CORRADE_COMPARE(font.descent(), 2.0f); CORRADE_COMPARE(font.lineHeight(), 3.0f); CORRADE_COMPARE(font.glyphCount(), 15); + + font.close(); + CORRADE_VERIFY(!font.isOpened()); +} + +void AbstractFontTest::openFileFailed() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenFile(Containers::StringView, Float) override { + called = true; + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openFile("hello.ttf", 1.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_COMPARE(out, ""); } void AbstractFontTest::openFileAsData() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override {} + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } Properties doOpenData(Containers::ArrayView data, Float size) override { CORRADE_COMPARE_AS(data, @@ -322,6 +405,9 @@ void AbstractFontTest::openFileAsData() { CORRADE_COMPARE(font.descent(), 2.0f); CORRADE_COMPARE(font.lineHeight(), 3.0f); CORRADE_COMPARE(font.glyphCount(), 15); + + font.close(); + CORRADE_VERIFY(!font.isOpened()); } void AbstractFontTest::openFileAsDataNotFound() { @@ -330,6 +416,11 @@ void AbstractFontTest::openFileAsDataNotFound() { bool doIsOpened() const override { return false; } void doClose() override {} + Properties doOpenData(Containers::ArrayView, Float) override { + CORRADE_FAIL("This should not be called"); + return {}; + } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } @@ -339,12 +430,41 @@ void AbstractFontTest::openFileAsDataNotFound() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!font.openFile("nonexistent.foo", 12.0f)); + CORRADE_VERIFY(!font.isOpened()); /* There's an error message from Path::read() before */ CORRADE_COMPARE_AS(out, "\nText::AbstractFont::openFile(): cannot open file nonexistent.foo\n", TestSuite::Compare::StringHasSuffix); } +void AbstractFontTest::openFileAsDataFailed() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenData(Containers::ArrayView, Float) override { + called = true; + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openData(nullptr, 1.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontTest::openFileNotImplemented() { CORRADE_SKIP_IF_NO_ASSERT(); @@ -624,6 +744,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() { }, &dummy); CORRADE_VERIFY(font.openFile("file.dat", 42.0f)); + CORRADE_VERIFY(font.isOpened()); CORRADE_COMPARE(font.size(), 42.0f); CORRADE_COMPARE(font.ascent(), 1.0f); CORRADE_COMPARE(font.descent(), 2.0f); @@ -631,6 +752,44 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() { CORRADE_COMPARE(font.glyphCount(), 15); } +void AbstractFontTest::setFileCallbackOpenFileDirectlyFailed() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::FileCallback|FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenFile(Containers::StringView, Float) override { + called = true; + return {}; + } + + Properties doOpenData(Containers::ArrayView, Float) override { + CORRADE_FAIL("This should not be called"); + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + font.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { + CORRADE_FAIL("This shouldn't be called"); + return {}; + }); + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openFile("file.dat", 42.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_COMPARE(out, ""); +} + void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::FileCallback|FontFeature::OpenData; } @@ -641,7 +800,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { CORRADE_COMPARE(filename, "file.dat"); CORRADE_VERIFY(fileCallback()); CORRADE_VERIFY(fileCallbackUserData()); - openFileCalled = true; + called = true; return AbstractFont::doOpenFile(filename, size); } @@ -658,7 +817,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } - bool openFileCalled = false; + bool called = false; private: bool _opened = false; @@ -687,7 +846,8 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { }, state); CORRADE_VERIFY(font.openFile("file.dat", 42.0f)); - CORRADE_VERIFY(font.openFileCalled); + CORRADE_VERIFY(font.isOpened()); + CORRADE_VERIFY(font.called); CORRADE_VERIFY(state.loaded); CORRADE_VERIFY(state.closed); CORRADE_COMPARE(font.size(), 42.0f); @@ -697,6 +857,48 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { CORRADE_COMPARE(font.glyphCount(), 15); } +void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationNotFound() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::FileCallback|FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenFile(Containers::StringView filename, Float size) override { + called = true; + return AbstractFont::doOpenFile(filename, size); + } + + Properties doOpenData(Containers::ArrayView, Float) override { + CORRADE_FAIL("This should not be called"); + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + bool fileCallbackCalled = false; + font.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, bool& fileCallbackCalled) -> Containers::Optional> { + /* The callback should be only called to open the file, not to close it + afterwards */ + CORRADE_COMPARE(policy, InputFileCallbackPolicy::LoadTemporary); + fileCallbackCalled = true; + return {}; + }, fileCallbackCalled); + + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openFile("file.dat", 42.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_VERIFY(fileCallbackCalled); + CORRADE_COMPARE(out, "Text::AbstractFont::openFile(): cannot open file file.dat\n"); +} + void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::FileCallback|FontFeature::OpenData; } @@ -708,24 +910,49 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed() return AbstractFont::doOpenFile(filename, size); } + Properties doOpenData(Containers::ArrayView, Float) override { + openDataCalled = true; + return {}; + } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } - bool openFileCalled = false; + bool openFileCalled = false; + bool openDataCalled = false; } font; - font.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { + struct State { + bool loaded = false; + bool closed = false; + } state; + font.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(policy == InputFileCallbackPolicy::LoadTemporary) { + state.loaded = true; + return Containers::ArrayView{}; + } + + if(policy == InputFileCallbackPolicy::Close) { + state.closed = true; + return {}; + } + + CORRADE_FAIL("Unexpected policy" << policy); return {}; - }); + }, state); + /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!font.openFile("file.dat", 42.0f)); + CORRADE_VERIFY(!font.isOpened()); CORRADE_VERIFY(font.openFileCalled); - CORRADE_COMPARE(out, "Text::AbstractFont::openFile(): cannot open file file.dat\n"); + CORRADE_VERIFY(font.openDataCalled); + CORRADE_VERIFY(state.loaded); + CORRADE_VERIFY(state.closed); + CORRADE_COMPARE(out, ""); } void AbstractFontTest::setFileCallbackOpenFileAsData() { @@ -735,7 +962,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { void doClose() override { _opened = false; } Properties doOpenFile(Containers::StringView, Float) override { - openFileCalled = true; + CORRADE_FAIL("This should not be called"); return {}; } @@ -752,8 +979,8 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } - bool _opened = false; - bool openFileCalled = false; + private: + bool _opened = false; } font; struct State { @@ -761,7 +988,6 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { bool loaded = false; bool closed = false; } state; - font.setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { CORRADE_COMPARE(Containers::StringView{filename}, "file.dat"); @@ -780,7 +1006,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { }, state); CORRADE_VERIFY(font.openFile("file.dat", 13.0f)); - CORRADE_VERIFY(!font.openFileCalled); + CORRADE_VERIFY(font.isOpened()); CORRADE_VERIFY(state.loaded); CORRADE_VERIFY(state.closed); CORRADE_COMPARE(font.size(), 13.0f); @@ -790,7 +1016,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { CORRADE_COMPARE(font.glyphCount(), 15); } -void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { +void AbstractFontTest::setFileCallbackOpenFileAsDataNotFound() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::OpenData; } bool doIsOpened() const override { return false; } @@ -801,22 +1027,88 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { return {}; } + Properties doOpenData(Containers::ArrayView, Float) override { + CORRADE_FAIL("This should not be called"); + return {}; + } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } } font; - font.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) { - return Containers::Optional>{}; - }); + bool fileCallbackCalled = false; + font.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, bool& fileCallbackCalled) -> Containers::Optional> { + /* The callback should be only called to open the file, not to close it + afterwards */ + CORRADE_COMPARE(policy, InputFileCallbackPolicy::LoadTemporary); + fileCallbackCalled = true; + return {}; + }, fileCallbackCalled); Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!font.openFile("file.dat", 132.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(fileCallbackCalled); CORRADE_COMPARE(out, "Text::AbstractFont::openFile(): cannot open file file.dat\n"); } +void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { + struct: AbstractFont { + FontFeatures doFeatures() const override { return FontFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + Properties doOpenFile(Containers::StringView, Float) override { + CORRADE_FAIL("This should not be called"); + return {}; + } + + Properties doOpenData(Containers::ArrayView, Float) override { + called = true; + return {}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + bool called = false; + } font; + + struct State { + bool loaded = false; + bool closed = false; + } state; + font.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(policy == InputFileCallbackPolicy::LoadTemporary) { + state.loaded = true; + return Containers::ArrayView{}; + } + + if(policy == InputFileCallbackPolicy::Close) { + state.closed = true; + return {}; + } + + CORRADE_FAIL("Unexpected policy" << policy); + return {}; + }, state); + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!font.openFile("file.dat", 132.0f)); + CORRADE_VERIFY(!font.isOpened()); + CORRADE_VERIFY(font.called); + CORRADE_VERIFY(state.loaded); + CORRADE_VERIFY(state.closed); + CORRADE_COMPARE(out, ""); +} + void AbstractFontTest::properties() { struct: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::OpenData; } @@ -837,6 +1129,7 @@ void AbstractFontTest::properties() { } font; CORRADE_VERIFY(font.openData(nullptr, 13.0f)); + CORRADE_VERIFY(font.isOpened()); CORRADE_COMPARE(font.size(), 13.0f); CORRADE_COMPARE(font.ascent(), 1.0f); CORRADE_COMPARE(font.descent(), 2.0f); diff --git a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp index c45699455..bdd4e755b 100644 --- a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp @@ -87,6 +87,9 @@ struct AbstractImageConverterTest: TestSuite::Tester { void convertImageData1D(); void convertImageData2D(); void convertImageData3D(); + void convertImageData1DFailed(); + void convertImageData2DFailed(); + void convertImageData3DFailed(); void convert1DToData(); void convert2DToData(); @@ -128,6 +131,9 @@ struct AbstractImageConverterTest: TestSuite::Tester { void convertImageData1DToData(); void convertImageData2DToData(); void convertImageData3DToData(); + void convertImageData1DToDataFailed(); + void convertImageData2DToDataFailed(); + void convertImageData3DToDataFailed(); void convertLevels1DToData(); void convertLevels2DToData(); @@ -180,10 +186,16 @@ struct AbstractImageConverterTest: TestSuite::Tester { void convert1DToDataThroughLevels(); void convert2DToDataThroughLevels(); void convert3DToDataThroughLevels(); + void convert1DToDataThroughLevelsFailed(); + void convert2DToDataThroughLevelsFailed(); + void convert3DToDataThroughLevelsFailed(); void convertCompressed1DToDataThroughLevels(); void convertCompressed2DToDataThroughLevels(); void convertCompressed3DToDataThroughLevels(); + void convertCompressed1DToDataThroughLevelsFailed(); + void convertCompressed2DToDataThroughLevelsFailed(); + void convertCompressed3DToDataThroughLevelsFailed(); void convert1DToFile(); void convert2DToFile(); @@ -236,6 +248,11 @@ struct AbstractImageConverterTest: TestSuite::Tester { void convertImageData1DToFile(); void convertImageData2DToFile(); void convertImageData3DToFile(); + void convertImageData1DToFileFailed(); + void convertImageData2DToFileFailed(); + void convertImageData3DToFileFailed(); + /* Conversion of ImageData to a file through data not tested, as that + should just work transitively */ void convertLevels1DToFile(); void convertLevels2DToFile(); @@ -288,10 +305,20 @@ struct AbstractImageConverterTest: TestSuite::Tester { void convert1DToFileThroughLevels(); void convert2DToFileThroughLevels(); void convert3DToFileThroughLevels(); + void convert1DToFileThroughLevelsFailed(); + void convert2DToFileThroughLevelsFailed(); + void convert3DToFileThroughLevelsFailed(); + /* Conversion of an image to a file through levels and through data not + tested, as that should just work transitively */ void convertCompressed1DToFileThroughLevels(); void convertCompressed2DToFileThroughLevels(); void convertCompressed3DToFileThroughLevels(); + void convertCompressed1DToFileThroughLevelsFailed(); + void convertCompressed2DToFileThroughLevelsFailed(); + void convertCompressed3DToFileThroughLevelsFailed(); + /* Conversion of a compressed image to a file through levels and through + data not tested, as that should just work transitively */ void debugFeature(); void debugFeaturePacked(); @@ -348,6 +375,9 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::convertImageData1D, &AbstractImageConverterTest::convertImageData2D, &AbstractImageConverterTest::convertImageData3D, + &AbstractImageConverterTest::convertImageData1DFailed, + &AbstractImageConverterTest::convertImageData2DFailed, + &AbstractImageConverterTest::convertImageData3DFailed, &AbstractImageConverterTest::convert1DToData, &AbstractImageConverterTest::convert2DToData, @@ -385,6 +415,9 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::convertImageData1DToData, &AbstractImageConverterTest::convertImageData2DToData, &AbstractImageConverterTest::convertImageData3DToData, + &AbstractImageConverterTest::convertImageData1DToDataFailed, + &AbstractImageConverterTest::convertImageData2DToDataFailed, + &AbstractImageConverterTest::convertImageData3DToDataFailed, &AbstractImageConverterTest::convertLevels1DToData, &AbstractImageConverterTest::convertLevels2DToData, @@ -430,10 +463,16 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::convert1DToDataThroughLevels, &AbstractImageConverterTest::convert2DToDataThroughLevels, &AbstractImageConverterTest::convert3DToDataThroughLevels, + &AbstractImageConverterTest::convert1DToDataThroughLevelsFailed, + &AbstractImageConverterTest::convert2DToDataThroughLevelsFailed, + &AbstractImageConverterTest::convert3DToDataThroughLevelsFailed, &AbstractImageConverterTest::convertCompressed1DToDataThroughLevels, &AbstractImageConverterTest::convertCompressed2DToDataThroughLevels, &AbstractImageConverterTest::convertCompressed3DToDataThroughLevels, + &AbstractImageConverterTest::convertCompressed1DToDataThroughLevelsFailed, + &AbstractImageConverterTest::convertCompressed2DToDataThroughLevelsFailed, + &AbstractImageConverterTest::convertCompressed3DToDataThroughLevelsFailed, &AbstractImageConverterTest::convert1DToFile, &AbstractImageConverterTest::convert2DToFile, @@ -482,6 +521,9 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::convertImageData1DToFile, &AbstractImageConverterTest::convertImageData2DToFile, &AbstractImageConverterTest::convertImageData3DToFile, + &AbstractImageConverterTest::convertImageData1DToFileFailed, + &AbstractImageConverterTest::convertImageData2DToFileFailed, + &AbstractImageConverterTest::convertImageData3DToFileFailed, &AbstractImageConverterTest::convertLevels1DToFile, &AbstractImageConverterTest::convertLevels2DToFile, @@ -530,10 +572,16 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::convert1DToFileThroughLevels, &AbstractImageConverterTest::convert2DToFileThroughLevels, &AbstractImageConverterTest::convert3DToFileThroughLevels, + &AbstractImageConverterTest::convert1DToFileThroughLevelsFailed, + &AbstractImageConverterTest::convert2DToFileThroughLevelsFailed, + &AbstractImageConverterTest::convert3DToFileThroughLevelsFailed, &AbstractImageConverterTest::convertCompressed1DToFileThroughLevels, &AbstractImageConverterTest::convertCompressed2DToFileThroughLevels, &AbstractImageConverterTest::convertCompressed3DToFileThroughLevels, + &AbstractImageConverterTest::convertCompressed1DToFileThroughLevelsFailed, + &AbstractImageConverterTest::convertCompressed2DToFileThroughLevelsFailed, + &AbstractImageConverterTest::convertCompressed3DToFileThroughLevelsFailed, &AbstractImageConverterTest::debugFeature, &AbstractImageConverterTest::debugFeaturePacked, @@ -783,14 +831,18 @@ void AbstractImageConverterTest::convert1DFailed() { return ImageConverterFeature::Convert1D; } Containers::Optional doConvert(const ImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(ImageView1D{PixelFormat::RGBA8Unorm, 1, {nullptr, 4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -800,14 +852,18 @@ void AbstractImageConverterTest::convert2DFailed() { return ImageConverterFeature::Convert2D; } Containers::Optional doConvert(const ImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, {nullptr, 4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -817,14 +873,18 @@ void AbstractImageConverterTest::convert3DFailed() { return ImageConverterFeature::Convert3D; } Containers::Optional doConvert(const ImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, {nullptr, 4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -966,14 +1026,18 @@ void AbstractImageConverterTest::convertCompressed1DFailed() { return ImageConverterFeature::ConvertCompressed1D; } Containers::Optional doConvert(const CompressedImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, {nullptr, 4*4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -983,14 +1047,18 @@ void AbstractImageConverterTest::convertCompressed2DFailed() { return ImageConverterFeature::ConvertCompressed2D; } Containers::Optional doConvert(const CompressedImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, {nullptr, 4*4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1000,14 +1068,18 @@ void AbstractImageConverterTest::convertCompressed3DFailed() { return ImageConverterFeature::ConvertCompressed3D; } Containers::Optional doConvert(const CompressedImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, {nullptr, 4*4}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1194,6 +1266,90 @@ void AbstractImageConverterTest::convertImageData3D() { } } +void AbstractImageConverterTest::convertImageData1DFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert1D|ImageConverterFeature::ConvertCompressed1D; + } + Containers::Optional doConvert(const ImageView1D&) override { + called = true; + return {}; + } + Containers::Optional doConvert(const CompressedImageView1D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convert(ImageView1D{PixelFormat::RGBA8Unorm, {}, nullptr})); + CORRADE_VERIFY(!converter.convert(CompressedImageView1D{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData2DFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert2D|ImageConverterFeature::ConvertCompressed2D; + } + Containers::Optional doConvert(const ImageView2D&) override { + called = true; + return {}; + } + Containers::Optional doConvert(const CompressedImageView2D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convert(ImageView2D{PixelFormat::RGBA8Unorm, {}, nullptr})); + CORRADE_VERIFY(!converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData3DFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert3D|ImageConverterFeature::ConvertCompressed3D; + } + Containers::Optional doConvert(const ImageView3D&) override { + called = true; + return {}; + } + Containers::Optional doConvert(const CompressedImageView3D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convert(ImageView3D{PixelFormat::RGBA8Unorm, {}, nullptr})); + CORRADE_VERIFY(!converter.convert(CompressedImageView3D{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convert1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } @@ -1242,8 +1398,11 @@ void AbstractImageConverterTest::convert1DToDataFailed() { return ImageConverterFeature::Convert1DToData; } Containers::Optional> doConvertToData(const ImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1252,6 +1411,7 @@ void AbstractImageConverterTest::convert1DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1261,8 +1421,11 @@ void AbstractImageConverterTest::convert2DToDataFailed() { return ImageConverterFeature::Convert2DToData; } Containers::Optional> doConvertToData(const ImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1271,6 +1434,7 @@ void AbstractImageConverterTest::convert2DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1280,8 +1444,11 @@ void AbstractImageConverterTest::convert3DToDataFailed() { return ImageConverterFeature::Convert3DToData; } Containers::Optional> doConvertToData(const ImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1290,6 +1457,7 @@ void AbstractImageConverterTest::convert3DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1487,8 +1655,11 @@ void AbstractImageConverterTest::convertCompressed1DToDataFailed() { return ImageConverterFeature::ConvertCompressed1DToData; } Containers::Optional> doConvertToData(const CompressedImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -1497,6 +1668,7 @@ void AbstractImageConverterTest::convertCompressed1DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1506,8 +1678,11 @@ void AbstractImageConverterTest::convertCompressed2DToDataFailed() { return ImageConverterFeature::ConvertCompressed2DToData; } Containers::Optional> doConvertToData(const CompressedImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -1516,6 +1691,7 @@ void AbstractImageConverterTest::convertCompressed2DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1525,8 +1701,11 @@ void AbstractImageConverterTest::convertCompressed3DToDataFailed() { return ImageConverterFeature::ConvertCompressed3DToData; } Containers::Optional> doConvertToData(const CompressedImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -1535,6 +1714,7 @@ void AbstractImageConverterTest::convertCompressed3DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1774,6 +1954,96 @@ void AbstractImageConverterTest::convertImageData3DToData() { } } +void AbstractImageConverterTest::convertImageData1DToDataFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert1DToData|ImageConverterFeature::ConvertCompressed1DToData; + } + Containers::Optional> doConvertToData(const ImageView1D&) override { + called = true; + return {}; + } + Containers::Optional> doConvertToData(const CompressedImageView1D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData})); + CORRADE_VERIFY(!converter.convertToData(CompressedImageView1D{CompressedPixelFormat::Bc1RGBUnorm, 1, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData2DToDataFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert2DToData|ImageConverterFeature::ConvertCompressed2DToData; + } + Containers::Optional> doConvertToData(const ImageView2D&) override { + called = true; + return {}; + } + Containers::Optional> doConvertToData(const CompressedImageView2D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData})); + CORRADE_VERIFY(!converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBUnorm, {1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData3DToDataFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert3DToData|ImageConverterFeature::ConvertCompressed3DToData; + } + Containers::Optional> doConvertToData(const ImageView3D&) override { + called = true; + return {}; + } + Containers::Optional> doConvertToData(const CompressedImageView3D&) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(!converter.convertToData(CompressedImageView3D{CompressedPixelFormat::Bc1RGBUnorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convertLevels1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { @@ -1847,8 +2117,11 @@ void AbstractImageConverterTest::convertLevels1DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1857,6 +2130,7 @@ void AbstractImageConverterTest::convertLevels1DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1867,8 +2141,11 @@ void AbstractImageConverterTest::convertLevels2DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1877,6 +2154,7 @@ void AbstractImageConverterTest::convertLevels2DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1887,8 +2165,11 @@ void AbstractImageConverterTest::convertLevels3DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -1897,6 +2178,7 @@ void AbstractImageConverterTest::convertLevels3DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2235,8 +2517,11 @@ void AbstractImageConverterTest::convertCompressedLevels1DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -2245,6 +2530,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2255,8 +2541,11 @@ void AbstractImageConverterTest::convertCompressedLevels2DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -2265,6 +2554,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2275,8 +2565,11 @@ void AbstractImageConverterTest::convertCompressedLevels3DToDataFailed() { ImageConverterFeature::Levels; } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -2285,6 +2578,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData({CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2580,6 +2874,78 @@ void AbstractImageConverterTest::convert3DToDataThroughLevels() { CORRADE_COMPARE(actual->size(), 48); } +void AbstractImageConverterTest::convert1DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert1DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convert2DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert2DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convert3DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert3DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convertCompressed1DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { @@ -2631,6 +2997,78 @@ void AbstractImageConverterTest::convertCompressed3DToDataThroughLevels() { CORRADE_COMPARE(actual->size(), 256); } +void AbstractImageConverterTest::convertCompressed1DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed1DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertCompressed2DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed2DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertCompressed3DToDataThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed3DToData| + ImageConverterFeature::Levels; + } + Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convert1DToFile() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToFile; } @@ -2694,8 +3132,11 @@ void AbstractImageConverterTest::convert1DToFileFailed() { return ImageConverterFeature::Convert1DToFile; } bool doConvertToFile(const ImageView1D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -2703,7 +3144,8 @@ void AbstractImageConverterTest::convert1DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2713,8 +3155,11 @@ void AbstractImageConverterTest::convert2DToFileFailed() { return ImageConverterFeature::Convert2DToFile; } bool doConvertToFile(const ImageView2D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -2722,7 +3167,8 @@ void AbstractImageConverterTest::convert2DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2732,8 +3178,11 @@ void AbstractImageConverterTest::convert3DToFileFailed() { return ImageConverterFeature::Convert3DToFile; } bool doConvertToFile(const ImageView3D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -2741,7 +3190,8 @@ void AbstractImageConverterTest::convert3DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2810,8 +3260,11 @@ void AbstractImageConverterTest::convert1DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } Containers::Optional> doConvertToData(const ImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -2827,6 +3280,7 @@ void AbstractImageConverterTest::convert1DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(ImageView1D{PixelFormat::RGBA8Unorm, 1, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2835,8 +3289,11 @@ void AbstractImageConverterTest::convert2DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } Containers::Optional> doConvertToData(const ImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -2852,6 +3309,7 @@ void AbstractImageConverterTest::convert2DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2860,8 +3318,11 @@ void AbstractImageConverterTest::convert3DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } Containers::Optional> doConvertToData(const ImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -2877,6 +3338,7 @@ void AbstractImageConverterTest::convert3DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3078,8 +3540,11 @@ void AbstractImageConverterTest::convertCompressed1DToFileFailed() { return ImageConverterFeature::ConvertCompressed1DToFile; } bool doConvertToFile(const CompressedImageView1D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -3087,7 +3552,8 @@ void AbstractImageConverterTest::convertCompressed1DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3097,8 +3563,11 @@ void AbstractImageConverterTest::convertCompressed2DToFileFailed() { return ImageConverterFeature::ConvertCompressed2DToFile; } bool doConvertToFile(const CompressedImageView2D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -3106,7 +3575,8 @@ void AbstractImageConverterTest::convertCompressed2DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3116,8 +3586,11 @@ void AbstractImageConverterTest::convertCompressed3DToFileFailed() { return ImageConverterFeature::ConvertCompressed3DToFile; } bool doConvertToFile(const CompressedImageView3D&, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -3125,7 +3598,8 @@ void AbstractImageConverterTest::convertCompressed3DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3194,8 +3668,11 @@ void AbstractImageConverterTest::convertCompressed1DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } Containers::Optional> doConvertToData(const CompressedImageView1D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3211,6 +3688,7 @@ void AbstractImageConverterTest::convertCompressed1DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 4, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3219,8 +3697,11 @@ void AbstractImageConverterTest::convertCompressed2DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } Containers::Optional> doConvertToData(const CompressedImageView2D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3236,6 +3717,7 @@ void AbstractImageConverterTest::convertCompressed2DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3244,8 +3726,11 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughDataFailed() { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } Containers::Optional> doConvertToData(const CompressedImageView3D&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3261,6 +3746,7 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4, 1}, data}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3441,6 +3927,96 @@ void AbstractImageConverterTest::convertImageData3DToFile() { "C", TestSuite::Compare::FileToString); } +void AbstractImageConverterTest::convertImageData1DToFileFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert1DToFile|ImageConverterFeature::ConvertCompressed1DToFile; + } + bool doConvertToFile(const ImageView1D&, Containers::StringView) override { + called = true; + return false; + } + bool doConvertToFile(const CompressedImageView1D&, Containers::StringView) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}, "")); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView1D{CompressedPixelFormat::Bc1RGBUnorm, 1, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData2DToFileFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert2DToFile|ImageConverterFeature::ConvertCompressed2DToFile; + } + bool doConvertToFile(const ImageView2D&, Containers::StringView) override { + called = true; + return false; + } + bool doConvertToFile(const CompressedImageView2D&, Containers::StringView) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBUnorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertImageData3DToFileFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert3DToFile|ImageConverterFeature::ConvertCompressed3DToFile; + } + bool doConvertToFile(const ImageView3D&, Containers::StringView) override { + called = true; + return false; + } + bool doConvertToFile(const CompressedImageView3D&, Containers::StringView) override { + calledCompressed = true; + return {}; + } + + bool called = false; + bool calledCompressed = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView3D{CompressedPixelFormat::Bc1RGBUnorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_VERIFY(converter.calledCompressed); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convertLevels1DToFile() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { @@ -3529,8 +4105,11 @@ void AbstractImageConverterTest::convertLevels1DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -3538,7 +4117,8 @@ void AbstractImageConverterTest::convertLevels1DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3549,8 +4129,11 @@ void AbstractImageConverterTest::convertLevels2DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -3558,7 +4141,8 @@ void AbstractImageConverterTest::convertLevels2DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3569,8 +4153,11 @@ void AbstractImageConverterTest::convertLevels3DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4]{}; @@ -3578,7 +4165,8 @@ void AbstractImageConverterTest::convertLevels3DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3675,8 +4263,11 @@ void AbstractImageConverterTest::convertLevels1DToFileThroughDataFailed() { } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3692,6 +4283,7 @@ void AbstractImageConverterTest::convertLevels1DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({ImageView1D{PixelFormat::RGBA8Unorm, 1, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3703,8 +4295,11 @@ void AbstractImageConverterTest::convertLevels2DToFileThroughDataFailed() { } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3720,6 +4315,7 @@ void AbstractImageConverterTest::convertLevels2DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3731,8 +4327,11 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughDataFailed() { } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3748,6 +4347,7 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3997,8 +4597,11 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -4006,7 +4609,8 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4017,8 +4621,11 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[4*4]{}; @@ -4026,7 +4633,8 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4037,8 +4645,11 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileFailed() { ImageConverterFeature::Levels; } bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; const char imageData[8]{}; @@ -4046,7 +4657,8 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileFailed() { /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile({CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_VERIFY(!converter.convertToFile({CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4142,8 +4754,11 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileThroughDataFaile } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -4159,6 +4774,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileThroughDataFaile Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 4, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4170,8 +4786,11 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileThroughDataFaile } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -4187,6 +4806,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileThroughDataFaile Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4198,8 +4818,11 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileThroughDataFaile } Containers::Optional> doConvertToData(Containers::ArrayView) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -4215,6 +4838,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileThroughDataFaile Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile({CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4, 1}, data}}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4446,6 +5070,78 @@ void AbstractImageConverterTest::convert3DToFileThroughLevels() { "\x0f\x0d\x0e\x01", TestSuite::Compare::FileToString); } +void AbstractImageConverterTest::convert1DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert1DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convert2DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert2DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convert3DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::Convert3DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::convertCompressed1DToFileThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { @@ -4512,6 +5208,78 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughLevels() { "\x0f\x0d\x0e\x01", TestSuite::Compare::FileToString); } +void AbstractImageConverterTest::convertCompressed1DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed1DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView1D{CompressedPixelFormat::Bc1RGBAUnorm, 1, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertCompressed2DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed2DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + +void AbstractImageConverterTest::convertCompressed3DToFileThroughLevelsFailed() { + struct: AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { + return ImageConverterFeature::ConvertCompressed3DToFile| + ImageConverterFeature::Levels; + } + bool doConvertToFile(Containers::ArrayView, Containers::StringView) override { + called = true; + return {}; + } + + bool called = false; + } converter; + + const char imageData[4*4]{}; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView3D{CompressedPixelFormat::Bc1RGBAUnorm, {1, 1, 1}, imageData}, "")); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); +} + void AbstractImageConverterTest::debugFeature() { Containers::String out; diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index 4f5aff891..29ec6a013 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -28,6 +28,7 @@ #include #include #include +#include /** @todo remove once file callbacks are std::string-free */ #include #include #include @@ -83,6 +84,7 @@ struct AbstractImporterTest: TestSuite::Tester { void openDataFailed(); #ifdef MAGNUM_BUILD_DEPRECATED void openDataDeprecatedFallback(); + void openDataDeprecatedFallbackFailed(); #endif void openMemory(); void openMemoryFailed(); @@ -90,6 +92,7 @@ struct AbstractImporterTest: TestSuite::Tester { void openFileFailed(); void openFileAsData(); void openFileAsDataNotFound(); + void openFileAsDataFailed(); void openState(); void openStateFailed(); @@ -107,9 +110,12 @@ struct AbstractImporterTest: TestSuite::Tester { void setFileCallbackNotImplemented(); void setFileCallbackNotSupported(); void setFileCallbackOpenFileDirectly(); + void setFileCallbackOpenFileDirectlyFailed(); void setFileCallbackOpenFileThroughBaseImplementation(); + void setFileCallbackOpenFileThroughBaseImplementationNotFound(); void setFileCallbackOpenFileThroughBaseImplementationFailed(); void setFileCallbackOpenFileAsData(); + void setFileCallbackOpenFileAsDataNotFound(); void setFileCallbackOpenFileAsDataFailed(); void thingCountNotImplemented(); @@ -407,6 +413,7 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::openDataFailed, #ifdef MAGNUM_BUILD_DEPRECATED &AbstractImporterTest::openDataDeprecatedFallback, + &AbstractImporterTest::openDataDeprecatedFallbackFailed, #endif &AbstractImporterTest::openMemory, &AbstractImporterTest::openMemoryFailed, @@ -414,6 +421,7 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::openFileFailed, &AbstractImporterTest::openFileAsData, &AbstractImporterTest::openFileAsDataNotFound, + &AbstractImporterTest::openFileAsDataFailed, &AbstractImporterTest::openState, &AbstractImporterTest::openStateFailed, @@ -431,9 +439,12 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::setFileCallbackNotImplemented, &AbstractImporterTest::setFileCallbackNotSupported, &AbstractImporterTest::setFileCallbackOpenFileDirectly, + &AbstractImporterTest::setFileCallbackOpenFileDirectlyFailed, &AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementation, + &AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationNotFound, &AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationFailed, &AbstractImporterTest::setFileCallbackOpenFileAsData, + &AbstractImporterTest::setFileCallbackOpenFileAsDataNotFound, &AbstractImporterTest::setFileCallbackOpenFileAsDataFailed, &AbstractImporterTest::thingCountNotImplemented, @@ -812,7 +823,10 @@ void AbstractImporterTest::openData() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenData(Containers::Array&& data, DataFlags dataFlags) override { CORRADE_COMPARE_AS(data, @@ -844,13 +858,19 @@ void AbstractImporterTest::openDataFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenData(Containers::Array&&, DataFlags) override {} + void doOpenData(Containers::Array&&, DataFlags) override { + called = true; + } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.openData(nullptr)); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -859,7 +879,10 @@ void AbstractImporterTest::openDataDeprecatedFallback() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenData(Containers::ArrayView data) override { CORRADE_COMPARE_AS(data, @@ -879,13 +902,40 @@ void AbstractImporterTest::openDataDeprecatedFallback() { importer.close(); CORRADE_VERIFY(!importer.isOpened()); } + +void AbstractImporterTest::openDataDeprecatedFallbackFailed() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { + return ImporterFeature::OpenData; + } + bool doIsOpened() const override { return false; } + void doClose() override {} + + void doOpenData(Containers::ArrayView) override { + called = true; + } + + bool called = false; + } importer; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer.openData(nullptr)); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); + CORRADE_COMPARE(out, ""); +} #endif void AbstractImporterTest::openMemory() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenData(Containers::Array&& data, DataFlags dataFlags) override { CORRADE_COMPARE_AS(data, @@ -917,13 +967,19 @@ void AbstractImporterTest::openMemoryFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenData(Containers::Array&&, DataFlags) override {} + void doOpenData(Containers::Array&&, DataFlags) override { + called = true; + } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.openMemory(nullptr)); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -931,7 +987,10 @@ void AbstractImporterTest::openFile() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenFile(Containers::StringView filename) override { CORRADE_COMPARE(filename, "yello.foo"); @@ -955,13 +1014,19 @@ void AbstractImporterTest::openFileFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenFile(Containers::StringView) override {} + void doOpenFile(Containers::StringView) override { + called = true; + } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.openFile({})); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -969,7 +1034,10 @@ void AbstractImporterTest::openFileAsData() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenData(Containers::Array&& data, DataFlags dataFlags) override { CORRADE_COMPARE_AS(data, @@ -996,11 +1064,11 @@ void AbstractImporterTest::openFileAsData() { void AbstractImporterTest::openFileAsDataNotFound() { struct Importer: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } - bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + bool doIsOpened() const override { return false; } + void doClose() override {} void doOpenData(Containers::Array&&, DataFlags) override { - _opened = true; + CORRADE_FAIL("This should not be called"); } bool _opened = false; @@ -1008,7 +1076,6 @@ void AbstractImporterTest::openFileAsDataNotFound() { Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!importer.openFile("nonexistent.bin")); CORRADE_VERIFY(!importer.isOpened()); /* There's an error message from Path::read() before */ @@ -1017,13 +1084,40 @@ void AbstractImporterTest::openFileAsDataNotFound() { TestSuite::Compare::StringHasSuffix); } +void AbstractImporterTest::openFileAsDataFailed() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { + return ImporterFeature::OpenData; + } + bool doIsOpened() const override { return false; } + void doClose() override {} + + void doOpenData(Containers::Array&&, DataFlags) override { + called = true; + } + + bool called = false; + } importer; + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer.openFile(Utility::Path::join(TRADE_TEST_DIR, "file.bin"))); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); + CORRADE_COMPARE(out, ""); +} + void AbstractImporterTest::openState() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenState; } bool doIsOpened() const override { return _opened; } - void doClose() override { _opened = false; } + void doClose() override { + CORRADE_VERIFY(_opened); + _opened = false; + } void doOpenState(const void* state, Containers::StringView filePath) override { CORRADE_COMPARE(state, reinterpret_cast(std::size_t{0xbadcafe})); @@ -1050,13 +1144,19 @@ void AbstractImporterTest::openStateFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenState(const void*, Containers::StringView) override {} + void doOpenState(const void*, Containers::StringView) override { + called = true; + } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.openState({})); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -1300,23 +1400,55 @@ void AbstractImporterTest::setFileCallbackOpenFileDirectly() { } void doOpenData(Containers::Array&&, DataFlags) override { - /* Shouldn't be called because FileCallback is supported */ - openDataCalledNotSureWhy = true; + CORRADE_FAIL("This should not be called"); } - bool _opened = false; - bool openDataCalledNotSureWhy = false; + private: + bool _opened = false; } importer; - bool calledNotSureWhy = false; - importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, bool& calledNotSureWhy) -> Containers::Optional> { - calledNotSureWhy = true; + /* The callback shouldn't be called from the class itself, it's the + doOpenFile() implementation responsibility to call it. In this case the + implementation only verifies that it's set, along with the user data. */ + int dummy; + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { + CORRADE_FAIL("This shouldn't be called"); return {}; - }, calledNotSureWhy); + }, &dummy); CORRADE_VERIFY(importer.openFile("file.dat")); - CORRADE_VERIFY(!calledNotSureWhy); - CORRADE_VERIFY(!importer.openDataCalledNotSureWhy); + CORRADE_VERIFY(importer.isOpened()); +} + +void AbstractImporterTest::setFileCallbackOpenFileDirectlyFailed() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return ImporterFeature::FileCallback|ImporterFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + void doOpenFile(Containers::StringView) override { + called = true; + } + + void doOpenData(Containers::Array&&, DataFlags) override { + CORRADE_FAIL("This should not be called"); + } + + bool called = false; + } importer; + + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { + CORRADE_FAIL("This shouldn't be called"); + return {}; + }); + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer.openFile("file.dat")); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); + CORRADE_COMPARE(out, ""); } void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementation() { @@ -1329,7 +1461,7 @@ void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementation() { CORRADE_COMPARE(filename, "file.dat"); CORRADE_VERIFY(fileCallback()); CORRADE_VERIFY(fileCallbackUserData()); - openFileCalled = true; + called = true; AbstractImporter::doOpenFile(filename); } @@ -1341,37 +1473,74 @@ void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementation() { _opened = true; } - bool _opened = false; - bool openFileCalled = false; + bool called = false; + + private: + bool _opened = false; } importer; struct State { const char data = '\xb0'; bool loaded = false; bool closed = false; - bool calledNotSureWhy = false; } state; - importer.setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { - if(filename == "file.dat" && policy == InputFileCallbackPolicy::LoadTemporary) { + CORRADE_COMPARE(Containers::StringView{filename}, "file.dat"); + + if(policy == InputFileCallbackPolicy::LoadTemporary) { state.loaded = true; return Containers::arrayView(&state.data, 1); } - if(filename == "file.dat" && policy == InputFileCallbackPolicy::Close) { + if(policy == InputFileCallbackPolicy::Close) { state.closed = true; return {}; } - state.calledNotSureWhy = true; + CORRADE_FAIL("Unexpected policy" << policy); return {}; }, state); CORRADE_VERIFY(importer.openFile("file.dat")); - CORRADE_VERIFY(importer.openFileCalled); + CORRADE_VERIFY(importer.called); CORRADE_VERIFY(state.loaded); CORRADE_VERIFY(state.closed); - CORRADE_VERIFY(!state.calledNotSureWhy); +} + +void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationNotFound() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return ImporterFeature::FileCallback|ImporterFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + void doOpenFile(Containers::StringView filename) override { + called = true; + AbstractImporter::doOpenFile(filename); + } + + void doOpenData(Containers::Array&&, DataFlags) override { + CORRADE_FAIL("This should not be called"); + } + + bool called = false; + } importer; + + bool fileCallbackCalled = false; + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, bool& fileCallbackCalled) -> Containers::Optional> { + /* The callback should be only called to open the file, not to close it + afterwards */ + CORRADE_COMPARE(policy, InputFileCallbackPolicy::LoadTemporary); + fileCallbackCalled = true; + return {}; + }, fileCallbackCalled); + + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer.openFile("file.dat")); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); + CORRADE_VERIFY(fileCallbackCalled); + CORRADE_COMPARE(out, "Trade::AbstractImporter::openFile(): cannot open file file.dat\n"); } void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationFailed() { @@ -1385,19 +1554,43 @@ void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationFaile AbstractImporter::doOpenFile(filename); } + void doOpenData(Containers::Array&&, DataFlags) override { + openDataCalled = true; + } + bool openFileCalled = false; + bool openDataCalled = false; } importer; - importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { + struct State { + bool loaded = false; + bool closed = false; + } state; + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(policy == InputFileCallbackPolicy::LoadTemporary) { + state.loaded = true; + return Containers::ArrayView{}; + } + + if(policy == InputFileCallbackPolicy::Close) { + state.closed = true; + return {}; + } + + CORRADE_FAIL("Unexpected policy" << policy); return {}; - }); + }, state); + /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!importer.openFile("file.dat")); + CORRADE_VERIFY(!importer.isOpened()); CORRADE_VERIFY(importer.openFileCalled); - CORRADE_COMPARE(out, "Trade::AbstractImporter::openFile(): cannot open file file.dat\n"); + CORRADE_VERIFY(importer.openDataCalled); + CORRADE_VERIFY(state.loaded); + CORRADE_VERIFY(state.closed); + CORRADE_COMPARE(out, ""); } void AbstractImporterTest::setFileCallbackOpenFileAsData() { @@ -1407,7 +1600,7 @@ void AbstractImporterTest::setFileCallbackOpenFileAsData() { void doClose() override { _opened = false; } void doOpenFile(Containers::StringView) override { - openFileCalled = true; + CORRADE_FAIL("This should not be called"); } void doOpenData(Containers::Array&& data, DataFlags dataFlags) override { @@ -1418,64 +1611,117 @@ void AbstractImporterTest::setFileCallbackOpenFileAsData() { _opened = true; } - bool _opened = false; - bool openFileCalled = false; + private: + bool _opened = false; } importer; struct State { const char data = '\xb0'; bool loaded = false; bool closed = false; - bool calledNotSureWhy = false; } state; - importer.setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { - if(filename == "file.dat" && policy == InputFileCallbackPolicy::LoadTemporary) { + CORRADE_COMPARE(Containers::StringView{filename}, "file.dat"); + + if(policy == InputFileCallbackPolicy::LoadTemporary) { state.loaded = true; return Containers::arrayView(&state.data, 1); } - if(filename == "file.dat" && policy == InputFileCallbackPolicy::Close) { + if(policy == InputFileCallbackPolicy::Close) { state.closed = true; return {}; } - state.calledNotSureWhy = true; + CORRADE_FAIL("Unexpected policy" << policy); return {}; }, state); CORRADE_VERIFY(importer.openFile("file.dat")); - CORRADE_VERIFY(!importer.openFileCalled); CORRADE_VERIFY(state.loaded); CORRADE_VERIFY(state.closed); - CORRADE_VERIFY(!state.calledNotSureWhy); } -void AbstractImporterTest::setFileCallbackOpenFileAsDataFailed() { +void AbstractImporterTest::setFileCallbackOpenFileAsDataNotFound() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } bool doIsOpened() const override { return false; } void doClose() override {} void doOpenFile(Containers::StringView) override { - openFileCalled = true; + CORRADE_FAIL("This should not be called"); } - bool openFileCalled = false; + void doOpenData(Containers::Array&&, DataFlags) override { + CORRADE_FAIL("This should not be called"); + } } importer; - importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) { - return Containers::Optional>{}; - }); + bool fileCallbackCalled = false; + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, bool& fileCallbackCalled) -> Containers::Optional> { + /* The callback should be only called to open the file, not to close it + afterwards */ + CORRADE_COMPARE(policy, InputFileCallbackPolicy::LoadTemporary); + fileCallbackCalled = true; + return {}; + }, fileCallbackCalled); Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.openFile("file.dat")); - CORRADE_VERIFY(!importer.openFileCalled); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(fileCallbackCalled); CORRADE_COMPARE(out, "Trade::AbstractImporter::openFile(): cannot open file file.dat\n"); } +void AbstractImporterTest::setFileCallbackOpenFileAsDataFailed() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } + bool doIsOpened() const override { return false; } + void doClose() override {} + + void doOpenFile(Containers::StringView) override { + CORRADE_FAIL("This should not be called"); + } + + void doOpenData(Containers::Array&&, DataFlags) override { + called = true; + } + + bool called = false; + } importer; + + struct State { + bool loaded = false; + bool closed = false; + } state; + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(policy == InputFileCallbackPolicy::LoadTemporary) { + state.loaded = true; + return Containers::ArrayView{}; + } + + if(policy == InputFileCallbackPolicy::Close) { + state.closed = true; + return {}; + } + + CORRADE_FAIL("Unexpected policy" << policy); + return {}; + }, state); + + /* The implementation is expected to print an error message on its own */ + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer.openFile("file.dat")); + CORRADE_VERIFY(!importer.isOpened()); + CORRADE_VERIFY(importer.called); + CORRADE_VERIFY(state.loaded); + CORRADE_VERIFY(state.closed); + CORRADE_COMPARE(out, ""); +} + void AbstractImporterTest::thingCountNotImplemented() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -1908,14 +2154,18 @@ void AbstractImporterTest::sceneFailed() { UnsignedInt doSceneCount() const override { return 1; } Containers::Optional doScene(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.scene(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -3881,14 +4131,18 @@ void AbstractImporterTest::animationFailed() { UnsignedInt doAnimationCount() const override { return 1; } Containers::Optional doAnimation(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.animation(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -4204,14 +4458,18 @@ void AbstractImporterTest::lightFailed() { UnsignedInt doLightCount() const override { return 1; } Containers::Optional doLight(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.light(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -4363,14 +4621,18 @@ void AbstractImporterTest::cameraFailed() { UnsignedInt doCameraCount() const override { return 1; } Containers::Optional doCamera(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.camera(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -5054,14 +5316,18 @@ void AbstractImporterTest::skin2DFailed() { UnsignedInt doSkin2DCount() const override { return 1; } Containers::Optional doSkin2D(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.skin2D(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -5293,14 +5559,18 @@ void AbstractImporterTest::skin3DFailed() { UnsignedInt doSkin3DCount() const override { return 1; } Containers::Optional doSkin3D(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.skin3D(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -5537,14 +5807,18 @@ void AbstractImporterTest::meshFailed() { UnsignedInt doMeshCount() const override { return 1; } Containers::Optional doMesh(UnsignedInt, UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.mesh(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -6429,14 +6703,18 @@ void AbstractImporterTest::materialFailed() { UnsignedInt doMaterialCount() const override { return 1; } Containers::Optional doMaterial(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.material(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -6709,14 +6987,18 @@ void AbstractImporterTest::textureFailed() { UnsignedInt doTextureCount() const override { return 1; } Containers::Optional doTexture(UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.texture(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -6873,14 +7155,18 @@ void AbstractImporterTest::image1DFailed() { UnsignedInt doImage1DCount() const override { return 1; } Containers::Optional doImage1D(UnsignedInt, UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.image1D(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -7177,14 +7463,18 @@ void AbstractImporterTest::image2DFailed() { UnsignedInt doImage2DCount() const override { return 1; } Containers::Optional doImage2D(UnsignedInt, UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.image2D(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } @@ -7481,14 +7771,18 @@ void AbstractImporterTest::image3DFailed() { UnsignedInt doImage3DCount() const override { return 1; } Containers::Optional doImage3D(UnsignedInt, UnsignedInt) override { + called = true; return {}; } + + bool called = false; } importer; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!importer.image3D(0)); + CORRADE_VERIFY(importer.called); CORRADE_COMPARE(out, ""); } diff --git a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp index 751c537f5..b601626a2 100644 --- a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp @@ -208,6 +208,7 @@ struct AbstractSceneConverterTest: TestSuite::Tester { void addMeshLevelsNotImplemented(); void addMeshThroughLevels(); + void addMeshThroughLevelsFailed(); void setMeshAttributeName(); void setMeshAttributeNameNotImplemented(); @@ -284,6 +285,9 @@ struct AbstractSceneConverterTest: TestSuite::Tester { void addImage1DThroughLevels(); void addImage2DThroughLevels(); void addImage3DThroughLevels(); + void addImage1DThroughLevelsFailed(); + void addImage2DThroughLevelsFailed(); + void addImage3DThroughLevelsFailed(); void addImporterContents(); void addImporterContentsCustomSceneFields(); @@ -771,7 +775,8 @@ AbstractSceneConverterTest::AbstractSceneConverterTest() { &AbstractSceneConverterTest::addMeshLevelsNoLevels, &AbstractSceneConverterTest::addMeshLevelsNotImplemented, - &AbstractSceneConverterTest::addMeshThroughLevels}); + &AbstractSceneConverterTest::addMeshThroughLevels, + &AbstractSceneConverterTest::addMeshThroughLevelsFailed}); addInstancedTests({&AbstractSceneConverterTest::setMeshAttributeName}, Containers::arraySize(SetMeshAttributeData)); @@ -839,7 +844,10 @@ AbstractSceneConverterTest::AbstractSceneConverterTest() { &AbstractSceneConverterTest::addImage1DThroughLevels, &AbstractSceneConverterTest::addImage2DThroughLevels, - &AbstractSceneConverterTest::addImage3DThroughLevels}); + &AbstractSceneConverterTest::addImage3DThroughLevels, + &AbstractSceneConverterTest::addImage1DThroughLevelsFailed, + &AbstractSceneConverterTest::addImage2DThroughLevelsFailed, + &AbstractSceneConverterTest::addImage3DThroughLevelsFailed}); addInstancedTests({&AbstractSceneConverterTest::addImporterContents}, Containers::arraySize(AddImporterContentsData)); @@ -1245,14 +1253,18 @@ void AbstractSceneConverterTest::convertMeshFailed() { } Containers::Optional doConvert(const MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convert(MeshData{MeshPrimitive::Triangles, 0})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1408,8 +1420,11 @@ void AbstractSceneConverterTest::convertMeshInPlaceFailed() { } bool doConvertInPlace(MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; MeshData mesh{MeshPrimitive::Triangles, 0}; @@ -1418,6 +1433,7 @@ void AbstractSceneConverterTest::convertMeshInPlaceFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertInPlace(mesh)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1457,14 +1473,18 @@ void AbstractSceneConverterTest::convertMeshToDataFailed() { } Containers::Optional> doConvertToData(const MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(MeshData{MeshPrimitive::Triangles, 0})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1515,6 +1535,7 @@ void AbstractSceneConverterTest::convertMeshToDataThroughBatchAddFailed() { bool doBeginData() override { return true; } bool doAdd(UnsignedInt, const MeshData&, Containers::StringView) override { + called = true; return false; } @@ -1522,6 +1543,8 @@ void AbstractSceneConverterTest::convertMeshToDataThroughBatchAddFailed() { CORRADE_FAIL("doEndData() shouldn't be called"); return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -1529,6 +1552,7 @@ void AbstractSceneConverterTest::convertMeshToDataThroughBatchAddFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(MeshData{MeshPrimitive::Triangles, 6})); CORRADE_VERIFY(!converter.isConverting()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1546,8 +1570,11 @@ void AbstractSceneConverterTest::convertMeshToDataThroughBatchEndFailed() { } Containers::Optional> doEndData() override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -1555,6 +1582,7 @@ void AbstractSceneConverterTest::convertMeshToDataThroughBatchEndFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToData(MeshData{MeshPrimitive::Triangles, 6})); CORRADE_VERIFY(!converter.isConverting()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1654,14 +1682,18 @@ void AbstractSceneConverterTest::convertMeshToFileFailed() { } bool doConvertToFile(const MeshData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.convertToFile(MeshData{MeshPrimitive::Triangles, 0}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "mesh.out"))); + CORRADE_VERIFY(!converter.convertToFile(MeshData{MeshPrimitive::Triangles, 0}, "")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1690,8 +1722,11 @@ void AbstractSceneConverterTest::convertMeshToFileThroughDataFailed() { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } Containers::Optional> doConvertToData(const MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -1705,6 +1740,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughDataFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(MeshData{MeshPrimitive::Triangles, 0xef}, filename)); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1780,6 +1816,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughBatchAddFailed() { bool doBeginFile(Containers::StringView) override { return true; } bool doAdd(UnsignedInt, const MeshData&, Containers::StringView) override { + called = true; return false; } @@ -1787,6 +1824,8 @@ void AbstractSceneConverterTest::convertMeshToFileThroughBatchAddFailed() { CORRADE_FAIL("doEndFile() shouldn't be called"); return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -1794,6 +1833,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughBatchAddFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(MeshData{MeshPrimitive::Triangles, 0xfc}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "mesh.out"))); CORRADE_VERIFY(!converter.isConverting()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1811,8 +1851,11 @@ void AbstractSceneConverterTest::convertMeshToFileThroughBatchEndFailed() { } bool doEndFile(Containers::StringView) override { + called = true; return {}; } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ @@ -1820,6 +1863,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughBatchEndFailed() { Error redirectError{&out}; CORRADE_VERIFY(!converter.convertToFile(MeshData{MeshPrimitive::Triangles, 0xfc}, Utility::Path::join(TRADE_TEST_OUTPUT_DIR, "mesh.out"))); CORRADE_VERIFY(!converter.isConverting()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -1887,13 +1931,19 @@ void AbstractSceneConverterTest::beginFailed() { return SceneConverterFeature::ConvertMultiple; } - bool doBegin() override { return false; } + bool doBegin() override { + called = true; + return false; + } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.begin()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -1908,8 +1958,11 @@ void AbstractSceneConverterTest::endFailed() { bool doBegin() override { return true; } Containers::Pointer doEnd() override { + called = true; return nullptr; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -1918,6 +1971,7 @@ void AbstractSceneConverterTest::endFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.end()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -2001,13 +2055,19 @@ void AbstractSceneConverterTest::beginDataFailed() { return SceneConverterFeature::ConvertMultipleToData; } - bool doBeginData() override { return false; } + bool doBeginData() override { + called = true; + return false; + } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.beginData()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -2022,8 +2082,11 @@ void AbstractSceneConverterTest::endDataFailed() { bool doBeginData() override { return true; } Containers::Optional> doEndData() override { + called = true; return {}; } + + bool called = false; } converter; CORRADE_VERIFY(converter.beginData()); @@ -2032,6 +2095,7 @@ void AbstractSceneConverterTest::endDataFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.endData()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -2143,13 +2207,19 @@ void AbstractSceneConverterTest::beginFileFailed() { return SceneConverterFeature::ConvertMultipleToFile; } - bool doBeginFile(Containers::StringView) override { return false; } + bool doBeginFile(Containers::StringView) override { + called = true; + return false; + } + + bool called = false; } converter; /* The implementation is expected to print an error message on its own */ Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.beginFile("file.gltf")); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -2163,7 +2233,12 @@ void AbstractSceneConverterTest::endFileFailed() { bool doBeginFile(Containers::StringView) override { return true; } - bool doEndFile(Containers::StringView) override { return false; } + bool doEndFile(Containers::StringView) override { + called = true; + return false; + } + + bool called = false; } converter; CORRADE_VERIFY(converter.beginFile("file.gltf")); @@ -2172,6 +2247,7 @@ void AbstractSceneConverterTest::endFileFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.endFile()); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); CORRADE_VERIFY(!converter.isConverting()); @@ -2212,8 +2288,11 @@ void AbstractSceneConverterTest::beginEndFileThroughDataFailed() { bool doBeginData() override { return true; } Containers::Optional> doEndData() override { + called = true; return {}; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -2230,6 +2309,7 @@ void AbstractSceneConverterTest::beginEndFileThroughDataFailed() { CORRADE_VERIFY(!converter.endFile()); CORRADE_VERIFY(!converter.isConverting()); CORRADE_VERIFY(!Utility::Path::exists(filename)); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -2800,8 +2880,11 @@ void AbstractSceneConverterTest::addSceneFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const SceneData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -2812,6 +2895,7 @@ void AbstractSceneConverterTest::addSceneFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(SceneData{SceneMappingType::UnsignedInt, 0, nullptr, nullptr})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3066,8 +3150,11 @@ void AbstractSceneConverterTest::addAnimationFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const AnimationData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3078,6 +3165,7 @@ void AbstractSceneConverterTest::addAnimationFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(AnimationData{nullptr, nullptr})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3210,8 +3298,11 @@ void AbstractSceneConverterTest::addLightFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const LightData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3222,6 +3313,7 @@ void AbstractSceneConverterTest::addLightFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(LightData{LightType::Point, {}, 0.0f})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3293,8 +3385,11 @@ void AbstractSceneConverterTest::addCameraFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const CameraData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3305,6 +3400,7 @@ void AbstractSceneConverterTest::addCameraFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(CameraData{CameraType::Orthographic3D, {}, 0.0f, 1.0f})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3376,8 +3472,11 @@ void AbstractSceneConverterTest::addSkin2DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const SkinData2D&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3388,6 +3487,7 @@ void AbstractSceneConverterTest::addSkin2DFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(SkinData2D{nullptr, nullptr})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3459,8 +3559,11 @@ void AbstractSceneConverterTest::addSkin3DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const SkinData3D&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3471,6 +3574,7 @@ void AbstractSceneConverterTest::addSkin3DFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(SkinData3D{nullptr, nullptr})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3542,8 +3646,11 @@ void AbstractSceneConverterTest::addMeshFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const MeshData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -3554,6 +3661,7 @@ void AbstractSceneConverterTest::addMeshFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(MeshData{MeshPrimitive::Triangles, 0})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -3630,13 +3738,17 @@ void AbstractSceneConverterTest::addMeshThroughConvertMeshFailed() { } Containers::Optional doConvert(const MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); CORRADE_VERIFY(!converter.add(MeshData{MeshPrimitive::Lines, 6})); + CORRADE_VERIFY(converter.called); /* It shouldn't abort the whole process */ CORRADE_VERIFY(converter.isConverting()); CORRADE_COMPARE(converter.meshCount(), 0); @@ -3749,13 +3861,17 @@ void AbstractSceneConverterTest::addMeshThroughConvertMeshToDataFailed() { } Containers::Optional> doConvertToData(const MeshData&) override { + called = true; return {}; } + + bool called = false; } converter; CORRADE_VERIFY(converter.beginData()); CORRADE_VERIFY(!converter.add(MeshData{MeshPrimitive::Lines, 6})); + CORRADE_VERIFY(converter.called); /* It shouldn't abort the whole process */ CORRADE_VERIFY(converter.isConverting()); CORRADE_COMPARE(converter.meshCount(), 0); @@ -3935,8 +4051,11 @@ void AbstractSceneConverterTest::addMeshThroughConvertMeshToFileFailed() { } bool doConvertToFile(const MeshData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; /* Remove previous file, if any */ @@ -3948,6 +4067,7 @@ void AbstractSceneConverterTest::addMeshThroughConvertMeshToFileFailed() { CORRADE_VERIFY(!Utility::Path::exists(filename)); CORRADE_VERIFY(!converter.add(MeshData{MeshPrimitive::Lines, 6})); + CORRADE_VERIFY(converter.called); /* It shouldn't abort the whole process */ CORRADE_VERIFY(converter.isConverting()); CORRADE_COMPARE(converter.meshCount(), 0); @@ -4104,8 +4224,11 @@ void AbstractSceneConverterTest::addMeshLevelsFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -4119,6 +4242,7 @@ void AbstractSceneConverterTest::addMeshLevelsFailed() { MeshData{MeshPrimitive::Triangles, 0}, MeshData{MeshPrimitive::Triangles, 0} })); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4200,6 +4324,41 @@ void AbstractSceneConverterTest::addMeshThroughLevels() { CORRADE_COMPARE(converter.meshCount(), 1); } +void AbstractSceneConverterTest::addMeshThroughLevelsFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddMeshes| + SceneConverterFeature::MeshLevels; + } + + bool doBegin() override { return true; } + + bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + called = true; + return false; + } + + bool called = false; + } converter; + + CORRADE_VERIFY(converter.begin()); + CORRADE_COMPARE(converter.meshCount(), 0); + + /* The implementation is expected to print an error message on its own */ + { + Containers::String out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.add(MeshData{MeshPrimitive::Triangles, 0})); + CORRADE_VERIFY(converter.called); + CORRADE_COMPARE(out, ""); + } + + /* It shouldn't abort the whole process */ + CORRADE_VERIFY(converter.isConverting()); + CORRADE_COMPARE(converter.meshCount(), 0); +} + void AbstractSceneConverterTest::setMeshAttributeName() { auto&& data = SetMeshAttributeData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -4312,8 +4471,11 @@ void AbstractSceneConverterTest::addMaterialFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const MaterialData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -4324,6 +4486,7 @@ void AbstractSceneConverterTest::addMaterialFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(MaterialData{{}, nullptr})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4395,8 +4558,11 @@ void AbstractSceneConverterTest::addTextureFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const TextureData&, Containers::StringView) override { + called = true; return false; } + + bool called = false; } converter; CORRADE_VERIFY(converter.begin()); @@ -4407,6 +4573,7 @@ void AbstractSceneConverterTest::addTextureFailed() { Containers::String out; Error redirectError{&out}; CORRADE_VERIFY(!converter.add(TextureData{{}, {}, {}, {}, {}, 0})); + CORRADE_VERIFY(converter.called); CORRADE_COMPARE(out, ""); } @@ -4553,8 +4720,11 @@ void AbstractSceneConverterTest::addImage1DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const ImageData1D&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -4571,6 +4741,7 @@ void AbstractSceneConverterTest::addImage1DFailed() { CORRADE_VERIFY(!converter.add(ImageData1D{PixelFormat::RGBA8Unorm, 1, DataFlags{}, imageData})); CORRADE_VERIFY(!converter.add(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData})); CORRADE_VERIFY(!converter.add(CompressedImageView1D{CompressedPixelFormat::Astc4x4RGBAUnorm, 1, imageData})); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -4741,8 +4912,11 @@ void AbstractSceneConverterTest::addImage2DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const ImageData2D&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -4759,6 +4933,7 @@ void AbstractSceneConverterTest::addImage2DFailed() { CORRADE_VERIFY(!converter.add(ImageData2D{PixelFormat::RGBA8Unorm, {1, 1}, DataFlags{}, imageData})); CORRADE_VERIFY(!converter.add(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData})); CORRADE_VERIFY(!converter.add(CompressedImageView2D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1}, imageData})); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -4951,8 +5126,11 @@ void AbstractSceneConverterTest::addImage3DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const ImageData3D&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -4969,6 +5147,7 @@ void AbstractSceneConverterTest::addImage3DFailed() { CORRADE_VERIFY(!converter.add(ImageData3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, DataFlags{}, imageData})); CORRADE_VERIFY(!converter.add(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData})); CORRADE_VERIFY(!converter.add(CompressedImageView3D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1, 1}, imageData})); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -5155,8 +5334,11 @@ void AbstractSceneConverterTest::addImageLevels1DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -5182,6 +5364,7 @@ void AbstractSceneConverterTest::addImageLevels1DFailed() { CompressedImageView1D{CompressedPixelFormat::Astc4x4RGBAUnorm, 1, imageData}, CompressedImageView1D{CompressedPixelFormat::Astc4x4RGBAUnorm, 1, imageData}, })); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -5373,8 +5556,11 @@ void AbstractSceneConverterTest::addImageLevels2DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -5400,6 +5586,7 @@ void AbstractSceneConverterTest::addImageLevels2DFailed() { CompressedImageView2D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1}, imageData}, CompressedImageView2D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1}, imageData} })); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -5780,8 +5967,11 @@ void AbstractSceneConverterTest::addImageLevels3DFailed() { bool doBegin() override { return true; } bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; return false; } + + Int called = 0; } converter; const char imageData[16]{}; @@ -5807,6 +5997,7 @@ void AbstractSceneConverterTest::addImageLevels3DFailed() { CompressedImageView3D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1, 1}, imageData}, CompressedImageView3D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1, 1}, imageData} })); + CORRADE_COMPARE(converter.called, 3); CORRADE_COMPARE(out, ""); } @@ -5952,6 +6143,132 @@ void AbstractSceneConverterTest::addImage3DThroughLevels() { CORRADE_COMPARE(converter.image3DCount(), 1); } +void AbstractSceneConverterTest::addImage1DThroughLevelsFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddImages1D| + SceneConverterFeature::AddCompressedImages1D| + SceneConverterFeature::ImageLevels; + } + + bool doBegin() override { return true; } + + bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; + return false; + } + + Int called = 0; + } converter; + + const char imageData[16]{}; + + CORRADE_VERIFY(converter.begin()); + CORRADE_COMPARE(converter.image1DCount(), 0); + + /* The implementation is expected to print an error message on its own */ + { + Containers::String out; + Error redirectError{&out}; + /* Testing all three variants to "fake" coverage for the name-less + overloads as well */ + CORRADE_VERIFY(!converter.add(ImageData1D{PixelFormat::RGBA8Unorm, 1, DataFlags{}, imageData})); + CORRADE_VERIFY(!converter.add(ImageView1D{PixelFormat::RGBA8Unorm, 1, imageData})); + CORRADE_VERIFY(!converter.add(CompressedImageView1D{CompressedPixelFormat::Astc4x4RGBAUnorm, 1, imageData})); + CORRADE_COMPARE(converter.called, 3); + CORRADE_COMPARE(out, ""); + } + + /* It shouldn't abort the whole process */ + CORRADE_VERIFY(converter.isConverting()); + CORRADE_COMPARE(converter.image1DCount(), 0); +} + +void AbstractSceneConverterTest::addImage2DThroughLevelsFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddImages2D| + SceneConverterFeature::AddCompressedImages2D| + SceneConverterFeature::ImageLevels; + } + + bool doBegin() override { return true; } + + bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; + return false; + } + + Int called = 0; + } converter; + + const char imageData[16]{}; + + CORRADE_VERIFY(converter.begin()); + CORRADE_COMPARE(converter.image2DCount(), 0); + + /* The implementation is expected to print an error message on its own */ + { + Containers::String out; + Error redirectError{&out}; + /* Testing all three variants to "fake" coverage for the name-less + overloads as well */ + CORRADE_VERIFY(!converter.add(ImageData2D{PixelFormat::RGBA8Unorm, {1, 1}, DataFlags{}, imageData})); + CORRADE_VERIFY(!converter.add(ImageView2D{PixelFormat::RGBA8Unorm, {1, 1}, imageData})); + CORRADE_VERIFY(!converter.add(CompressedImageView2D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1}, imageData})); + CORRADE_COMPARE(converter.called, 3); + CORRADE_COMPARE(out, ""); + } + + /* It shouldn't abort the whole process */ + CORRADE_VERIFY(converter.isConverting()); + CORRADE_COMPARE(converter.image2DCount(), 0); +} + +void AbstractSceneConverterTest::addImage3DThroughLevelsFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddImages3D| + SceneConverterFeature::AddCompressedImages3D| + SceneConverterFeature::ImageLevels; + } + + bool doBegin() override { return true; } + + bool doAdd(UnsignedInt, const Containers::Iterable&, Containers::StringView) override { + ++called; + return false; + } + + Int called = 0; + } converter; + + const char imageData[16]{}; + + CORRADE_VERIFY(converter.begin()); + CORRADE_COMPARE(converter.image3DCount(), 0); + + /* The implementation is expected to print an error message on its own */ + { + Containers::String out; + Error redirectError{&out}; + /* Testing all three variants to "fake" coverage for the name-less + overloads as well */ + CORRADE_VERIFY(!converter.add(ImageData3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, DataFlags{}, imageData})); + CORRADE_VERIFY(!converter.add(ImageView3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, imageData})); + CORRADE_VERIFY(!converter.add(CompressedImageView3D{CompressedPixelFormat::Astc4x4RGBAUnorm, {1, 1, 1}, imageData})); + CORRADE_COMPARE(converter.called, 3); + CORRADE_COMPARE(out, ""); + } + + /* It shouldn't abort the whole process */ + CORRADE_VERIFY(converter.isConverting()); + CORRADE_COMPARE(converter.image3DCount(), 0); +} + void AbstractSceneConverterTest::addImporterContents() { auto&& data = AddImporterContentsData[testCaseInstanceId()]; setTestCaseDescription(data.name);