use sorting_race::models::traits::Sorter;
use sorting_race::services::sorters::shell::ShellSort;
#[test]
fn test_shell_sort_basic_sorting() {
let mut shell_sort = ShellSort::new();
let test_data = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
let expected = {
let mut sorted = test_data.clone();
sorted.sort();
sorted
};
shell_sort.reset(test_data.clone());
assert!(!shell_sort.is_complete());
assert_eq!(shell_sort.get_array(), &test_data);
let mut steps = 0;
let max_steps = 1000;
while !shell_sort.is_complete() && steps < max_steps {
let result = shell_sort.step(16);
steps += 1;
assert!(result.comparisons_used <= 16);
let telemetry = shell_sort.get_telemetry();
assert!(telemetry.progress_hint >= 0.0 && telemetry.progress_hint <= 1.0);
assert!(telemetry.total_comparisons >= result.comparisons_used as u64);
assert!(telemetry.total_moves >= result.moves_made as u64);
}
assert!(shell_sort.is_complete());
assert_eq!(shell_sort.get_array(), &expected);
let result = shell_sort.step(16);
assert_eq!(result.comparisons_used, 0);
assert_eq!(result.moves_made, 0);
assert!(!result.continued);
}
#[test]
fn test_shell_sort_with_various_budgets() {
let mut shell_sort = ShellSort::new();
let test_data = vec![3, 1, 4, 1, 5, 9, 2, 6];
shell_sort.reset(test_data.clone());
let result1 = shell_sort.step(1);
assert!(result1.comparisons_used <= 1);
let result2 = shell_sort.step(5);
assert!(result2.comparisons_used <= 5);
let prev_comparisons = shell_sort.get_telemetry().total_comparisons;
let result3 = shell_sort.step(0);
assert_eq!(result3.comparisons_used, 0);
assert_eq!(
shell_sort.get_telemetry().total_comparisons,
prev_comparisons
);
}
#[test]
fn test_shell_sort_edge_cases() {
let mut shell_sort = ShellSort::new();
shell_sort.reset(vec![]);
assert!(shell_sort.is_complete());
shell_sort.reset(vec![42]);
assert!(shell_sort.is_complete());
assert_eq!(shell_sort.get_array(), &[42]);
shell_sort.reset(vec![1, 2, 3, 4, 5]);
while !shell_sort.is_complete() {
shell_sort.step(16);
}
assert_eq!(shell_sort.get_array(), &[1, 2, 3, 4, 5]);
shell_sort.reset(vec![5, 4, 3, 2, 1]);
while !shell_sort.is_complete() {
shell_sort.step(16);
}
assert_eq!(shell_sort.get_array(), &[1, 2, 3, 4, 5]);
shell_sort.reset(vec![3, 3, 3, 3, 3]);
while !shell_sort.is_complete() {
shell_sort.step(16);
}
assert_eq!(shell_sort.get_array(), &[3, 3, 3, 3, 3]);
}
#[test]
fn test_shell_sort_gap_sequence() {
let mut shell_sort = ShellSort::new();
let test_data = vec![8, 7, 6, 5, 4, 3, 2, 1];
shell_sort.reset(test_data);
if !shell_sort.is_complete() {
shell_sort.step(1);
let telemetry = shell_sort.get_telemetry();
assert!(telemetry.markers.gap.is_some());
let gap = telemetry.markers.gap.unwrap();
assert!(gap > 0);
assert!(gap < 8);
assert!(telemetry.status_text.contains("Gap"));
}
}
#[test]
fn test_shell_sort_memory_usage() {
let shell_sort = ShellSort::new();
assert_eq!(shell_sort.get_memory_usage(), 0);
let telemetry = shell_sort.get_telemetry();
assert_eq!(telemetry.memory_current, 0);
assert_eq!(telemetry.memory_peak, 0);
}
#[test]
fn test_shell_sort_name() {
let shell_sort = ShellSort::new();
assert_eq!(shell_sort.name(), "Shell Sort");
}