Add tests for expected error messages

This commit is contained in:
Chris Thrasher 2024-06-12 13:02:49 -05:00
parent 51b8b44e14
commit 206dcfb234
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C
3 changed files with 74 additions and 15 deletions

View File

@ -4,6 +4,7 @@
#include <SFML/System/FileInputStream.hpp> #include <SFML/System/FileInputStream.hpp>
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>
#include <GraphicsUtil.hpp> #include <GraphicsUtil.hpp>
#include <array> #include <array>
@ -78,12 +79,21 @@ TEST_CASE("[Graphics] sf::Image")
} }
} }
ErrReader errReader;
SECTION("loadFromFile()") SECTION("loadFromFile()")
{ {
SECTION("Invalid file") SECTION("Invalid path")
{ {
CHECK(!sf::Image::loadFromFile(".")); CHECK(!sf::Image::loadFromFile("."));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to load image"));
}
SECTION("Nonexistent file")
{
CHECK(!sf::Image::loadFromFile("this/does/not/exist.jpg")); CHECK(!sf::Image::loadFromFile("this/does/not/exist.jpg"));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to load image"));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("this/does/not/exist.jpg"));
} }
SECTION("Successful load") SECTION("Successful load")
@ -132,6 +142,7 @@ TEST_CASE("[Graphics] sf::Image")
CHECK(image->getSize() == sf::Vector2u(1001, 304)); CHECK(image->getSize() == sf::Vector2u(1001, 304));
CHECK(image->getPixelsPtr() != nullptr); CHECK(image->getPixelsPtr() != nullptr);
CHECK(errReader.get().empty());
} }
} }
@ -140,12 +151,14 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("Invalid pointer") SECTION("Invalid pointer")
{ {
CHECK(!sf::Image::loadFromMemory(nullptr, 1)); CHECK(!sf::Image::loadFromMemory(nullptr, 1));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to load image from memory, no data provided"));
} }
SECTION("Invalid size") SECTION("Invalid size")
{ {
const std::byte testByte{0xAB}; const std::byte testByte{0xAB};
CHECK(!sf::Image::loadFromMemory(&testByte, 0)); CHECK(!sf::Image::loadFromMemory(&testByte, 0));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to load image from memory, no data provided"));
} }
SECTION("Failed load") SECTION("Failed load")
@ -154,15 +167,19 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("Empty") SECTION("Empty")
{ {
memory.clear(); CHECK(!sf::Image::loadFromMemory(memory.data(), memory.size()));
CHECK_THAT(errReader.get(),
Catch::Matchers::StartsWith("Failed to load image from memory, no data provided"));
} }
SECTION("Junk data") SECTION("Junk data")
{ {
memory = {1, 2, 3, 4}; memory = {1, 2, 3, 4};
CHECK(!sf::Image::loadFromMemory(memory.data(), memory.size()));
CHECK_THAT(errReader.get(),
Catch::Matchers::StartsWith("Failed to load image from memory. Reason: Image not of any "
"known type, or corrupt"));
} }
CHECK(!sf::Image::loadFromMemory(memory.data(), memory.size()));
} }
SECTION("Successful load") SECTION("Successful load")
@ -173,6 +190,7 @@ TEST_CASE("[Graphics] sf::Image")
CHECK(image.getPixelsPtr() != nullptr); CHECK(image.getPixelsPtr() != nullptr);
CHECK(image.getPixel({0, 0}) == sf::Color::Green); CHECK(image.getPixel({0, 0}) == sf::Color::Green);
CHECK(image.getPixel({23, 23}) == sf::Color::Green); CHECK(image.getPixel({23, 23}) == sf::Color::Green);
CHECK(errReader.get().empty());
} }
} }
@ -184,6 +202,7 @@ TEST_CASE("[Graphics] sf::Image")
CHECK(image.getPixelsPtr() != nullptr); CHECK(image.getPixelsPtr() != nullptr);
CHECK(image.getPixel({0, 0}) == sf::Color(255, 255, 255, 0)); CHECK(image.getPixel({0, 0}) == sf::Color(255, 255, 255, 0));
CHECK(image.getPixel({200, 150}) == sf::Color(144, 208, 62)); CHECK(image.getPixel({200, 150}) == sf::Color(144, 208, 62));
CHECK(errReader.get().empty());
} }
SECTION("saveToFile()") SECTION("saveToFile()")
@ -191,6 +210,9 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("Invalid size") SECTION("Invalid size")
{ {
CHECK(!sf::Image({10, 0}, sf::Color::Magenta).saveToFile("test.jpg")); CHECK(!sf::Image({10, 0}, sf::Color::Magenta).saveToFile("test.jpg"));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to save image"));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("test.jpg"));
CHECK(!sf::Image({0, 10}, sf::Color::Magenta).saveToFile("test.jpg")); CHECK(!sf::Image({0, 10}, sf::Color::Magenta).saveToFile("test.jpg"));
} }
@ -199,12 +221,19 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("No extension") SECTION("No extension")
{ {
CHECK(!image.saveToFile("wheresmyextension")); CHECK(!image.saveToFile("wheresmyextension"));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Image file extension \"\" not supported"));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("wheresmyextension"));
CHECK(!image.saveToFile("pls/add/extension")); CHECK(!image.saveToFile("pls/add/extension"));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("pls/add/extension"));
} }
SECTION("Invalid extension") SECTION("Invalid extension")
{ {
CHECK(!image.saveToFile("test.ps")); CHECK(!image.saveToFile("test.ps"));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Image file extension \".ps\" not supported"));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("test.ps"));
CHECK(!image.saveToFile("test.foo")); CHECK(!image.saveToFile("test.foo"));
} }
@ -235,6 +264,7 @@ TEST_CASE("[Graphics] sf::Image")
const auto loadedImage = sf::Image::loadFromFile(filename).value(); const auto loadedImage = sf::Image::loadFromFile(filename).value();
CHECK(loadedImage.getSize() == sf::Vector2u(256, 256)); CHECK(loadedImage.getSize() == sf::Vector2u(256, 256));
CHECK(loadedImage.getPixelsPtr() != nullptr); CHECK(loadedImage.getPixelsPtr() != nullptr);
CHECK(errReader.get().empty());
CHECK(std::filesystem::remove(filename)); CHECK(std::filesystem::remove(filename));
} }
@ -245,6 +275,9 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("Invalid size") SECTION("Invalid size")
{ {
CHECK(!sf::Image({10, 0}, sf::Color::Magenta).saveToMemory("test.jpg")); CHECK(!sf::Image({10, 0}, sf::Color::Magenta).saveToMemory("test.jpg"));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to save image with format \"test.jpg\""));
CHECK_THAT(errReader.get(), Catch::Matchers::ContainsSubstring("test.jpg"));
CHECK(!sf::Image({0, 10}, sf::Color::Magenta).saveToMemory("test.jpg")); CHECK(!sf::Image({0, 10}, sf::Color::Magenta).saveToMemory("test.jpg"));
} }
@ -253,24 +286,23 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("No extension") SECTION("No extension")
{ {
CHECK(!image.saveToMemory("")); CHECK(!image.saveToMemory(""));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to save image with format \"\""));
} }
SECTION("Invalid extension") SECTION("Invalid extension")
{ {
CHECK(!image.saveToMemory(".")); CHECK(!image.saveToMemory("."));
CHECK_THAT(errReader.get(), Catch::Matchers::StartsWith("Failed to save image with format \".\""));
CHECK(!image.saveToMemory("gif")); CHECK(!image.saveToMemory("gif"));
CHECK(!image.saveToMemory(".jpg")); // Supposed to be "jpg" CHECK(!image.saveToMemory(".jpg")); // Supposed to be "jpg"
} }
SECTION("Successful save") SECTION("Successful save")
{ {
std::optional<std::vector<std::uint8_t>> maybeOutput;
SECTION("To bmp") SECTION("To bmp")
{ {
maybeOutput = image.saveToMemory("bmp"); const auto output = image.saveToMemory("bmp").value();
REQUIRE(maybeOutput.has_value());
const auto& output = *maybeOutput;
REQUIRE(output.size() == 1146); REQUIRE(output.size() == 1146);
CHECK(output[0] == 66); CHECK(output[0] == 66);
CHECK(output[1] == 77); CHECK(output[1] == 77);
@ -284,9 +316,7 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("To tga") SECTION("To tga")
{ {
maybeOutput = image.saveToMemory("tga"); const auto output = image.saveToMemory("tga").value();
REQUIRE(maybeOutput.has_value());
const auto& output = *maybeOutput;
REQUIRE(output.size() == 98); REQUIRE(output.size() == 98);
CHECK(output[0] == 0); CHECK(output[0] == 0);
CHECK(output[1] == 0); CHECK(output[1] == 0);
@ -296,9 +326,7 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("To png") SECTION("To png")
{ {
maybeOutput = image.saveToMemory("png"); const auto output = image.saveToMemory("png").value();
REQUIRE(maybeOutput.has_value());
const auto& output = *maybeOutput;
REQUIRE(output.size() == 92); REQUIRE(output.size() == 92);
CHECK(output[0] == 137); CHECK(output[0] == 137);
CHECK(output[1] == 80); CHECK(output[1] == 80);
@ -306,6 +334,8 @@ TEST_CASE("[Graphics] sf::Image")
CHECK(output[3] == 71); CHECK(output[3] == 71);
} }
CHECK(errReader.get().empty());
// Cannot test JPEG encoding due to it triggering UB in stbiw__jpg_writeBits // Cannot test JPEG encoding due to it triggering UB in stbiw__jpg_writeBits
} }
} }

View File

@ -1,4 +1,5 @@
#include <SFML/System/Angle.hpp> #include <SFML/System/Angle.hpp>
#include <SFML/System/Err.hpp>
#include <SFML/System/String.hpp> #include <SFML/System/String.hpp>
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
@ -92,3 +93,18 @@ std::vector<std::byte> loadIntoMemory(const std::filesystem::path& path)
assert(result); assert(result);
return buffer; return buffer;
} }
ErrReader::ErrReader() : m_stringBuffer(sf::err().rdbuf())
{
sf::err().rdbuf(m_stream.rdbuf());
}
ErrReader::~ErrReader()
{
sf::err().rdbuf(m_stringBuffer);
}
std::string ErrReader::get()
{
return m_stream.str();
}

View File

@ -7,6 +7,7 @@
#include <filesystem> #include <filesystem>
#include <iosfwd> #include <iosfwd>
#include <sstream>
#include <vector> #include <vector>
#include <cstddef> #include <cstddef>
@ -64,3 +65,15 @@ std::ostream& operator<<(std::ostream& os, const Approx<T>& approx)
} }
[[nodiscard]] std::vector<std::byte> loadIntoMemory(const std::filesystem::path& path); [[nodiscard]] std::vector<std::byte> loadIntoMemory(const std::filesystem::path& path);
class ErrReader
{
public:
ErrReader();
~ErrReader();
std::string get();
private:
std::streambuf* m_stringBuffer;
std::stringstream m_stream;
};