xref: /openbmc/phosphor-power/test/json_parser_utils_tests.cpp (revision 38f8500414fe5c1be6f5159c563937289fe557c2)
1*38f85004SShawn McCarney /**
2*38f85004SShawn McCarney  * Copyright © 2025 IBM Corporation
3*38f85004SShawn McCarney  *
4*38f85004SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
5*38f85004SShawn McCarney  * you may not use this file except in compliance with the License.
6*38f85004SShawn McCarney  * You may obtain a copy of the License at
7*38f85004SShawn McCarney  *
8*38f85004SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
9*38f85004SShawn McCarney  *
10*38f85004SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
11*38f85004SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
12*38f85004SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38f85004SShawn McCarney  * See the License for the specific language governing permissions and
14*38f85004SShawn McCarney  * limitations under the License.
15*38f85004SShawn McCarney  */
16*38f85004SShawn McCarney #include "json_parser_utils.hpp"
17*38f85004SShawn McCarney 
18*38f85004SShawn McCarney #include <nlohmann/json.hpp>
19*38f85004SShawn McCarney 
20*38f85004SShawn McCarney #include <cstdint>
21*38f85004SShawn McCarney #include <exception>
22*38f85004SShawn McCarney #include <stdexcept>
23*38f85004SShawn McCarney #include <string>
24*38f85004SShawn McCarney #include <vector>
25*38f85004SShawn McCarney 
26*38f85004SShawn McCarney #include <gtest/gtest.h>
27*38f85004SShawn McCarney 
28*38f85004SShawn McCarney using namespace phosphor::power::json_parser_utils;
29*38f85004SShawn McCarney using json = nlohmann::json;
30*38f85004SShawn McCarney 
31*38f85004SShawn McCarney TEST(JSONParserUtilsTests, GetRequiredProperty)
32*38f85004SShawn McCarney {
33*38f85004SShawn McCarney     // Test where property exists
34*38f85004SShawn McCarney     {
35*38f85004SShawn McCarney         const json element = R"( { "format": "linear" } )"_json;
36*38f85004SShawn McCarney         const json& propertyElement = getRequiredProperty(element, "format");
37*38f85004SShawn McCarney         EXPECT_EQ(propertyElement.get<std::string>(), "linear");
38*38f85004SShawn McCarney     }
39*38f85004SShawn McCarney 
40*38f85004SShawn McCarney     // Test where property does not exist
41*38f85004SShawn McCarney     try
42*38f85004SShawn McCarney     {
43*38f85004SShawn McCarney         const json element = R"( { "volts": 1.03 } )"_json;
44*38f85004SShawn McCarney         getRequiredProperty(element, "format");
45*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
46*38f85004SShawn McCarney     }
47*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
48*38f85004SShawn McCarney     {
49*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Required property missing: format");
50*38f85004SShawn McCarney     }
51*38f85004SShawn McCarney }
52*38f85004SShawn McCarney 
53*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBitPosition)
54*38f85004SShawn McCarney {
55*38f85004SShawn McCarney     // Test where works: 0
56*38f85004SShawn McCarney     {
57*38f85004SShawn McCarney         const json element = R"( 0 )"_json;
58*38f85004SShawn McCarney         uint8_t value = parseBitPosition(element);
59*38f85004SShawn McCarney         EXPECT_EQ(value, 0);
60*38f85004SShawn McCarney     }
61*38f85004SShawn McCarney 
62*38f85004SShawn McCarney     // Test where works: 7
63*38f85004SShawn McCarney     {
64*38f85004SShawn McCarney         const json element = R"( 7 )"_json;
65*38f85004SShawn McCarney         uint8_t value = parseBitPosition(element);
66*38f85004SShawn McCarney         EXPECT_EQ(value, 7);
67*38f85004SShawn McCarney     }
68*38f85004SShawn McCarney 
69*38f85004SShawn McCarney     // Test where fails: Element is not an integer
70*38f85004SShawn McCarney     try
71*38f85004SShawn McCarney     {
72*38f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
73*38f85004SShawn McCarney         parseBitPosition(element);
74*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
75*38f85004SShawn McCarney     }
76*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
77*38f85004SShawn McCarney     {
78*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
79*38f85004SShawn McCarney     }
80*38f85004SShawn McCarney 
81*38f85004SShawn McCarney     // Test where fails: Value < 0
82*38f85004SShawn McCarney     try
83*38f85004SShawn McCarney     {
84*38f85004SShawn McCarney         const json element = R"( -1 )"_json;
85*38f85004SShawn McCarney         parseBitPosition(element);
86*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
87*38f85004SShawn McCarney     }
88*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
89*38f85004SShawn McCarney     {
90*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
91*38f85004SShawn McCarney     }
92*38f85004SShawn McCarney 
93*38f85004SShawn McCarney     // Test where fails: Value > 7
94*38f85004SShawn McCarney     try
95*38f85004SShawn McCarney     {
96*38f85004SShawn McCarney         const json element = R"( 8 )"_json;
97*38f85004SShawn McCarney         parseBitPosition(element);
98*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
99*38f85004SShawn McCarney     }
100*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
101*38f85004SShawn McCarney     {
102*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
103*38f85004SShawn McCarney     }
104*38f85004SShawn McCarney }
105*38f85004SShawn McCarney 
106*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBitValue)
107*38f85004SShawn McCarney {
108*38f85004SShawn McCarney     // Test where works: 0
109*38f85004SShawn McCarney     {
110*38f85004SShawn McCarney         const json element = R"( 0 )"_json;
111*38f85004SShawn McCarney         uint8_t value = parseBitValue(element);
112*38f85004SShawn McCarney         EXPECT_EQ(value, 0);
113*38f85004SShawn McCarney     }
114*38f85004SShawn McCarney 
115*38f85004SShawn McCarney     // Test where works: 1
116*38f85004SShawn McCarney     {
117*38f85004SShawn McCarney         const json element = R"( 1 )"_json;
118*38f85004SShawn McCarney         uint8_t value = parseBitValue(element);
119*38f85004SShawn McCarney         EXPECT_EQ(value, 1);
120*38f85004SShawn McCarney     }
121*38f85004SShawn McCarney 
122*38f85004SShawn McCarney     // Test where fails: Element is not an integer
123*38f85004SShawn McCarney     try
124*38f85004SShawn McCarney     {
125*38f85004SShawn McCarney         const json element = R"( 0.5 )"_json;
126*38f85004SShawn McCarney         parseBitValue(element);
127*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
128*38f85004SShawn McCarney     }
129*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
130*38f85004SShawn McCarney     {
131*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
132*38f85004SShawn McCarney     }
133*38f85004SShawn McCarney 
134*38f85004SShawn McCarney     // Test where fails: Value < 0
135*38f85004SShawn McCarney     try
136*38f85004SShawn McCarney     {
137*38f85004SShawn McCarney         const json element = R"( -1 )"_json;
138*38f85004SShawn McCarney         parseBitValue(element);
139*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
140*38f85004SShawn McCarney     }
141*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
142*38f85004SShawn McCarney     {
143*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit value");
144*38f85004SShawn McCarney     }
145*38f85004SShawn McCarney 
146*38f85004SShawn McCarney     // Test where fails: Value > 1
147*38f85004SShawn McCarney     try
148*38f85004SShawn McCarney     {
149*38f85004SShawn McCarney         const json element = R"( 2 )"_json;
150*38f85004SShawn McCarney         parseBitValue(element);
151*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
152*38f85004SShawn McCarney     }
153*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
154*38f85004SShawn McCarney     {
155*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit value");
156*38f85004SShawn McCarney     }
157*38f85004SShawn McCarney }
158*38f85004SShawn McCarney 
159*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBoolean)
160*38f85004SShawn McCarney {
161*38f85004SShawn McCarney     // Test where works: true
162*38f85004SShawn McCarney     {
163*38f85004SShawn McCarney         const json element = R"( true )"_json;
164*38f85004SShawn McCarney         bool value = parseBoolean(element);
165*38f85004SShawn McCarney         EXPECT_EQ(value, true);
166*38f85004SShawn McCarney     }
167*38f85004SShawn McCarney 
168*38f85004SShawn McCarney     // Test where works: false
169*38f85004SShawn McCarney     {
170*38f85004SShawn McCarney         const json element = R"( false )"_json;
171*38f85004SShawn McCarney         bool value = parseBoolean(element);
172*38f85004SShawn McCarney         EXPECT_EQ(value, false);
173*38f85004SShawn McCarney     }
174*38f85004SShawn McCarney 
175*38f85004SShawn McCarney     // Test where fails: Element is not a boolean
176*38f85004SShawn McCarney     try
177*38f85004SShawn McCarney     {
178*38f85004SShawn McCarney         const json element = R"( 1 )"_json;
179*38f85004SShawn McCarney         parseBoolean(element);
180*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
181*38f85004SShawn McCarney     }
182*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
183*38f85004SShawn McCarney     {
184*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
185*38f85004SShawn McCarney     }
186*38f85004SShawn McCarney }
187*38f85004SShawn McCarney 
188*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseDouble)
189*38f85004SShawn McCarney {
190*38f85004SShawn McCarney     // Test where works: floating point value
191*38f85004SShawn McCarney     {
192*38f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
193*38f85004SShawn McCarney         double value = parseDouble(element);
194*38f85004SShawn McCarney         EXPECT_EQ(value, 1.03);
195*38f85004SShawn McCarney     }
196*38f85004SShawn McCarney 
197*38f85004SShawn McCarney     // Test where works: integer value
198*38f85004SShawn McCarney     {
199*38f85004SShawn McCarney         const json element = R"( 24 )"_json;
200*38f85004SShawn McCarney         double value = parseDouble(element);
201*38f85004SShawn McCarney         EXPECT_EQ(value, 24.0);
202*38f85004SShawn McCarney     }
203*38f85004SShawn McCarney 
204*38f85004SShawn McCarney     // Test where fails: Element is not a number
205*38f85004SShawn McCarney     try
206*38f85004SShawn McCarney     {
207*38f85004SShawn McCarney         const json element = R"( true )"_json;
208*38f85004SShawn McCarney         parseDouble(element);
209*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
210*38f85004SShawn McCarney     }
211*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
212*38f85004SShawn McCarney     {
213*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a number");
214*38f85004SShawn McCarney     }
215*38f85004SShawn McCarney }
216*38f85004SShawn McCarney 
217*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseHexByte)
218*38f85004SShawn McCarney {
219*38f85004SShawn McCarney     // Test where works: "0xFF"
220*38f85004SShawn McCarney     {
221*38f85004SShawn McCarney         const json element = R"( "0xFF" )"_json;
222*38f85004SShawn McCarney         uint8_t value = parseHexByte(element);
223*38f85004SShawn McCarney         EXPECT_EQ(value, 0xFF);
224*38f85004SShawn McCarney     }
225*38f85004SShawn McCarney 
226*38f85004SShawn McCarney     // Test where works: "0xff"
227*38f85004SShawn McCarney     {
228*38f85004SShawn McCarney         const json element = R"( "0xff" )"_json;
229*38f85004SShawn McCarney         uint8_t value = parseHexByte(element);
230*38f85004SShawn McCarney         EXPECT_EQ(value, 0xff);
231*38f85004SShawn McCarney     }
232*38f85004SShawn McCarney 
233*38f85004SShawn McCarney     // Test where works: "0xf"
234*38f85004SShawn McCarney     {
235*38f85004SShawn McCarney         const json element = R"( "0xf" )"_json;
236*38f85004SShawn McCarney         uint8_t value = parseHexByte(element);
237*38f85004SShawn McCarney         EXPECT_EQ(value, 0xf);
238*38f85004SShawn McCarney     }
239*38f85004SShawn McCarney 
240*38f85004SShawn McCarney     // Test where fails: "0xfff"
241*38f85004SShawn McCarney     try
242*38f85004SShawn McCarney     {
243*38f85004SShawn McCarney         const json element = R"( "0xfff" )"_json;
244*38f85004SShawn McCarney         parseHexByte(element);
245*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
246*38f85004SShawn McCarney     }
247*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
248*38f85004SShawn McCarney     {
249*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
250*38f85004SShawn McCarney     }
251*38f85004SShawn McCarney 
252*38f85004SShawn McCarney     // Test where fails: "0xAG"
253*38f85004SShawn McCarney     try
254*38f85004SShawn McCarney     {
255*38f85004SShawn McCarney         const json element = R"( "0xAG" )"_json;
256*38f85004SShawn McCarney         parseHexByte(element);
257*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
258*38f85004SShawn McCarney     }
259*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
260*38f85004SShawn McCarney     {
261*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
262*38f85004SShawn McCarney     }
263*38f85004SShawn McCarney 
264*38f85004SShawn McCarney     // Test where fails: "ff"
265*38f85004SShawn McCarney     try
266*38f85004SShawn McCarney     {
267*38f85004SShawn McCarney         const json element = R"( "ff" )"_json;
268*38f85004SShawn McCarney         parseHexByte(element);
269*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
270*38f85004SShawn McCarney     }
271*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
272*38f85004SShawn McCarney     {
273*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
274*38f85004SShawn McCarney     }
275*38f85004SShawn McCarney 
276*38f85004SShawn McCarney     // Test where fails: ""
277*38f85004SShawn McCarney     try
278*38f85004SShawn McCarney     {
279*38f85004SShawn McCarney         const json element = "";
280*38f85004SShawn McCarney         parseHexByte(element);
281*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
282*38f85004SShawn McCarney     }
283*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
284*38f85004SShawn McCarney     {
285*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
286*38f85004SShawn McCarney     }
287*38f85004SShawn McCarney 
288*38f85004SShawn McCarney     // Test where fails: "f"
289*38f85004SShawn McCarney     try
290*38f85004SShawn McCarney     {
291*38f85004SShawn McCarney         const json element = R"( "f" )"_json;
292*38f85004SShawn McCarney         parseHexByte(element);
293*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
294*38f85004SShawn McCarney     }
295*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
296*38f85004SShawn McCarney     {
297*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
298*38f85004SShawn McCarney     }
299*38f85004SShawn McCarney 
300*38f85004SShawn McCarney     // Test where fails: "0x"
301*38f85004SShawn McCarney     try
302*38f85004SShawn McCarney     {
303*38f85004SShawn McCarney         const json element = R"( "0x" )"_json;
304*38f85004SShawn McCarney         parseHexByte(element);
305*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
306*38f85004SShawn McCarney     }
307*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
308*38f85004SShawn McCarney     {
309*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
310*38f85004SShawn McCarney     }
311*38f85004SShawn McCarney 
312*38f85004SShawn McCarney     // Test where fails: "0Xff"
313*38f85004SShawn McCarney     try
314*38f85004SShawn McCarney     {
315*38f85004SShawn McCarney         const json element = R"( "0XFF" )"_json;
316*38f85004SShawn McCarney         parseHexByte(element);
317*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
318*38f85004SShawn McCarney     }
319*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
320*38f85004SShawn McCarney     {
321*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
322*38f85004SShawn McCarney     }
323*38f85004SShawn McCarney }
324*38f85004SShawn McCarney 
325*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseHexByteArray)
326*38f85004SShawn McCarney {
327*38f85004SShawn McCarney     // Test where works
328*38f85004SShawn McCarney     {
329*38f85004SShawn McCarney         const json element = R"( [ "0xCC", "0xFF" ] )"_json;
330*38f85004SShawn McCarney         std::vector<uint8_t> hexBytes = parseHexByteArray(element);
331*38f85004SShawn McCarney         std::vector<uint8_t> expected = {0xcc, 0xff};
332*38f85004SShawn McCarney         EXPECT_EQ(hexBytes, expected);
333*38f85004SShawn McCarney     }
334*38f85004SShawn McCarney 
335*38f85004SShawn McCarney     // Test where fails: Element is not an array
336*38f85004SShawn McCarney     try
337*38f85004SShawn McCarney     {
338*38f85004SShawn McCarney         const json element = 0;
339*38f85004SShawn McCarney         parseHexByteArray(element);
340*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
341*38f85004SShawn McCarney     }
342*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
343*38f85004SShawn McCarney     {
344*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an array");
345*38f85004SShawn McCarney     }
346*38f85004SShawn McCarney }
347*38f85004SShawn McCarney 
348*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseInt8)
349*38f85004SShawn McCarney {
350*38f85004SShawn McCarney     // Test where works: INT8_MIN
351*38f85004SShawn McCarney     {
352*38f85004SShawn McCarney         const json element = R"( -128 )"_json;
353*38f85004SShawn McCarney         int8_t value = parseInt8(element);
354*38f85004SShawn McCarney         EXPECT_EQ(value, -128);
355*38f85004SShawn McCarney     }
356*38f85004SShawn McCarney 
357*38f85004SShawn McCarney     // Test where works: INT8_MAX
358*38f85004SShawn McCarney     {
359*38f85004SShawn McCarney         const json element = R"( 127 )"_json;
360*38f85004SShawn McCarney         int8_t value = parseInt8(element);
361*38f85004SShawn McCarney         EXPECT_EQ(value, 127);
362*38f85004SShawn McCarney     }
363*38f85004SShawn McCarney 
364*38f85004SShawn McCarney     // Test where fails: Element is not an integer
365*38f85004SShawn McCarney     try
366*38f85004SShawn McCarney     {
367*38f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
368*38f85004SShawn McCarney         parseInt8(element);
369*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
370*38f85004SShawn McCarney     }
371*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
372*38f85004SShawn McCarney     {
373*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
374*38f85004SShawn McCarney     }
375*38f85004SShawn McCarney 
376*38f85004SShawn McCarney     // Test where fails: Value < INT8_MIN
377*38f85004SShawn McCarney     try
378*38f85004SShawn McCarney     {
379*38f85004SShawn McCarney         const json element = R"( -129 )"_json;
380*38f85004SShawn McCarney         parseInt8(element);
381*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
382*38f85004SShawn McCarney     }
383*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
384*38f85004SShawn McCarney     {
385*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
386*38f85004SShawn McCarney     }
387*38f85004SShawn McCarney 
388*38f85004SShawn McCarney     // Test where fails: Value > INT8_MAX
389*38f85004SShawn McCarney     try
390*38f85004SShawn McCarney     {
391*38f85004SShawn McCarney         const json element = R"( 128 )"_json;
392*38f85004SShawn McCarney         parseInt8(element);
393*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
394*38f85004SShawn McCarney     }
395*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
396*38f85004SShawn McCarney     {
397*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
398*38f85004SShawn McCarney     }
399*38f85004SShawn McCarney }
400*38f85004SShawn McCarney 
401*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseString)
402*38f85004SShawn McCarney {
403*38f85004SShawn McCarney     // Test where works: Empty string
404*38f85004SShawn McCarney     {
405*38f85004SShawn McCarney         const json element = "";
406*38f85004SShawn McCarney         std::string value = parseString(element, true);
407*38f85004SShawn McCarney         EXPECT_EQ(value, "");
408*38f85004SShawn McCarney     }
409*38f85004SShawn McCarney 
410*38f85004SShawn McCarney     // Test where works: Non-empty string
411*38f85004SShawn McCarney     {
412*38f85004SShawn McCarney         const json element = "vdd_regulator";
413*38f85004SShawn McCarney         std::string value = parseString(element, false);
414*38f85004SShawn McCarney         EXPECT_EQ(value, "vdd_regulator");
415*38f85004SShawn McCarney     }
416*38f85004SShawn McCarney 
417*38f85004SShawn McCarney     // Test where fails: Element is not a string
418*38f85004SShawn McCarney     try
419*38f85004SShawn McCarney     {
420*38f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
421*38f85004SShawn McCarney         parseString(element);
422*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
423*38f85004SShawn McCarney     }
424*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
425*38f85004SShawn McCarney     {
426*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a string");
427*38f85004SShawn McCarney     }
428*38f85004SShawn McCarney 
429*38f85004SShawn McCarney     // Test where fails: Empty string
430*38f85004SShawn McCarney     try
431*38f85004SShawn McCarney     {
432*38f85004SShawn McCarney         const json element = "";
433*38f85004SShawn McCarney         parseString(element);
434*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
435*38f85004SShawn McCarney     }
436*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
437*38f85004SShawn McCarney     {
438*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an empty string");
439*38f85004SShawn McCarney     }
440*38f85004SShawn McCarney }
441*38f85004SShawn McCarney 
442*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseUint8)
443*38f85004SShawn McCarney {
444*38f85004SShawn McCarney     // Test where works: 0
445*38f85004SShawn McCarney     {
446*38f85004SShawn McCarney         const json element = R"( 0 )"_json;
447*38f85004SShawn McCarney         uint8_t value = parseUint8(element);
448*38f85004SShawn McCarney         EXPECT_EQ(value, 0);
449*38f85004SShawn McCarney     }
450*38f85004SShawn McCarney 
451*38f85004SShawn McCarney     // Test where works: UINT8_MAX
452*38f85004SShawn McCarney     {
453*38f85004SShawn McCarney         const json element = R"( 255 )"_json;
454*38f85004SShawn McCarney         uint8_t value = parseUint8(element);
455*38f85004SShawn McCarney         EXPECT_EQ(value, 255);
456*38f85004SShawn McCarney     }
457*38f85004SShawn McCarney 
458*38f85004SShawn McCarney     // Test where fails: Element is not an integer
459*38f85004SShawn McCarney     try
460*38f85004SShawn McCarney     {
461*38f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
462*38f85004SShawn McCarney         parseUint8(element);
463*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
464*38f85004SShawn McCarney     }
465*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
466*38f85004SShawn McCarney     {
467*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
468*38f85004SShawn McCarney     }
469*38f85004SShawn McCarney 
470*38f85004SShawn McCarney     // Test where fails: Value < 0
471*38f85004SShawn McCarney     try
472*38f85004SShawn McCarney     {
473*38f85004SShawn McCarney         const json element = R"( -1 )"_json;
474*38f85004SShawn McCarney         parseUint8(element);
475*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
476*38f85004SShawn McCarney     }
477*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
478*38f85004SShawn McCarney     {
479*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
480*38f85004SShawn McCarney     }
481*38f85004SShawn McCarney 
482*38f85004SShawn McCarney     // Test where fails: Value > UINT8_MAX
483*38f85004SShawn McCarney     try
484*38f85004SShawn McCarney     {
485*38f85004SShawn McCarney         const json element = R"( 256 )"_json;
486*38f85004SShawn McCarney         parseUint8(element);
487*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
488*38f85004SShawn McCarney     }
489*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
490*38f85004SShawn McCarney     {
491*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
492*38f85004SShawn McCarney     }
493*38f85004SShawn McCarney }
494*38f85004SShawn McCarney 
495*38f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseUnsignedInteger)
496*38f85004SShawn McCarney {
497*38f85004SShawn McCarney     // Test where works: 1
498*38f85004SShawn McCarney     {
499*38f85004SShawn McCarney         const json element = R"( 1 )"_json;
500*38f85004SShawn McCarney         unsigned int value = parseUnsignedInteger(element);
501*38f85004SShawn McCarney         EXPECT_EQ(value, 1);
502*38f85004SShawn McCarney     }
503*38f85004SShawn McCarney 
504*38f85004SShawn McCarney     // Test where fails: Element is not an integer
505*38f85004SShawn McCarney     try
506*38f85004SShawn McCarney     {
507*38f85004SShawn McCarney         const json element = R"( 1.5 )"_json;
508*38f85004SShawn McCarney         parseUnsignedInteger(element);
509*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
510*38f85004SShawn McCarney     }
511*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
512*38f85004SShawn McCarney     {
513*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
514*38f85004SShawn McCarney     }
515*38f85004SShawn McCarney 
516*38f85004SShawn McCarney     // Test where fails: Value < 0
517*38f85004SShawn McCarney     try
518*38f85004SShawn McCarney     {
519*38f85004SShawn McCarney         const json element = R"( -1 )"_json;
520*38f85004SShawn McCarney         parseUnsignedInteger(element);
521*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
522*38f85004SShawn McCarney     }
523*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
524*38f85004SShawn McCarney     {
525*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
526*38f85004SShawn McCarney     }
527*38f85004SShawn McCarney }
528*38f85004SShawn McCarney 
529*38f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsArray)
530*38f85004SShawn McCarney {
531*38f85004SShawn McCarney     // Test where element is an array
532*38f85004SShawn McCarney     {
533*38f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
534*38f85004SShawn McCarney         verifyIsArray(element);
535*38f85004SShawn McCarney     }
536*38f85004SShawn McCarney 
537*38f85004SShawn McCarney     // Test where element is not an array
538*38f85004SShawn McCarney     try
539*38f85004SShawn McCarney     {
540*38f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
541*38f85004SShawn McCarney         verifyIsArray(element);
542*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
543*38f85004SShawn McCarney     }
544*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
545*38f85004SShawn McCarney     {
546*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an array");
547*38f85004SShawn McCarney     }
548*38f85004SShawn McCarney }
549*38f85004SShawn McCarney 
550*38f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsObject)
551*38f85004SShawn McCarney {
552*38f85004SShawn McCarney     // Test where element is an object
553*38f85004SShawn McCarney     {
554*38f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
555*38f85004SShawn McCarney         verifyIsObject(element);
556*38f85004SShawn McCarney     }
557*38f85004SShawn McCarney 
558*38f85004SShawn McCarney     // Test where element is not an object
559*38f85004SShawn McCarney     try
560*38f85004SShawn McCarney     {
561*38f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
562*38f85004SShawn McCarney         verifyIsObject(element);
563*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
564*38f85004SShawn McCarney     }
565*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
566*38f85004SShawn McCarney     {
567*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an object");
568*38f85004SShawn McCarney     }
569*38f85004SShawn McCarney }
570*38f85004SShawn McCarney 
571*38f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyPropertyCount)
572*38f85004SShawn McCarney {
573*38f85004SShawn McCarney     // Test where element has expected number of properties
574*38f85004SShawn McCarney     {
575*38f85004SShawn McCarney         const json element = R"(
576*38f85004SShawn McCarney             {
577*38f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
578*38f85004SShawn McCarney               "id": "set_voltage_rule"
579*38f85004SShawn McCarney             }
580*38f85004SShawn McCarney         )"_json;
581*38f85004SShawn McCarney         verifyPropertyCount(element, 2);
582*38f85004SShawn McCarney     }
583*38f85004SShawn McCarney 
584*38f85004SShawn McCarney     // Test where element has unexpected number of properties
585*38f85004SShawn McCarney     try
586*38f85004SShawn McCarney     {
587*38f85004SShawn McCarney         const json element = R"(
588*38f85004SShawn McCarney             {
589*38f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
590*38f85004SShawn McCarney               "id": "set_voltage_rule",
591*38f85004SShawn McCarney               "foo": 1.3
592*38f85004SShawn McCarney             }
593*38f85004SShawn McCarney         )"_json;
594*38f85004SShawn McCarney         verifyPropertyCount(element, 2);
595*38f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
596*38f85004SShawn McCarney     }
597*38f85004SShawn McCarney     catch (const std::invalid_argument& e)
598*38f85004SShawn McCarney     {
599*38f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an invalid property");
600*38f85004SShawn McCarney     }
601*38f85004SShawn McCarney }
602