use mlua_swarm_cli::dsl;
fn build_node(node_lua: &str) -> serde_json::Value {
let source = format!(
r#"
local F = require("flow_dsl")
return {node_lua}
"#
);
dsl::build_bp_from_script(&source)
.unwrap_or_else(|e| panic!("script failed: {e}\nsource:\n{source}"))
}
fn assert_node_parity(kind: &str, node_lua: &str) {
let value = build_node(node_lua);
serde_json::from_value::<mlua_flow_ir::Node>(value.clone()).unwrap_or_else(|e| {
panic!(
"flow_dsl Node builder for kind `{kind}` (`{node_lua}` -> {value}) does not \
deserialize as mlua_flow_ir::Node: {e}"
)
});
}
#[test]
fn every_node_builder_round_trips_through_flow_dsl() {
let cases: &[(&str, &str)] = &[
(
"step",
r#"F.step({ id = "a", agent = "mock-agent", input = F.lit(1), out = F.p("$.out") })"#,
),
(
"seq",
r#"F.seq({ F.assign({ at = F.p("$.x"), value = F.lit(1) }) })"#,
),
(
"branch",
r#"F.branch({ cond = F.lit(true), on_true = F.assign({ at = F.p("$.x"), value = F.lit(1) }), on_false = F.assign({ at = F.p("$.x"), value = F.lit(2) }) })"#,
),
(
"loop",
r#"F.loop_({ counter = F.p("$.n"), cond = F.lit(true), max = 3, body = F.seq({}) })"#,
),
(
"assign",
r#"F.assign({ at = F.p("$.x"), value = F.lit(1) })"#,
),
(
"try",
r#"F.try_({ body = F.seq({}), catch = F.seq({}), err_at = F.p("$.err") })"#,
),
];
assert_eq!(
cases.len(),
6,
"the guide documents exactly 6 Node builders (fanout has no flow_dsl builder yet)"
);
for (kind, node_lua) in cases {
assert_node_parity(kind, node_lua);
}
}
#[test]
fn step_node_emits_the_documented_field_names() {
let value = build_node(
r#"F.step({ id = "a", agent = "mock-agent", input = F.lit(1), out = F.p("$.out") })"#,
);
assert_eq!(
value,
serde_json::json!({
"kind": "step",
"ref": "mock-agent",
"in": {"op": "lit", "value": 1},
"out": {"op": "path", "at": "$.out"},
})
);
}
#[test]
fn branch_node_emits_the_documented_field_names() {
let value = build_node(
r#"F.branch({ cond = F.lit(true), on_true = F.assign({ at = F.p("$.x"), value = F.lit(1) }), on_false = F.assign({ at = F.p("$.x"), value = F.lit(2) }) })"#,
);
assert_eq!(
value,
serde_json::json!({
"kind": "branch",
"cond": {"op": "lit", "value": true},
"then": {"kind": "assign", "at": {"op": "path", "at": "$.x"}, "value": {"op": "lit", "value": 1}},
"else": {"kind": "assign", "at": {"op": "path", "at": "$.x"}, "value": {"op": "lit", "value": 2}},
})
);
}