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