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