#include #include #include "../src/qpdf/qpdf_extractor.hpp" #include #include using namespace pdfengine; using namespace pdfengine::qpdf_layer; #ifndef TEST_CORPUS_DIR #define TEST_CORPUS_DIR "../../corpus" #endif namespace { std::filesystem::path getCorpusPath(const std::string& subfolder, const std::string& filename) { return std::filesystem::path(TEST_CORPUS_DIR) / subfolder / filename; } std::vector readFile(const std::filesystem::path& path) { std::ifstream file(path, std::ios::binary | std::ios::ate); if (!file.is_open()) return {}; std::streamsize size = file.tellg(); file.seekg(0, std::ios::beg); std::vector buffer(size); if (file.read(reinterpret_cast(buffer.data()), size)) { return buffer; } return {}; } } class QpdfExtractorTest : public ::testing::Test { protected: QpdfExtractor extractor; }; TEST_F(QpdfExtractorTest, ExtractFromMemory) { auto path = getCorpusPath("basic", "hello_world.pdf"); auto stream = extractor.extractPageStream(path.string(), 0); ASSERT_TRUE(stream.has_value()); EXPECT_EQ(stream->pageIndex, 0); EXPECT_FALSE(stream->compressed); // Or true depending on qpdf, but we only verify success here StreamVerification v = verifyContentStream(stream.value()); EXPECT_TRUE(v.hasBT); EXPECT_TRUE(v.hasET); EXPECT_TRUE(v.hasTf); EXPECT_TRUE(v.hasTj); } TEST_F(QpdfExtractorTest, PageOutOfBounds) { auto path = getCorpusPath("basic", "hello_world.pdf"); auto data = readFile(path); ASSERT_FALSE(data.empty()); auto stream = extractor.extractPageStreamFromMemory(data, 1); ASSERT_FALSE(stream.has_value()); EXPECT_EQ(stream.error(), QpdfError::PageOutOfBounds); stream = extractor.extractPageStreamFromMemory(data, -1); ASSERT_FALSE(stream.has_value()); EXPECT_EQ(stream.error(), QpdfError::PageOutOfBounds); } TEST_F(QpdfExtractorTest, CorruptPdf) { std::vector data = {0x00, 0x01, 0x02}; auto stream = extractor.extractPageStreamFromMemory(data, 0); ASSERT_FALSE(stream.has_value()); EXPECT_EQ(stream.error(), QpdfError::InvalidFormat); } TEST_F(QpdfExtractorTest, EmptyContents) { // about_blank.pdf usually has an empty page or no text auto path = getCorpusPath("basic", "about_blank.pdf"); auto stream = extractor.extractPageStream(path.string(), 0); ASSERT_TRUE(stream.has_value()); EXPECT_EQ(stream->pageIndex, 0); StreamVerification v = verifyContentStream(stream.value()); EXPECT_FALSE(v.hasTj); } TEST_F(QpdfExtractorTest, VerifyNoText) { // black.pdf or rectangles.pdf has no text, just graphics auto path = getCorpusPath("basic", "black.pdf"); auto stream = extractor.extractPageStream(path.string(), 0); ASSERT_TRUE(stream.has_value()); StreamVerification v = verifyContentStream(stream.value()); EXPECT_FALSE(v.hasBT); EXPECT_FALSE(v.hasET); EXPECT_FALSE(v.hasTf); EXPECT_FALSE(v.hasTj); }