#include #include #include #include using namespace kpn; static int double_it(int x) { return x * 2; } static std::tuple split_it(int x) { return {x, float(x) * 0.5f}; } static void consume_it(int x) { (void)x; } TEST_CASE("node input/output counts", "[node]") { STATIC_REQUIRE(Node::input_count == 1); STATIC_REQUIRE(Node::output_count == 1); STATIC_REQUIRE(Node::output_count == 2); STATIC_REQUIRE(Node::output_count == 0); } TEST_CASE("node named port index resolution", "[node]") { using N = Node, out<"result">>; STATIC_REQUIRE(index_of() == 0); STATIC_REQUIRE(index_of() == 0); } TEST_CASE("node processes a single item end-to-end", "[node]") { Node src_node(5); // used only as input source placeholder Node node(5); // Manually wire: push to input channel, connect a downstream channel, run one item auto& in_ch = node.input_channel<0>(); Channel out_ch(5); node.set_output_channel<0>(&out_ch); node.start(); in_ch.push(21); int result = out_ch.pop(); node.stop(); REQUIRE(result == 42); } TEST_CASE("node stop unblocks cleanly", "[node]") { Node node(5); node.start(); // Node is blocked waiting for input — stop() must return without deadlock node.stop(); REQUIRE_FALSE(node.running()); }