Skip to content

Commit

Permalink
Add test for Plugin::ConfigStr() (#447)
Browse files Browse the repository at this point in the history
Signed-off-by: youhy <haoyuan2019@outlook.com>
Co-authored-by: Louise Poubel <louise@openrobotics.org>
  • Loading branch information
AzulRadio and chapulina committed Aug 6, 2022
1 parent 33bbf41 commit f59ae67
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,11 @@ std::string Plugin::ConfigStr()
auto pluginElem = doc.FirstChildElement("plugin");
if (!pluginElem)
{
// LCOV_EXCL_START
ignerr << "Missing <plugin> element, not updating config string."
<< std::endl;
return this->configStr;
// LCOV_EXCL_STOP
}

// <ignition-gui>
Expand Down Expand Up @@ -360,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
{
Expand Down
187 changes: 187 additions & 0 deletions src/Plugin_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <unordered_map>
#include <gtest/gtest.h>

#include <ignition/common/Console.hh>
Expand Down Expand Up @@ -134,3 +135,189 @@ 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(
common::joinPaths(std::string(PROJECT_BINARY_PATH), "lib"));

// Load normal plugin
const char *pluginStr =
"<plugin filename=\"WorldStats\" name=\"World stats\">"
" <ignition-gui>"
" <title>World stats</title>"
" <property type=\"bool\" key=\"showTitleBar\">true</property>"
" <property type=\"bool\" key=\"resizable\">true</property>"
" <property type=\"double\" key=\"height\">200</property>"
" <property type=\"double\" key=\"width\">300</property>"
" <property type=\"double\" key=\"z\">2</property>"
" <property type=\"string\" key=\"state\">floating</property>"
" <anchors target=\"3D View\">"
" <line own=\"right\" target=\"right\"/>"
" <line own=\"bottom\" target=\"bottom\"/>"
" </anchors>"
" </ignition-gui>"
"</plugin>";

std::unordered_map<std::string, std::string> pluginProps;
std::unordered_map<std::string, std::string> pluginTypes;
pluginProps["showTitleBar"] = "true";
pluginProps["resizable"] = "true";
pluginProps["height"] = "200";
pluginProps["width"] = "300";
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",
pluginDoc.FirstChildElement("plugin")));

// Create main window
auto win = app.findChild<MainWindow *>();
ASSERT_NE(nullptr, win);

// Check plugin count
EXPECT_EQ(1, win->findChildren<Plugin *>().size());

// Get the output for ConfigStr()
std::string configStr;
tinyxml2::XMLDocument configDoc;
auto plugin = win->findChildren<Plugin *>()[0];
configStr = plugin->ConfigStr();
configDoc.Parse(configStr.c_str());

// <plugin>
auto pluginElem = configDoc.FirstChildElement("plugin");
ASSERT_NE(nullptr, pluginElem);

// <ignition-gui>
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())
{
// 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 checked
for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++)
{
EXPECT_EQ(itr->second, "Verified") << "Did not find property: "
<< itr->first;
}

}

/////////////////////////////////////////////////
TEST(PluginTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ConfigStrInputNoPlugin))
{
ignition::common::Console::SetVerbosity(4);

Application app(g_argc, g_argv);
app.AddPluginPath(
common::joinPaths(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<MainWindow *>();
ASSERT_NE(nullptr, win);

// Check plugin count
EXPECT_EQ(1, win->findChildren<Plugin *>().size());

// Get the output for ConfigStr()
std::string configStr;
tinyxml2::XMLDocument configDoc;
auto plugin = win->findChildren<Plugin *>()[0];
configStr = plugin->ConfigStr();
configDoc.Parse(configStr.c_str());

// ConfigStr() creates a plugin with default value when input doesn't
// contain a <plugin> tag.
// We select a few to verify.
std::unordered_map<std::string, std::string> pluginProps;
std::unordered_map<std::string, std::string> pluginTypes;
pluginProps["showTitleBar"] = "true";
pluginProps["resizable"] = "true";
pluginProps["cardMinimumWidth"] = "290";
pluginProps["cardMinimumHeight"] = "110";
pluginProps["z"] = "0";
pluginProps["state"] = "docked";

pluginTypes["showTitleBar"] = "bool";
pluginTypes["resizable"] = "bool";
pluginTypes["cardMinimumWidth"] = "int";
pluginTypes["cardMinimumHeight"] = "int";
pluginTypes["z"] = "double";
pluginTypes["state"] = "string";

// <plugin>
auto pluginElem = configDoc.FirstChildElement("plugin");
ASSERT_NE(nullptr, pluginElem);

// <ignition-gui>
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())
{
// 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 checked
for (auto itr = pluginProps.begin(); itr != pluginProps.end(); itr++)
{
EXPECT_EQ(itr->second, "Verified") << "Did not find property: "
<< itr->first;
}
}

0 comments on commit f59ae67

Please sign in to comment.