co-maps/libs/coding/coding_tests/xml_parser_tests.cpp
2025-11-22 13:58:55 +01:00

119 lines
3 KiB
C++

#include "testing/testing.hpp"
#include "coding/parse_xml.hpp"
#include "coding/reader.hpp"
#include <string>
#include <vector>
namespace
{
std::string const smokeXml = R"(
<root>
</root>
)";
std::string const longXml = R"(
<root>
<ruler>
<portrait>
<anchor vertical="bottom" horizontal="left"/>
<offset x="10"/>
</portrait>
</ruler>
<compass>
<portrait>
<anchor vertical="center"/>
<relative vertical="top"/>
</portrait>
<landscape>
<relative vertical="top"/>
<offset x="34" y="48"/>
</landscape>
</compass>
</root>
)";
class SmokeDispatcher
{
public:
void CharData(std::string const &) {}
void AddAttr(char const *, char const *) {}
bool Push(std::string_view push)
{
TEST_EQUAL(push, "root", ());
return true;
}
void Pop(std::string_view pop) { TEST_EQUAL(pop, "root", ()); }
};
class Dispatcher
{
public:
using PairsOfStrings = std::vector<std::pair<std::string, std::string>>;
using Strings = std::vector<std::string>;
void CharData(std::string const & ch) {}
void AddAttr(std::string key, std::string value) { m_addAttrs.emplace_back(std::move(key), std::move(value)); }
bool Push(std::string push)
{
m_pushes.emplace_back(std::move(push));
return true;
}
void Pop(std::string pop) { m_pops.emplace_back(std::move(pop)); }
void TestAddAttrs(PairsOfStrings const & addAttrs) { TestEquality(m_addAttrs, addAttrs); }
void TestPushes(Strings const & pushes) { TestEquality(m_pushes, pushes); }
void TestPops(Strings const & pops) { TestEquality(m_pops, pops); }
private:
template <typename F>
void TestEquality(F const & f1, F const & f2)
{
TEST_EQUAL(f1.size(), f2.size(), ());
for (size_t i = 0; i < f1.size(); ++i)
TEST_EQUAL(f1[i], f2[i], (i));
}
PairsOfStrings m_addAttrs;
Strings m_pushes;
Strings m_pops;
};
template <typename D>
void TestXML(std::string const & xmlStr, D & dispatcher)
{
std::vector<uint8_t> xml(xmlStr.cbegin(), xmlStr.cend());
MemReader reader(xml.data(), xml.size());
ReaderSource<MemReader> source(reader);
ParseXML(source, dispatcher);
}
UNIT_TEST(XmlParser_SmokeTest)
{
Dispatcher d;
TestXML(smokeXml, d);
d.TestAddAttrs({});
d.TestPushes({"root"});
d.TestPops({"root"});
}
UNIT_TEST(XmlParser_LongTest)
{
Dispatcher d;
TestXML(longXml, d);
d.TestAddAttrs({std::make_pair("vertical", "bottom"), std::make_pair("horizontal", "left"), std::make_pair("x", "10"),
std::make_pair("vertical", "center"), std::make_pair("vertical", "top"),
std::make_pair("vertical", "top"), std::make_pair("x", "34"), std::make_pair("y", "48")});
d.TestPushes({"root", "ruler", "portrait", "anchor", "offset", "compass", "portrait", "anchor", "relative",
"landscape", "relative", "offset"});
d.TestPops({"anchor", "offset", "portrait", "ruler", "anchor", "relative", "portrait", "relative", "offset",
"landscape", "compass", "root"});
}
} // namespace