From ae80d45939bab1f4c72f2063c7a305fc8fd71910 Mon Sep 17 00:00:00 2001 From: youhy Date: Fri, 29 Jul 2022 14:22:44 -0700 Subject: [PATCH 1/4] add lcov excl to input check Signed-off-by: youhy --- src/Plugin.cc | 2 + src/Plugin_TEST.cc | 226 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/src/Plugin.cc b/src/Plugin.cc index b6c58d292..51935a459 100644 --- a/src/Plugin.cc +++ b/src/Plugin.cc @@ -289,9 +289,11 @@ std::string Plugin::ConfigStr() auto pluginElem = doc.FirstChildElement("plugin"); if (!pluginElem) { + // LCOV_EXCL_START ignerr << "Missing element, not updating config string." << std::endl; return this->configStr; + // LCOV_EXCL_STOP } // diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index 532171f97..3c5f63c37 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -134,3 +134,229 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(Getters)) ASSERT_NE(nullptr, plugin->CardItem()); ASSERT_NE(nullptr, plugin->Context()); } + +///////////////////////////////////////////////// +TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStr)) +{ + ignition::common::Console::SetVerbosity(4); + + Application app(g_argc, g_argv); + app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); + + // Load normal plugin + const char *pluginStr = + "" + " " + " World stats" + " true" + " true" + " 200" + " 300" + " 2" + " floating" + " " + " " + " " + " " + " " + ""; + + std::unordered_map pluginProps; + pluginProps["showTitleBar"] = "true"; + pluginProps["resizable"] = "true"; + pluginProps["height"] = "200"; + pluginProps["width"] = "300"; + pluginProps["z"] = "2"; + pluginProps["state"] = "floating"; + + tinyxml2::XMLDocument pluginDoc; + pluginDoc.Parse(pluginStr); + EXPECT_TRUE(app.LoadPlugin("WorldStats", + pluginDoc.FirstChildElement("plugin"))); + + // Create main window + auto win = app.findChild(); + ASSERT_NE(nullptr, win); + + // Check plugin count + EXPECT_EQ(1, win->findChildren().size()); + + // Get the output for ConfigStr() + std::string configStr; + tinyxml2::XMLDocument configDoc; + auto plugin = win->findChildren()[0]; + configStr = plugin->ConfigStr(); + configDoc.Parse(configStr.c_str()); + + // + auto pluginElem = configDoc.FirstChildElement("plugin"); + ASSERT_NE(nullptr, pluginElem); + + // + auto ignGuiElem = pluginElem->FirstChildElement("ignition-gui"); + ASSERT_NE(nullptr, ignGuiElem); + + // Iterate properties + for (auto propElem = ignGuiElem->FirstChildElement("property"); + propElem != nullptr;) + { + // If property in map, mark it as "Verified" + if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) + { + EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); + pluginProps[propElem->Attribute("key")] = "Verified"; + } + auto nextProp = propElem->NextSiblingElement("property"); + propElem = nextProp; + } + + // Verify all inputs properties are correct + for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) + { + EXPECT_EQ(itr->second, "Verified"); + } + +} + +///////////////////////////////////////////////// +TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoPlugin)) +{ + ignition::common::Console::SetVerbosity(4); + + Application app(g_argc, g_argv); + app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); + + // Load normal plugin + const char *pluginStr = ""; + + tinyxml2::XMLDocument pluginDoc; + pluginDoc.Parse(pluginStr); + EXPECT_TRUE(app.LoadPlugin("WorldStats", + pluginDoc.FirstChildElement("plugin"))); + + // Create main window + auto win = app.findChild(); + ASSERT_NE(nullptr, win); + + // Check plugin count + EXPECT_EQ(1, win->findChildren().size()); + + // Get the output for ConfigStr() + std::string configStr; + tinyxml2::XMLDocument configDoc; + auto plugin = win->findChildren()[0]; + configStr = plugin->ConfigStr(); + configDoc.Parse(configStr.c_str()); + + // ConfigStr() creates a plugin with default value when input doesn't + // contain a tag. + // We select a few to verify. + std::unordered_map pluginProps; + pluginProps["showTitleBar"] = "true"; + pluginProps["resizable"] = "true"; + pluginProps["height"] = "952"; + pluginProps["width"] = "1199"; + pluginProps["z"] = "0"; + pluginProps["state"] = "docked"; + + // + auto pluginElem = configDoc.FirstChildElement("plugin"); + ASSERT_NE(nullptr, pluginElem); + + // + auto ignGuiElem = pluginElem->FirstChildElement("ignition-gui"); + ASSERT_NE(nullptr, ignGuiElem); + + // Iterate properties + for (auto propElem = ignGuiElem->FirstChildElement("property"); + propElem != nullptr;) + { + // If property in map, mark it as "Verified" + if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) + { + EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); + pluginProps[propElem->Attribute("key")] = "Verified"; + } + auto nextProp = propElem->NextSiblingElement("property"); + propElem = nextProp; + } + + // Verify all selected inputs properties are correct + for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) + { + EXPECT_EQ(itr->second, "Verified"); + } +} + +///////////////////////////////////////////////// +TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoIgn)) +{ + ignition::common::Console::SetVerbosity(4); + + Application app(g_argc, g_argv); + app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); + + // Load normal plugin + const char *pluginStr = + "" + ""; + + tinyxml2::XMLDocument pluginDoc; + pluginDoc.Parse(pluginStr); + EXPECT_TRUE(app.LoadPlugin("WorldStats", + pluginDoc.FirstChildElement("plugin"))); + + // Create main window + auto win = app.findChild(); + ASSERT_NE(nullptr, win); + + // Check plugin count + EXPECT_EQ(1, win->findChildren().size()); + + // Get the output for ConfigStr() + std::string configStr; + tinyxml2::XMLDocument configDoc; + auto plugin = win->findChildren()[0]; + configStr = plugin->ConfigStr(); + configDoc.Parse(configStr.c_str()); + + // ConfigStr() creates a plugin with default value when input doesn't + // contain a tag. + // We select a few to verify. + std::unordered_map pluginProps; + pluginProps["showTitleBar"] = "true"; + pluginProps["resizable"] = "true"; + pluginProps["height"] = "952"; + pluginProps["width"] = "1199"; + pluginProps["z"] = "0"; + pluginProps["state"] = "docked"; + + // + auto pluginElem = configDoc.FirstChildElement("plugin"); + ASSERT_NE(nullptr, pluginElem); + + // + auto ignGuiElem = pluginElem->FirstChildElement("ignition-gui"); + ASSERT_NE(nullptr, ignGuiElem); + + // Iterate properties + for (auto propElem = ignGuiElem->FirstChildElement("property"); + propElem != nullptr;) + { + // If property in map, mark it as "Verified" + if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) + { + EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); + pluginProps[propElem->Attribute("key")] = "Verified"; + } + auto nextProp = propElem->NextSiblingElement("property"); + propElem = nextProp; + } + + // Verify all selected inputs properties are correct + for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) + { + EXPECT_EQ(itr->second, "Verified"); + } +} + From 81223eec47f127e72f05444616ecad79da501b5e Mon Sep 17 00:00:00 2001 From: youhy Date: Fri, 29 Jul 2022 14:40:27 -0700 Subject: [PATCH 2/4] codecheck Signed-off-by: youhy --- src/Plugin_TEST.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index 3c5f63c37..39ec05d4d 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -297,7 +297,7 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoIgn)) app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); // Load normal plugin - const char *pluginStr = + const char *pluginStr = "" ""; From e0acd4a1e2704fd07acc5a7ace33b1f4e7db4c45 Mon Sep 17 00:00:00 2001 From: youhy Date: Mon, 1 Aug 2022 08:32:24 -0700 Subject: [PATCH 3/4] include unordered map Signed-off-by: youhy --- src/Plugin_TEST.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index 39ec05d4d..800375db0 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -15,6 +15,7 @@ * */ +#include #include #include From aadc348b8d24a05a97f5896b942cbf9dd7815fcc Mon Sep 17 00:00:00 2001 From: youhy Date: Mon, 1 Aug 2022 14:04:44 -0700 Subject: [PATCH 4/4] add type check and error message Signed-off-by: youhy --- src/Plugin.cc | 2 + src/Plugin_TEST.cc | 122 +++++++++++++++------------------------------ 2 files changed, 43 insertions(+), 81 deletions(-) diff --git a/src/Plugin.cc b/src/Plugin.cc index 51935a459..d95c87229 100644 --- a/src/Plugin.cc +++ b/src/Plugin.cc @@ -362,8 +362,10 @@ std::string Plugin::ConfigStr() tinyxml2::XMLPrinter printer; if (!pluginElem->Accept(&printer)) { + // LCOV_EXCL_START ignwarn << "There was an error parsing the plugin element for " << "[" << this->title << "]." << std::endl; + // LCOV_EXCL_STOP } else { diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index 800375db0..4f8d94cca 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -142,7 +142,8 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStr)) ignition::common::Console::SetVerbosity(4); Application app(g_argc, g_argv); - app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); + app.AddPluginPath( + common::joinPaths(std::string(PROJECT_BINARY_PATH), "lib")); // Load normal plugin const char *pluginStr = @@ -163,6 +164,7 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStr)) ""; std::unordered_map pluginProps; + std::unordered_map pluginTypes; pluginProps["showTitleBar"] = "true"; pluginProps["resizable"] = "true"; pluginProps["height"] = "200"; @@ -170,6 +172,13 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStr)) pluginProps["z"] = "2"; pluginProps["state"] = "floating"; + pluginTypes["showTitleBar"] = "bool"; + pluginTypes["resizable"] = "bool"; + pluginTypes["height"] = "double"; + pluginTypes["width"] = "double"; + pluginTypes["z"] = "double"; + pluginTypes["state"] = "string"; + tinyxml2::XMLDocument pluginDoc; pluginDoc.Parse(pluginStr); EXPECT_TRUE(app.LoadPlugin("WorldStats", @@ -204,17 +213,24 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStr)) // If property in map, mark it as "Verified" if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) { - EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); + // check if the type is correct + EXPECT_EQ(propElem->Attribute("type"), + pluginTypes[propElem->Attribute("key")]) << propElem->Attribute("key"); + + // check if the value is correct + EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]) + << propElem->Attribute("key"); pluginProps[propElem->Attribute("key")] = "Verified"; } auto nextProp = propElem->NextSiblingElement("property"); propElem = nextProp; } - // Verify all inputs properties are correct + // Verify all inputs properties are checked for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) { - EXPECT_EQ(itr->second, "Verified"); + EXPECT_EQ(itr->second, "Verified") << "Did not find property: " + << itr->first; } } @@ -225,7 +241,8 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoPlugin)) ignition::common::Console::SetVerbosity(4); Application app(g_argc, g_argv); - app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); + app.AddPluginPath( + common::joinPaths(std::string(PROJECT_BINARY_PATH), "lib")); // Load normal plugin const char *pluginStr = ""; @@ -253,84 +270,20 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoPlugin)) // contain a tag. // We select a few to verify. std::unordered_map pluginProps; + std::unordered_map pluginTypes; pluginProps["showTitleBar"] = "true"; pluginProps["resizable"] = "true"; - pluginProps["height"] = "952"; - pluginProps["width"] = "1199"; + pluginProps["cardMinimumWidth"] = "290"; + pluginProps["cardMinimumHeight"] = "110"; pluginProps["z"] = "0"; pluginProps["state"] = "docked"; - // - auto pluginElem = configDoc.FirstChildElement("plugin"); - ASSERT_NE(nullptr, pluginElem); - - // - auto ignGuiElem = pluginElem->FirstChildElement("ignition-gui"); - ASSERT_NE(nullptr, ignGuiElem); - - // Iterate properties - for (auto propElem = ignGuiElem->FirstChildElement("property"); - propElem != nullptr;) - { - // If property in map, mark it as "Verified" - if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) - { - EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); - pluginProps[propElem->Attribute("key")] = "Verified"; - } - auto nextProp = propElem->NextSiblingElement("property"); - propElem = nextProp; - } - - // Verify all selected inputs properties are correct - for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) - { - EXPECT_EQ(itr->second, "Verified"); - } -} - -///////////////////////////////////////////////// -TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoIgn)) -{ - ignition::common::Console::SetVerbosity(4); - - Application app(g_argc, g_argv); - app.AddPluginPath(std::string(PROJECT_BINARY_PATH) + "/lib"); - - // Load normal plugin - const char *pluginStr = - "" - ""; - - tinyxml2::XMLDocument pluginDoc; - pluginDoc.Parse(pluginStr); - EXPECT_TRUE(app.LoadPlugin("WorldStats", - pluginDoc.FirstChildElement("plugin"))); - - // Create main window - auto win = app.findChild(); - ASSERT_NE(nullptr, win); - - // Check plugin count - EXPECT_EQ(1, win->findChildren().size()); - - // Get the output for ConfigStr() - std::string configStr; - tinyxml2::XMLDocument configDoc; - auto plugin = win->findChildren()[0]; - configStr = plugin->ConfigStr(); - configDoc.Parse(configStr.c_str()); - - // ConfigStr() creates a plugin with default value when input doesn't - // contain a tag. - // We select a few to verify. - std::unordered_map pluginProps; - pluginProps["showTitleBar"] = "true"; - pluginProps["resizable"] = "true"; - pluginProps["height"] = "952"; - pluginProps["width"] = "1199"; - pluginProps["z"] = "0"; - pluginProps["state"] = "docked"; + pluginTypes["showTitleBar"] = "bool"; + pluginTypes["resizable"] = "bool"; + pluginTypes["cardMinimumWidth"] = "int"; + pluginTypes["cardMinimumHeight"] = "int"; + pluginTypes["z"] = "double"; + pluginTypes["state"] = "string"; // auto pluginElem = configDoc.FirstChildElement("plugin"); @@ -347,17 +300,24 @@ TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoIgn)) // If property in map, mark it as "Verified" if (pluginProps.find(propElem->Attribute("key")) != pluginProps.end()) { - EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]); + // check if the type is correct + EXPECT_EQ(propElem->Attribute("type"), + pluginTypes[propElem->Attribute("key")]) << propElem->Attribute("key"); + + // check if the value is correct + EXPECT_EQ(propElem->GetText(), pluginProps[propElem->Attribute("key")]) + << propElem->Attribute("key"); pluginProps[propElem->Attribute("key")] = "Verified"; } auto nextProp = propElem->NextSiblingElement("property"); propElem = nextProp; } - // Verify all selected inputs properties are correct + // Verify all selected inputs properties are checked for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++) { - EXPECT_EQ(itr->second, "Verified"); + EXPECT_EQ(itr->second, "Verified") << "Did not find property: " + << itr->first; } }