2024-10-06 18:56:10 +00:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
#include <larra/jid.hpp>
|
2024-10-06 18:56:10 +00:00
|
|
|
#include <larra/serialization.hpp>
|
2024-10-18 15:03:19 +00:00
|
|
|
#include <larra/serialization/auto.hpp>
|
|
|
|
#include <larra/serialization/error.hpp>
|
2024-10-06 18:56:10 +00:00
|
|
|
#include <larra/stream_error.hpp>
|
2024-11-18 23:04:57 +00:00
|
|
|
#include <variant>
|
|
|
|
|
|
|
|
#include "utempl/utils.hpp"
|
2024-10-06 18:56:10 +00:00
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
using namespace std::literals;
|
|
|
|
|
2024-10-06 18:56:10 +00:00
|
|
|
namespace larra::xmpp {
|
|
|
|
|
|
|
|
TEST(Parse, Variant) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("stream:error");
|
|
|
|
node->add_child_element("unsupported-stanza-type");
|
|
|
|
node->set_namespace_declaration("urn:ietf:params:xml:ns:xmpp-streams");
|
|
|
|
auto streamError = Serialization<StreamError>::Parse(node);
|
|
|
|
EXPECT_TRUE(std::get_if<error::stream::UnsupportedStanzaType>(&streamError));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Serialize, Variant) {
|
|
|
|
using S = Serialization<StreamError>;
|
|
|
|
StreamError data = error::stream::UnsupportedStanzaType{};
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("stream:error");
|
|
|
|
S::Serialize(node, data);
|
|
|
|
EXPECT_EQ(doc.write_to_string(),
|
2024-10-18 15:03:19 +00:00
|
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<stream:error><unsupported-stanza-type "
|
|
|
|
"xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/></stream:error>\n"sv);
|
|
|
|
}
|
|
|
|
|
2024-11-18 23:04:57 +00:00
|
|
|
TEST(CheckFinalErrorPlace, Variant) {
|
|
|
|
StreamError stream_error = error::stream::UnknownXmppError{};
|
|
|
|
EXPECT_NO_THROW(std::get<std::variant_size_v<StreamError> - 1>(stream_error))
|
|
|
|
<< "'UnknownXmppError' must be at the end of 'StreamError' variant";
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
namespace tests::serialization {
|
|
|
|
|
|
|
|
struct SomeStruct {
|
|
|
|
static constexpr auto kDefaultName = "some";
|
|
|
|
std::string value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct;
|
|
|
|
friend auto operator<<(xmlpp::Element* element, const SomeStruct& self);
|
2024-11-10 14:56:41 +00:00
|
|
|
constexpr auto operator==(const SomeStruct&) const -> bool = default;
|
2024-10-18 15:03:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SomeStruct2 {
|
|
|
|
static constexpr auto kDefaultName = "some2";
|
|
|
|
SomeStruct value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct2;
|
|
|
|
friend auto operator<<(xmlpp::Element* element, const SomeStruct2& self);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SomeStruct3 {
|
|
|
|
static constexpr auto kDefaultName = "some3";
|
|
|
|
int value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct3;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SomeStruct4 {
|
|
|
|
static constexpr auto kDefaultName = "some4";
|
|
|
|
SomeStruct3 value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct4;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SomeStruct5 {
|
|
|
|
static constexpr auto kDefaultName = "some5";
|
|
|
|
BareJid value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct5;
|
|
|
|
friend auto operator<<(xmlpp::Element* element, const SomeStruct5& self);
|
|
|
|
};
|
|
|
|
|
2024-11-10 14:56:41 +00:00
|
|
|
struct SomeStruct6 {
|
|
|
|
static constexpr auto kDefaultName = "some6";
|
|
|
|
std::vector<SomeStruct> some;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct6;
|
|
|
|
};
|
|
|
|
|
2024-11-12 14:36:18 +00:00
|
|
|
struct SomeStruct7 {
|
|
|
|
static constexpr auto kDefaultName = "some7";
|
|
|
|
std::optional<FullJid> value;
|
|
|
|
[[nodiscard]] static auto Parse(xmlpp::Element* element) -> SomeStruct7;
|
|
|
|
};
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
} // namespace tests::serialization
|
|
|
|
|
|
|
|
namespace serialization {
|
|
|
|
|
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct> = SerializationConfig<tests::serialization::SomeStruct>{};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct2> = SerializationConfig<tests::serialization::SomeStruct2>{};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct4> = SerializationConfig<tests::serialization::SomeStruct4>{};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct5> = SerializationConfig<tests::serialization::SomeStruct5>{};
|
|
|
|
|
2024-11-10 14:56:41 +00:00
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct6> =
|
|
|
|
SerializationConfig<tests::serialization::SomeStruct6>{}.With<"some">({Config<std::vector<tests::serialization::SomeStruct>>{}});
|
2024-11-12 14:36:18 +00:00
|
|
|
|
|
|
|
template <>
|
|
|
|
constexpr auto kSerializationConfig<tests::serialization::SomeStruct7> = SerializationConfig<tests::serialization::SomeStruct7>{};
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
} // namespace serialization
|
|
|
|
|
|
|
|
namespace tests::serialization {
|
|
|
|
|
|
|
|
auto SomeStruct::Parse(xmlpp::Element* element) -> SomeStruct {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct>(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto SomeStruct2::Parse(xmlpp::Element* element) -> SomeStruct2 {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct2>(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto SomeStruct3::Parse(xmlpp::Element*) -> SomeStruct3 {
|
|
|
|
return {.value = 42}; // NOLINT
|
|
|
|
}
|
|
|
|
|
|
|
|
auto SomeStruct4::Parse(xmlpp::Element* element) -> SomeStruct4 {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct4>(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto SomeStruct5::Parse(xmlpp::Element* element) -> SomeStruct5 {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct5>(element);
|
|
|
|
}
|
|
|
|
|
2024-11-10 14:56:41 +00:00
|
|
|
auto SomeStruct6::Parse(xmlpp::Element* element) -> SomeStruct6 {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct6>(element);
|
|
|
|
}
|
|
|
|
|
2024-11-12 14:36:18 +00:00
|
|
|
auto SomeStruct7::Parse(xmlpp::Element* element) -> SomeStruct7 {
|
|
|
|
return ::larra::xmpp::serialization::Parse<tests::serialization::SomeStruct7>(element);
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
auto operator<<(xmlpp::Element* element, const SomeStruct& self) {
|
|
|
|
::larra::xmpp::serialization::Serialize(element, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto operator<<(xmlpp::Element* element, const SomeStruct2& self) {
|
|
|
|
::larra::xmpp::serialization::Serialize(element, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto operator<<(xmlpp::Element* element, const SomeStruct5& self) {
|
|
|
|
::larra::xmpp::serialization::Serialize(element, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace tests::serialization
|
|
|
|
|
|
|
|
TEST(AutoParse, Basic) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some2");
|
|
|
|
node = node->add_child_element("some");
|
|
|
|
node->set_attribute("value", "Hello");
|
|
|
|
auto a = Serialization<tests::serialization::SomeStruct>::Parse(node);
|
|
|
|
EXPECT_EQ(a.value, "Hello"sv);
|
|
|
|
auto b = Serialization<tests::serialization::SomeStruct2>::Parse(doc.get_root_node());
|
|
|
|
EXPECT_EQ(b.value.value, "Hello"sv);
|
|
|
|
EXPECT_THROW(std::ignore = tests::serialization::SomeStruct2::Parse(node), serialization::ParsingError);
|
|
|
|
auto node2 = node->add_child_element("some4");
|
|
|
|
node2->add_child_element("some3");
|
|
|
|
auto c = Serialization<tests::serialization::SomeStruct4>::Parse(node2);
|
|
|
|
EXPECT_EQ(c.value.value, 42);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(AutoParse, Attribute) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some5");
|
|
|
|
node->set_attribute("value", "user@server.i2p");
|
|
|
|
auto a = Serialization<tests::serialization::SomeStruct5>::Parse(node);
|
|
|
|
EXPECT_EQ(a.value.server, "server.i2p"sv);
|
|
|
|
EXPECT_EQ(a.value.username, "user"sv);
|
|
|
|
}
|
|
|
|
|
2024-11-10 14:56:41 +00:00
|
|
|
TEST(AutoParse, Vector) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some6");
|
|
|
|
for(auto i : std::views::iota(0, 10)) {
|
|
|
|
auto child = node->add_child_element("some");
|
|
|
|
child->set_attribute("value", std::format("Hello {}", i));
|
|
|
|
}
|
|
|
|
auto value = Serialization<tests::serialization::SomeStruct6>::Parse(node);
|
|
|
|
EXPECT_EQ(value.some, std::views::iota(0, 10) | std::views::transform([](auto i) -> tests::serialization::SomeStruct {
|
|
|
|
return {.value = std::format("Hello {}", i)};
|
|
|
|
}) | std::ranges::to<std::vector<tests::serialization::SomeStruct>>());
|
|
|
|
}
|
|
|
|
|
2024-11-12 14:36:18 +00:00
|
|
|
TEST(AutoParse, Optional) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some7");
|
|
|
|
auto value = Serialization<tests::serialization::SomeStruct7>::Parse(node).value;
|
|
|
|
EXPECT_EQ(value, std::nullopt);
|
|
|
|
node->set_attribute("value", "user@server.i2p/resource");
|
|
|
|
auto value2 = Serialization<tests::serialization::SomeStruct7>::Parse(node).value;
|
|
|
|
FullJid expectData{.username = "user", .server = "server.i2p", .resource = "resource"};
|
|
|
|
EXPECT_EQ(value2, expectData);
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:03:19 +00:00
|
|
|
TEST(AutoSerialize, Basic) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some2");
|
|
|
|
node << tests::serialization::SomeStruct2{.value = {.value = "testData"}};
|
|
|
|
EXPECT_EQ(doc.write_to_string(), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<some2><some value=\"testData\"/></some2>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(AutoSerialize, Attribute) {
|
|
|
|
xmlpp::Document doc;
|
|
|
|
auto node = doc.create_root_node("some5");
|
|
|
|
node << tests::serialization::SomeStruct5{.value = {.username = "user", .server = "server.i2p"}};
|
|
|
|
EXPECT_EQ(doc.write_to_string(), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<some5 value=\"user@server.i2p\"/>\n");
|
2024-10-06 18:56:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace larra::xmpp
|