use sorting_race::models::traits::Sorter;
use sorting_race::services::sorters::quick::QuickSort;
#[test]
#[should_panic(expected = "Incremental partitioning not yet implemented")]
fn test_quicksort_with_limited_budget() {
let mut quicksort = QuickSort::new();
let data = vec![
64, 34, 25, 12, 22, 11, 90, 5, 77, 30, 40, 60, 35, 65, 15, 85,
];
quicksort.reset(data.clone());
let budget = 16;
let mut total_steps = 0;
let mut _total_comparisons = 0;
while !quicksort.is_complete() && total_steps < 100 {
let result = quicksort.step(budget);
_total_comparisons += result.comparisons_used;
total_steps += 1;
assert!(
result.comparisons_used <= budget,
"Step used {} comparisons but budget was {}",
result.comparisons_used,
budget
);
assert!(
result.continued || quicksort.is_complete(),
"Algorithm neither continued nor completed"
);
}
assert!(
quicksort.is_complete(),
"Quick Sort did not complete after {} steps with budget {}",
total_steps,
budget
);
let final_array = quicksort.get_array();
let mut expected = data.clone();
expected.sort();
assert_eq!(final_array, expected, "Array not properly sorted");
panic!("Incremental partitioning not yet implemented");
}
#[test]
#[should_panic(expected = "Incremental partitioning guarantees not met")]
fn test_completion_guarantee_with_minimal_budget() {
let mut quicksort = QuickSort::new();
let data: Vec<i32> = (1..=20).rev().collect(); quicksort.reset(data.clone());
let minimal_budget = 1; let mut total_steps = 0;
let max_expected_steps = data.len() * data.len();
while !quicksort.is_complete() && total_steps < max_expected_steps {
let result = quicksort.step(minimal_budget);
total_steps += 1;
if total_steps > max_expected_steps / 2 {
assert!(
result.comparisons_used > 0 || quicksort.is_complete(),
"Algorithm made no progress with minimal budget"
);
}
}
assert!(
quicksort.is_complete(),
"Quick Sort failed to complete with minimal budget after {} steps",
total_steps
);
let final_array = quicksort.get_array();
let mut expected = data.clone();
expected.sort();
assert_eq!(
final_array, expected,
"Array not properly sorted with minimal budget"
);
panic!("Incremental partitioning guarantees not met");
}
#[test]
#[should_panic(expected = "Budget management not implemented")]
fn test_budget_allocation_across_partitions() {
let mut quicksort = QuickSort::new();
let data: Vec<i32> = (0..50).collect();
quicksort.reset(data);
let budget = 16;
let mut step_results = Vec::new();
while !quicksort.is_complete() && step_results.len() < 20 {
let result = quicksort.step(budget);
step_results.push(result.clone());
assert!(
result.comparisons_used <= budget,
"Budget exceeded: used {} but limit was {}",
result.comparisons_used,
budget
);
}
let total_comparisons: usize = step_results.iter().map(|r| r.comparisons_used).sum();
assert!(
total_comparisons > 0,
"No comparisons made across all steps"
);
assert!(
step_results.len() > 1,
"Should require multiple steps with budget {}",
budget
);
let full_budget_steps = step_results
.iter()
.filter(|r| r.comparisons_used == budget && r.continued)
.count();
assert!(
full_budget_steps > 0,
"No steps used full budget, suggesting poor budget utilization"
);
panic!("Budget management not implemented");
}
#[test]
#[should_panic(expected = "Incremental pivot strategies not supported")]
fn test_incremental_partitioning_pivot_strategies() {
let mut quicksort = QuickSort::new();
let data = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
quicksort.reset(data.clone());
let budget = 5;
let mut telemetry_history = Vec::new();
while !quicksort.is_complete() {
quicksort.step(budget);
let telemetry = quicksort.get_telemetry();
telemetry_history.push(telemetry);
if telemetry_history.len() > 20 {
break; }
}
let pivot_changes = telemetry_history
.iter()
.map(|t| t.markers.pivot)
.collect::<Vec<_>>();
let unique_pivots: std::collections::HashSet<_> =
pivot_changes.into_iter().flatten().collect();
assert!(
unique_pivots.len() > 1,
"Expected multiple pivots during incremental partitioning, found {:?}",
unique_pivots
);
panic!("Incremental pivot strategies not supported");
}