Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit38f9b42

Browse files
committed
Add unit test for Any/Blackboard type casting
1 parentb5cba99 commit38f9b42

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed

‎tests/gtest_any.cpp‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include<gtest/gtest.h>
1818

1919
#include<behaviortree_cpp/utils/safe_any.hpp>
20+
#include"greeter_test.h"
2021

2122
usingnamespaceBT;
2223

@@ -249,4 +250,81 @@ TEST(Any, Cast)
249250
Anya(v);
250251
EXPECT_EQ(a.cast<std::vector<int>>(), v);
251252
}
253+
254+
/// Issue 943
255+
// Type casting: polymorphic class w/ registered base class
256+
{
257+
auto g = std::make_shared<Greeter>();
258+
Anyany_g(g);
259+
EXPECT_NO_THROW(auto res = any_g.cast<Greeter::Ptr>());
260+
EXPECT_ANY_THROW(auto res = any_g.cast<HelloGreeter::Ptr>());
261+
EXPECT_ANY_THROW(auto res = any_g.cast<FancyHelloGreeter::Ptr>());
262+
EXPECT_TRUE(any_g.castPtr<Greeter::Ptr>());
263+
EXPECT_FALSE(any_g.castPtr<HelloGreeter::Ptr>());
264+
EXPECT_FALSE(any_g.castPtr<FancyHelloGreeter::Ptr>());
265+
266+
auto hg = std::make_shared<HelloGreeter>();
267+
Anyany_hg(hg);
268+
EXPECT_NO_THROW(auto res = any_hg.cast<Greeter::Ptr>());
269+
EXPECT_NO_THROW(auto res = any_hg.cast<HelloGreeter::Ptr>());
270+
EXPECT_ANY_THROW(auto res = any_hg.cast<FancyHelloGreeter::Ptr>());
271+
EXPECT_TRUE(any_hg.castPtr<Greeter::Ptr>());
272+
EXPECT_TRUE(any_hg.castPtr<HelloGreeter::Ptr>());
273+
EXPECT_FALSE(any_hg.castPtr<FancyHelloGreeter::Ptr>());
274+
275+
auto fhg = std::make_shared<FancyHelloGreeter>();
276+
Anyany_fhg(fhg);
277+
EXPECT_NO_THROW(auto res = any_fhg.cast<Greeter::Ptr>());
278+
EXPECT_NO_THROW(auto res = any_fhg.cast<HelloGreeter::Ptr>());
279+
EXPECT_NO_THROW(auto res = any_fhg.cast<FancyHelloGreeter::Ptr>());
280+
EXPECT_TRUE(any_fhg.castPtr<Greeter::Ptr>());
281+
EXPECT_TRUE(any_fhg.castPtr<HelloGreeter::Ptr>());
282+
EXPECT_TRUE(any_fhg.castPtr<FancyHelloGreeter::Ptr>());
283+
284+
// Try to upcast to an incorrectly registered base
285+
auto u = std::make_shared<Unwelcomer>();
286+
287+
// OK, fails to compile -> invalid static cast
288+
// Any any_u(u);
289+
// EXPECT_ANY_THROW(auto res = any_g.cast<Unwelcomer::Ptr>());
290+
}
291+
292+
// Type casting: polymorphic class w/o registered base class
293+
{
294+
auto g = std::make_shared<GreeterNoReg>();
295+
Anyany_g(g);
296+
EXPECT_NO_THROW(auto res = any_g.cast<GreeterNoReg::Ptr>());
297+
EXPECT_ANY_THROW(auto res = any_g.cast<HelloGreeterNoReg::Ptr>());
298+
EXPECT_TRUE(any_g.castPtr<GreeterNoReg::Ptr>());
299+
EXPECT_FALSE(any_g.castPtr<HelloGreeterNoReg::Ptr>());
300+
301+
auto hg = std::make_shared<HelloGreeterNoReg>();
302+
Anyany_hg(hg);
303+
EXPECT_ANY_THROW(auto res = any_hg.cast<GreeterNoReg::Ptr>());
304+
EXPECT_NO_THROW(auto res = any_hg.cast<HelloGreeterNoReg::Ptr>());
305+
EXPECT_FALSE(any_hg.castPtr<GreeterNoReg::Ptr>());
306+
EXPECT_TRUE(any_hg.castPtr<HelloGreeterNoReg::Ptr>());
307+
}
308+
309+
// Type casting: non polymorphic class w/ registered base class
310+
{
311+
// OK: static_assert(std::is_polymorphic_v<Base>, "Base must be polymorphic")
312+
}
313+
314+
// Type casting: non polymorphic class w/o registered base class
315+
{
316+
auto g = std::make_shared<GreeterNoPolyReg>();
317+
Anyany_g(g);
318+
EXPECT_NO_THROW(auto res = any_g.cast<GreeterNoPolyReg::Ptr>());
319+
EXPECT_ANY_THROW(auto res = any_g.cast<HelloGreeterNoPolyReg::Ptr>());
320+
EXPECT_TRUE(any_g.castPtr<GreeterNoPolyReg::Ptr>());
321+
EXPECT_FALSE(any_g.castPtr<HelloGreeterNoPolyReg::Ptr>());
322+
323+
auto hg = std::make_shared<HelloGreeterNoPolyReg>();
324+
Anyany_hg(hg);
325+
EXPECT_ANY_THROW(auto res = any_hg.cast<GreeterNoPolyReg::Ptr>());
326+
EXPECT_NO_THROW(auto res = any_hg.cast<HelloGreeterNoPolyReg::Ptr>());
327+
EXPECT_FALSE(any_hg.castPtr<GreeterNoPolyReg::Ptr>());
328+
EXPECT_TRUE(any_hg.castPtr<HelloGreeterNoPolyReg::Ptr>());
329+
}
252330
}

‎tests/gtest_blackboard.cpp‎

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include"behaviortree_cpp/blackboard.h"
1616

1717
#include"../sample_nodes/dummy_nodes.h"
18+
#include"greeter_test.h"
1819

1920
usingnamespaceBT;
2021

@@ -654,3 +655,113 @@ TEST(BlackboardTest, TimestampedInterface)
654655
ASSERT_EQ(stamp_opt->seq,2);
655656
ASSERT_GE(stamp_opt->time.count(), nsec_before);
656657
}
658+
659+
classCreateHelloGreeter :publicSyncActionNode
660+
{
661+
public:
662+
CreateHelloGreeter(const std::string& name,const NodeConfig& config)
663+
: SyncActionNode(name, config)
664+
{}
665+
666+
NodeStatustick()override
667+
{
668+
auto hello_greeter = std::make_shared<HelloGreeter>();
669+
670+
setOutput("out_derived", hello_greeter);
671+
672+
return NodeStatus::SUCCESS;
673+
}
674+
675+
static PortsListprovidedPorts()
676+
{
677+
return { BT::OutputPort<HelloGreeter::Ptr>("out_derived") };
678+
}
679+
};
680+
681+
classSetDerivedParameter :publicSyncActionNode
682+
{
683+
public:
684+
SetDerivedParameter(const std::string& name,const NodeConfig& config)
685+
: SyncActionNode(name, config)
686+
{}
687+
688+
NodeStatustick()override
689+
{
690+
int n;
691+
HelloGreeter::Ptr hello_greeter{};
692+
693+
getInput("n", n);
694+
getInput("in_derived", hello_greeter);
695+
696+
hello_greeter->setDerivedParameter(n);
697+
hello_greeter->show_msg();
698+
699+
return NodeStatus::SUCCESS;
700+
}
701+
702+
static PortsListprovidedPorts()
703+
{
704+
return { BT::InputPort<int>("n"), BT::InputPort<HelloGreeter::Ptr>("in_derived") };
705+
}
706+
};
707+
708+
classShowGreetMessage :publicSyncActionNode
709+
{
710+
public:
711+
ShowGreetMessage(const std::string& name,const NodeConfig& config)
712+
: SyncActionNode(name, config)
713+
{}
714+
715+
NodeStatustick()override
716+
{
717+
Greeter::Ptr greeter{};
718+
719+
getInput("in_base", greeter);
720+
greeter->show_msg();
721+
722+
return NodeStatus::SUCCESS;
723+
}
724+
725+
static PortsListprovidedPorts()
726+
{
727+
return { BT::InputPort<Greeter::Ptr>("in_base") };
728+
}
729+
};
730+
731+
TEST(BlackboardTest, Upcasting_Issue943)
732+
{
733+
auto bb =BT::Blackboard::create();
734+
735+
auto hello_greeter = std::make_shared<HelloGreeter>();
736+
bb->set("hello_greeter", hello_greeter);
737+
738+
std::shared_ptr<Greeter> g{};
739+
ASSERT_TRUE(bb->get("hello_greeter", g));
740+
ASSERT_STREQ("hello", g->show_msg().c_str());
741+
742+
std::shared_ptr<HelloGreeter> hg{};
743+
ASSERT_TRUE(bb->get("hello_greeter", hg));
744+
ASSERT_STREQ("hello", hg->show_msg().c_str());
745+
746+
std::string xml_txt =R"(
747+
<root BTCPP_format="4" >
748+
<BehaviorTree ID="Main">
749+
<Sequence>
750+
<CreateHelloGreeter out_derived="{hello_greeter}" />
751+
<SetDerivedParameter in_derived="{hello_greeter}" n="2" />
752+
<ShowGreetMessage in_base="{hello_greeter}" />
753+
</Sequence>
754+
</BehaviorTree>
755+
</root>)";
756+
757+
BehaviorTreeFactory factory;
758+
factory.registerNodeType<CreateHelloGreeter>("CreateHelloGreeter");
759+
factory.registerNodeType<SetDerivedParameter>("SetDerivedParameter");
760+
factory.registerNodeType<ShowGreetMessage>("ShowGreetMessage");
761+
762+
auto tree = factory.createTreeFromText(xml_txt);
763+
764+
NodeStatus status = tree.tickWhileRunning();
765+
766+
ASSERT_EQ(status, NodeStatus::SUCCESS);
767+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp