#include "sax_decoder.hh" #include "sax_decoder_factory.hh" #include "sax_processor.hh" #include "sax_delegate.hh" #include #include namespace { class TestDelegate : public modxml::sax::Delegate { public: ~TestDelegate() override = default; void empty_element(std::string_view name, modxml::sax::Attributes const&) override { EXPECT_EQ(name, "root"); if (name == "root") { EXPECT_FALSE(have_root_); have_root_ = true; } } void error(std::string_view message) override { have_error_ = true; FAIL() << message; } bool have_root() const { return have_root_; } bool have_error() const { return have_error_; } private: bool have_root_{false}; bool have_error_{false}; }; bool process_all(modxml::sax::Processor& processor, TestDelegate& delegate, std::span data) { std::size_t offset = 0; while (offset < data.size()) { auto consumed = processor.process(data, offset); if (consumed == 0 || delegate.have_error()) return false; offset += consumed; } return true; } } // namespace TEST(sax, decoder_utf8) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::string input = R"()"; EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(reinterpret_cast(input.data()), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf8_bom) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::string input = "\xef\xbb\xbf" R"()"; EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(reinterpret_cast(input.data()), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf16) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u16string input = uR"()"; EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(reinterpret_cast(input.data()), input.size() * sizeof(char16_t)))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf16be) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u16string str = uR"()"; std::vector input; for (char16_t c : str) { input.push_back(c >> 8); input.push_back(c & 0xff); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf16le) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u16string str = uR"()"; std::vector input; for (char16_t c : str) { input.push_back(c & 0xff); input.push_back(c >> 8); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf16be_bom) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u16string str = u"\ufeff" uR"()"; std::vector input; for (char16_t c : str) { input.push_back(c >> 8); input.push_back(c & 0xff); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf16le_bom) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u16string str = u"\ufeff" uR"()"; std::vector input; for (char16_t c : str) { input.push_back(c & 0xff); input.push_back(c >> 8); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf32) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u32string input = UR"()"; EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(reinterpret_cast(input.data()), input.size() * sizeof(char32_t)))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf32be) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u32string str = UR"()"; std::vector input; for (char32_t c : str) { input.push_back(c >> 24); input.push_back((c >> 16) & 0xff); input.push_back((c >> 8) & 0xff); input.push_back(c & 0xff); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf32le) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u32string str = UR"()"; std::vector input; for (char32_t c : str) { input.push_back(c & 0xff); input.push_back((c >> 8) & 0xff); input.push_back((c >> 16) & 0xff); input.push_back(c >> 24); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf32be_bom) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u32string str = U"\ufeff" UR"()"; std::vector input; for (char32_t c : str) { input.push_back(c >> 24); input.push_back((c >> 16) & 0xff); input.push_back((c >> 8) & 0xff); input.push_back(c & 0xff); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); } TEST(sax, decoder_utf32le_bom) { auto delegate = std::make_shared(); auto processor = modxml::sax::Processor::create(delegate); std::u32string str = U"\ufeff" R"()"; std::vector input; for (char32_t c : str) { input.push_back(c & 0xff); input.push_back((c >> 8) & 0xff); input.push_back((c >> 16) & 0xff); input.push_back(c >> 24); } EXPECT_TRUE(process_all( *processor.get(), *delegate.get(), std::span(input.data(), input.size()))); EXPECT_TRUE(delegate->have_root()); }