blob: 90415cb955a1cebacdcdcfb5b7b0e97d341520ef [file] [log] [blame]
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02001#include <boost/container/flat_map.hpp>
2#include <sdbusplus/unpack_properties.hpp>
3
4#include <gmock/gmock.h>
5
6namespace sdbusplus
7{
8
9using VariantType = std::variant<std::string, uint32_t, float, double>;
10using ContainerTypes =
11 testing::Types<std::vector<std::pair<std::string, VariantType>>,
12 boost::container::flat_map<std::string, VariantType>,
13 std::map<std::string, VariantType>>;
14
15template <typename Exception, typename F>
16std::optional<Exception> captureException(F&& code)
17{
18 try
19 {
20 code();
21 }
22 catch (const Exception& e)
23 {
24 return e;
25 }
26
27 return std::nullopt;
28}
29
30template <typename Container>
31struct UnpackPropertiesTest : public testing::Test
32{
33 void SetUp() override
34 {
35 using namespace std::string_literals;
36
37 data.insert(data.end(),
38 std::make_pair("Key-1"s, VariantType("string"s)));
39 data.insert(data.end(), std::make_pair("Key-2"s, VariantType(42.f)));
40 data.insert(data.end(), std::make_pair("Key-3"s, VariantType(15.)));
41 }
42
43 Container data;
44};
45
46TYPED_TEST_SUITE(UnpackPropertiesTest, ContainerTypes);
47
48TYPED_TEST(UnpackPropertiesTest, returnsValueWhenKeyIsPresentAndTypeMatches)
49{
50 using namespace testing;
51
52 std::string val1;
53 float val2 = 0.f;
54 double val3 = 0.;
55
56 unpackProperties(this->data, "Key-1", val1, "Key-2", val2, "Key-3", val3);
57
58 ASSERT_THAT(val1, Eq("string"));
59 ASSERT_THAT(val2, FloatEq(42.f));
60 ASSERT_THAT(val3, DoubleEq(15.));
61}
62
63TYPED_TEST(UnpackPropertiesTest,
64 unpackChangesOriginalDataWhenPassedAsNonConstReference)
65{
66 using namespace testing;
67
68 std::string val1, val2;
69
70 unpackProperties(this->data, "Key-1", val1);
71 unpackProperties(this->data, "Key-1", val2);
72
73 ASSERT_THAT(val1, Eq("string"));
74 ASSERT_THAT(val2, Not(Eq("string")));
75}
76
77TYPED_TEST(UnpackPropertiesTest,
78 unpackDoesntChangeOriginalDataWhenPassesAsConstReference)
79{
80 using namespace testing;
81
82 std::string val1, val2;
83
84 unpackProperties(Const(this->data), "Key-1", val1);
85 unpackProperties(Const(this->data), "Key-1", val2);
86
87 ASSERT_THAT(val1, Eq("string"));
88 ASSERT_THAT(val2, Eq("string"));
89}
90
91TYPED_TEST(UnpackPropertiesTest, throwsErrorWhenKeyIsMissing)
92{
93 using namespace testing;
94
95 std::string val1;
96 float val2 = 0.f;
97 double val3 = 0.;
98
99 auto error = captureException<exception::UnpackPropertyError>([&] {
100 unpackProperties(this->data, "Key-1", val1, "Key-4", val2, "Key-3",
101 val3);
102 });
103
104 ASSERT_TRUE(error);
105 ASSERT_THAT(error->reason,
106 Eq(exception::UnpackPropertyError::reasonMissingProperty));
107 ASSERT_THAT(error->propertyName, Eq("Key-4"));
108}
109
110TYPED_TEST(UnpackPropertiesTest, throwsErrorWhenTypeDoesntMatch)
111{
112 using namespace testing;
113
114 std::string val1;
115 std::string val2;
116 double val3 = 0.;
117
118 auto error = captureException<exception::UnpackPropertyError>([&] {
119 unpackProperties(this->data, "Key-1", val1, "Key-2", val2, "Key-3",
120 val3);
121 });
122
123 ASSERT_TRUE(error);
124 ASSERT_THAT(error->reason,
125 Eq(exception::UnpackPropertyError::reasonTypeNotMatched));
126 ASSERT_THAT(error->propertyName, Eq("Key-2"));
127}
128
129TYPED_TEST(UnpackPropertiesTest,
130 returnsUndefinedValueForDuplicatedKeysWhenDataIsNonConstReference)
131{
132 using namespace testing;
133 using namespace std::string_literals;
134
135 std::string val1;
136 float val2 = 0.f;
137 double val3 = 0.;
138 std::string val4;
139
140 unpackProperties(this->data, "Key-1", val1, "Key-2", val2, "Key-3", val3,
141 "Key-1", val4);
142
143 ASSERT_THAT(val1, Eq("string"));
144 ASSERT_THAT(val2, FloatEq(42.f));
145 ASSERT_THAT(val3, DoubleEq(15.));
146 ASSERT_THAT(val4, Not(Eq("string")));
147}
148
149TYPED_TEST(UnpackPropertiesTest,
150 returnsValueForDuplicatedKeysWhenDataIsConstReference)
151{
152 using namespace testing;
153 using namespace std::string_literals;
154
155 std::string val1;
156 float val2 = 0.f;
157 double val3 = 0.;
158 std::string val4;
159
160 unpackProperties(Const(this->data), "Key-1", val1, "Key-2", val2, "Key-3",
161 val3, "Key-1", val4);
162
163 ASSERT_THAT(val1, Eq("string"));
164 ASSERT_THAT(val2, FloatEq(42.f));
165 ASSERT_THAT(val3, DoubleEq(15.));
166 ASSERT_THAT(val4, Eq("string"));
167}
168
169struct UnpackPropertiesTest_ForVector :
170 public UnpackPropertiesTest<
171 std::vector<std::pair<std::string, VariantType>>>
172{};
173
174TEST_F(UnpackPropertiesTest_ForVector, silentlyDiscardsDuplicatedKeyInData)
175{
176 using namespace testing;
177 using namespace std::string_literals;
178
179 std::string val1;
180 float val2 = 0.f;
181 double val3 = 0.;
182
183 this->data.insert(this->data.end(),
184 std::make_pair("Key-1"s, VariantType("string2"s)));
185
186 unpackProperties(this->data, "Key-1", val1, "Key-2", val2, "Key-3", val3);
187
188 ASSERT_THAT(val1, Eq("string"));
189 ASSERT_THAT(val2, FloatEq(42.f));
190 ASSERT_THAT(val3, DoubleEq(15.));
191}
192
193} // namespace sdbusplus