4#include <catch2/catch_test_macros.hpp>
10#include <Core/Utils/StdFilesystem.hpp>
12#include <Dataflow/Core/DataflowGraph.hpp>
13#include <Dataflow/Core/Functionals/Types.hpp>
14#include <Dataflow/Core/Sinks/Types.hpp>
15#include <Dataflow/Core/Sources/Types.hpp>
17using namespace Ra::Dataflow::Core;
45 REQUIRE( m_portName->has_data() );
46 m_nameOut->set_data( &m_portName->data() );
47 m_currentFunction = m_functions.at( m_portName->data() );
54 REQUIRE( data.contains(
"operator" ) );
55 m_portName->set_default_value(
"true" );
56 REQUIRE( data.contains(
"threshold" ) );
57 m_portThreshold->set_default_value( data[
"threshold"] );
62 data[
"operator"] = m_portName->data();
63 data[
"threshold"] = m_portThreshold->data();
69 std::string {
"FilterSelector<" } + Ra::Core::Utils::simplifiedDemangledType<T>() +
">";
70 return demangledTypeName;
75 Node( instanceName, typeName ) {}
78 {
"true", [](
const T& ) {
return true; } },
79 {
"false", [](
const T& ) {
return false; } },
80 {
"<", [
this](
const T& v ) {
return v < this->m_portThreshold->data(); } },
81 {
">", [
this](
const T& v ) {
return v > this->m_portThreshold->data(); } } };
83 function_type m_currentFunction = m_functions[
"true"];
96template <
typename DataType>
98template <
typename DataType>
100template <
typename DataType>
102template <
typename DataType>
106template <
typename DataType>
111 REQUIRE( g->add_node( ds ) );
114 REQUIRE( g->add_node( rs ) );
117 REQUIRE( g->add_node( ts ) );
120 REQUIRE( g->add_node( ss ) );
123 REQUIRE( g->add_node( nm ) );
126 REQUIRE( g->add_node( fs ) );
129 REQUIRE( g->add_node( fl ) );
137 REQUIRE( g->add_link( ds,
"to", fl,
"data" ) );
138 REQUIRE( g->add_link( fl,
"result", rs,
"from" ) );
139 REQUIRE( g->add_link( ss,
"to", fs,
"name" ) );
140 REQUIRE( g->add_link( ts,
"to", fs,
"threshold" ) );
141 REQUIRE( g->add_link( fs,
"f", fl,
"predicate" ) );
142 REQUIRE( g->add_link( fs,
"name", nm,
"from" ) );
147TEST_CASE(
"Dataflow/Core/Custom nodes",
"[unittests][Dataflow][Core][Custom nodes]" ) {
148 SECTION(
"Build graph with custom nodes" ) {
150 auto g = buildgraph<Scalar>(
"testCustomNodes" );
153 auto inputCollection =
155 REQUIRE( inputCollection !=
nullptr );
158 REQUIRE( inputOpName !=
nullptr );
159 auto inputThreshold =
161 REQUIRE( inputThreshold !=
nullptr );
163 auto filteredCollection = g->node(
"rs" );
164 REQUIRE( filteredCollection !=
nullptr );
165 auto generatedOperator = g->node(
"nm" );
166 REQUIRE( generatedOperator !=
nullptr );
175 for (
size_t n = 0; n < testVector.
capacity(); ++n ) {
179 inputCollection->set_data( testVector );
180 inputThreshold->set_data( .5_ra );
181 inputOpName->set_data(
"true" );
184 REQUIRE( g->execute() );
189 auto& vres = filteredCollection->input_by_name(
"from" ).second->data<
CollectionType>();
190 auto& vop = generatedOperator->input_by_name(
"from" ).second->
data<
std::string>();
192 REQUIRE( vop ==
"true" );
193 REQUIRE( vres.size() == testVector.
size() );
196 inputOpName->set_data(
"false" );
198 REQUIRE( g->execute() );
199 REQUIRE( vop ==
"false" );
200 REQUIRE( vres.size() == 0 );
203 inputOpName->set_data(
"<" );
205 REQUIRE( g->execute() );
207 REQUIRE( *(
std::max_element( vres.begin(), vres.end() ) ) < *inputThreshold->data() );
210 inputOpName->set_data(
">" );
211 REQUIRE( g->execute() );
212 REQUIRE( *(
std::max_element( vres.begin(), vres.end() ) ) > *inputThreshold->data() );
214 SECTION(
"Serialization of a custom graph" ) {
221 Customs::CustomStringSource::node_typename() +
"_",
"Custom" ) );
223 Customs::CustomStringSink::node_typename() +
"_",
"Custom" ) );
230 nlohmann::json emptyData;
231 auto customSource = customFactory->create_node(
232 Customs::CustomStringSource::node_typename(), emptyData,
nullptr );
233 REQUIRE( customSource );
236 auto g = buildgraph<Scalar>(
"testCustomNodes" );
239 std::filesystem::create_directories( tmpdir );
242 g->saveToJson( tmpdir +
"customGraph.json" );
248 REQUIRE( g->loadFromJson( tmpdir +
"customGraph.json" ) );
254 REQUIRE( unregistered ==
true );
257 REQUIRE( !g->loadFromJson( tmpdir +
"customGraph.json" ) );
260 std::filesystem::remove_all( tmpdir );
bool execute() override
Executes the node.
bool fromJsonInternal(const nlohmann::json &data) override
Internal json representation of the Node.
void toJsonInternal(nlohmann::json &data) const override
Internal json representation of the Node.
This class implements ContainerIntrospectionInterface for AlignedStdVector.
Represent a set of connected nodes that define a Direct Acyclic Computational Graph Ownership of node...
Filter on iterable collection.
Base abstract class for all the nodes added and used by the node system.
PortIndex add_output(PortBaseOutPtr out)
Convenience alias to add_port(outputs(), out)
PortIndex add_input(PortBaseInPtr in)
Convenience alias to add_port(inputs(), in)
Base class for nodes that will store the result of a computation graph.
Base class for nodes that will give access to some input data to the graph. This class can be used to...
auto unregister_factory(const NodeFactorySet::key_type &name) -> bool
Unregister the factory from the manager.
auto default_factory() -> NodeFactorySet::mapped_type
Gets the "default" factory for nodes exported by the Core dataflow library.
auto create_factory(const NodeFactorySet::key_type &name) -> NodeFactorySet::mapped_type
Create and register a factory to the manager.
T dynamic_pointer_cast(T... args)