diff --git a/doc/changelog.dox b/doc/changelog.dox index 8dbff9a14..e24bcc993 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -84,6 +84,9 @@ See also: - @ref DebugTools::CompareImageFile and @ref DebugTools::CompareImageToFile now support the new @ref TestSuite-Tester-save-diagnostic "--save-diagnostic option", making it possible to save images when a comparison fails +- @ref DebugTools::CompareImage and variants can now print a verbose + diagnostic also if the `--verbose` @ref TestSuite-Tester-command-line "command-line option" + is specified and comparison delta is non-zero - @ref DebugTools::CompareImage and @ref DebugTools::CompareImageToFile now accept also @ref Corrade::Containers::StridedArrayView2D on the left side of the comparison for added flexibility. See diff --git a/src/Magnum/DebugTools/CompareImage.cpp b/src/Magnum/DebugTools/CompareImage.cpp index 429c8bbc3..ff6fec134 100644 --- a/src/Magnum/DebugTools/CompareImage.cpp +++ b/src/Magnum/DebugTools/CompareImage.cpp @@ -369,7 +369,8 @@ enum class Result: UnsignedByte { DifferentFormat, AboveThresholds, AboveMeanThreshold, - AboveMaxThreshold + AboveMaxThreshold, + VerboseMessage }; class ImageComparatorBase::State { @@ -450,19 +451,25 @@ TestSuite::ComparisonStatusFlags ImageComparatorBase::compare(const PixelFormat CORRADE_INTERNAL_ASSERT(!(_state->mean < 0.0f)); CORRADE_INTERNAL_ASSERT(_state->max >= 0.0f && !Math::isInf(_state->max) && !Math::isNan(_state->max)); - /* If both values are not above threshold, success. Comparing this way in - order to properly catch NaNs in mean values. */ + /* If both values are not above threshold, success. If the values are + above, save the delta. If the values are below thresholds but nonzero, + we can provide optional message -- save the delta in that case too. */ + TestSuite::ComparisonStatusFlags flags = TestSuite::ComparisonStatusFlag::Failed; if(_state->max > _state->maxThreshold && !(_state->mean <= _state->meanThreshold)) _state->result = Result::AboveThresholds; else if(_state->max > _state->maxThreshold) _state->result = Result::AboveMaxThreshold; + /* Comparing this way in order to propely catch NaNs in mean values */ else if(!(_state->mean <= _state->meanThreshold)) _state->result = Result::AboveMeanThreshold; - else return TestSuite::ComparisonStatusFlags{}; + else if(_state->max > 0.0f || _state->mean > 0.0f) { + _state->result = Result::VerboseMessage; + flags = TestSuite::ComparisonStatusFlag::Verbose; + } else return TestSuite::ComparisonStatusFlags{}; /* Otherwise save the deltas and fail */ _state->delta = std::move(delta); - return TestSuite::ComparisonStatusFlag::Failed; + return flags; } TestSuite::ComparisonStatusFlags ImageComparatorBase::operator()(const ImageView2D& actual, const ImageView2D& expected) { @@ -605,7 +612,7 @@ TestSuite::ComparisonStatusFlags ImageComparatorBase::operator()(const std::stri return compare(_state->actualFormat, _state->actualPixels, expected); } -void ImageComparatorBase::printMessage(TestSuite::ComparisonStatusFlags, Debug& out, const std::string& actual, const std::string& expected) const { +void ImageComparatorBase::printMessage(const TestSuite::ComparisonStatusFlags flags, Debug& out, const std::string& actual, const std::string& expected) const { if(_state->result == Result::PluginLoadFailed) { out << "AnyImageImporter plugin could not be loaded."; return; @@ -651,7 +658,13 @@ void ImageComparatorBase::printMessage(TestSuite::ComparisonStatusFlags, Debug& << "but at most" << _state->meanThreshold << "expected. Max delta" << _state->max << "is within threshold" << _state->maxThreshold << Debug::nospace << "."; - else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ + else if(_state->result == Result::VerboseMessage) { + CORRADE_INTERNAL_ASSERT(flags & TestSuite::ComparisonStatusFlag::Verbose); + out << "deltas" << _state->max << Debug::nospace << "/" + << Debug::nospace << _state->mean << "below threshold" + << _state->maxThreshold << Debug::nospace << "/" + << Debug::nospace << _state->meanThreshold << Debug::nospace << "."; + } else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ out << "Delta image:" << Debug::newline; DebugTools::Implementation::printDeltaImage(out, _state->delta, _state->expectedImage->size(), _state->max, _state->maxThreshold, _state->meanThreshold); diff --git a/src/Magnum/DebugTools/CompareImage.h b/src/Magnum/DebugTools/CompareImage.h index e166be381..5b0268b4c 100644 --- a/src/Magnum/DebugTools/CompareImage.h +++ b/src/Magnum/DebugTools/CompareImage.h @@ -255,6 +255,13 @@ the max threshold are colored red, blocks with delta over the mean threshold are colored yellow. The delta list contains X,Y pixel position (with origin at bottom left), actual and expected pixel value and calculated delta. +Sometimes it's desirable to print the delta image even if the comparison passed +--- for example, to check that the thresholds aren't too high to hide real +issues. If the `--verbose` @ref TestSuite-Tester-command-line "command-line option" +is specified, every image comparison with a non-zero delta will print an +@cb{.ansi} INFO @ce message in the same form as the error diagnostic +shown above. + @section DebugTools-CompareImage-specials Special floating-point values For floating-point input, the comparator treats the values similarly to how diff --git a/src/Magnum/DebugTools/Test/CompareImageTest.cpp b/src/Magnum/DebugTools/Test/CompareImageTest.cpp index f533a32cd..db2a1b4ee 100644 --- a/src/Magnum/DebugTools/Test/CompareImageTest.cpp +++ b/src/Magnum/DebugTools/Test/CompareImageTest.cpp @@ -76,6 +76,7 @@ struct CompareImageTest: TestSuite::Tester { void compareAboveThresholds(); void compareAboveMaxThreshold(); void compareAboveMeanThreshold(); + void compareNonZeroThreshold(); void compareSpecials(); void compareSpecialsMeanOnly(); void compareSpecialsDisallowedThreshold(); @@ -83,29 +84,36 @@ struct CompareImageTest: TestSuite::Tester { void setupExternalPluginManager(); void teardownExternalPluginManager(); - void image(); + void imageZeroDelta(); + void imageNonZeroDelta(); void imageError(); void imageFile(); + void imageFileZeroDelta(); + void imageFileNonZeroDelta(); void imageFileError(); void imageFilePluginLoadFailed(); void imageFileActualLoadFailed(); void imageFileExpectedLoadFailed(); void imageFileActualIsCompressed(); void imageFileExpectedIsCompressed(); - void imageToFile(); + void imageToFileZeroDelta(); + void imageToFileNonZeroDelta(); void imageToFileError(); void imageToFilePluginLoadFailed(); void imageToFileExpectedLoadFailed(); void imageToFileExpectedIsCompressed(); - void fileToImage(); + void fileToImageZeroDelta(); + void fileToImageNonZeroDelta(); void fileToImageError(); void fileToImagePluginLoadFailed(); void fileToImageActualLoadFailed(); void fileToImageActualIsCompressed(); - void pixelsToImage(); + void pixelsToImageZeroDelta(); + void pixelsToImageNonZeroDelta(); void pixelsToImageError(); - void pixelsToFile(); + void pixelsToFileZeroDelta(); + void pixelsToFileNonZeroDelta(); void pixelsToFileError(); private: @@ -138,14 +146,17 @@ CompareImageTest::CompareImageTest() { &CompareImageTest::compareAboveThresholds, &CompareImageTest::compareAboveMaxThreshold, &CompareImageTest::compareAboveMeanThreshold, + &CompareImageTest::compareNonZeroThreshold, &CompareImageTest::compareSpecials, &CompareImageTest::compareSpecialsMeanOnly, &CompareImageTest::compareSpecialsDisallowedThreshold, - &CompareImageTest::image, + &CompareImageTest::imageZeroDelta, + &CompareImageTest::imageNonZeroDelta, &CompareImageTest::imageError}); - addTests({&CompareImageTest::imageFile, + addTests({&CompareImageTest::imageFileZeroDelta, + &CompareImageTest::imageFileNonZeroDelta, &CompareImageTest::imageFileError}, &CompareImageTest::setupExternalPluginManager, &CompareImageTest::teardownExternalPluginManager); @@ -160,7 +171,8 @@ CompareImageTest::CompareImageTest() { addTests({&CompareImageTest::imageFileActualIsCompressed, &CompareImageTest::imageFileExpectedIsCompressed}); - addTests({&CompareImageTest::imageToFile, + addTests({&CompareImageTest::imageToFileZeroDelta, + &CompareImageTest::imageToFileNonZeroDelta, &CompareImageTest::imageToFileError}, &CompareImageTest::setupExternalPluginManager, &CompareImageTest::teardownExternalPluginManager); @@ -173,7 +185,8 @@ CompareImageTest::CompareImageTest() { addTests({&CompareImageTest::imageToFileExpectedIsCompressed}); - addTests({&CompareImageTest::fileToImage, + addTests({&CompareImageTest::fileToImageZeroDelta, + &CompareImageTest::fileToImageNonZeroDelta, &CompareImageTest::fileToImageError}, &CompareImageTest::setupExternalPluginManager, &CompareImageTest::teardownExternalPluginManager); @@ -186,10 +199,12 @@ CompareImageTest::CompareImageTest() { addTests({&CompareImageTest::fileToImageActualIsCompressed}); - addTests({&CompareImageTest::pixelsToImage, + addTests({&CompareImageTest::pixelsToImageZeroDelta, + &CompareImageTest::pixelsToImageNonZeroDelta, &CompareImageTest::pixelsToImageError}); - addTests({&CompareImageTest::pixelsToFile, + addTests({&CompareImageTest::pixelsToFileZeroDelta, + &CompareImageTest::pixelsToFileNonZeroDelta, &CompareImageTest::pixelsToFileError}, &CompareImageTest::setupExternalPluginManager, &CompareImageTest::teardownExternalPluginManager); @@ -615,6 +630,25 @@ void CompareImageTest::compareAboveMeanThreshold() { " [1,0] #5647ec, expected #5610ed (Δ = 18.6667)\n"); } +void CompareImageTest::compareNonZeroThreshold() { + std::stringstream out; + + { + TestSuite::Comparator compare{40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(ActualRgb, ExpectedRgb); + /* No diagnostic as we don't have any expected filename */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), + "Images a and b have deltas 39/18.5 below threshold 40/20. Delta image:\n" + " |?M|\n" + " Pixels above max/mean threshold:\n" + " [1,1] #abcd85, expected #abcdfa (Δ = 39)\n"); +} + void CompareImageTest::compareSpecials() { std::stringstream out; @@ -761,6 +795,12 @@ void CompareImageTest::teardownExternalPluginManager() { _converterManager = Containers::NullOpt; } +constexpr const char* ImageCompareVerbose = + "Images a and b have deltas 39/18.5 below threshold 40/20. Delta image:\n" + " |?M|\n" + " Pixels above max/mean threshold:\n" + " [1,1] #abcd85, expected #abcdfa (Δ = 39)\n"; + constexpr const char* ImageCompareError = "Images a and b have both max and mean delta above threshold, actual 39/18.5 but at most 20/10 expected. Delta image:\n" " |?M|\n" @@ -769,12 +809,30 @@ constexpr const char* ImageCompareError = " [1,0] #5647ec, expected #5610ed (Δ = 18.6667)\n" " [0,1] #235710, expected #232710 (Δ = 16)\n"; -void CompareImageTest::image() { - CORRADE_COMPARE_WITH(ActualRgb, ExpectedRgb, (CompareImage{40.0f, 20.0f})); +void CompareImageTest::imageZeroDelta() { + CORRADE_COMPARE_WITH(ExpectedRgb, ExpectedRgb, (CompareImage{40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{40.0f, 20.0f}; - CORRADE_COMPARE(compare(ActualRgb, ExpectedRgb), TestSuite::ComparisonStatusFlags{}); + CORRADE_COMPARE(compare(ExpectedRgb, ExpectedRgb), TestSuite::ComparisonStatusFlags{}); +} + +void CompareImageTest::imageNonZeroDelta() { + /* This will produce output if --verbose is specified */ + CORRADE_COMPARE_WITH(ActualRgb, ExpectedRgb, (CompareImage{40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(ActualRgb, ExpectedRgb); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); } void CompareImageTest::imageError() { @@ -792,22 +850,49 @@ void CompareImageTest::imageError() { CORRADE_COMPARE(out.str(), ImageCompareError); } -void CompareImageTest::imageFile() { +void CompareImageTest::imageFileZeroDelta() { if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); CORRADE_COMPARE_WITH( - Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), (CompareImageFile{*_importerManager, 40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; CORRADE_COMPARE(compare( - Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")), - TestSuite::ComparisonStatusFlags{}); + TestSuite::ComparisonStatusFlag{}); +} + +void CompareImageTest::imageFileNonZeroDelta() { + if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || + _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) + CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); + + /* This will produce output if --verbose is specified */ + CORRADE_COMPARE_WITH( + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), + (CompareImageFile{*_importerManager, 40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare( + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); } void CompareImageTest::imageFileError() { @@ -995,21 +1080,45 @@ void CompareImageTest::imageFileExpectedIsCompressed() { CORRADE_VERIFY(!Utility::Directory::exists(filename)); } -void CompareImageTest::imageToFile() { +void CompareImageTest::imageToFileZeroDelta() { if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); - CORRADE_COMPARE_WITH(ActualRgb, + CORRADE_COMPARE_WITH(ExpectedRgb, Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), (CompareImageToFile{*_importerManager, 40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; - CORRADE_COMPARE(compare(ActualRgb, Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")), + CORRADE_COMPARE(compare(ExpectedRgb, Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")), TestSuite::ComparisonStatusFlags{}); } +void CompareImageTest::imageToFileNonZeroDelta() { + if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || + _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) + CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); + + /* This will produce output if --verbose is specified */ + CORRADE_COMPARE_WITH(ActualRgb, + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), + (CompareImageToFile{*_importerManager, 40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(ActualRgb, Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); +} + void CompareImageTest::imageToFileError() { if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) @@ -1149,22 +1258,48 @@ void CompareImageTest::imageToFileExpectedIsCompressed() { CORRADE_VERIFY(!Utility::Directory::exists(filename)); } -void CompareImageTest::fileToImage() { +void CompareImageTest::fileToImageZeroDelta() { if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); CORRADE_COMPARE_WITH( - Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), ExpectedRgb, (CompareFileToImage{*_importerManager, 40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{&*_importerManager, 40.0f, 20.0f}; - CORRADE_COMPARE(compare(Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + CORRADE_COMPARE(compare(Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), ExpectedRgb), TestSuite::ComparisonStatusFlags{}); } +void CompareImageTest::fileToImageNonZeroDelta() { + if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || + _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) + CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); + + /* This will produce output if --verbose is specified */ + CORRADE_COMPARE_WITH( + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + ExpectedRgb, + (CompareFileToImage{*_importerManager, 40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{&*_importerManager, 40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageActual.tga"), + ExpectedRgb); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); +} + void CompareImageTest::fileToImageError() { if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) @@ -1247,15 +1382,35 @@ void CompareImageTest::fileToImageActualIsCompressed() { "Actual image a (.../CompareImageCompressed.dds) is compressed, comparison not possible.\n"); } -void CompareImageTest::pixelsToImage() { +void CompareImageTest::pixelsToImageZeroDelta() { /* Same as image(), but taking pixels instead */ - CORRADE_COMPARE_WITH(ActualRgb.pixels(), + CORRADE_COMPARE_WITH(ExpectedRgb.pixels(), ExpectedRgb, (CompareImage{40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{40.0f, 20.0f}; - CORRADE_COMPARE(compare(ActualRgb.pixels(), ExpectedRgb), TestSuite::ComparisonStatusFlags{}); + CORRADE_COMPARE(compare(ExpectedRgb.pixels(), ExpectedRgb), TestSuite::ComparisonStatusFlags{}); +} + +void CompareImageTest::pixelsToImageNonZeroDelta() { + /* Same as image(), but taking pixels instead */ + + CORRADE_COMPARE_WITH(ActualRgb.pixels(), + ExpectedRgb, (CompareImage{40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(ActualRgb.pixels(), ExpectedRgb); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); } void CompareImageTest::pixelsToImageError() { @@ -1276,23 +1431,48 @@ void CompareImageTest::pixelsToImageError() { CORRADE_COMPARE(out.str(), ImageCompareError); } -void CompareImageTest::pixelsToFile() { +void CompareImageTest::pixelsToFileZeroDelta() { /* Same as imageToFile(), but taking pixels instead */ if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); - CORRADE_COMPARE_WITH(ActualRgb.pixels(), + CORRADE_COMPARE_WITH(ExpectedRgb.pixels(), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), (CompareImageToFile{*_importerManager, 40.0f, 20.0f})); /* No diagnostic as there's no error */ TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; - CORRADE_COMPARE(compare(ActualRgb.pixels(), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")), + CORRADE_COMPARE(compare(ExpectedRgb.pixels(), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")), TestSuite::ComparisonStatusFlags{}); } +void CompareImageTest::pixelsToFileNonZeroDelta() { + /* Same as imageToFile(), but taking pixels instead */ + + if(_importerManager->loadState("AnyImageImporter") == PluginManager::LoadState::NotFound || + _importerManager->loadState("TgaImporter") == PluginManager::LoadState::NotFound) + CORRADE_SKIP("AnyImageImporter or TgaImporter plugins not found."); + + CORRADE_COMPARE_WITH(ActualRgb.pixels(), + Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga"), + (CompareImageToFile{*_importerManager, 40.0f, 20.0f})); + + std::ostringstream out; + + { + TestSuite::Comparator compare{&*_importerManager, nullptr, 40.0f, 20.0f}; + TestSuite::ComparisonStatusFlags flags = compare(ActualRgb.pixels(), Utility::Directory::join(DEBUGTOOLS_TEST_DIR, "CompareImageExpected.tga")); + /* No diagnostic as there's no error */ + CORRADE_COMPARE(flags, TestSuite::ComparisonStatusFlag::Verbose); + Debug d{&out, Debug::Flag::DisableColors}; + compare.printMessage(flags, d, "a", "b"); + } + + CORRADE_COMPARE(out.str(), ImageCompareVerbose); +} + void CompareImageTest::pixelsToFileError() { /* Same as imageToFileError(), but taking pixels instead */