#include #include #include #include using namespace kpn; static int increment(int x) { return x + 1; } static int multiply2(int x) { return x * 2; } TEST_CASE("network build and run: linear pipeline", "[network]") { // Nodes declared first — they own their input channels and must outlive the network auto src = make_node(5); auto dst = make_node(5); auto& src_in = src.input_channel<0>(); Channel final_out(5); dst.set_output_channel<0>(&final_out); Network net; net.add("src", src) .add("dst", dst) .connect("src", src.output<0>(), "dst", dst.input<0>()) .build(); net.start(); src_in.push(5); // 5 → increment → 6 → multiply2 → 12 int result = final_out.pop(); net.stop(); REQUIRE(result == 12); } TEST_CASE("network detects cycle", "[network]") { auto a = make_node(5); auto b = make_node(5); Network net; net.add("a", a).add("b", b); net.connect("a", a.output<0>(), "b", b.input<0>()); net.connect("b", b.output<0>(), "a", a.input<0>()); REQUIRE_THROWS_AS(net.build(), NetworkCycleError); } TEST_CASE("stop disables input channels — producer push is silently dropped", "[network]") { auto node = make_node(5); auto& in_ch = node.input_channel<0>(); node.start(); node.stop(); // After stop, channel is disabled — push must not throw in_ch.push(99); REQUIRE(in_ch.size() == 0); }