@@ -582,6 +582,61 @@ TEST(PortTest, DefaultWronglyOverriden)
582582 ASSERT_NO_THROW (auto tree = factory.createTreeFromText (xml_txt_correct));
583583}
584584
585+ // Issue #858: getInput should return the default value declared in
586+ // providedPorts when the XML does not specify the port.
587+ class ActionWithDefaultPort : public SyncActionNode
588+ {
589+ public:
590+ ActionWithDefaultPort (const std::string& name, const NodeConfig& config)
591+ : SyncActionNode(name, config)
592+ {}
593+
594+ NodeStatus tick () override
595+ {
596+ auto res = getInput<std::string>(" log_name" );
597+ if (!res)
598+ {
599+ throw RuntimeError (" getInput failed: " + res.error ());
600+ }
601+ result = res.value ();
602+ return NodeStatus::SUCCESS;
603+ }
604+
605+ static PortsList providedPorts ()
606+ {
607+ return { InputPort<std::string>(" log_name" , " my_default_logger" , " Logger name" ),
608+ InputPort<std::string>(" message" , " Message to be logged" ) };
609+ }
610+
611+ std::string result;
612+ };
613+
614+ TEST (PortTest, GetInputDefaultValue_Issue858)
615+ {
616+ // XML does NOT specify "log_name" — should use the default from providedPorts
617+ std::string xml_txt = R"(
618+ <root BTCPP_format="4" >
619+ <BehaviorTree ID="Main">
620+ <ActionWithDefaultPort message="hello"/>
621+ </BehaviorTree>
622+ </root>)" ;
623+
624+ BehaviorTreeFactory factory;
625+ factory.registerNodeType <ActionWithDefaultPort>(" ActionWithDefaultPort" );
626+ auto tree = factory.createTreeFromText (xml_txt);
627+ auto status = tree.tickWhileRunning ();
628+
629+ ASSERT_EQ (status, NodeStatus::SUCCESS);
630+
631+ for (const auto & node : tree.subtrees .front ()->nodes )
632+ {
633+ if (auto action = dynamic_cast <ActionWithDefaultPort*>(node.get ()))
634+ {
635+ ASSERT_EQ (" my_default_logger" , action->result );
636+ }
637+ }
638+ }
639+
585640// Helper class used by Issue #969 test
586641class CollectDoubleAction : public SyncActionNode
587642{
0 commit comments