use ruvector_mincut::instance::StubInstance;
use ruvector_mincut::prelude::*;
use ruvector_mincut::wrapper::{MinCutResult, MinCutWrapper};
use std::sync::Arc;
#[test]
fn test_path_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
for i in 0..9 {
graph.insert_edge(i, i + 1, 1.0).unwrap();
}
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
for i in 0..9 {
wrapper.insert_edge(i as u64, i, i + 1);
}
let result = wrapper.query();
assert!(result.is_connected(), "Path graph should be connected");
assert_eq!(result.value(), 1, "Path graph has min cut 1");
}
#[test]
fn test_cycle_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
let n = 5;
for i in 0..n {
let j = (i + 1) % n;
graph.insert_edge(i, j, 1.0).unwrap();
}
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
for i in 0..n {
let j = (i + 1) % n;
wrapper.insert_edge(i as u64, i, j);
}
let result = wrapper.query();
assert!(result.is_connected(), "Cycle graph should be connected");
assert_eq!(result.value(), 2, "Cycle graph has min cut 2");
}
#[test]
fn test_complete_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
let n = 5;
let mut edge_id = 0;
for i in 0..n {
for j in (i + 1)..n {
graph.insert_edge(i, j, 1.0).unwrap();
}
}
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
for i in 0..n {
for j in (i + 1)..n {
wrapper.insert_edge(edge_id, i, j);
edge_id += 1;
}
}
let result = wrapper.query();
assert!(result.is_connected(), "Complete graph should be connected");
assert_eq!(result.value(), (n - 1) as u64, "K_5 has min cut 4");
}
#[test]
fn test_dynamic_updates_integration() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
for i in 0..3 {
graph.insert_edge(i, i + 1, 1.0).unwrap();
wrapper.insert_edge(i as u64, i, i + 1);
}
let result = wrapper.query();
assert_eq!(result.value(), 1, "Path has min cut 1");
graph.insert_edge(3, 0, 1.0).unwrap();
wrapper.insert_edge(3, 3, 0);
let result = wrapper.query();
assert_eq!(result.value(), 2, "Cycle has min cut 2");
graph.delete_edge(1, 2).unwrap();
wrapper.delete_edge(1, 1, 2);
let result = wrapper.query();
assert_eq!(result.value(), 1, "After deletion, min cut should be 1");
}
#[test]
fn test_disconnected_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
graph.insert_edge(0, 1, 1.0).unwrap();
graph.insert_edge(2, 3, 1.0).unwrap();
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 2, 3);
let result = wrapper.query();
assert!(!result.is_connected(), "Graph should be disconnected");
assert_eq!(result.value(), 0, "Disconnected graph has min cut 0");
}
#[test]
fn test_star_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
let n = 5;
for i in 1..n {
graph.insert_edge(0, i, 1.0).unwrap();
}
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
for i in 1..n {
wrapper.insert_edge((i - 1) as u64, 0, i);
}
let result = wrapper.query();
assert!(result.is_connected());
assert_eq!(result.value(), 1, "Star graph has min cut 1");
}
#[test]
fn test_weighted_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
graph.insert_edge(0, 1, 5.0).unwrap();
graph.insert_edge(1, 2, 3.0).unwrap();
graph.insert_edge(2, 0, 4.0).unwrap();
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 1, 2);
wrapper.insert_edge(2, 2, 0);
let result = wrapper.query();
assert!(result.is_connected());
assert!(
result.value() > 0,
"Weighted graph should have positive min cut"
);
}
#[test]
fn test_stress_many_updates() {
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
let mut rng = StdRng::seed_from_u64(12345);
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
let mut successful_inserts = 0;
for i in 0..1000 {
let u = rng.gen_range(0..100);
let v = rng.gen_range(0..100);
if u != v {
if graph.insert_edge(u, v, 1.0).is_ok() {
wrapper.insert_edge(i, u, v);
successful_inserts += 1;
}
}
}
println!("Successfully inserted {} edges", successful_inserts);
let result = wrapper.query();
if result.is_connected() {
assert!(
result.value() >= 1,
"Connected graph should have min cut >= 1"
);
} else {
assert_eq!(
result.value(),
0,
"Disconnected graph should have min cut 0"
);
}
assert_eq!(
wrapper.pending_updates(),
0,
"After query, updates should be processed"
);
}
#[test]
fn test_determinism() {
let graph1 = Arc::new(DynamicGraph::new());
let mut wrapper1 = MinCutWrapper::new(Arc::clone(&graph1));
let edges = vec![(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)];
for (i, (u, v)) in edges.iter().enumerate() {
graph1.insert_edge(*u, *v, 1.0).unwrap();
wrapper1.insert_edge(i as u64, *u, *v);
}
let result1 = wrapper1.query();
let graph2 = Arc::new(DynamicGraph::new());
let mut wrapper2 = MinCutWrapper::new(Arc::clone(&graph2));
for (i, (u, v)) in edges.iter().enumerate() {
graph2.insert_edge(*u, *v, 1.0).unwrap();
wrapper2.insert_edge(i as u64, *u, *v);
}
let result2 = wrapper2.query();
assert_eq!(
result1.value(),
result2.value(),
"Determinism: same input should produce same output"
);
assert_eq!(result1.is_connected(), result2.is_connected());
}
#[test]
fn test_buffered_updates() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
graph.insert_edge(0, 1, 1.0).unwrap();
graph.insert_edge(1, 2, 1.0).unwrap();
graph.insert_edge(2, 3, 1.0).unwrap();
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 1, 2);
wrapper.insert_edge(2, 2, 3);
assert_eq!(wrapper.pending_updates(), 3);
let result = wrapper.query();
assert_eq!(wrapper.pending_updates(), 0);
assert_eq!(result.value(), 1);
}
#[test]
fn test_lazy_instantiation() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
assert_eq!(wrapper.num_instances(), 0);
graph.insert_edge(0, 1, 1.0).unwrap();
graph.insert_edge(1, 2, 1.0).unwrap();
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 1, 2);
assert_eq!(wrapper.num_instances(), 0);
let _ = wrapper.query();
assert!(
wrapper.num_instances() > 0,
"Query should instantiate instances"
);
}
#[test]
fn test_multiple_queries_consistent() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
graph.insert_edge(0, 1, 1.0).unwrap();
graph.insert_edge(1, 2, 1.0).unwrap();
graph.insert_edge(2, 0, 1.0).unwrap();
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 1, 2);
wrapper.insert_edge(2, 2, 0);
let result1 = wrapper.query();
let result2 = wrapper.query();
let result3 = wrapper.query();
assert_eq!(result1.value(), result2.value());
assert_eq!(result2.value(), result3.value());
assert_eq!(result1.value(), 2, "Triangle has min cut 2");
}
#[test]
fn test_empty_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
let result = wrapper.query();
assert_eq!(result.value(), 0);
}
#[test]
fn test_single_edge_integration() {
let graph = Arc::new(DynamicGraph::new());
graph.insert_edge(0, 1, 1.0).unwrap();
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
wrapper.insert_edge(0, 0, 1);
let result = wrapper.query();
assert!(result.is_connected());
assert_eq!(result.value(), 1, "Single edge has min cut 1");
}
#[test]
fn test_grid_graph_integration() {
let graph = Arc::new(DynamicGraph::new());
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
let width = 3;
let height = 3;
let mut edge_id = 0;
for i in 0..height {
for j in 0..width {
let v = i * width + j;
if j + 1 < width {
let u = v;
let w = v + 1;
graph.insert_edge(u as u64, w as u64, 1.0).unwrap();
wrapper.insert_edge(edge_id, u as u64, w as u64);
edge_id += 1;
}
if i + 1 < height {
let u = v;
let w = v + width;
graph.insert_edge(u as u64, w as u64, 1.0).unwrap();
wrapper.insert_edge(edge_id, u as u64, w as u64);
edge_id += 1;
}
}
}
let result = wrapper.query();
assert!(result.is_connected());
assert_eq!(result.value(), 2, "3x3 grid has min cut 2");
}
#[test]
fn test_bridge_edge_integration() {
let graph = Arc::new(DynamicGraph::new());
graph.insert_edge(0, 1, 1.0).unwrap();
graph.insert_edge(1, 2, 1.0).unwrap();
graph.insert_edge(2, 0, 1.0).unwrap();
graph.insert_edge(2, 3, 1.0).unwrap();
graph.insert_edge(3, 4, 1.0).unwrap();
graph.insert_edge(4, 5, 1.0).unwrap();
graph.insert_edge(5, 3, 1.0).unwrap();
let mut wrapper = MinCutWrapper::new(Arc::clone(&graph));
wrapper.insert_edge(0, 0, 1);
wrapper.insert_edge(1, 1, 2);
wrapper.insert_edge(2, 2, 0);
wrapper.insert_edge(3, 2, 3); wrapper.insert_edge(4, 3, 4);
wrapper.insert_edge(5, 4, 5);
wrapper.insert_edge(6, 5, 3);
let result = wrapper.query();
assert!(result.is_connected());
assert_eq!(result.value(), 1, "Bridge edge gives min cut 1");
}