1 #include "helpers.hpp"
2 #include "utils/labeled_tuple.hpp"
3 
4 #include <limits>
5 
6 #include <gmock/gmock.h>
7 
8 using namespace testing;
9 
10 struct TestingLabelDouble
11 {
12     static std::string str()
13     {
14         return "DoubleValue";
15     }
16 };
17 
18 struct TestingLabelString
19 {
20     static std::string str()
21     {
22         return "StringValue";
23     }
24 };
25 
26 using LabeledTestingTuple =
27     utils::LabeledTuple<std::tuple<double, std::string>, TestingLabelDouble,
28                         TestingLabelString>;
29 
30 class TestLabeledTupleDoubleSpecialization :
31     public Test,
32     public WithParamInterface<
33         std::tuple<double, std::variant<double, std::string>>>
34 {
35   public:
36     const std::string string_value = "Some value";
37 };
38 
39 TEST_P(TestLabeledTupleDoubleSpecialization,
40        serializeAndDeserializeMakesSameTuple)
41 {
42     auto [double_value, expected_serialized_value] = GetParam();
43     LabeledTestingTuple initial(double_value, string_value);
44     nlohmann::json serialized(initial);
45 
46     EXPECT_EQ(serialized["StringValue"], string_value);
47 
48     auto& actual_serialized_value = serialized["DoubleValue"];
49     if (std::holds_alternative<std::string>(expected_serialized_value))
50     {
51         EXPECT_TRUE(actual_serialized_value.is_string());
52         EXPECT_EQ(actual_serialized_value.get<std::string>(),
53                   std::get<std::string>(expected_serialized_value));
54     }
55     else
56     {
57         EXPECT_TRUE(actual_serialized_value.is_number());
58         EXPECT_EQ(actual_serialized_value.get<double>(),
59                   std::get<double>(expected_serialized_value));
60     }
61 
62     LabeledTestingTuple deserialized = serialized.get<LabeledTestingTuple>();
63     EXPECT_EQ(initial, deserialized);
64 }
65 
66 INSTANTIATE_TEST_SUITE_P(
67     _, TestLabeledTupleDoubleSpecialization,
68     Values(std::make_tuple(10.0, std::variant<double, std::string>(10.0)),
69            std::make_tuple(std::numeric_limits<double>::infinity(),
70                            std::variant<double, std::string>("inf")),
71            std::make_tuple(-std::numeric_limits<double>::infinity(),
72                            std::variant<double, std::string>("-inf")),
73            std::make_tuple(std::numeric_limits<double>::quiet_NaN(),
74                            std::variant<double, std::string>("NaN"))));
75 
76 TEST(TestLabeledTupleDoubleSpecializationNegative,
77      ThrowsWhenUnknownLiteralDuringDeserialization)
78 {
79     nlohmann::json data = nlohmann::json{{"DoubleValue", "FooBar"},
80                                          {"StringValue", "Some Text Val"}};
81 
82     EXPECT_THROW(data.get<LabeledTestingTuple>(), std::invalid_argument);
83 }
84