From 3e68a16d028e58c28ee290fc1f508fe9aa4a5c0a Mon Sep 17 00:00:00 2001 From: Pepe Date: Wed, 15 Jul 2026 15:20:34 +0200 Subject: [PATCH] Add scripted return status support for TestNode mocks Introduce `return_status_script` on TestNodeConfig, allowing a mock's completion status to be computed at runtime from blackboard state instead of being fixed. When set, it takes precedence over `return_status`; it may reference the NodeStatus names (SUCCESS/FAILURE/...) and is rejected if it resolves to IDLE. The NodeStatus enum names are injected only into the return_status_script environment. The pre-existing success_script/failure_script/post_script continue to evaluate against the node's own enums, so a blackboard entry named like a status (e.g. "SUCCESS") is not shadowed. To pay the ABI break only once, TestNode's state is moved behind a PImpl, so future changes to it no longer alter the layout consumers link against (mirroring StatusChangeLogger). The new return_status_script field is appended at the end of TestNodeConfig, preserving the byte offsets of the existing fields. Also add JSON validation rejecting a TestNodeConfig with neither a return_status nor a return_status_script, and a tutorial example (t15_nodes_mocking_strict_failure) demonstrating the strict-failure flow. Addresses #995. Co-Authored-By: Claude Opus 4.8 --- examples/CMakeLists.txt | 1 + examples/t15_nodes_mocking.cpp | 2 +- examples/t15_nodes_mocking_strict_failure.cpp | 143 ++++++++++++++++ include/behaviortree_cpp/actions/test_node.h | 49 ++++-- src/actions/test_node.cpp | 154 ++++++++++++++--- src/bt_factory.cpp | 20 ++- tests/gtest_substitution.cpp | 155 +++++++++++++++++- 7 files changed, 484 insertions(+), 40 deletions(-) create mode 100644 examples/t15_nodes_mocking_strict_failure.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9a94c95e8..7ccb5f05d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -35,6 +35,7 @@ CompileExample("t12_default_ports") CompileExample("t13_access_by_ref") CompileExample("t14_subtree_model") CompileExample("t15_nodes_mocking") +CompileExample("t15_nodes_mocking_strict_failure") CompileExample("t16_global_blackboard") CompileExample("t17_blackboard_backup") CompileExample("t18_waypoints") diff --git a/examples/t15_nodes_mocking.cpp b/examples/t15_nodes_mocking.cpp index 805a46b95..6e6007066 100644 --- a/examples/t15_nodes_mocking.cpp +++ b/examples/t15_nodes_mocking.cpp @@ -39,7 +39,7 @@ const char* xml_text = R"( /** * @brief In this example we will see how we can substitute some nodes - * in the Tree above with + * in the Tree above with mocks. * @param argc * @param argv * @return diff --git a/examples/t15_nodes_mocking_strict_failure.cpp b/examples/t15_nodes_mocking_strict_failure.cpp new file mode 100644 index 000000000..c3374ba5e --- /dev/null +++ b/examples/t15_nodes_mocking_strict_failure.cpp @@ -0,0 +1,143 @@ +#include "dummy_nodes.h" + +#include "behaviortree_cpp/bt_factory.h" + +// clang-format off +namespace +{ +const char* xml_text = R"( + + + + + + + + +