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);