xref: /openbmc/phosphor-power/test/json_parser_utils_tests.cpp (revision 8873f428276818761348b4091574334870ae51a7)
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;
29f1845c06SShawn McCarney using namespace phosphor::power::json_parser_utils::internal;
3038f85004SShawn McCarney using json = nlohmann::json;
3138f85004SShawn McCarney 
TEST(JSONParserUtilsTests,GetRequiredProperty)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 
TEST(JSONParserUtilsTests,ParseBitPosition)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 
70f1845c06SShawn McCarney     // Test where works: Variable specified
71f1845c06SShawn McCarney     {
72f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_pos", "3"}};
73f1845c06SShawn McCarney         const json element = R"( "${bit_pos}" )"_json;
74f1845c06SShawn McCarney         uint8_t value = parseBitPosition(element, variables);
75f1845c06SShawn McCarney         EXPECT_EQ(value, 3);
76f1845c06SShawn McCarney     }
77f1845c06SShawn 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     }
113f1845c06SShawn McCarney 
114f1845c06SShawn McCarney     // Test where fails: Variable specified: Value < 0
115f1845c06SShawn McCarney     try
116f1845c06SShawn McCarney     {
117f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_pos", "-1"}};
118f1845c06SShawn McCarney         const json element = R"( "${bit_pos}" )"_json;
119f1845c06SShawn McCarney         parseBitPosition(element, variables);
120f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
121f1845c06SShawn McCarney     }
122f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
123f1845c06SShawn McCarney     {
124f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a bit position");
125f1845c06SShawn McCarney     }
12638f85004SShawn McCarney }
12738f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseBitValue)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 
144f1845c06SShawn McCarney     // Test where works: Variable specified
145f1845c06SShawn McCarney     {
146f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_val", "1"}};
147f1845c06SShawn McCarney         const json element = R"( "${bit_val}" )"_json;
148f1845c06SShawn McCarney         uint8_t value = parseBitValue(element, variables);
149f1845c06SShawn McCarney         EXPECT_EQ(value, 1);
150f1845c06SShawn McCarney     }
151f1845c06SShawn 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     }
187f1845c06SShawn McCarney 
188f1845c06SShawn McCarney     // Test where fails: Variable specified: Not an integer
189f1845c06SShawn McCarney     try
190f1845c06SShawn McCarney     {
191f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bit_val", "one"}};
192f1845c06SShawn McCarney         const json element = R"( "${bit_val}" )"_json;
193f1845c06SShawn McCarney         parseBitValue(element, variables);
194f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
195f1845c06SShawn McCarney     }
196f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
197f1845c06SShawn McCarney     {
198f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
199f1845c06SShawn McCarney     }
20038f85004SShawn McCarney }
20138f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseBoolean)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 
218f1845c06SShawn McCarney     // Test where works: Variable specified: true
219f1845c06SShawn McCarney     {
220f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "true"}};
221f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
222f1845c06SShawn McCarney         bool value = parseBoolean(element, variables);
223f1845c06SShawn McCarney         EXPECT_EQ(value, true);
224f1845c06SShawn McCarney     }
225f1845c06SShawn McCarney 
226f1845c06SShawn McCarney     // Test where works: Variable specified: false
227f1845c06SShawn McCarney     {
228f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "false"}};
229f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
230f1845c06SShawn McCarney         bool value = parseBoolean(element, variables);
231f1845c06SShawn McCarney         EXPECT_EQ(value, false);
232f1845c06SShawn McCarney     }
233f1845c06SShawn 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     }
245f1845c06SShawn McCarney 
246f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
247f1845c06SShawn McCarney     try
248f1845c06SShawn McCarney     {
249f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
250f1845c06SShawn McCarney         parseBoolean(element);
251f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
252f1845c06SShawn McCarney     }
253f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
254f1845c06SShawn McCarney     {
255f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
256f1845c06SShawn McCarney     }
257f1845c06SShawn McCarney 
258f1845c06SShawn McCarney     // Test where fails: Variable specified: Value is not a boolean
259f1845c06SShawn McCarney     try
260f1845c06SShawn McCarney     {
261f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"bool_val", "3.2"}};
262f1845c06SShawn McCarney         const json element = R"( "${bool_val}" )"_json;
263f1845c06SShawn McCarney         parseBoolean(element, variables);
264f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
265f1845c06SShawn McCarney     }
266f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
267f1845c06SShawn McCarney     {
268f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a boolean");
269f1845c06SShawn McCarney     }
27038f85004SShawn McCarney }
27138f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseDouble)27238f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseDouble)
27338f85004SShawn McCarney {
274f1845c06SShawn 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 
281f1845c06SShawn McCarney     // Test where works: Integer value
28238f85004SShawn McCarney     {
283f1845c06SShawn McCarney         const json element = R"( -24 )"_json;
28438f85004SShawn McCarney         double value = parseDouble(element);
285f1845c06SShawn McCarney         EXPECT_EQ(value, -24.0);
286f1845c06SShawn McCarney     }
287f1845c06SShawn McCarney 
288f1845c06SShawn McCarney     // Test where works: Variable specified: Floating point value
289f1845c06SShawn McCarney     {
290f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03"}};
291f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
292f1845c06SShawn McCarney         double value = parseDouble(element, variables);
293f1845c06SShawn McCarney         EXPECT_EQ(value, -1.03);
294f1845c06SShawn McCarney     }
295f1845c06SShawn McCarney 
296f1845c06SShawn McCarney     // Test where works: Variable specified: Integer value
297f1845c06SShawn McCarney     {
298f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "24"}};
299f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
300f1845c06SShawn McCarney         double value = parseDouble(element, variables);
30138f85004SShawn McCarney         EXPECT_EQ(value, 24.0);
30238f85004SShawn McCarney     }
30338f85004SShawn McCarney 
304f1845c06SShawn 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     {
313f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
314f1845c06SShawn McCarney     }
315f1845c06SShawn McCarney 
316f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
317f1845c06SShawn McCarney     try
318f1845c06SShawn McCarney     {
319f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
320f1845c06SShawn McCarney         parseDouble(element);
321f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
322f1845c06SShawn McCarney     }
323f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
324f1845c06SShawn McCarney     {
325f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
326f1845c06SShawn McCarney     }
327f1845c06SShawn McCarney 
328f1845c06SShawn McCarney     // Test where fails: Variable specified: Leading whitespace
329f1845c06SShawn McCarney     try
330f1845c06SShawn McCarney     {
331f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", " -1.03"}};
332f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
333f1845c06SShawn McCarney         parseDouble(element, variables);
334f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
335f1845c06SShawn McCarney     }
336f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
337f1845c06SShawn McCarney     {
338f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
339f1845c06SShawn McCarney     }
340f1845c06SShawn McCarney 
341f1845c06SShawn McCarney     // Test where fails: Variable specified: Trailing whitespace
342f1845c06SShawn McCarney     try
343f1845c06SShawn McCarney     {
344f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03 "}};
345f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
346f1845c06SShawn McCarney         parseDouble(element, variables);
347f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
348f1845c06SShawn McCarney     }
349f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
350f1845c06SShawn McCarney     {
351f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
352f1845c06SShawn McCarney     }
353f1845c06SShawn McCarney 
354f1845c06SShawn McCarney     // Test where fails: Variable specified: Starts with non-number character
355f1845c06SShawn McCarney     try
356f1845c06SShawn McCarney     {
357f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "x-1.03"}};
358f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
359f1845c06SShawn McCarney         parseDouble(element, variables);
360f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
361f1845c06SShawn McCarney     }
362f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
363f1845c06SShawn McCarney     {
364f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
365f1845c06SShawn McCarney     }
366f1845c06SShawn McCarney 
367f1845c06SShawn McCarney     // Test where fails: Variable specified: Ends with non-number character
368f1845c06SShawn McCarney     try
369f1845c06SShawn McCarney     {
370f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-1.03x"}};
371f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
372f1845c06SShawn McCarney         parseDouble(element, variables);
373f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
374f1845c06SShawn McCarney     }
375f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
376f1845c06SShawn McCarney     {
377f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
378f1845c06SShawn McCarney     }
379f1845c06SShawn McCarney 
380f1845c06SShawn McCarney     // Test where fails: Variable specified: Not a double
381f1845c06SShawn McCarney     try
382f1845c06SShawn McCarney     {
383f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "foo"}};
384f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
385f1845c06SShawn McCarney         parseDouble(element, variables);
386f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
387f1845c06SShawn McCarney     }
388f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
389f1845c06SShawn McCarney     {
390f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a double");
39138f85004SShawn McCarney     }
39238f85004SShawn McCarney }
39338f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseHexByte)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 
417f1845c06SShawn McCarney     // Test where works: Variable specified
418f1845c06SShawn McCarney     {
419f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "ed"}};
420f1845c06SShawn McCarney         const json element = R"( "0x${var}" )"_json;
421f1845c06SShawn McCarney         uint8_t value = parseHexByte(element, variables);
422f1845c06SShawn McCarney         EXPECT_EQ(value, 0xed);
423f1845c06SShawn McCarney     }
424f1845c06SShawn 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     }
508f1845c06SShawn McCarney 
509f1845c06SShawn McCarney     // Test where fails: Variable specified: Not a hex string
510f1845c06SShawn McCarney     try
511f1845c06SShawn McCarney     {
512f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "0xsz"}};
513f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
514f1845c06SShawn McCarney         parseHexByte(element, variables);
515f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
516f1845c06SShawn McCarney     }
517f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
518f1845c06SShawn McCarney     {
519f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
520f1845c06SShawn McCarney     }
52138f85004SShawn McCarney }
52238f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseHexByteArray)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 
533f1845c06SShawn McCarney     // Test where works: Variables specified
534f1845c06SShawn McCarney     {
535f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "0xCC"},
536f1845c06SShawn McCarney                                                      {"var2", "0xFF"}};
537f1845c06SShawn McCarney         const json element = R"( [ "${var1}", "${var2}" ] )"_json;
538f1845c06SShawn McCarney         std::vector<uint8_t> hexBytes = parseHexByteArray(element, variables);
539f1845c06SShawn McCarney         std::vector<uint8_t> expected = {0xcc, 0xff};
540f1845c06SShawn McCarney         EXPECT_EQ(hexBytes, expected);
541f1845c06SShawn McCarney     }
542f1845c06SShawn 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     }
554f1845c06SShawn McCarney 
555f1845c06SShawn McCarney     // Test where fails: Variables specified: Invalid byte value
556f1845c06SShawn McCarney     try
557f1845c06SShawn McCarney     {
558f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "0xCC"},
559f1845c06SShawn McCarney                                                      {"var2", "99"}};
560f1845c06SShawn McCarney         const json element = R"( [ "${var1}", "${var2}" ] )"_json;
561f1845c06SShawn McCarney         parseHexByteArray(element, variables);
562f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
563f1845c06SShawn McCarney     }
564f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
565f1845c06SShawn McCarney     {
566f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not hexadecimal string");
567f1845c06SShawn McCarney     }
56838f85004SShawn McCarney }
56938f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseInt8)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 
586f1845c06SShawn McCarney     // Test where works: Variable specified
587f1845c06SShawn McCarney     {
588f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-23"}};
589f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
590f1845c06SShawn McCarney         int8_t value = parseInt8(element, variables);
591f1845c06SShawn McCarney         EXPECT_EQ(value, -23);
592f1845c06SShawn McCarney     }
593f1845c06SShawn 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     }
629f1845c06SShawn McCarney 
630f1845c06SShawn McCarney     // Test where fails: Variable specified: Value > INT8_MAX
631f1845c06SShawn McCarney     try
632f1845c06SShawn McCarney     {
633f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "128"}};
634f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
635f1845c06SShawn McCarney         parseInt8(element, variables);
636f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
637f1845c06SShawn McCarney     }
638f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
639f1845c06SShawn McCarney     {
640f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit signed integer");
641f1845c06SShawn McCarney     }
642f1845c06SShawn McCarney }
643f1845c06SShawn McCarney 
TEST(JSONParserUtilsTests,ParseInteger)644f1845c06SShawn McCarney TEST(JSONParserUtilsTests, ParseInteger)
645f1845c06SShawn McCarney {
646f1845c06SShawn McCarney     // Test where works: Zero
647f1845c06SShawn McCarney     {
648f1845c06SShawn McCarney         const json element = R"( 0 )"_json;
649f1845c06SShawn McCarney         int value = parseInteger(element);
650f1845c06SShawn McCarney         EXPECT_EQ(value, 0);
651f1845c06SShawn McCarney     }
652f1845c06SShawn McCarney 
653f1845c06SShawn McCarney     // Test where works: Positive value
654f1845c06SShawn McCarney     {
655f1845c06SShawn McCarney         const json element = R"( 103 )"_json;
656f1845c06SShawn McCarney         int value = parseInteger(element);
657f1845c06SShawn McCarney         EXPECT_EQ(value, 103);
658f1845c06SShawn McCarney     }
659f1845c06SShawn McCarney 
660f1845c06SShawn McCarney     // Test where works: Negative value
661f1845c06SShawn McCarney     {
662f1845c06SShawn McCarney         const json element = R"( -24 )"_json;
663f1845c06SShawn McCarney         int value = parseInteger(element);
664f1845c06SShawn McCarney         EXPECT_EQ(value, -24);
665f1845c06SShawn McCarney     }
666f1845c06SShawn McCarney 
667f1845c06SShawn McCarney     // Test where works: Variable specified: Positive value
668f1845c06SShawn McCarney     {
669f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "1024"}};
670f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
671f1845c06SShawn McCarney         int value = parseInteger(element, variables);
672f1845c06SShawn McCarney         EXPECT_EQ(value, 1024);
673f1845c06SShawn McCarney     }
674f1845c06SShawn McCarney 
675f1845c06SShawn McCarney     // Test where works: Variable specified: Negative value
676f1845c06SShawn McCarney     {
677f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-9924"}};
678f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
679f1845c06SShawn McCarney         int value = parseInteger(element, variables);
680f1845c06SShawn McCarney         EXPECT_EQ(value, -9924);
681f1845c06SShawn McCarney     }
682f1845c06SShawn McCarney 
683f1845c06SShawn McCarney     // Test where fails: Element is not a integer
684f1845c06SShawn McCarney     try
685f1845c06SShawn McCarney     {
686f1845c06SShawn McCarney         const json element = R"( true )"_json;
687f1845c06SShawn McCarney         parseInteger(element);
688f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
689f1845c06SShawn McCarney     }
690f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
691f1845c06SShawn McCarney     {
692f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
693f1845c06SShawn McCarney     }
694f1845c06SShawn McCarney 
695f1845c06SShawn McCarney     // Test where fails: Variable specified: Variables map not specified
696f1845c06SShawn McCarney     try
697f1845c06SShawn McCarney     {
698f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
699f1845c06SShawn McCarney         parseInteger(element);
700f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
701f1845c06SShawn McCarney     }
702f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
703f1845c06SShawn McCarney     {
704f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
705f1845c06SShawn McCarney     }
706f1845c06SShawn McCarney 
707f1845c06SShawn McCarney     // Test where fails: Variable specified: Leading whitespace
708f1845c06SShawn McCarney     try
709f1845c06SShawn McCarney     {
710f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", " -13"}};
711f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
712f1845c06SShawn McCarney         parseInteger(element, variables);
713f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
714f1845c06SShawn McCarney     }
715f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
716f1845c06SShawn McCarney     {
717f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
718f1845c06SShawn McCarney     }
719f1845c06SShawn McCarney 
720f1845c06SShawn McCarney     // Test where fails: Variable specified: Trailing whitespace
721f1845c06SShawn McCarney     try
722f1845c06SShawn McCarney     {
723f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-13 "}};
724f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
725f1845c06SShawn McCarney         parseInteger(element, variables);
726f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
727f1845c06SShawn McCarney     }
728f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
729f1845c06SShawn McCarney     {
730f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
731f1845c06SShawn McCarney     }
732f1845c06SShawn McCarney 
733f1845c06SShawn McCarney     // Test where fails: Variable specified: Starts with non-number character
734f1845c06SShawn McCarney     try
735f1845c06SShawn McCarney     {
736f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "x-13"}};
737f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
738f1845c06SShawn McCarney         parseInteger(element, variables);
739f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
740f1845c06SShawn McCarney     }
741f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
742f1845c06SShawn McCarney     {
743f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
744f1845c06SShawn McCarney     }
745f1845c06SShawn McCarney 
746f1845c06SShawn McCarney     // Test where fails: Variable specified: Ends with non-number character
747f1845c06SShawn McCarney     try
748f1845c06SShawn McCarney     {
749f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-13x"}};
750f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
751f1845c06SShawn McCarney         parseInteger(element, variables);
752f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
753f1845c06SShawn McCarney     }
754f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
755f1845c06SShawn McCarney     {
756f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
757f1845c06SShawn McCarney     }
758f1845c06SShawn McCarney 
759f1845c06SShawn McCarney     // Test where fails: Variable specified: Not an integer
760f1845c06SShawn McCarney     try
761f1845c06SShawn McCarney     {
762f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "foo"}};
763f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
764f1845c06SShawn McCarney         parseInteger(element, variables);
765f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
766f1845c06SShawn McCarney     }
767f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
768f1845c06SShawn McCarney     {
769f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
770f1845c06SShawn McCarney     }
77138f85004SShawn McCarney }
77238f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseString)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 
789f1845c06SShawn McCarney     // Test where works: Variable specified: Empty string
790f1845c06SShawn McCarney     {
791f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", ""}};
792f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
793f1845c06SShawn McCarney         std::string value = parseString(element, true, variables);
794f1845c06SShawn McCarney         EXPECT_EQ(value, "");
795f1845c06SShawn McCarney     }
796f1845c06SShawn McCarney 
797f1845c06SShawn McCarney     // Test where works: Variable specified: Non-empty string
798f1845c06SShawn McCarney     {
799f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
800f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
801f1845c06SShawn McCarney         std::string value = parseString(element, false, variables);
802f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
803f1845c06SShawn McCarney     }
804f1845c06SShawn 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     }
828f1845c06SShawn McCarney 
829f1845c06SShawn McCarney     // Test where fails: Variable specified: Empty string
830f1845c06SShawn McCarney     try
831f1845c06SShawn McCarney     {
832f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", ""}};
833f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
834f1845c06SShawn McCarney         parseString(element, false, variables);
835f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
836f1845c06SShawn McCarney     }
837f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
838f1845c06SShawn McCarney     {
839f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an empty string");
840f1845c06SShawn McCarney     }
841f1845c06SShawn McCarney 
842f1845c06SShawn McCarney     // Test where fails: Variable specified: Variable not defined
843f1845c06SShawn McCarney     try
844f1845c06SShawn McCarney     {
845f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "foo"}};
846f1845c06SShawn McCarney         const json element = R"( "${var2}" )"_json;
847f1845c06SShawn McCarney         parseString(element, false, variables);
848f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
849f1845c06SShawn McCarney     }
850f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
851f1845c06SShawn McCarney     {
852f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Undefined variable: var2");
853f1845c06SShawn McCarney     }
85438f85004SShawn McCarney }
85538f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseUint8)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 
872f1845c06SShawn McCarney     // Test where works: Variable specified
873f1845c06SShawn McCarney     {
874f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "19"}};
875f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
876f1845c06SShawn McCarney         uint8_t value = parseUint8(element, variables);
877f1845c06SShawn McCarney         EXPECT_EQ(value, 19);
878f1845c06SShawn McCarney     }
879f1845c06SShawn 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     }
915f1845c06SShawn McCarney 
916f1845c06SShawn McCarney     // Test where fails: Variable specified: Value > UINT8_MAX
917f1845c06SShawn McCarney     try
918f1845c06SShawn McCarney     {
919f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "256"}};
920f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
921f1845c06SShawn McCarney         parseUint8(element, variables);
922f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
923f1845c06SShawn McCarney     }
924f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
925f1845c06SShawn McCarney     {
926f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an 8-bit unsigned integer");
927f1845c06SShawn McCarney     }
92838f85004SShawn McCarney }
92938f85004SShawn McCarney 
TEST(JSONParserUtilsTests,ParseUint16)930*8873f428SShawn McCarney TEST(JSONParserUtilsTests, ParseUint16)
931*8873f428SShawn McCarney {
932*8873f428SShawn McCarney     // Test where works: 0
933*8873f428SShawn McCarney     {
934*8873f428SShawn McCarney         const json element = R"( 0 )"_json;
935*8873f428SShawn McCarney         uint16_t value = parseUint16(element);
936*8873f428SShawn McCarney         EXPECT_EQ(value, 0);
937*8873f428SShawn McCarney     }
938*8873f428SShawn McCarney 
939*8873f428SShawn McCarney     // Test where works: UINT16_MAX
940*8873f428SShawn McCarney     {
941*8873f428SShawn McCarney         const json element = R"( 65535 )"_json;
942*8873f428SShawn McCarney         uint16_t value = parseUint16(element);
943*8873f428SShawn McCarney         EXPECT_EQ(value, 65535);
944*8873f428SShawn McCarney     }
945*8873f428SShawn McCarney 
946*8873f428SShawn McCarney     // Test where works: Variable specified
947*8873f428SShawn McCarney     {
948*8873f428SShawn McCarney         std::map<std::string, std::string> variables{{"var", "24699"}};
949*8873f428SShawn McCarney         const json element = R"( "${var}" )"_json;
950*8873f428SShawn McCarney         uint16_t value = parseUint16(element, variables);
951*8873f428SShawn McCarney         EXPECT_EQ(value, 24699);
952*8873f428SShawn McCarney     }
953*8873f428SShawn McCarney 
954*8873f428SShawn McCarney     // Test where fails: Element is not an integer
955*8873f428SShawn McCarney     try
956*8873f428SShawn McCarney     {
957*8873f428SShawn McCarney         const json element = R"( 1.03 )"_json;
958*8873f428SShawn McCarney         parseUint16(element);
959*8873f428SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
960*8873f428SShawn McCarney     }
961*8873f428SShawn McCarney     catch (const std::invalid_argument& e)
962*8873f428SShawn McCarney     {
963*8873f428SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
964*8873f428SShawn McCarney     }
965*8873f428SShawn McCarney 
966*8873f428SShawn McCarney     // Test where fails: Value < 0
967*8873f428SShawn McCarney     try
968*8873f428SShawn McCarney     {
969*8873f428SShawn McCarney         const json element = R"( -1 )"_json;
970*8873f428SShawn McCarney         parseUint16(element);
971*8873f428SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
972*8873f428SShawn McCarney     }
973*8873f428SShawn McCarney     catch (const std::invalid_argument& e)
974*8873f428SShawn McCarney     {
975*8873f428SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
976*8873f428SShawn McCarney     }
977*8873f428SShawn McCarney 
978*8873f428SShawn McCarney     // Test where fails: Value > UINT16_MAX
979*8873f428SShawn McCarney     try
980*8873f428SShawn McCarney     {
981*8873f428SShawn McCarney         const json element = R"( 65536 )"_json;
982*8873f428SShawn McCarney         parseUint16(element);
983*8873f428SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
984*8873f428SShawn McCarney     }
985*8873f428SShawn McCarney     catch (const std::invalid_argument& e)
986*8873f428SShawn McCarney     {
987*8873f428SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
988*8873f428SShawn McCarney     }
989*8873f428SShawn McCarney 
990*8873f428SShawn McCarney     // Test where fails: Variable specified: Value > UINT16_MAX
991*8873f428SShawn McCarney     try
992*8873f428SShawn McCarney     {
993*8873f428SShawn McCarney         std::map<std::string, std::string> variables{{"var", "65536"}};
994*8873f428SShawn McCarney         const json element = R"( "${var}" )"_json;
995*8873f428SShawn McCarney         parseUint16(element, variables);
996*8873f428SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
997*8873f428SShawn McCarney     }
998*8873f428SShawn McCarney     catch (const std::invalid_argument& e)
999*8873f428SShawn McCarney     {
1000*8873f428SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
1001*8873f428SShawn McCarney     }
1002*8873f428SShawn McCarney }
1003*8873f428SShawn McCarney 
TEST(JSONParserUtilsTests,ParseUnsignedInteger)100438f85004SShawn McCarney TEST(JSONParserUtilsTests, ParseUnsignedInteger)
100538f85004SShawn McCarney {
100638f85004SShawn McCarney     // Test where works: 1
100738f85004SShawn McCarney     {
100838f85004SShawn McCarney         const json element = R"( 1 )"_json;
100938f85004SShawn McCarney         unsigned int value = parseUnsignedInteger(element);
101038f85004SShawn McCarney         EXPECT_EQ(value, 1);
101138f85004SShawn McCarney     }
101238f85004SShawn McCarney 
1013f1845c06SShawn McCarney     // Test where works: Variable specified
1014f1845c06SShawn McCarney     {
1015f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "25678"}};
1016f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
1017f1845c06SShawn McCarney         unsigned int value = parseUnsignedInteger(element, variables);
1018f1845c06SShawn McCarney         EXPECT_EQ(value, 25678);
1019f1845c06SShawn McCarney     }
1020f1845c06SShawn McCarney 
102138f85004SShawn McCarney     // Test where fails: Element is not an integer
102238f85004SShawn McCarney     try
102338f85004SShawn McCarney     {
102438f85004SShawn McCarney         const json element = R"( 1.5 )"_json;
102538f85004SShawn McCarney         parseUnsignedInteger(element);
102638f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
102738f85004SShawn McCarney     }
102838f85004SShawn McCarney     catch (const std::invalid_argument& e)
102938f85004SShawn McCarney     {
1030f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an integer");
103138f85004SShawn McCarney     }
103238f85004SShawn McCarney 
103338f85004SShawn McCarney     // Test where fails: Value < 0
103438f85004SShawn McCarney     try
103538f85004SShawn McCarney     {
103638f85004SShawn McCarney         const json element = R"( -1 )"_json;
103738f85004SShawn McCarney         parseUnsignedInteger(element);
103838f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
103938f85004SShawn McCarney     }
104038f85004SShawn McCarney     catch (const std::invalid_argument& e)
104138f85004SShawn McCarney     {
104238f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
104338f85004SShawn McCarney     }
1044f1845c06SShawn McCarney 
1045f1845c06SShawn McCarney     // Test where fails: Variable specified: Value < 0
1046f1845c06SShawn McCarney     try
1047f1845c06SShawn McCarney     {
1048f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "-23"}};
1049f1845c06SShawn McCarney         const json element = R"( "${var}" )"_json;
1050f1845c06SShawn McCarney         parseUnsignedInteger(element, variables);
1051f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
1052f1845c06SShawn McCarney     }
1053f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
1054f1845c06SShawn McCarney     {
1055f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an unsigned integer");
1056f1845c06SShawn McCarney     }
105738f85004SShawn McCarney }
105838f85004SShawn McCarney 
TEST(JSONParserUtilsTests,VerifyIsArray)105938f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsArray)
106038f85004SShawn McCarney {
106138f85004SShawn McCarney     // Test where element is an array
106238f85004SShawn McCarney     {
106338f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
106438f85004SShawn McCarney         verifyIsArray(element);
106538f85004SShawn McCarney     }
106638f85004SShawn McCarney 
106738f85004SShawn McCarney     // Test where element is not an array
106838f85004SShawn McCarney     try
106938f85004SShawn McCarney     {
107038f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
107138f85004SShawn McCarney         verifyIsArray(element);
107238f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
107338f85004SShawn McCarney     }
107438f85004SShawn McCarney     catch (const std::invalid_argument& e)
107538f85004SShawn McCarney     {
107638f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an array");
107738f85004SShawn McCarney     }
107838f85004SShawn McCarney }
107938f85004SShawn McCarney 
TEST(JSONParserUtilsTests,VerifyIsObject)108038f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyIsObject)
108138f85004SShawn McCarney {
108238f85004SShawn McCarney     // Test where element is an object
108338f85004SShawn McCarney     {
108438f85004SShawn McCarney         const json element = R"( { "foo": "bar" } )"_json;
108538f85004SShawn McCarney         verifyIsObject(element);
108638f85004SShawn McCarney     }
108738f85004SShawn McCarney 
108838f85004SShawn McCarney     // Test where element is not an object
108938f85004SShawn McCarney     try
109038f85004SShawn McCarney     {
109138f85004SShawn McCarney         const json element = R"( [ "foo", "bar" ] )"_json;
109238f85004SShawn McCarney         verifyIsObject(element);
109338f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
109438f85004SShawn McCarney     }
109538f85004SShawn McCarney     catch (const std::invalid_argument& e)
109638f85004SShawn McCarney     {
109738f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element is not an object");
109838f85004SShawn McCarney     }
109938f85004SShawn McCarney }
110038f85004SShawn McCarney 
TEST(JSONParserUtilsTests,VerifyPropertyCount)110138f85004SShawn McCarney TEST(JSONParserUtilsTests, VerifyPropertyCount)
110238f85004SShawn McCarney {
110338f85004SShawn McCarney     // Test where element has expected number of properties
110438f85004SShawn McCarney     {
110538f85004SShawn McCarney         const json element = R"(
110638f85004SShawn McCarney             {
110738f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
110838f85004SShawn McCarney               "id": "set_voltage_rule"
110938f85004SShawn McCarney             }
111038f85004SShawn McCarney         )"_json;
111138f85004SShawn McCarney         verifyPropertyCount(element, 2);
111238f85004SShawn McCarney     }
111338f85004SShawn McCarney 
111438f85004SShawn McCarney     // Test where element has unexpected number of properties
111538f85004SShawn McCarney     try
111638f85004SShawn McCarney     {
111738f85004SShawn McCarney         const json element = R"(
111838f85004SShawn McCarney             {
111938f85004SShawn McCarney               "comments": [ "Set voltage rule" ],
112038f85004SShawn McCarney               "id": "set_voltage_rule",
112138f85004SShawn McCarney               "foo": 1.3
112238f85004SShawn McCarney             }
112338f85004SShawn McCarney         )"_json;
112438f85004SShawn McCarney         verifyPropertyCount(element, 2);
112538f85004SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
112638f85004SShawn McCarney     }
112738f85004SShawn McCarney     catch (const std::invalid_argument& e)
112838f85004SShawn McCarney     {
112938f85004SShawn McCarney         EXPECT_STREQ(e.what(), "Element contains an invalid property");
113038f85004SShawn McCarney     }
113138f85004SShawn McCarney }
1132f1845c06SShawn McCarney 
TEST(JSONParserUtilsTests,ExpandVariables)1133f1845c06SShawn McCarney TEST(JSONParserUtilsTests, ExpandVariables)
1134f1845c06SShawn McCarney {
1135f1845c06SShawn McCarney     // Test where works: Single variable: Variable is entire value: Lower case
1136f1845c06SShawn McCarney     // in variable name
1137f1845c06SShawn McCarney     {
1138f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
1139f1845c06SShawn McCarney         std::string value{"${var}"};
1140f1845c06SShawn McCarney         expandVariables(value, variables);
1141f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
1142f1845c06SShawn McCarney     }
1143f1845c06SShawn McCarney 
1144f1845c06SShawn McCarney     // Test where works: Multiple variables: Variables are part of value: Upper
1145f1845c06SShawn McCarney     // case and underscore in variable name
1146f1845c06SShawn McCarney     {
1147f1845c06SShawn McCarney         std::map<std::string, std::string> variables{
1148f1845c06SShawn McCarney             {"CHASSIS_NUMBER", "1"}, {"REGULATOR", "vcs_vio"}, {"RAIL", "vio"}};
1149f1845c06SShawn McCarney         std::string value{
1150f1845c06SShawn McCarney             "chassis${CHASSIS_NUMBER}_${REGULATOR}_regulator_${RAIL}_rail"};
1151f1845c06SShawn McCarney         expandVariables(value, variables);
1152f1845c06SShawn McCarney         EXPECT_EQ(value, "chassis1_vcs_vio_regulator_vio_rail");
1153f1845c06SShawn McCarney     }
1154f1845c06SShawn McCarney 
1155f1845c06SShawn McCarney     // Test where works: Variable at start of value: Number in variable name
1156f1845c06SShawn McCarney     {
1157f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "vio_regulator"}};
1158f1845c06SShawn McCarney         std::string value{"${var1}_rail"};
1159f1845c06SShawn McCarney         expandVariables(value, variables);
1160f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator_rail");
1161f1845c06SShawn McCarney     }
1162f1845c06SShawn McCarney 
1163f1845c06SShawn McCarney     // Test where works: Variable at end of value
1164f1845c06SShawn McCarney     {
1165f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", "3"}};
1166f1845c06SShawn McCarney         std::string value{
1167f1845c06SShawn McCarney             "/xyz/openbmc_project/inventory/system/chassis${chassis_number}"};
1168f1845c06SShawn McCarney         expandVariables(value, variables);
1169f1845c06SShawn McCarney         EXPECT_EQ(value, "/xyz/openbmc_project/inventory/system/chassis3");
1170f1845c06SShawn McCarney     }
1171f1845c06SShawn McCarney 
1172f1845c06SShawn McCarney     // Test where works: Variable has empty value: Start of value
1173f1845c06SShawn McCarney     {
1174f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_prefix", ""}};
1175f1845c06SShawn McCarney         std::string value{"${chassis_prefix}vio_regulator"};
1176f1845c06SShawn McCarney         expandVariables(value, variables);
1177f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_regulator");
1178f1845c06SShawn McCarney     }
1179f1845c06SShawn McCarney 
1180f1845c06SShawn McCarney     // Test where works: Variable has empty value: Middle of value
1181f1845c06SShawn McCarney     {
1182f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", ""}};
1183f1845c06SShawn McCarney         std::string value{"c${chassis_number}_vio_regulator"};
1184f1845c06SShawn McCarney         expandVariables(value, variables);
1185f1845c06SShawn McCarney         EXPECT_EQ(value, "c_vio_regulator");
1186f1845c06SShawn McCarney     }
1187f1845c06SShawn McCarney 
1188f1845c06SShawn McCarney     // Test where works: Variable has empty value: End of value
1189f1845c06SShawn McCarney     {
1190f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"chassis_number", ""}};
1191f1845c06SShawn McCarney         std::string value{
1192f1845c06SShawn McCarney             "/xyz/openbmc_project/inventory/system/chassis${chassis_number}"};
1193f1845c06SShawn McCarney         expandVariables(value, variables);
1194f1845c06SShawn McCarney         EXPECT_EQ(value, "/xyz/openbmc_project/inventory/system/chassis");
1195f1845c06SShawn McCarney     }
1196f1845c06SShawn McCarney 
1197f1845c06SShawn McCarney     // Test where works: No variables specified
1198f1845c06SShawn McCarney     {
1199f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_regulator"}};
1200f1845c06SShawn McCarney         std::string value{"vcs_rail"};
1201f1845c06SShawn McCarney         expandVariables(value, variables);
1202f1845c06SShawn McCarney         EXPECT_EQ(value, "vcs_rail");
1203f1845c06SShawn McCarney     }
1204f1845c06SShawn McCarney 
1205f1845c06SShawn McCarney     // Test where works: Nested variable expansion
1206f1845c06SShawn McCarney     {
1207f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var1", "${var2}"},
1208f1845c06SShawn McCarney                                                      {"var2", "vio_reg"}};
1209f1845c06SShawn McCarney         std::string value{"${var1}_rail"};
1210f1845c06SShawn McCarney         expandVariables(value, variables);
1211f1845c06SShawn McCarney         EXPECT_EQ(value, "vio_reg_rail");
1212f1845c06SShawn McCarney     }
1213f1845c06SShawn McCarney 
1214f1845c06SShawn McCarney     // Test where fails: Variables map is empty
1215f1845c06SShawn McCarney     {
1216f1845c06SShawn McCarney         std::map<std::string, std::string> variables{};
1217f1845c06SShawn McCarney         std::string value{"${var}_rail"};
1218f1845c06SShawn McCarney         expandVariables(value, variables);
1219f1845c06SShawn McCarney         EXPECT_EQ(value, "${var}_rail");
1220f1845c06SShawn McCarney     }
1221f1845c06SShawn McCarney 
1222f1845c06SShawn McCarney     // Test where fails: Variable missing $
1223f1845c06SShawn McCarney     {
1224f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1225f1845c06SShawn McCarney         std::string value{"{var}_rail"};
1226f1845c06SShawn McCarney         expandVariables(value, variables);
1227f1845c06SShawn McCarney         EXPECT_EQ(value, "{var}_rail");
1228f1845c06SShawn McCarney     }
1229f1845c06SShawn McCarney 
1230f1845c06SShawn McCarney     // Test where fails: Variable missing {
1231f1845c06SShawn McCarney     {
1232f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1233f1845c06SShawn McCarney         std::string value{"$var}_rail"};
1234f1845c06SShawn McCarney         expandVariables(value, variables);
1235f1845c06SShawn McCarney         EXPECT_EQ(value, "$var}_rail");
1236f1845c06SShawn McCarney     }
1237f1845c06SShawn McCarney 
1238f1845c06SShawn McCarney     // Test where fails: Variable missing }
1239f1845c06SShawn McCarney     {
1240f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1241f1845c06SShawn McCarney         std::string value{"${var_rail"};
1242f1845c06SShawn McCarney         expandVariables(value, variables);
1243f1845c06SShawn McCarney         EXPECT_EQ(value, "${var_rail");
1244f1845c06SShawn McCarney     }
1245f1845c06SShawn McCarney 
1246f1845c06SShawn McCarney     // Test where fails: Variable missing name
1247f1845c06SShawn McCarney     {
1248f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1249f1845c06SShawn McCarney         std::string value{"${}_rail"};
1250f1845c06SShawn McCarney         expandVariables(value, variables);
1251f1845c06SShawn McCarney         EXPECT_EQ(value, "${}_rail");
1252f1845c06SShawn McCarney     }
1253f1845c06SShawn McCarney 
1254f1845c06SShawn McCarney     // Test where fails: Variable name has invalid characters
1255f1845c06SShawn McCarney     {
1256f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var-2", "vio_reg"}};
1257f1845c06SShawn McCarney         std::string value{"${var-2}_rail"};
1258f1845c06SShawn McCarney         expandVariables(value, variables);
1259f1845c06SShawn McCarney         EXPECT_EQ(value, "${var-2}_rail");
1260f1845c06SShawn McCarney     }
1261f1845c06SShawn McCarney 
1262f1845c06SShawn McCarney     // Test where fails: Variable has unexpected whitespace
1263f1845c06SShawn McCarney     {
1264f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1265f1845c06SShawn McCarney         std::string value{"${ var }_rail"};
1266f1845c06SShawn McCarney         expandVariables(value, variables);
1267f1845c06SShawn McCarney         EXPECT_EQ(value, "${ var }_rail");
1268f1845c06SShawn McCarney     }
1269f1845c06SShawn McCarney 
1270f1845c06SShawn McCarney     // Test where fails: Undefined variable
1271f1845c06SShawn McCarney     try
1272f1845c06SShawn McCarney     {
1273f1845c06SShawn McCarney         std::map<std::string, std::string> variables{{"var", "vio_reg"}};
1274f1845c06SShawn McCarney         std::string value{"${foo}_rail"};
1275f1845c06SShawn McCarney         expandVariables(value, variables);
1276f1845c06SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
1277f1845c06SShawn McCarney     }
1278f1845c06SShawn McCarney     catch (const std::invalid_argument& e)
1279f1845c06SShawn McCarney     {
1280f1845c06SShawn McCarney         EXPECT_STREQ(e.what(), "Undefined variable: foo");
1281f1845c06SShawn McCarney     }
1282f1845c06SShawn McCarney }
1283