use ruvector_dag::dag::{OperatorNode, OperatorType, QueryDag};
#[test]
fn test_complex_query_dag() {
let mut dag = QueryDag::new();
let scan1 = dag.add_node(OperatorNode::seq_scan(0, "users"));
let scan2 = dag.add_node(OperatorNode::hnsw_scan(1, "vectors_idx", 64));
let join = dag.add_node(OperatorNode::hash_join(2, "user_id"));
dag.add_edge(scan1, join).unwrap();
dag.add_edge(scan2, join).unwrap();
let filter = dag.add_node(OperatorNode::filter(3, "score > 0.5"));
dag.add_edge(join, filter).unwrap();
let result = dag.add_node(OperatorNode::new(4, OperatorType::Result));
dag.add_edge(filter, result).unwrap();
assert_eq!(dag.node_count(), 5);
assert_eq!(dag.edge_count(), 4);
let order = dag.topological_sort().unwrap();
assert_eq!(order.len(), 5);
let scan1_pos = order.iter().position(|&x| x == scan1).unwrap();
let scan2_pos = order.iter().position(|&x| x == scan2).unwrap();
let join_pos = order.iter().position(|&x| x == join).unwrap();
assert!(scan1_pos < join_pos);
assert!(scan2_pos < join_pos);
}
#[test]
fn test_dag_depths() {
let mut dag = QueryDag::new();
for i in 0..5 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(3, 1).unwrap();
dag.add_edge(4, 1).unwrap();
dag.add_edge(1, 0).unwrap();
dag.add_edge(2, 0).unwrap();
let depths = dag.compute_depths();
assert!(depths.contains_key(&0));
assert!(depths.contains_key(&1));
assert!(depths.contains_key(&2));
assert!(depths.contains_key(&3));
assert!(depths.contains_key(&4));
assert_eq!(depths[&0], 0);
assert_eq!(depths[&1], 1);
assert_eq!(depths[&2], 1);
assert_eq!(depths[&3], 2);
assert_eq!(depths[&4], 2);
}
#[test]
fn test_dag_cycle_detection() {
let mut dag = QueryDag::new();
for i in 0..3 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(0, 1).unwrap();
dag.add_edge(1, 2).unwrap();
let result = dag.add_edge(2, 0);
assert!(result.is_err());
}
#[test]
fn test_dag_node_removal() {
let mut dag = QueryDag::new();
for i in 0..5 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(0, 1).unwrap();
dag.add_edge(1, 2).unwrap();
dag.add_edge(2, 3).unwrap();
dag.add_edge(3, 4).unwrap();
dag.remove_node(2);
assert_eq!(dag.node_count(), 4);
let topo = dag.topological_sort();
assert!(topo.is_ok());
}
#[test]
fn test_dag_clone() {
let mut dag = QueryDag::new();
for i in 0..5 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
for i in 0..4 {
dag.add_edge(i, i + 1).unwrap();
}
let cloned = dag.clone();
assert_eq!(dag.node_count(), cloned.node_count());
assert_eq!(dag.edge_count(), cloned.edge_count());
}
#[test]
fn test_dag_topological_order() {
let mut dag = QueryDag::new();
for i in 0..4 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(0, 1).unwrap();
dag.add_edge(0, 2).unwrap();
dag.add_edge(1, 3).unwrap();
dag.add_edge(2, 3).unwrap();
let order = dag.topological_sort().unwrap();
assert_eq!(order[0], 0);
assert_eq!(order[3], 3);
assert!(order.contains(&1));
assert!(order.contains(&2));
}
#[test]
fn test_dag_parents_children() {
let mut dag = QueryDag::new();
for i in 0..4 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(0, 1).unwrap();
dag.add_edge(1, 3).unwrap();
dag.add_edge(2, 3).unwrap();
let preds = dag.parents(3);
assert_eq!(preds.len(), 2);
assert!(preds.contains(&1));
assert!(preds.contains(&2));
let succs = dag.children(0);
assert_eq!(succs.len(), 1);
assert!(succs.contains(&1));
}
#[test]
fn test_dag_leaves() {
let mut dag = QueryDag::new();
for i in 0..5 {
dag.add_node(OperatorNode::new(i, OperatorType::Result));
}
dag.add_edge(0, 2).unwrap();
dag.add_edge(1, 2).unwrap();
dag.add_edge(2, 3).unwrap();
dag.add_edge(2, 4).unwrap();
let leaves = dag.leaves();
assert_eq!(leaves.len(), 2);
assert!(leaves.contains(&3));
assert!(leaves.contains(&4));
}
#[test]
fn test_dag_empty() {
let dag = QueryDag::new();
assert_eq!(dag.node_count(), 0);
assert_eq!(dag.edge_count(), 0);
let order = dag.topological_sort().unwrap();
assert!(order.is_empty());
}
#[test]
fn test_dag_single_node() {
let mut dag = QueryDag::new();
dag.add_node(OperatorNode::new(0, OperatorType::Result));
assert_eq!(dag.node_count(), 1);
assert_eq!(dag.edge_count(), 0);
let order = dag.topological_sort().unwrap();
assert_eq!(order.len(), 1);
assert_eq!(order[0], 0);
}