use std::sync::Arc;
use af_workflow::{Event, MemoryState, NodeRegistry, Spec, State, Terminal, WorkflowHost};
use serde_json::json;
#[tokio::test]
async fn runs_hello_world_tick_end_to_end() {
let raw = include_str!("fixtures/hello_world.json");
let spec = Spec::from_json(raw).unwrap();
spec.validate_structure().unwrap();
let registry = NodeRegistry::with_builtins();
let host = WorkflowHost::from_spec(&spec, ®istry).expect("hello_world should compile");
let state = Arc::new(MemoryState::new());
let ctx = host.context(state.clone());
for ts in [1_000_u64, 2_000] {
let event = Event::from_json(json!({ "fired_at": ts }));
let outcome = host.run_event(&ctx, event).await.unwrap();
assert_eq!(outcome.steps_run, 2);
assert_eq!(outcome.terminal, Terminal::Completed);
assert!(outcome.matched);
assert!(outcome.succeeded);
}
let ticks = state
.get("__root__.ticks")
.await
.expect("ticks key should exist");
assert_eq!(ticks, json!([1_000, 2_000]));
}
#[tokio::test]
async fn state_append_respects_max_len_over_many_ticks() {
let spec = Spec::from_json(
r#"{
"spec_id": "ring", "version": "1.0",
"branches": [{ "branch_id": "__root__",
"nodes": [
{"id": "t", "type": "ingress.cron", "config": {}},
{"id": "rec", "type": "transform.state_append",
"config": {"path": "n", "key": "win", "max_len": 3}}
],
"edges": [{"source": "t", "target": "rec"}]
}]
}"#,
)
.unwrap();
let registry = NodeRegistry::with_builtins();
let host = WorkflowHost::from_spec(&spec, ®istry).unwrap();
let state = Arc::new(MemoryState::new());
let ctx = host.context(state.clone());
for n in 0..5u64 {
let outcome = host
.run_event(&ctx, Event::from_json(json!({ "n": n })))
.await;
assert_eq!(outcome.unwrap().terminal, Terminal::Completed);
}
assert_eq!(state.get("__root__.win").await.unwrap(), json!([2, 3, 4]));
}