diff options
Diffstat (limited to 'sax/tst/test_decoder.cc')
| -rw-r--r-- | sax/tst/test_decoder.cc | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/sax/tst/test_decoder.cc b/sax/tst/test_decoder.cc new file mode 100644 index 0000000..86f230b --- /dev/null +++ b/sax/tst/test_decoder.cc @@ -0,0 +1,242 @@ +#include "sax_decoder.hh" +#include "sax_decoder_factory.hh" +#include "sax_processor.hh" +#include "sax_delegate.hh" + +#include <memory> +#include <gtest/gtest.h> + +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<uint8_t const> 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<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::string input = R"(<?xml version="1.0" encoding="utf-8"?><root />)"; + std::cerr << input << std::endl; + EXPECT_TRUE(process_all( + *processor.get(), + *delegate.get(), + std::span<uint8_t const>(reinterpret_cast<uint8_t const*>(input.data()), + input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf8_bom) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::string input = + "\xef\xbb\xbf" R"(<?xml version="1.0" encoding="utf-8"?><root />)"; + std::cerr << input << std::endl; + EXPECT_TRUE(process_all( + *processor.get(), + *delegate.get(), + std::span<uint8_t const>(reinterpret_cast<uint8_t const*>(input.data()), + input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf16) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u16string input = uR"(<?xml version="1.0" encoding="utf-16"?><root />)"; + EXPECT_TRUE(process_all( + *processor.get(), + *delegate.get(), + std::span<uint8_t const>(reinterpret_cast<uint8_t const*>(input.data()), + input.size() * sizeof(char16_t)))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf16be) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u16string str = uR"(<?xml version="1.0" encoding="utf-16"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf16le) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u16string str = uR"(<?xml version="1.0" encoding="utf-16"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf16be_bom) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u16string str = + u"\ufffe" uR"(<?xml version="1.0" encoding="utf-16"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf16le_bom) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u16string str = + u"\ufffe" uR"(<?xml version="1.0" encoding="utf-16"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf32) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u32string input = UR"(<?xml version="1.0" encoding="utf-32"?><root />)"; + EXPECT_TRUE(process_all( + *processor.get(), + *delegate.get(), + std::span<uint8_t const>(reinterpret_cast<uint8_t const*>(input.data()), + input.size() * sizeof(char32_t)))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf32be) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u32string str = UR"(<?xml version="1.0" encoding="utf-32"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf32le) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u32string str = UR"(<?xml version="1.0" encoding="utf-32"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf32be_bom) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u32string str = + U"\ufffe" UR"(<?xml version="1.0" encoding="utf-32"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} + +TEST(sax, decoder_utf32le_bom) { + auto delegate = std::make_shared<TestDelegate>(); + auto processor = modxml::sax::Processor::create(delegate); + std::u32string str = + U"\ufffe" R"(<?xml version="1.0" encoding="utf-32"?><root />)"; + std::vector<uint8_t> 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<uint8_t const>(input.data(), input.size()))); + EXPECT_TRUE(delegate->have_root()); +} |
