TemplateCharReplace: fix failing testcase and add more

This fix the failing test and adds a couple more
tests.

Tested:
Test cases pass

Change-Id: I39435c7f938da007826682d17a670609ccc4704d
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 4662c2a..010a55a 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -174,7 +174,11 @@
             boost::ifind_first(*strPtr, templateName);
         if (find)
         {
+            constexpr const std::array<char, 5> mathChars = {'+', '-', '%', '*',
+                                                             '/'};
             size_t start = find.begin() - strPtr->begin();
+            size_t nextItemIdx = start + templateName.size() + 1;
+
             // check for additional operations
             if (!start && find.end() == strPtr->end())
             {
@@ -182,20 +186,22 @@
                            foundDevicePair.second);
                 return;
             }
-            else if (find.end() == strPtr->end())
+            else if (nextItemIdx > strPtr->size() ||
+                     std::find(mathChars.begin(), mathChars.end(),
+                               strPtr->at(nextItemIdx)) == mathChars.end())
             {
                 std::string val = std::visit(VariantToStringVisitor(),
                                              foundDevicePair.second);
                 boost::replace_all(*strPtr,
                                    templateChar + foundDevicePair.first, val);
-                return;
+                continue;
             }
 
             // save the prefix
             std::string prefix = strPtr->substr(0, start);
 
-            // operate on the rest (+1 for trailing space)
-            std::string end = strPtr->substr(start + templateName.size() + 1);
+            // operate on the rest
+            std::string end = strPtr->substr(nextItemIdx);
 
             std::vector<std::string> split;
             boost::split(split, end, boost::is_any_of(" "));
diff --git a/test/test_entity-manager.cpp b/test/test_entity-manager.cpp
index 653a982..7dc1c72 100644
--- a/test/test_entity-manager.cpp
+++ b/test/test_entity-manager.cpp
@@ -45,9 +45,6 @@
     EXPECT_EQ(expected, j["foo"]);
 }
 
-/*
-TODO This should work
-
 TEST(TemplateCharReplace, replaceMiddleStr)
 {
     nlohmann::json j = {{"foo", "the $TEST worked"}};
@@ -60,7 +57,6 @@
     nlohmann::json expected = "the Test worked";
     EXPECT_EQ(expected, j["foo"]);
 }
-*/
 
 TEST(TemplateCharReplace, replaceLastStr)
 {
@@ -138,4 +134,45 @@
 
     nlohmann::json expected = "4 / 2 equals 2";
     EXPECT_EQ(expected, j["foo"]);
+}
+
+TEST(TemplateCharReplace, multiMath)
+{
+    nlohmann::json j = {{"foo", "4 * 2 % 6 equals $TEST * 2 % 6"}};
+    auto it = j.begin();
+    boost::container::flat_map<std::string, BasicVariantType> data;
+    data["TEST"] = 4;
+
+    templateCharReplace(it, data, 0);
+
+    nlohmann::json expected = "4 * 2 % 6 equals 2";
+    EXPECT_EQ(expected, j["foo"]);
+}
+
+TEST(TemplateCharReplace, twoReplacements)
+{
+    nlohmann::json j = {{"foo", "$FOO $BAR"}};
+    auto it = j.begin();
+    boost::container::flat_map<std::string, BasicVariantType> data;
+    data["FOO"] = std::string("foo");
+    data["BAR"] = std::string("bar");
+
+    templateCharReplace(it, data, 0);
+
+    nlohmann::json expected = "foo bar";
+    EXPECT_EQ(expected, j["foo"]);
+}
+
+TEST(TemplateCharReplace, twoReplacementsWithMath)
+{
+    nlohmann::json j = {{"foo", "4 / 2 equals $TEST / 2 $BAR"}};
+    auto it = j.begin();
+    boost::container::flat_map<std::string, BasicVariantType> data;
+    data["TEST"] = 4;
+    data["BAR"] = std::string("bar");
+
+    templateCharReplace(it, data, 0);
+
+    nlohmann::json expected = "4 / 2 equals 2 bar";
+    EXPECT_EQ(expected, j["foo"]);
 }
\ No newline at end of file