regulators: Add phase fault type to parser

Enhance the JSON configuration file parser to support the new
phase fault type values.

Add gtest test cases to exercise new code.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: If5ac011f740fdb6f24692c713a56d4947709d660
diff --git a/phosphor-regulators/src/config_file_parser.cpp b/phosphor-regulators/src/config_file_parser.cpp
index be28fdc..5330f59 100644
--- a/phosphor-regulators/src/config_file_parser.cpp
+++ b/phosphor-regulators/src/config_file_parser.cpp
@@ -738,6 +738,27 @@
     return std::make_unique<OrAction>(std::move(actions));
 }
 
+PhaseFaultType parsePhaseFaultType(const json& element)
+{
+    std::string value = parseString(element);
+    PhaseFaultType type{};
+
+    if (value == "n")
+    {
+        type = PhaseFaultType::n;
+    }
+    else if (value == "n+1")
+    {
+        type = PhaseFaultType::n_plus_1;
+    }
+    else
+    {
+        throw std::invalid_argument{"Element is not a phase fault type"};
+    }
+
+    return type;
+}
+
 std::unique_ptr<PMBusReadSensorAction> parsePMBusReadSensor(const json& element)
 {
     verifyIsObject(element);
@@ -1054,11 +1075,7 @@
 
 SensorType parseSensorType(const json& element)
 {
-    if (!element.is_string())
-    {
-        throw std::invalid_argument{"Element is not a string"};
-    }
-    std::string value = element.get<std::string>();
+    std::string value = parseString(element);
     SensorType type{};
 
     if (value == "iout")
diff --git a/phosphor-regulators/src/config_file_parser.hpp b/phosphor-regulators/src/config_file_parser.hpp
index 1062ced..a1bdd6e 100644
--- a/phosphor-regulators/src/config_file_parser.hpp
+++ b/phosphor-regulators/src/config_file_parser.hpp
@@ -33,6 +33,7 @@
 #include "if_action.hpp"
 #include "not_action.hpp"
 #include "or_action.hpp"
+#include "phase_fault.hpp"
 #include "pmbus_read_sensor_action.hpp"
 #include "pmbus_write_vout_command_action.hpp"
 #include "presence_detection.hpp"
@@ -539,6 +540,18 @@
 std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
 
 /**
+ * Parses a JSON element containing a PhaseFaultType expressed as a string.
+ *
+ * Returns the corresponding PhaseFaultType enum value.
+ *
+ * Throws an exception if parsing fails.
+ *
+ * @param element JSON element
+ * @return PhaseFaultType enum value
+ */
+PhaseFaultType parsePhaseFaultType(const nlohmann::json& element);
+
+/**
  * Parses a JSON element containing a pmbus_read_sensor action.
  *
  * Returns the corresponding C++ PMBusReadSensorAction object.
diff --git a/phosphor-regulators/test/config_file_parser_tests.cpp b/phosphor-regulators/test/config_file_parser_tests.cpp
index 27df51e..cf261fa 100644
--- a/phosphor-regulators/test/config_file_parser_tests.cpp
+++ b/phosphor-regulators/test/config_file_parser_tests.cpp
@@ -32,6 +32,7 @@
 #include "i2c_write_bytes_action.hpp"
 #include "not_action.hpp"
 #include "or_action.hpp"
+#include "phase_fault.hpp"
 #include "pmbus_read_sensor_action.hpp"
 #include "pmbus_utils.hpp"
 #include "pmbus_write_vout_command_action.hpp"
@@ -3399,6 +3400,47 @@
     }
 }
 
+TEST(ConfigFileParserTests, ParsePhaseFaultType)
+{
+    // Test where works: n
+    {
+        const json element = "n";
+        PhaseFaultType type = parsePhaseFaultType(element);
+        EXPECT_EQ(type, PhaseFaultType::n);
+    }
+
+    // Test where works: n+1
+    {
+        const json element = "n+1";
+        PhaseFaultType type = parsePhaseFaultType(element);
+        EXPECT_EQ(type, PhaseFaultType::n_plus_1);
+    }
+
+    // Test where fails: Element is not a phase fault type
+    try
+    {
+        const json element = "n+2";
+        parsePhaseFaultType(element);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not a phase fault type");
+    }
+
+    // Test where fails: Element is not a string
+    try
+    {
+        const json element = R"( { "foo": "bar" } )"_json;
+        parsePhaseFaultType(element);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not a string");
+    }
+}
+
 TEST(ConfigFileParserTests, ParsePMBusReadSensor)
 {
     // Test where works: Only required properties specified