Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 474f33b

Browse files
authored
Added XML validation for decorators without children (BehaviorTree#424)
* Added unit tests to demonstrate failure * Added validation that decorators have only one child
1 parent 8f7d0e2 commit 474f33b

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

include/behaviortree_cpp_v3/xml_parsing.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "behaviortree_cpp_v3/bt_parser.h"
55

6+
#include <unordered_map>
7+
68
namespace BT
79
{
810

@@ -38,7 +40,7 @@ class XMLParser: public Parser
3840
};
3941

4042
void VerifyXML(const std::string& xml_text,
41-
const std::set<std::string> &registered_nodes);
43+
const std::unordered_map<std::string, NodeType> &registered_nodes);
4244

4345
std::string writeTreeNodesModelXML(const BehaviorTreeFactory& factory,
4446
bool include_builtin = false);

src/xml_parsing.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,25 +214,25 @@ void XMLParser::Pimpl::loadDocImpl(BT_TinyXML2::XMLDocument* doc, bool add_inclu
214214
tree_roots.insert( {tree_name, bt_node} );
215215
}
216216

217-
std::set<std::string> registered_nodes;
217+
std::unordered_map<std::string, BT::NodeType> registered_nodes;
218218
XMLPrinter printer;
219219
doc->Print(&printer);
220220
auto xml_text = std::string(printer.CStr(), size_t(printer.CStrSize() - 1));
221221

222222
for( const auto& it: factory.manifests())
223223
{
224-
registered_nodes.insert( it.first );
224+
registered_nodes.insert({it.first, it.second.type});
225225
}
226226
for( const auto& it: tree_roots)
227227
{
228-
registered_nodes.insert( it.first );
228+
registered_nodes.insert({it.first, NodeType::SUBTREE});
229229
}
230230

231231
VerifyXML(xml_text, registered_nodes);
232232
}
233233

234234
void VerifyXML(const std::string& xml_text,
235-
const std::set<std::string>& registered_nodes)
235+
const std::unordered_map<std::string, BT::NodeType>& registered_nodes)
236236
{
237237

238238
BT_TinyXML2::XMLDocument doc;
@@ -391,12 +391,22 @@ void VerifyXML(const std::string& xml_text,
391391
else
392392
{
393393
// search in the factory and the list of subtrees
394-
bool found = ( registered_nodes.find(name) != registered_nodes.end() );
394+
const auto search = registered_nodes.find(name);
395+
bool found = ( search != registered_nodes.end() );
395396
if (!found)
396397
{
397398
ThrowError(node->GetLineNum(),
398399
std::string("Node not recognized: ") + name);
399400
}
401+
402+
if (search->second == NodeType::DECORATOR)
403+
{
404+
if (children_count != 1)
405+
{
406+
ThrowError(node->GetLineNum(),
407+
std::string("The node <") + name + "> must have exactly 1 child");
408+
}
409+
}
400410
}
401411
//recursion
402412
if (StrEqual(name, "SubTree") == false)

tests/gtest_factory.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,35 @@ TEST(BehaviorTreeFactory, CreateTreeFromFileWhichIncludesFileFromChildDirectoryW
359359
ASSERT_EQ(NodeStatus::SUCCESS, tree.tickRoot());
360360
}
361361
#endif
362+
363+
TEST(BehaviorTreeFactory, DecoratorWithoutChildThrows)
364+
{
365+
BehaviorTreeFactory factory;
366+
const std::string tree_xml = R"(
367+
<root>
368+
<BehaviorTree ID="Main">
369+
<ForceSuccess>
370+
</ForceSuccess>
371+
</BehaviorTree>
372+
</root>
373+
)";
374+
375+
ASSERT_THROW(factory.createTreeFromText(tree_xml), BehaviorTreeException);
376+
}
377+
378+
TEST(BehaviorTreeFactory, DecoratorWithTwoChildrenThrows)
379+
{
380+
BehaviorTreeFactory factory;
381+
const std::string tree_xml = R"(
382+
<root>
383+
<BehaviorTree ID="Main">
384+
<ForceSuccess>
385+
<AlwaysSuccess />
386+
<AlwaysSuccess />
387+
</ForceSuccess>
388+
</BehaviorTree>
389+
</root>
390+
)";
391+
392+
ASSERT_THROW(factory.createTreeFromText(xml_text), BehaviorTreeException);
393+
}

0 commit comments

Comments
 (0)