#include #include #include #include #include #include "Test/Test.h" #include "Support/JSON.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" namespace { struct ValueRef { std::size_t index; }; } // namespace template <> struct clice::json::Serde { constexpr inline static bool stateful = true; std::vector& encoder; std::vector& decoder; json::Value serialize(const ValueRef& ref) { return json::Value(decoder[ref.index]); } ValueRef deserialize(const json::Value& value) { encoder.emplace_back(*value.getAsInteger()); return ValueRef{encoder.size() - 1}; } }; namespace clice::testing { namespace { TEST_SUITE(JSON) { TEST_CASE(String) { json::Value expected = "hello"; std::string input = "hello"; ASSERT_EQ(json::serialize(input), expected); ASSERT_EQ(json::deserialize(expected), input); std::string_view input2 = "hello"; ASSERT_EQ(json::serialize(input2), expected); ASSERT_EQ(json::deserialize(expected), input2); llvm::StringRef input3 = "hello"; ASSERT_EQ(json::serialize(input3), expected); ASSERT_EQ(json::deserialize(expected), input3); llvm::SmallString<5> input4 = {"hello"}; ASSERT_EQ(json::serialize(input4), expected); ASSERT_EQ(json::deserialize>(expected), input4); } TEST_CASE(MapRange) { json::Value expected = json::Object{ {"1", 2}, {"3", 4}, {"5", 6} }; std::map input = { {1, 2}, {3, 4}, {5, 6} }; ASSERT_EQ(json::serialize(input), expected); ASSERT_EQ(json::deserialize(expected), input); std::unordered_map input2 = { {1, 2}, {3, 4}, {5, 6} }; ASSERT_EQ(json::serialize(input2), expected); ASSERT_EQ(json::deserialize(expected), input2); llvm::DenseMap input4 = { {1, 2}, {3, 4}, {5, 6} }; ASSERT_EQ(json::serialize(input4), expected); ASSERT_EQ(json::deserialize(expected), input4); } TEST_CASE(SetRange) { json::Value expected = {1, 2, 3, 4, 5}; std::set input = {1, 2, 3, 4, 5}; ASSERT_EQ(json::deserialize(expected), input); std::unordered_set input2 = {1, 2, 3, 4, 5}; ASSERT_EQ(json::deserialize(expected), input2); } TEST_CASE(SequenceRange) { json::Value expected = {1, 2, 3, 4, 5}; std::vector input = {1, 2, 3, 4, 5}; ASSERT_EQ(json::serialize(input), expected); ASSERT_EQ(json::deserialize>(expected), input); llvm::ArrayRef input2 = input; ASSERT_EQ(json::serialize(input2), expected); llvm::SmallVector input3 = {1, 2, 3, 4, 5}; ASSERT_EQ(json::serialize(input3), expected); ASSERT_EQ((json::deserialize>(expected)), input3); } TEST_CASE(Enum) { enum class E { A, B, C }; json::Value expected = json::Value(1); E input = E::B; ASSERT_EQ(json::serialize(input), expected); ASSERT_EQ(json::deserialize(expected), input); struct Color : refl::Enum { enum Kind { Red = 0, Green, Blue, Yellow, }; using Enum::Enum; }; json::Value expected2 = json::Value(2); Color input2 = Color::Blue; ASSERT_EQ(json::serialize(input2), expected2); ASSERT_EQ(json::deserialize(expected2), input2); } TEST_CASE(Struct) { struct A { int x; int y; bool operator==(const A& other) const = default; }; json::Value expected = json::Object{ {"x", 1}, {"y", 2} }; A input = {1, 2}; ASSERT_EQ(json::serialize(input), expected); ASSERT_EQ(json::deserialize(expected), input); struct B { A a; std::string s; bool operator==(const B& other) const = default; }; json::Value expected2 = json::Object{ {"a", json::Object{{"x", 1}, {"y", 2}}}, {"s", "hello" } }; B input2 = { {1, 2}, "hello", }; ASSERT_EQ(json::serialize(input2), expected2); ASSERT_EQ(json::deserialize(expected2), input2); } }; // TEST_SUITE(JSON) } // namespace } // namespace clice::testing