use super::*;
#[test]
fn test_single_file_full_event_sequence() {
let def = parse_def(
r#"{
"nodes": [
{ "id": "in", "type": "input" },
{ "id": "proc", "type": "test-echo" },
{ "id": "out", "type": "output" }
]
}"#,
);
let registry = mock_registry();
let recorder = RecordingReporter::new();
let reporter = recorder.reporter();
let files = vec![make_file("photo.jpg", b"image-data")];
execute_pipeline(&def, files, ®istry, &reporter, &NoopContext, fake_now).unwrap();
let events = recorder.events();
assert_eq!(
events.len(),
6,
"Expected exactly 6 events for 1 file, 1 node"
);
if let PipelineEvent::PipelineStarted {
total_nodes,
total_files,
} = &events[0]
{
assert_eq!(*total_nodes, 1, "1 processing node (I/O excluded)");
assert_eq!(*total_files, 1);
} else {
panic!("Event 0 should be PipelineStarted, got {:?}", events[0]);
}
if let PipelineEvent::NodeStarted {
node_id,
node_index,
total_nodes,
node_type,
} = &events[1]
{
assert_eq!(node_id, "proc");
assert_eq!(*node_index, 0);
assert_eq!(*total_nodes, 1);
assert_eq!(node_type, "test-echo");
} else {
panic!("Event 1 should be NodeStarted, got {:?}", events[1]);
}
if let PipelineEvent::FileProgress {
node_id,
file_index,
total_files,
percent,
message,
} = &events[2]
{
assert_eq!(node_id, "proc");
assert_eq!(*file_index, 0);
assert_eq!(*total_files, 1);
assert_eq!(*percent, 0);
assert!(
message.contains("photo.jpg"),
"Message should include filename: {}",
message
);
} else {
panic!("Event 2 should be FileProgress(0%), got {:?}", events[2]);
}
if let PipelineEvent::FileProgress {
percent, message, ..
} = &events[3]
{
assert_eq!(*percent, 100);
assert!(
message.contains("photo.jpg"),
"Message should include filename: {}",
message
);
} else {
panic!("Event 3 should be FileProgress(100%), got {:?}", events[3]);
}
if let PipelineEvent::NodeCompleted {
node_id,
files_processed,
duration_ms,
} = &events[4]
{
assert_eq!(node_id, "proc");
assert_eq!(*files_processed, 1);
assert_eq!(*duration_ms, 0, "fake_now produces 0ms duration");
} else {
panic!("Event 4 should be NodeCompleted, got {:?}", events[4]);
}
if let PipelineEvent::PipelineCompleted {
total_files_processed,
duration_ms,
} = &events[5]
{
assert_eq!(*total_files_processed, 1);
assert_eq!(*duration_ms, 0);
} else {
panic!("Event 5 should be PipelineCompleted, got {:?}", events[5]);
}
}
#[test]
fn test_multi_file_progress_tracking() {
let def = parse_def(
r#"{
"nodes": [
{ "id": "in", "type": "input" },
{ "id": "proc", "type": "test-echo" },
{ "id": "out", "type": "output" }
]
}"#,
);
let registry = mock_registry();
let recorder = RecordingReporter::new();
let reporter = recorder.reporter();
let files = vec![
make_file("a.jpg", b"aaa"),
make_file("b.jpg", b"bbb"),
make_file("c.jpg", b"ccc"),
];
execute_pipeline(&def, files, ®istry, &reporter, &NoopContext, fake_now).unwrap();
let events = recorder.events();
let progress_events: Vec<&PipelineEvent> = events
.iter()
.filter(|e| matches!(e, PipelineEvent::FileProgress { .. }))
.collect();
assert_eq!(
progress_events.len(),
6,
"3 files × (0% + 100%) = 6 progress events"
);
let expected_sequence = [
(0, 0, "a.jpg"),
(0, 100, "a.jpg"),
(1, 0, "b.jpg"),
(1, 100, "b.jpg"),
(2, 0, "c.jpg"),
(2, 100, "c.jpg"),
];
for (i, (expected_idx, expected_pct, expected_name)) in expected_sequence.iter().enumerate() {
if let PipelineEvent::FileProgress {
file_index,
total_files,
percent,
message,
..
} = &progress_events[i]
{
assert_eq!(
*file_index, *expected_idx,
"Event {} file_index: expected {}, got {}",
i, expected_idx, file_index
);
assert_eq!(*total_files, 3, "total_files should always be 3");
assert_eq!(
*percent, *expected_pct as u32,
"Event {} percent: expected {}, got {}",
i, expected_pct, percent
);
assert!(
message.contains(expected_name),
"Event {} message should contain '{}': {}",
i,
expected_name,
message
);
} else {
panic!("Expected FileProgress at index {}", i);
}
}
if let PipelineEvent::PipelineCompleted {
total_files_processed,
..
} = events.last().unwrap()
{
assert_eq!(*total_files_processed, 3);
} else {
panic!("Last event should be PipelineCompleted");
}
}