xref: /openbmc/phosphor-power/test/json_parser_utils_tests.cpp (revision f1845c0621324fc8435a8e29377f0b1306e636b7)
138f85004SShawn McCarney /**
238f85004SShawn McCarney  * Copyright © 2025 IBM Corporation
338f85004SShawn McCarney  *
438f85004SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
538f85004SShawn McCarney  * you may not use this file except in compliance with the License.
638f85004SShawn McCarney  * You may obtain a copy of the License at
738f85004SShawn McCarney  *
838f85004SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
938f85004SShawn McCarney  *
1038f85004SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
1138f85004SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
1238f85004SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338f85004SShawn McCarney  * See the License for the specific language governing permissions and
1438f85004SShawn McCarney  * limitations under the License.
1538f85004SShawn McCarney  */
1638f85004SShawn McCarney #include "json_parser_utils.hpp"
1738f85004SShawn McCarney 
1838f85004SShawn McCarney #include <nlohmann/json.hpp>
1938f85004SShawn McCarney 
2038f85004SShawn McCarney #include <cstdint>
2138f85004SShawn McCarney #include <exception>
2238f85004SShawn McCarney #include <stdexcept>
2338f85004SShawn McCarney #include <string>
2438f85004SShawn McCarney #include <vector>
2538f85004SShawn McCarney 
2638f85004SShawn McCarney #include <gtest/gtest.h>
2738f85004SShawn McCarney 
2838f85004SShawn McCarney using namespace phosphor::power::json_parser_utils;
29*f1845c06SShawn McCarney using namespace phosphor::power::json_parser_utils::internal;
3038f85004SShawn McCarney using json = nlohmann::json;
3138f85004SShawn McCarney 
3238f85004SShawn McCarney TEST(JSONParserUtilsTests, GetRequiredProperty)
3338f85004SShawn McCarney {
3438f85004SShawn McCarney     // Test where property exists
3538f85004SShawn McCarney     {
3638f85004SShawn McCarney         const json element = R"( { "format": "linear" } )"_json;
3738f85004SShawn McCarney         const json& propertyElement = getRequiredProperty(element, "format");
3838f85004SShawn McCarney         EXPECT_EQ(propertyElement.get<std::string>(), "linear");
3938f85004SShawn McCarney     }
4038f85004SShawn McCarney 
4138f85004SShawn McCarney     // Test where property does not exist
4238f85004SShawn McCarney     try
4338f85004SShawn McCarney     {
4438f85004SShawn McCarney         const json element = R"( { "volts": 1.03 } )"_json;
4538f85004SShawn McCarney         getRequiredProperty(element, "format");
4638f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
4738f85004SShawn McCarney     }
4838f85004SShawn McCarney     catch (const std::invalid_argument& e)
4938f85004SShawn McCarney     {
5038f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Required property missing: format");
5138f85004SShawn McCarney     }
5238f85004SShawn McCarney }
5338f85004SShawn McCarney 
5438f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBitPosition)
5538f85004SShawn McCarney {
5638f85004SShawn McCarney     // Test where works: 0
5738f85004SShawn McCarney     {
5838f85004SShawn McCarney         const json element = R"( 0 )"_json;
5938f85004SShawn McCarney         uint8_t value = parseBitPosition(element);
6038f85004SShawn McCarney         EXPECT_EQ(value, 0);
6138f85004SShawn McCarney     }
6238f85004SShawn McCarney 
6338f85004SShawn McCarney     // Test where works: 7
6438f85004SShawn McCarney     {
6538f85004SShawn McCarney         const json element = R"( 7 )"_json;
6638f85004SShawn McCarney         uint8_t value = parseBitPosition(element);
6738f85004SShawn McCarney         EXPECT_EQ(value, 7);
6838f85004SShawn McCarney     }
6938f85004SShawn McCarney 
70*f1845c06SShawn McCarney     // Test where works: Variable specified
71*f1845c06SShawn McCarney     {
72*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_pos", "3"}};
73*f1845c06SShawn McCarney         const json element = R"( "${bit_pos}" )"_json;
74*f1845c06SShawn McCarney         uint8_t value = parseBitPosition(element, variables);
75*f1845c06SShawn McCarney         EXPECT_EQ(value, 3);
76*f1845c06SShawn McCarney     }
77*f1845c06SShawn McCarney 
7838f85004SShawn McCarney     // Test where fails: Element is not an integer
7938f85004SShawn McCarney     try
8038f85004SShawn McCarney     {
8138f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
8238f85004SShawn McCarney         parseBitPosition(element);
8338f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
8438f85004SShawn McCarney     }
8538f85004SShawn McCarney     catch (const std::invalid_argument& e)
8638f85004SShawn McCarney     {
8738f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
8838f85004SShawn McCarney     }
8938f85004SShawn McCarney 
9038f85004SShawn McCarney     // Test where fails: Value < 0
9138f85004SShawn McCarney     try
9238f85004SShawn McCarney     {
9338f85004SShawn McCarney         const json element = R"( -1 )"_json;
9438f85004SShawn McCarney         parseBitPosition(element);
9538f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
9638f85004SShawn McCarney     }
9738f85004SShawn McCarney     catch (const std::invalid_argument& e)
9838f85004SShawn McCarney     {
9938f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
10038f85004SShawn McCarney     }
10138f85004SShawn McCarney 
10238f85004SShawn McCarney     // Test where fails: Value > 7
10338f85004SShawn McCarney     try
10438f85004SShawn McCarney     {
10538f85004SShawn McCarney         const json element = R"( 8 )"_json;
10638f85004SShawn McCarney         parseBitPosition(element);
10738f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
10838f85004SShawn McCarney     }
10938f85004SShawn McCarney     catch (const std::invalid_argument& e)
11038f85004SShawn McCarney     {
11138f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
11238f85004SShawn McCarney     }
113*f1845c06SShawn McCarney 
114*f1845c06SShawn McCarney     // Test where fails: Variable specified: Value < 0
115*f1845c06SShawn McCarney     try
116*f1845c06SShawn McCarney     {
117*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_pos", "-1"}};
118*f1845c06SShawn McCarney         const json element = R"( "${bit_pos}" )"_json;
119*f1845c06SShawn McCarney         parseBitPosition(element, variables);
120*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
121*f1845c06SShawn McCarney     }
122*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
123*f1845c06SShawn McCarney     {
124*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
125*f1845c06SShawn McCarney     }
12638f85004SShawn McCarney }
12738f85004SShawn McCarney 
12838f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBitValue)
12938f85004SShawn McCarney {
13038f85004SShawn McCarney     // Test where works: 0
13138f85004SShawn McCarney     {
13238f85004SShawn McCarney         const json element = R"( 0 )"_json;
13338f85004SShawn McCarney         uint8_t value = parseBitValue(element);
13438f85004SShawn McCarney         EXPECT_EQ(value, 0);
13538f85004SShawn McCarney     }
13638f85004SShawn McCarney 
13738f85004SShawn McCarney     // Test where works: 1
13838f85004SShawn McCarney     {
13938f85004SShawn McCarney         const json element = R"( 1 )"_json;
14038f85004SShawn McCarney         uint8_t value = parseBitValue(element);
14138f85004SShawn McCarney         EXPECT_EQ(value, 1);
14238f85004SShawn McCarney     }
14338f85004SShawn McCarney 
144*f1845c06SShawn McCarney     // Test where works: Variable specified
145*f1845c06SShawn McCarney     {
146*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_val", "1"}};
147*f1845c06SShawn McCarney         const json element = R"( "${bit_val}" )"_json;
148*f1845c06SShawn McCarney         uint8_t value = parseBitValue(element, variables);
149*f1845c06SShawn McCarney         EXPECT_EQ(value, 1);
150*f1845c06SShawn McCarney     }
151*f1845c06SShawn McCarney 
15238f85004SShawn McCarney     // Test where fails: Element is not an integer
15338f85004SShawn McCarney     try
15438f85004SShawn McCarney     {
15538f85004SShawn McCarney         const json element = R"( 0.5 )"_json;
15638f85004SShawn McCarney         parseBitValue(element);
15738f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
15838f85004SShawn McCarney     }
15938f85004SShawn McCarney     catch (const std::invalid_argument& e)
16038f85004SShawn McCarney     {
16138f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
16238f85004SShawn McCarney     }
16338f85004SShawn McCarney 
16438f85004SShawn McCarney     // Test where fails: Value < 0
16538f85004SShawn McCarney     try
16638f85004SShawn McCarney     {
16738f85004SShawn McCarney         const json element = R"( -1 )"_json;
16838f85004SShawn McCarney         parseBitValue(element);
16938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
17038f85004SShawn McCarney     }
17138f85004SShawn McCarney     catch (const std::invalid_argument& e)
17238f85004SShawn McCarney     {
17338f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit value");
17438f85004SShawn McCarney     }
17538f85004SShawn McCarney 
17638f85004SShawn McCarney     // Test where fails: Value > 1
17738f85004SShawn McCarney     try
17838f85004SShawn McCarney     {
17938f85004SShawn McCarney         const json element = R"( 2 )"_json;
18038f85004SShawn McCarney         parseBitValue(element);
18138f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
18238f85004SShawn McCarney     }
18338f85004SShawn McCarney     catch (const std::invalid_argument& e)
18438f85004SShawn McCarney     {
18538f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit value");
18638f85004SShawn McCarney     }
187*f1845c06SShawn McCarney 
188*f1845c06SShawn McCarney     // Test where fails: Variable specified: Not an integer
189*f1845c06SShawn McCarney     try
190*f1845c06SShawn McCarney     {
191*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_val", "one"}};
192*f1845c06SShawn McCarney         const json element = R"( "${bit_val}" )"_json;
193*f1845c06SShawn McCarney         parseBitValue(element, variables);
194*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
195*f1845c06SShawn McCarney     }
196*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
197*f1845c06SShawn McCarney     {
198*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
199*f1845c06SShawn McCarney     }
20038f85004SShawn McCarney }
20138f85004SShawn McCarney 
20238f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseBoolean)
20338f85004SShawn McCarney {
20438f85004SShawn McCarney     // Test where works: true
20538f85004SShawn McCarney     {
20638f85004SShawn McCarney         const json element = R"( true )"_json;
20738f85004SShawn McCarney         bool value = parseBoolean(element);
20838f85004SShawn McCarney         EXPECT_EQ(value, true);
20938f85004SShawn McCarney     }
21038f85004SShawn McCarney 
21138f85004SShawn McCarney     // Test where works: false
21238f85004SShawn McCarney     {
21338f85004SShawn McCarney         const json element = R"( false )"_json;
21438f85004SShawn McCarney         bool value = parseBoolean(element);
21538f85004SShawn McCarney         EXPECT_EQ(value, false);
21638f85004SShawn McCarney     }
21738f85004SShawn McCarney 
218*f1845c06SShawn McCarney     // Test where works: Variable specified: true
219*f1845c06SShawn McCarney     {
220*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "true"}};
221*f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
222*f1845c06SShawn McCarney         bool value = parseBoolean(element, variables);
223*f1845c06SShawn McCarney         EXPECT_EQ(value, true);
224*f1845c06SShawn McCarney     }
225*f1845c06SShawn McCarney 
226*f1845c06SShawn McCarney     // Test where works: Variable specified: false
227*f1845c06SShawn McCarney     {
228*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "false"}};
229*f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
230*f1845c06SShawn McCarney         bool value = parseBoolean(element, variables);
231*f1845c06SShawn McCarney         EXPECT_EQ(value, false);
232*f1845c06SShawn McCarney     }
233*f1845c06SShawn McCarney 
23438f85004SShawn McCarney     // Test where fails: Element is not a boolean
23538f85004SShawn McCarney     try
23638f85004SShawn McCarney     {
23738f85004SShawn McCarney         const json element = R"( 1 )"_json;
23838f85004SShawn McCarney         parseBoolean(element);
23938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
24038f85004SShawn McCarney     }
24138f85004SShawn McCarney     catch (const std::invalid_argument& e)
24238f85004SShawn McCarney     {
24338f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
24438f85004SShawn McCarney     }
245*f1845c06SShawn McCarney 
246*f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
247*f1845c06SShawn McCarney     try
248*f1845c06SShawn McCarney     {
249*f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
250*f1845c06SShawn McCarney         parseBoolean(element);
251*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
252*f1845c06SShawn McCarney     }
253*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
254*f1845c06SShawn McCarney     {
255*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
256*f1845c06SShawn McCarney     }
257*f1845c06SShawn McCarney 
258*f1845c06SShawn McCarney     // Test where fails: Variable specified: Value is not a boolean
259*f1845c06SShawn McCarney     try
260*f1845c06SShawn McCarney     {
261*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "3.2"}};
262*f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
263*f1845c06SShawn McCarney         parseBoolean(element, variables);
264*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
265*f1845c06SShawn McCarney     }
266*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
267*f1845c06SShawn McCarney     {
268*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
269*f1845c06SShawn McCarney     }
27038f85004SShawn McCarney }
27138f85004SShawn McCarney 
27238f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseDouble)
27338f85004SShawn McCarney {
274*f1845c06SShawn McCarney     // Test where works: Floating point value
27538f85004SShawn McCarney     {
27638f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
27738f85004SShawn McCarney         double value = parseDouble(element);
27838f85004SShawn McCarney         EXPECT_EQ(value, 1.03);
27938f85004SShawn McCarney     }
28038f85004SShawn McCarney 
281*f1845c06SShawn McCarney     // Test where works: Integer value
28238f85004SShawn McCarney     {
283*f1845c06SShawn McCarney         const json element = R"( -24 )"_json;
28438f85004SShawn McCarney         double value = parseDouble(element);
285*f1845c06SShawn McCarney         EXPECT_EQ(value, -24.0);
286*f1845c06SShawn McCarney     }
287*f1845c06SShawn McCarney 
288*f1845c06SShawn McCarney     // Test where works: Variable specified: Floating point value
289*f1845c06SShawn McCarney     {
290*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03"}};
291*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
292*f1845c06SShawn McCarney         double value = parseDouble(element, variables);
293*f1845c06SShawn McCarney         EXPECT_EQ(value, -1.03);
294*f1845c06SShawn McCarney     }
295*f1845c06SShawn McCarney 
296*f1845c06SShawn McCarney     // Test where works: Variable specified: Integer value
297*f1845c06SShawn McCarney     {
298*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "24"}};
299*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
300*f1845c06SShawn McCarney         double value = parseDouble(element, variables);
30138f85004SShawn McCarney         EXPECT_EQ(value, 24.0);
30238f85004SShawn McCarney     }
30338f85004SShawn McCarney 
304*f1845c06SShawn McCarney     // Test where fails: Element is not a double
30538f85004SShawn McCarney     try
30638f85004SShawn McCarney     {
30738f85004SShawn McCarney         const json element = R"( true )"_json;
30838f85004SShawn McCarney         parseDouble(element);
30938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
31038f85004SShawn McCarney     }
31138f85004SShawn McCarney     catch (const std::invalid_argument& e)
31238f85004SShawn McCarney     {
313*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
314*f1845c06SShawn McCarney     }
315*f1845c06SShawn McCarney 
316*f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
317*f1845c06SShawn McCarney     try
318*f1845c06SShawn McCarney     {
319*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
320*f1845c06SShawn McCarney         parseDouble(element);
321*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
322*f1845c06SShawn McCarney     }
323*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
324*f1845c06SShawn McCarney     {
325*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
326*f1845c06SShawn McCarney     }
327*f1845c06SShawn McCarney 
328*f1845c06SShawn McCarney     // Test where fails: Variable specified: Leading whitespace
329*f1845c06SShawn McCarney     try
330*f1845c06SShawn McCarney     {
331*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", " -1.03"}};
332*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
333*f1845c06SShawn McCarney         parseDouble(element, variables);
334*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
335*f1845c06SShawn McCarney     }
336*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
337*f1845c06SShawn McCarney     {
338*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
339*f1845c06SShawn McCarney     }
340*f1845c06SShawn McCarney 
341*f1845c06SShawn McCarney     // Test where fails: Variable specified: Trailing whitespace
342*f1845c06SShawn McCarney     try
343*f1845c06SShawn McCarney     {
344*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03 "}};
345*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
346*f1845c06SShawn McCarney         parseDouble(element, variables);
347*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
348*f1845c06SShawn McCarney     }
349*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
350*f1845c06SShawn McCarney     {
351*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
352*f1845c06SShawn McCarney     }
353*f1845c06SShawn McCarney 
354*f1845c06SShawn McCarney     // Test where fails: Variable specified: Starts with non-number character
355*f1845c06SShawn McCarney     try
356*f1845c06SShawn McCarney     {
357*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "x-1.03"}};
358*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
359*f1845c06SShawn McCarney         parseDouble(element, variables);
360*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
361*f1845c06SShawn McCarney     }
362*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
363*f1845c06SShawn McCarney     {
364*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
365*f1845c06SShawn McCarney     }
366*f1845c06SShawn McCarney 
367*f1845c06SShawn McCarney     // Test where fails: Variable specified: Ends with non-number character
368*f1845c06SShawn McCarney     try
369*f1845c06SShawn McCarney     {
370*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03x"}};
371*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
372*f1845c06SShawn McCarney         parseDouble(element, variables);
373*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
374*f1845c06SShawn McCarney     }
375*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
376*f1845c06SShawn McCarney     {
377*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
378*f1845c06SShawn McCarney     }
379*f1845c06SShawn McCarney 
380*f1845c06SShawn McCarney     // Test where fails: Variable specified: Not a double
381*f1845c06SShawn McCarney     try
382*f1845c06SShawn McCarney     {
383*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "foo"}};
384*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
385*f1845c06SShawn McCarney         parseDouble(element, variables);
386*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
387*f1845c06SShawn McCarney     }
388*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
389*f1845c06SShawn McCarney     {
390*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
39138f85004SShawn McCarney     }
39238f85004SShawn McCarney }
39338f85004SShawn McCarney 
39438f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseHexByte)
39538f85004SShawn McCarney {
39638f85004SShawn McCarney     // Test where works: "0xFF"
39738f85004SShawn McCarney     {
39838f85004SShawn McCarney         const json element = R"( "0xFF" )"_json;
39938f85004SShawn McCarney         uint8_t value = parseHexByte(element);
40038f85004SShawn McCarney         EXPECT_EQ(value, 0xFF);
40138f85004SShawn McCarney     }
40238f85004SShawn McCarney 
40338f85004SShawn McCarney     // Test where works: "0xff"
40438f85004SShawn McCarney     {
40538f85004SShawn McCarney         const json element = R"( "0xff" )"_json;
40638f85004SShawn McCarney         uint8_t value = parseHexByte(element);
40738f85004SShawn McCarney         EXPECT_EQ(value, 0xff);
40838f85004SShawn McCarney     }
40938f85004SShawn McCarney 
41038f85004SShawn McCarney     // Test where works: "0xf"
41138f85004SShawn McCarney     {
41238f85004SShawn McCarney         const json element = R"( "0xf" )"_json;
41338f85004SShawn McCarney         uint8_t value = parseHexByte(element);
41438f85004SShawn McCarney         EXPECT_EQ(value, 0xf);
41538f85004SShawn McCarney     }
41638f85004SShawn McCarney 
417*f1845c06SShawn McCarney     // Test where works: Variable specified
418*f1845c06SShawn McCarney     {
419*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "ed"}};
420*f1845c06SShawn McCarney         const json element = R"( "0x${var}" )"_json;
421*f1845c06SShawn McCarney         uint8_t value = parseHexByte(element, variables);
422*f1845c06SShawn McCarney         EXPECT_EQ(value, 0xed);
423*f1845c06SShawn McCarney     }
424*f1845c06SShawn McCarney 
42538f85004SShawn McCarney     // Test where fails: "0xfff"
42638f85004SShawn McCarney     try
42738f85004SShawn McCarney     {
42838f85004SShawn McCarney         const json element = R"( "0xfff" )"_json;
42938f85004SShawn McCarney         parseHexByte(element);
43038f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
43138f85004SShawn McCarney     }
43238f85004SShawn McCarney     catch (const std::invalid_argument& e)
43338f85004SShawn McCarney     {
43438f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
43538f85004SShawn McCarney     }
43638f85004SShawn McCarney 
43738f85004SShawn McCarney     // Test where fails: "0xAG"
43838f85004SShawn McCarney     try
43938f85004SShawn McCarney     {
44038f85004SShawn McCarney         const json element = R"( "0xAG" )"_json;
44138f85004SShawn McCarney         parseHexByte(element);
44238f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
44338f85004SShawn McCarney     }
44438f85004SShawn McCarney     catch (const std::invalid_argument& e)
44538f85004SShawn McCarney     {
44638f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
44738f85004SShawn McCarney     }
44838f85004SShawn McCarney 
44938f85004SShawn McCarney     // Test where fails: "ff"
45038f85004SShawn McCarney     try
45138f85004SShawn McCarney     {
45238f85004SShawn McCarney         const json element = R"( "ff" )"_json;
45338f85004SShawn McCarney         parseHexByte(element);
45438f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
45538f85004SShawn McCarney     }
45638f85004SShawn McCarney     catch (const std::invalid_argument& e)
45738f85004SShawn McCarney     {
45838f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
45938f85004SShawn McCarney     }
46038f85004SShawn McCarney 
46138f85004SShawn McCarney     // Test where fails: ""
46238f85004SShawn McCarney     try
46338f85004SShawn McCarney     {
46438f85004SShawn McCarney         const json element = "";
46538f85004SShawn McCarney         parseHexByte(element);
46638f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
46738f85004SShawn McCarney     }
46838f85004SShawn McCarney     catch (const std::invalid_argument& e)
46938f85004SShawn McCarney     {
47038f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
47138f85004SShawn McCarney     }
47238f85004SShawn McCarney 
47338f85004SShawn McCarney     // Test where fails: "f"
47438f85004SShawn McCarney     try
47538f85004SShawn McCarney     {
47638f85004SShawn McCarney         const json element = R"( "f" )"_json;
47738f85004SShawn McCarney         parseHexByte(element);
47838f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
47938f85004SShawn McCarney     }
48038f85004SShawn McCarney     catch (const std::invalid_argument& e)
48138f85004SShawn McCarney     {
48238f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
48338f85004SShawn McCarney     }
48438f85004SShawn McCarney 
48538f85004SShawn McCarney     // Test where fails: "0x"
48638f85004SShawn McCarney     try
48738f85004SShawn McCarney     {
48838f85004SShawn McCarney         const json element = R"( "0x" )"_json;
48938f85004SShawn McCarney         parseHexByte(element);
49038f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
49138f85004SShawn McCarney     }
49238f85004SShawn McCarney     catch (const std::invalid_argument& e)
49338f85004SShawn McCarney     {
49438f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
49538f85004SShawn McCarney     }
49638f85004SShawn McCarney 
49738f85004SShawn McCarney     // Test where fails: "0Xff"
49838f85004SShawn McCarney     try
49938f85004SShawn McCarney     {
50038f85004SShawn McCarney         const json element = R"( "0XFF" )"_json;
50138f85004SShawn McCarney         parseHexByte(element);
50238f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
50338f85004SShawn McCarney     }
50438f85004SShawn McCarney     catch (const std::invalid_argument& e)
50538f85004SShawn McCarney     {
50638f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
50738f85004SShawn McCarney     }
508*f1845c06SShawn McCarney 
509*f1845c06SShawn McCarney     // Test where fails: Variable specified: Not a hex string
510*f1845c06SShawn McCarney     try
511*f1845c06SShawn McCarney     {
512*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "0xsz"}};
513*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
514*f1845c06SShawn McCarney         parseHexByte(element, variables);
515*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
516*f1845c06SShawn McCarney     }
517*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
518*f1845c06SShawn McCarney     {
519*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
520*f1845c06SShawn McCarney     }
52138f85004SShawn McCarney }
52238f85004SShawn McCarney 
52338f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseHexByteArray)
52438f85004SShawn McCarney {
52538f85004SShawn McCarney     // Test where works
52638f85004SShawn McCarney     {
52738f85004SShawn McCarney         const json element = R"( [ "0xCC", "0xFF" ] )"_json;
52838f85004SShawn McCarney         std::vector<uint8_t> hexBytes = parseHexByteArray(element);
52938f85004SShawn McCarney         std::vector<uint8_t> expected = {0xcc, 0xff};
53038f85004SShawn McCarney         EXPECT_EQ(hexBytes, expected);
53138f85004SShawn McCarney     }
53238f85004SShawn McCarney 
533*f1845c06SShawn McCarney     // Test where works: Variables specified
534*f1845c06SShawn McCarney     {
535*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "0xCC"},
536*f1845c06SShawn McCarney                                                      {"var2", "0xFF"}};
537*f1845c06SShawn McCarney         const json element = R"( [ "${var1}", "${var2}" ] )"_json;
538*f1845c06SShawn McCarney         std::vector<uint8_t> hexBytes = parseHexByteArray(element, variables);
539*f1845c06SShawn McCarney         std::vector<uint8_t> expected = {0xcc, 0xff};
540*f1845c06SShawn McCarney         EXPECT_EQ(hexBytes, expected);
541*f1845c06SShawn McCarney     }
542*f1845c06SShawn McCarney 
54338f85004SShawn McCarney     // Test where fails: Element is not an array
54438f85004SShawn McCarney     try
54538f85004SShawn McCarney     {
54638f85004SShawn McCarney         const json element = 0;
54738f85004SShawn McCarney         parseHexByteArray(element);
54838f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
54938f85004SShawn McCarney     }
55038f85004SShawn McCarney     catch (const std::invalid_argument& e)
55138f85004SShawn McCarney     {
55238f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an array");
55338f85004SShawn McCarney     }
554*f1845c06SShawn McCarney 
555*f1845c06SShawn McCarney     // Test where fails: Variables specified: Invalid byte value
556*f1845c06SShawn McCarney     try
557*f1845c06SShawn McCarney     {
558*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "0xCC"},
559*f1845c06SShawn McCarney                                                      {"var2", "99"}};
560*f1845c06SShawn McCarney         const json element = R"( [ "${var1}", "${var2}" ] )"_json;
561*f1845c06SShawn McCarney         parseHexByteArray(element, variables);
562*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
563*f1845c06SShawn McCarney     }
564*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
565*f1845c06SShawn McCarney     {
566*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
567*f1845c06SShawn McCarney     }
56838f85004SShawn McCarney }
56938f85004SShawn McCarney 
57038f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseInt8)
57138f85004SShawn McCarney {
57238f85004SShawn McCarney     // Test where works: INT8_MIN
57338f85004SShawn McCarney     {
57438f85004SShawn McCarney         const json element = R"( -128 )"_json;
57538f85004SShawn McCarney         int8_t value = parseInt8(element);
57638f85004SShawn McCarney         EXPECT_EQ(value, -128);
57738f85004SShawn McCarney     }
57838f85004SShawn McCarney 
57938f85004SShawn McCarney     // Test where works: INT8_MAX
58038f85004SShawn McCarney     {
58138f85004SShawn McCarney         const json element = R"( 127 )"_json;
58238f85004SShawn McCarney         int8_t value = parseInt8(element);
58338f85004SShawn McCarney         EXPECT_EQ(value, 127);
58438f85004SShawn McCarney     }
58538f85004SShawn McCarney 
586*f1845c06SShawn McCarney     // Test where works: Variable specified
587*f1845c06SShawn McCarney     {
588*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-23"}};
589*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
590*f1845c06SShawn McCarney         int8_t value = parseInt8(element, variables);
591*f1845c06SShawn McCarney         EXPECT_EQ(value, -23);
592*f1845c06SShawn McCarney     }
593*f1845c06SShawn McCarney 
59438f85004SShawn McCarney     // Test where fails: Element is not an integer
59538f85004SShawn McCarney     try
59638f85004SShawn McCarney     {
59738f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
59838f85004SShawn McCarney         parseInt8(element);
59938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
60038f85004SShawn McCarney     }
60138f85004SShawn McCarney     catch (const std::invalid_argument& e)
60238f85004SShawn McCarney     {
60338f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
60438f85004SShawn McCarney     }
60538f85004SShawn McCarney 
60638f85004SShawn McCarney     // Test where fails: Value < INT8_MIN
60738f85004SShawn McCarney     try
60838f85004SShawn McCarney     {
60938f85004SShawn McCarney         const json element = R"( -129 )"_json;
61038f85004SShawn McCarney         parseInt8(element);
61138f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
61238f85004SShawn McCarney     }
61338f85004SShawn McCarney     catch (const std::invalid_argument& e)
61438f85004SShawn McCarney     {
61538f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
61638f85004SShawn McCarney     }
61738f85004SShawn McCarney 
61838f85004SShawn McCarney     // Test where fails: Value > INT8_MAX
61938f85004SShawn McCarney     try
62038f85004SShawn McCarney     {
62138f85004SShawn McCarney         const json element = R"( 128 )"_json;
62238f85004SShawn McCarney         parseInt8(element);
62338f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
62438f85004SShawn McCarney     }
62538f85004SShawn McCarney     catch (const std::invalid_argument& e)
62638f85004SShawn McCarney     {
62738f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
62838f85004SShawn McCarney     }
629*f1845c06SShawn McCarney 
630*f1845c06SShawn McCarney     // Test where fails: Variable specified: Value > INT8_MAX
631*f1845c06SShawn McCarney     try
632*f1845c06SShawn McCarney     {
633*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "128"}};
634*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
635*f1845c06SShawn McCarney         parseInt8(element, variables);
636*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
637*f1845c06SShawn McCarney     }
638*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
639*f1845c06SShawn McCarney     {
640*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
641*f1845c06SShawn McCarney     }
642*f1845c06SShawn McCarney }
643*f1845c06SShawn McCarney 
644*f1845c06SShawn McCarney TEST(JSONParserUtilsTests, ParseInteger)
645*f1845c06SShawn McCarney {
646*f1845c06SShawn McCarney     // Test where works: Zero
647*f1845c06SShawn McCarney     {
648*f1845c06SShawn McCarney         const json element = R"( 0 )"_json;
649*f1845c06SShawn McCarney         int value = parseInteger(element);
650*f1845c06SShawn McCarney         EXPECT_EQ(value, 0);
651*f1845c06SShawn McCarney     }
652*f1845c06SShawn McCarney 
653*f1845c06SShawn McCarney     // Test where works: Positive value
654*f1845c06SShawn McCarney     {
655*f1845c06SShawn McCarney         const json element = R"( 103 )"_json;
656*f1845c06SShawn McCarney         int value = parseInteger(element);
657*f1845c06SShawn McCarney         EXPECT_EQ(value, 103);
658*f1845c06SShawn McCarney     }
659*f1845c06SShawn McCarney 
660*f1845c06SShawn McCarney     // Test where works: Negative value
661*f1845c06SShawn McCarney     {
662*f1845c06SShawn McCarney         const json element = R"( -24 )"_json;
663*f1845c06SShawn McCarney         int value = parseInteger(element);
664*f1845c06SShawn McCarney         EXPECT_EQ(value, -24);
665*f1845c06SShawn McCarney     }
666*f1845c06SShawn McCarney 
667*f1845c06SShawn McCarney     // Test where works: Variable specified: Positive value
668*f1845c06SShawn McCarney     {
669*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "1024"}};
670*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
671*f1845c06SShawn McCarney         int value = parseInteger(element, variables);
672*f1845c06SShawn McCarney         EXPECT_EQ(value, 1024);
673*f1845c06SShawn McCarney     }
674*f1845c06SShawn McCarney 
675*f1845c06SShawn McCarney     // Test where works: Variable specified: Negative value
676*f1845c06SShawn McCarney     {
677*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-9924"}};
678*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
679*f1845c06SShawn McCarney         int value = parseInteger(element, variables);
680*f1845c06SShawn McCarney         EXPECT_EQ(value, -9924);
681*f1845c06SShawn McCarney     }
682*f1845c06SShawn McCarney 
683*f1845c06SShawn McCarney     // Test where fails: Element is not a integer
684*f1845c06SShawn McCarney     try
685*f1845c06SShawn McCarney     {
686*f1845c06SShawn McCarney         const json element = R"( true )"_json;
687*f1845c06SShawn McCarney         parseInteger(element);
688*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
689*f1845c06SShawn McCarney     }
690*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
691*f1845c06SShawn McCarney     {
692*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
693*f1845c06SShawn McCarney     }
694*f1845c06SShawn McCarney 
695*f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
696*f1845c06SShawn McCarney     try
697*f1845c06SShawn McCarney     {
698*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
699*f1845c06SShawn McCarney         parseInteger(element);
700*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
701*f1845c06SShawn McCarney     }
702*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
703*f1845c06SShawn McCarney     {
704*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
705*f1845c06SShawn McCarney     }
706*f1845c06SShawn McCarney 
707*f1845c06SShawn McCarney     // Test where fails: Variable specified: Leading whitespace
708*f1845c06SShawn McCarney     try
709*f1845c06SShawn McCarney     {
710*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", " -13"}};
711*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
712*f1845c06SShawn McCarney         parseInteger(element, variables);
713*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
714*f1845c06SShawn McCarney     }
715*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
716*f1845c06SShawn McCarney     {
717*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
718*f1845c06SShawn McCarney     }
719*f1845c06SShawn McCarney 
720*f1845c06SShawn McCarney     // Test where fails: Variable specified: Trailing whitespace
721*f1845c06SShawn McCarney     try
722*f1845c06SShawn McCarney     {
723*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-13 "}};
724*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
725*f1845c06SShawn McCarney         parseInteger(element, variables);
726*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
727*f1845c06SShawn McCarney     }
728*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
729*f1845c06SShawn McCarney     {
730*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
731*f1845c06SShawn McCarney     }
732*f1845c06SShawn McCarney 
733*f1845c06SShawn McCarney     // Test where fails: Variable specified: Starts with non-number character
734*f1845c06SShawn McCarney     try
735*f1845c06SShawn McCarney     {
736*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "x-13"}};
737*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
738*f1845c06SShawn McCarney         parseInteger(element, variables);
739*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
740*f1845c06SShawn McCarney     }
741*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
742*f1845c06SShawn McCarney     {
743*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
744*f1845c06SShawn McCarney     }
745*f1845c06SShawn McCarney 
746*f1845c06SShawn McCarney     // Test where fails: Variable specified: Ends with non-number character
747*f1845c06SShawn McCarney     try
748*f1845c06SShawn McCarney     {
749*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-13x"}};
750*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
751*f1845c06SShawn McCarney         parseInteger(element, variables);
752*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
753*f1845c06SShawn McCarney     }
754*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
755*f1845c06SShawn McCarney     {
756*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
757*f1845c06SShawn McCarney     }
758*f1845c06SShawn McCarney 
759*f1845c06SShawn McCarney     // Test where fails: Variable specified: Not an integer
760*f1845c06SShawn McCarney     try
761*f1845c06SShawn McCarney     {
762*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "foo"}};
763*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
764*f1845c06SShawn McCarney         parseInteger(element, variables);
765*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
766*f1845c06SShawn McCarney     }
767*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
768*f1845c06SShawn McCarney     {
769*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
770*f1845c06SShawn McCarney     }
77138f85004SShawn McCarney }
77238f85004SShawn McCarney 
77338f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseString)
77438f85004SShawn McCarney {
77538f85004SShawn McCarney     // Test where works: Empty string
77638f85004SShawn McCarney     {
77738f85004SShawn McCarney         const json element = "";
77838f85004SShawn McCarney         std::string value = parseString(element, true);
77938f85004SShawn McCarney         EXPECT_EQ(value, "");
78038f85004SShawn McCarney     }
78138f85004SShawn McCarney 
78238f85004SShawn McCarney     // Test where works: Non-empty string
78338f85004SShawn McCarney     {
78438f85004SShawn McCarney         const json element = "vdd_regulator";
78538f85004SShawn McCarney         std::string value = parseString(element, false);
78638f85004SShawn McCarney         EXPECT_EQ(value, "vdd_regulator");
78738f85004SShawn McCarney     }
78838f85004SShawn McCarney 
789*f1845c06SShawn McCarney     // Test where works: Variable specified: Empty string
790*f1845c06SShawn McCarney     {
791*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", ""}};
792*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
793*f1845c06SShawn McCarney         std::string value = parseString(element, true, variables);
794*f1845c06SShawn McCarney         EXPECT_EQ(value, "");
795*f1845c06SShawn McCarney     }
796*f1845c06SShawn McCarney 
797*f1845c06SShawn McCarney     // Test where works: Variable specified: Non-empty string
798*f1845c06SShawn McCarney     {
799*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
800*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
801*f1845c06SShawn McCarney         std::string value = parseString(element, false, variables);
802*f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
803*f1845c06SShawn McCarney     }
804*f1845c06SShawn McCarney 
80538f85004SShawn McCarney     // Test where fails: Element is not a string
80638f85004SShawn McCarney     try
80738f85004SShawn McCarney     {
80838f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
80938f85004SShawn McCarney         parseString(element);
81038f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
81138f85004SShawn McCarney     }
81238f85004SShawn McCarney     catch (const std::invalid_argument& e)
81338f85004SShawn McCarney     {
81438f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a string");
81538f85004SShawn McCarney     }
81638f85004SShawn McCarney 
81738f85004SShawn McCarney     // Test where fails: Empty string
81838f85004SShawn McCarney     try
81938f85004SShawn McCarney     {
82038f85004SShawn McCarney         const json element = "";
82138f85004SShawn McCarney         parseString(element);
82238f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
82338f85004SShawn McCarney     }
82438f85004SShawn McCarney     catch (const std::invalid_argument& e)
82538f85004SShawn McCarney     {
82638f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an empty string");
82738f85004SShawn McCarney     }
828*f1845c06SShawn McCarney 
829*f1845c06SShawn McCarney     // Test where fails: Variable specified: Empty string
830*f1845c06SShawn McCarney     try
831*f1845c06SShawn McCarney     {
832*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", ""}};
833*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
834*f1845c06SShawn McCarney         parseString(element, false, variables);
835*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
836*f1845c06SShawn McCarney     }
837*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
838*f1845c06SShawn McCarney     {
839*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an empty string");
840*f1845c06SShawn McCarney     }
841*f1845c06SShawn McCarney 
842*f1845c06SShawn McCarney     // Test where fails: Variable specified: Variable not defined
843*f1845c06SShawn McCarney     try
844*f1845c06SShawn McCarney     {
845*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "foo"}};
846*f1845c06SShawn McCarney         const json element = R"( "${var2}" )"_json;
847*f1845c06SShawn McCarney         parseString(element, false, variables);
848*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
849*f1845c06SShawn McCarney     }
850*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
851*f1845c06SShawn McCarney     {
852*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Undefined variable: var2");
853*f1845c06SShawn McCarney     }
85438f85004SShawn McCarney }
85538f85004SShawn McCarney 
85638f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseUint8)
85738f85004SShawn McCarney {
85838f85004SShawn McCarney     // Test where works: 0
85938f85004SShawn McCarney     {
86038f85004SShawn McCarney         const json element = R"( 0 )"_json;
86138f85004SShawn McCarney         uint8_t value = parseUint8(element);
86238f85004SShawn McCarney         EXPECT_EQ(value, 0);
86338f85004SShawn McCarney     }
86438f85004SShawn McCarney 
86538f85004SShawn McCarney     // Test where works: UINT8_MAX
86638f85004SShawn McCarney     {
86738f85004SShawn McCarney         const json element = R"( 255 )"_json;
86838f85004SShawn McCarney         uint8_t value = parseUint8(element);
86938f85004SShawn McCarney         EXPECT_EQ(value, 255);
87038f85004SShawn McCarney     }
87138f85004SShawn McCarney 
872*f1845c06SShawn McCarney     // Test where works: Variable specified
873*f1845c06SShawn McCarney     {
874*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "19"}};
875*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
876*f1845c06SShawn McCarney         uint8_t value = parseUint8(element, variables);
877*f1845c06SShawn McCarney         EXPECT_EQ(value, 19);
878*f1845c06SShawn McCarney     }
879*f1845c06SShawn McCarney 
88038f85004SShawn McCarney     // Test where fails: Element is not an integer
88138f85004SShawn McCarney     try
88238f85004SShawn McCarney     {
88338f85004SShawn McCarney         const json element = R"( 1.03 )"_json;
88438f85004SShawn McCarney         parseUint8(element);
88538f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
88638f85004SShawn McCarney     }
88738f85004SShawn McCarney     catch (const std::invalid_argument& e)
88838f85004SShawn McCarney     {
88938f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
89038f85004SShawn McCarney     }
89138f85004SShawn McCarney 
89238f85004SShawn McCarney     // Test where fails: Value < 0
89338f85004SShawn McCarney     try
89438f85004SShawn McCarney     {
89538f85004SShawn McCarney         const json element = R"( -1 )"_json;
89638f85004SShawn McCarney         parseUint8(element);
89738f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
89838f85004SShawn McCarney     }
89938f85004SShawn McCarney     catch (const std::invalid_argument& e)
90038f85004SShawn McCarney     {
90138f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
90238f85004SShawn McCarney     }
90338f85004SShawn McCarney 
90438f85004SShawn McCarney     // Test where fails: Value > UINT8_MAX
90538f85004SShawn McCarney     try
90638f85004SShawn McCarney     {
90738f85004SShawn McCarney         const json element = R"( 256 )"_json;
90838f85004SShawn McCarney         parseUint8(element);
90938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
91038f85004SShawn McCarney     }
91138f85004SShawn McCarney     catch (const std::invalid_argument& e)
91238f85004SShawn McCarney     {
91338f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
91438f85004SShawn McCarney     }
915*f1845c06SShawn McCarney 
916*f1845c06SShawn McCarney     // Test where fails: Variable specified: Value > UINT8_MAX
917*f1845c06SShawn McCarney     try
918*f1845c06SShawn McCarney     {
919*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "256"}};
920*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
921*f1845c06SShawn McCarney         parseUint8(element, variables);
922*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
923*f1845c06SShawn McCarney     }
924*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
925*f1845c06SShawn McCarney     {
926*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
927*f1845c06SShawn McCarney     }
92838f85004SShawn McCarney }
92938f85004SShawn McCarney 
93038f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseUnsignedInteger)
93138f85004SShawn McCarney {
93238f85004SShawn McCarney     // Test where works: 1
93338f85004SShawn McCarney     {
93438f85004SShawn McCarney         const json element = R"( 1 )"_json;
93538f85004SShawn McCarney         unsigned int value = parseUnsignedInteger(element);
93638f85004SShawn McCarney         EXPECT_EQ(value, 1);
93738f85004SShawn McCarney     }
93838f85004SShawn McCarney 
939*f1845c06SShawn McCarney     // Test where works: Variable specified
940*f1845c06SShawn McCarney     {
941*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "25678"}};
942*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
943*f1845c06SShawn McCarney         unsigned int value = parseUnsignedInteger(element, variables);
944*f1845c06SShawn McCarney         EXPECT_EQ(value, 25678);
945*f1845c06SShawn McCarney     }
946*f1845c06SShawn McCarney 
94738f85004SShawn McCarney     // Test where fails: Element is not an integer
94838f85004SShawn McCarney     try
94938f85004SShawn McCarney     {
95038f85004SShawn McCarney         const json element = R"( 1.5 )"_json;
95138f85004SShawn McCarney         parseUnsignedInteger(element);
95238f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
95338f85004SShawn McCarney     }
95438f85004SShawn McCarney     catch (const std::invalid_argument& e)
95538f85004SShawn McCarney     {
956*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
95738f85004SShawn McCarney     }
95838f85004SShawn McCarney 
95938f85004SShawn McCarney     // Test where fails: Value < 0
96038f85004SShawn McCarney     try
96138f85004SShawn McCarney     {
96238f85004SShawn McCarney         const json element = R"( -1 )"_json;
96338f85004SShawn McCarney         parseUnsignedInteger(element);
96438f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
96538f85004SShawn McCarney     }
96638f85004SShawn McCarney     catch (const std::invalid_argument& e)
96738f85004SShawn McCarney     {
96838f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
96938f85004SShawn McCarney     }
970*f1845c06SShawn McCarney 
971*f1845c06SShawn McCarney     // Test where fails: Variable specified: Value < 0
972*f1845c06SShawn McCarney     try
973*f1845c06SShawn McCarney     {
974*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-23"}};
975*f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
976*f1845c06SShawn McCarney         parseUnsignedInteger(element, variables);
977*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
978*f1845c06SShawn McCarney     }
979*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
980*f1845c06SShawn McCarney     {
981*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
982*f1845c06SShawn McCarney     }
98338f85004SShawn McCarney }
98438f85004SShawn McCarney 
98538f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsArray)
98638f85004SShawn McCarney {
98738f85004SShawn McCarney     // Test where element is an array
98838f85004SShawn McCarney     {
98938f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
99038f85004SShawn McCarney         verifyIsArray(element);
99138f85004SShawn McCarney     }
99238f85004SShawn McCarney 
99338f85004SShawn McCarney     // Test where element is not an array
99438f85004SShawn McCarney     try
99538f85004SShawn McCarney     {
99638f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
99738f85004SShawn McCarney         verifyIsArray(element);
99838f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
99938f85004SShawn McCarney     }
100038f85004SShawn McCarney     catch (const std::invalid_argument& e)
100138f85004SShawn McCarney     {
100238f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an array");
100338f85004SShawn McCarney     }
100438f85004SShawn McCarney }
100538f85004SShawn McCarney 
100638f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsObject)
100738f85004SShawn McCarney {
100838f85004SShawn McCarney     // Test where element is an object
100938f85004SShawn McCarney     {
101038f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
101138f85004SShawn McCarney         verifyIsObject(element);
101238f85004SShawn McCarney     }
101338f85004SShawn McCarney 
101438f85004SShawn McCarney     // Test where element is not an object
101538f85004SShawn McCarney     try
101638f85004SShawn McCarney     {
101738f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
101838f85004SShawn McCarney         verifyIsObject(element);
101938f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
102038f85004SShawn McCarney     }
102138f85004SShawn McCarney     catch (const std::invalid_argument& e)
102238f85004SShawn McCarney     {
102338f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an object");
102438f85004SShawn McCarney     }
102538f85004SShawn McCarney }
102638f85004SShawn McCarney 
102738f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyPropertyCount)
102838f85004SShawn McCarney {
102938f85004SShawn McCarney     // Test where element has expected number of properties
103038f85004SShawn McCarney     {
103138f85004SShawn McCarney         const json element = R"(
103238f85004SShawn McCarney             {
103338f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
103438f85004SShawn McCarney               "id": "set_voltage_rule"
103538f85004SShawn McCarney             }
103638f85004SShawn McCarney         )"_json;
103738f85004SShawn McCarney         verifyPropertyCount(element, 2);
103838f85004SShawn McCarney     }
103938f85004SShawn McCarney 
104038f85004SShawn McCarney     // Test where element has unexpected number of properties
104138f85004SShawn McCarney     try
104238f85004SShawn McCarney     {
104338f85004SShawn McCarney         const json element = R"(
104438f85004SShawn McCarney             {
104538f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
104638f85004SShawn McCarney               "id": "set_voltage_rule",
104738f85004SShawn McCarney               "foo": 1.3
104838f85004SShawn McCarney             }
104938f85004SShawn McCarney         )"_json;
105038f85004SShawn McCarney         verifyPropertyCount(element, 2);
105138f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
105238f85004SShawn McCarney     }
105338f85004SShawn McCarney     catch (const std::invalid_argument& e)
105438f85004SShawn McCarney     {
105538f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an invalid property");
105638f85004SShawn McCarney     }
105738f85004SShawn McCarney }
1058*f1845c06SShawn McCarney 
1059*f1845c06SShawn McCarney TEST(JSONParserUtilsTests, ExpandVariables)
1060*f1845c06SShawn McCarney {
1061*f1845c06SShawn McCarney     // Test where works: Single variable: Variable is entire value: Lower case
1062*f1845c06SShawn McCarney     // in variable name
1063*f1845c06SShawn McCarney     {
1064*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
1065*f1845c06SShawn McCarney         std::string value{"${var}"};
1066*f1845c06SShawn McCarney         expandVariables(value, variables);
1067*f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
1068*f1845c06SShawn McCarney     }
1069*f1845c06SShawn McCarney 
1070*f1845c06SShawn McCarney     // Test where works: Multiple variables: Variables are part of value: Upper
1071*f1845c06SShawn McCarney     // case and underscore in variable name
1072*f1845c06SShawn McCarney     {
1073*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{
1074*f1845c06SShawn McCarney             {"CHASSIS_NUMBER", "1"}, {"REGULATOR", "vcs_vio"}, {"RAIL", "vio"}};
1075*f1845c06SShawn McCarney         std::string value{
1076*f1845c06SShawn McCarney             "chassis${CHASSIS_NUMBER}_${REGULATOR}_regulator_${RAIL}_rail"};
1077*f1845c06SShawn McCarney         expandVariables(value, variables);
1078*f1845c06SShawn McCarney         EXPECT_EQ(value, "chassis1_vcs_vio_regulator_vio_rail");
1079*f1845c06SShawn McCarney     }
1080*f1845c06SShawn McCarney 
1081*f1845c06SShawn McCarney     // Test where works: Variable at start of value: Number in variable name
1082*f1845c06SShawn McCarney     {
1083*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "vio_regulator"}};
1084*f1845c06SShawn McCarney         std::string value{"${var1}_rail"};
1085*f1845c06SShawn McCarney         expandVariables(value, variables);
1086*f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator_rail");
1087*f1845c06SShawn McCarney     }
1088*f1845c06SShawn McCarney 
1089*f1845c06SShawn McCarney     // Test where works: Variable at end of value
1090*f1845c06SShawn McCarney     {
1091*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", "3"}};
1092*f1845c06SShawn McCarney         std::string value{
1093*f1845c06SShawn McCarney             "/xyz/openbmc_project/inventory/system/chassis${chassis_number}"};
1094*f1845c06SShawn McCarney         expandVariables(value, variables);
1095*f1845c06SShawn McCarney         EXPECT_EQ(value, "/xyz/openbmc_project/inventory/system/chassis3");
1096*f1845c06SShawn McCarney     }
1097*f1845c06SShawn McCarney 
1098*f1845c06SShawn McCarney     // Test where works: Variable has empty value: Start of value
1099*f1845c06SShawn McCarney     {
1100*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_prefix", ""}};
1101*f1845c06SShawn McCarney         std::string value{"${chassis_prefix}vio_regulator"};
1102*f1845c06SShawn McCarney         expandVariables(value, variables);
1103*f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
1104*f1845c06SShawn McCarney     }
1105*f1845c06SShawn McCarney 
1106*f1845c06SShawn McCarney     // Test where works: Variable has empty value: Middle of value
1107*f1845c06SShawn McCarney     {
1108*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", ""}};
1109*f1845c06SShawn McCarney         std::string value{"c${chassis_number}_vio_regulator"};
1110*f1845c06SShawn McCarney         expandVariables(value, variables);
1111*f1845c06SShawn McCarney         EXPECT_EQ(value, "c_vio_regulator");
1112*f1845c06SShawn McCarney     }
1113*f1845c06SShawn McCarney 
1114*f1845c06SShawn McCarney     // Test where works: Variable has empty value: End of value
1115*f1845c06SShawn McCarney     {
1116*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", ""}};
1117*f1845c06SShawn McCarney         std::string value{
1118*f1845c06SShawn McCarney             "/xyz/openbmc_project/inventory/system/chassis${chassis_number}"};
1119*f1845c06SShawn McCarney         expandVariables(value, variables);
1120*f1845c06SShawn McCarney         EXPECT_EQ(value, "/xyz/openbmc_project/inventory/system/chassis");
1121*f1845c06SShawn McCarney     }
1122*f1845c06SShawn McCarney 
1123*f1845c06SShawn McCarney     // Test where works: No variables specified
1124*f1845c06SShawn McCarney     {
1125*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
1126*f1845c06SShawn McCarney         std::string value{"vcs_rail"};
1127*f1845c06SShawn McCarney         expandVariables(value, variables);
1128*f1845c06SShawn McCarney         EXPECT_EQ(value, "vcs_rail");
1129*f1845c06SShawn McCarney     }
1130*f1845c06SShawn McCarney 
1131*f1845c06SShawn McCarney     // Test where works: Nested variable expansion
1132*f1845c06SShawn McCarney     {
1133*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "${var2}"},
1134*f1845c06SShawn McCarney                                                      {"var2", "vio_reg"}};
1135*f1845c06SShawn McCarney         std::string value{"${var1}_rail"};
1136*f1845c06SShawn McCarney         expandVariables(value, variables);
1137*f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_reg_rail");
1138*f1845c06SShawn McCarney     }
1139*f1845c06SShawn McCarney 
1140*f1845c06SShawn McCarney     // Test where fails: Variables map is empty
1141*f1845c06SShawn McCarney     {
1142*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{};
1143*f1845c06SShawn McCarney         std::string value{"${var}_rail"};
1144*f1845c06SShawn McCarney         expandVariables(value, variables);
1145*f1845c06SShawn McCarney         EXPECT_EQ(value, "${var}_rail");
1146*f1845c06SShawn McCarney     }
1147*f1845c06SShawn McCarney 
1148*f1845c06SShawn McCarney     // Test where fails: Variable missing $
1149*f1845c06SShawn McCarney     {
1150*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1151*f1845c06SShawn McCarney         std::string value{"{var}_rail"};
1152*f1845c06SShawn McCarney         expandVariables(value, variables);
1153*f1845c06SShawn McCarney         EXPECT_EQ(value, "{var}_rail");
1154*f1845c06SShawn McCarney     }
1155*f1845c06SShawn McCarney 
1156*f1845c06SShawn McCarney     // Test where fails: Variable missing {
1157*f1845c06SShawn McCarney     {
1158*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1159*f1845c06SShawn McCarney         std::string value{"$var}_rail"};
1160*f1845c06SShawn McCarney         expandVariables(value, variables);
1161*f1845c06SShawn McCarney         EXPECT_EQ(value, "$var}_rail");
1162*f1845c06SShawn McCarney     }
1163*f1845c06SShawn McCarney 
1164*f1845c06SShawn McCarney     // Test where fails: Variable missing }
1165*f1845c06SShawn McCarney     {
1166*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1167*f1845c06SShawn McCarney         std::string value{"${var_rail"};
1168*f1845c06SShawn McCarney         expandVariables(value, variables);
1169*f1845c06SShawn McCarney         EXPECT_EQ(value, "${var_rail");
1170*f1845c06SShawn McCarney     }
1171*f1845c06SShawn McCarney 
1172*f1845c06SShawn McCarney     // Test where fails: Variable missing name
1173*f1845c06SShawn McCarney     {
1174*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1175*f1845c06SShawn McCarney         std::string value{"${}_rail"};
1176*f1845c06SShawn McCarney         expandVariables(value, variables);
1177*f1845c06SShawn McCarney         EXPECT_EQ(value, "${}_rail");
1178*f1845c06SShawn McCarney     }
1179*f1845c06SShawn McCarney 
1180*f1845c06SShawn McCarney     // Test where fails: Variable name has invalid characters
1181*f1845c06SShawn McCarney     {
1182*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var-2", "vio_reg"}};
1183*f1845c06SShawn McCarney         std::string value{"${var-2}_rail"};
1184*f1845c06SShawn McCarney         expandVariables(value, variables);
1185*f1845c06SShawn McCarney         EXPECT_EQ(value, "${var-2}_rail");
1186*f1845c06SShawn McCarney     }
1187*f1845c06SShawn McCarney 
1188*f1845c06SShawn McCarney     // Test where fails: Variable has unexpected whitespace
1189*f1845c06SShawn McCarney     {
1190*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1191*f1845c06SShawn McCarney         std::string value{"${ var }_rail"};
1192*f1845c06SShawn McCarney         expandVariables(value, variables);
1193*f1845c06SShawn McCarney         EXPECT_EQ(value, "${ var }_rail");
1194*f1845c06SShawn McCarney     }
1195*f1845c06SShawn McCarney 
1196*f1845c06SShawn McCarney     // Test where fails: Undefined variable
1197*f1845c06SShawn McCarney     try
1198*f1845c06SShawn McCarney     {
1199*f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1200*f1845c06SShawn McCarney         std::string value{"${foo}_rail"};
1201*f1845c06SShawn McCarney         expandVariables(value, variables);
1202*f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
1203*f1845c06SShawn McCarney     }
1204*f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
1205*f1845c06SShawn McCarney     {
1206*f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Undefined variable: foo");
1207*f1845c06SShawn McCarney     }
1208*f1845c06SShawn McCarney }
1209