use crate::fixtures::ok_task;
use dag_executor::prelude::*;
#[test]
fn validates_a_well_formed_dag() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &[])).unwrap();
dag.add_task(ok_task("b", &["a"])).unwrap();
dag.add_task(ok_task("c", &["a", "b"])).unwrap();
assert!(dag.validate().is_ok());
assert_eq!(dag.len(), 3);
}
#[test]
fn rejects_duplicate_task_ids() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &[])).unwrap();
let err = dag.add_task(ok_task("a", &[])).unwrap_err();
assert!(matches!(
err,
DagExecutorError::Validation(ValidationError::DuplicateTask(_))
));
}
#[test]
fn rejects_self_dependency() {
let mut dag = Dag::new();
let err = dag.add_task(ok_task("a", &["a"])).unwrap_err();
assert!(matches!(
err,
DagExecutorError::Validation(ValidationError::SelfDependency(_))
));
}
#[test]
fn detects_missing_dependency() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &["ghost"])).unwrap();
let err = dag.validate().unwrap_err();
assert!(matches!(
err,
DagExecutorError::Validation(ValidationError::MissingDependency { .. })
));
}
#[test]
fn detects_cycles() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &["b"])).unwrap();
dag.add_task(ok_task("b", &["a"])).unwrap();
let err = dag.validate().unwrap_err();
assert!(matches!(
err,
DagExecutorError::Validation(ValidationError::Cycle(_))
));
}
#[test]
fn topological_order_respects_dependencies() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &[])).unwrap();
dag.add_task(ok_task("b", &["a"])).unwrap();
dag.add_task(ok_task("c", &["b"])).unwrap();
let order = dag.topological_order().unwrap();
let pos = |id: &str| order.iter().position(|x| x == id).unwrap();
assert!(pos("a") < pos("b"));
assert!(pos("b") < pos("c"));
}
#[test]
fn tracks_dependents_and_dependencies() {
let mut dag = Dag::new();
dag.add_task(ok_task("a", &[])).unwrap();
dag.add_task(ok_task("b", &["a"])).unwrap();
dag.add_task(ok_task("c", &["a"])).unwrap();
let mut deps = dag.dependencies_of("b");
deps.sort();
assert_eq!(deps, vec!["a".to_string()]);
let mut dependents = dag.dependents_of("a");
dependents.sort();
assert_eq!(dependents, vec!["b".to_string(), "c".to_string()]);
}