use sql_cli::data::data_view::DataView;
use sql_cli::data::datatable::{DataColumn, DataRow, DataTable, DataValue};
use std::sync::Arc;
fn create_test_table() -> Arc<DataTable> {
let mut table = DataTable::new("test");
table.add_column(DataColumn::new("id"));
table.add_column(DataColumn::new("name"));
table.add_column(DataColumn::new("amount"));
table.add_column(DataColumn::new("category"));
table.add_column(DataColumn::new("status"));
table.add_column(DataColumn::new("date"));
for i in 1..=5 {
table
.add_row(DataRow::new(vec![
DataValue::Integer(i),
DataValue::String(format!("Item{i}")),
DataValue::Float(100.0 * i as f64),
DataValue::String(if i % 2 == 0 { "A" } else { "B" }.to_string()),
DataValue::String("Active".to_string()),
DataValue::String("2024-01-01".to_string()),
]))
.unwrap();
}
Arc::new(table)
}
#[test]
fn test_pin_column_basic() {
let table = create_test_table();
let mut view = DataView::new(table);
assert_eq!(view.get_pinned_columns().len(), 0);
assert_eq!(view.column_count(), 6);
assert_eq!(
view.column_names(),
vec!["id", "name", "amount", "category", "status", "date"]
);
view.pin_column(0).unwrap();
assert_eq!(view.get_pinned_columns(), &[0]);
assert_eq!(view.column_count(), 6);
assert_eq!(
view.column_names(),
vec!["id", "name", "amount", "category", "status", "date"]
);
view.pin_column(2).unwrap();
assert_eq!(view.get_pinned_columns(), &[0, 2]);
assert_eq!(
view.column_names(),
vec!["id", "amount", "name", "category", "status", "date"]
);
}
#[test]
fn test_pin_column_by_name() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column_by_name("name").unwrap();
assert_eq!(view.get_pinned_column_names(), vec!["name"]);
view.pin_column_by_name("status").unwrap();
assert_eq!(view.get_pinned_column_names(), vec!["name", "status"]);
assert!(view.pin_column_by_name("nonexistent").is_err());
}
#[test]
fn test_max_pinned_columns() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap();
view.pin_column(1).unwrap();
view.pin_column(2).unwrap();
view.pin_column(3).unwrap();
assert!(view.pin_column(4).is_err());
assert_eq!(view.get_pinned_columns().len(), 4);
view.set_max_pinned_columns(2);
assert_eq!(view.get_pinned_columns().len(), 2);
assert_eq!(view.get_pinned_columns(), &[0, 1]);
}
#[test]
#[ignore = "Test needs update: pin/hide operations now use display indices, not source indices"]
fn test_cannot_hide_pinned_column() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(1).unwrap();
let hidden = view.hide_column(1);
assert!(!hidden);
assert!(view.is_column_visible(1));
assert!(view.column_names().contains(&"name".to_string()));
let hidden = view.hide_column(3);
assert!(hidden);
assert!(!view.column_names().contains(&"category".to_string()));
}
#[test]
fn test_unpin_column() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap();
view.pin_column(2).unwrap();
assert_eq!(view.get_pinned_columns().len(), 2);
assert!(view.unpin_column(0));
assert_eq!(view.get_pinned_columns(), &[2]);
assert!(view.is_column_visible(0));
assert!(view.unpin_column_by_name("amount"));
assert_eq!(view.get_pinned_columns().len(), 0);
}
#[test]
fn test_move_pinned_columns() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap(); view.pin_column(1).unwrap(); view.pin_column(2).unwrap();
assert_eq!(view.get_pinned_column_names(), vec!["id", "name", "amount"]);
view.move_column_left(1);
assert_eq!(view.get_pinned_column_names(), vec!["name", "id", "amount"]);
view.move_column_right(2);
assert_eq!(view.get_pinned_column_names(), vec!["amount", "name", "id"]);
let all_names = view.column_names();
assert_eq!(all_names[0..3], ["amount", "name", "id"]);
assert_eq!(all_names[3], "category"); }
#[test]
fn test_clear_pinned_columns() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap();
view.pin_column(2).unwrap();
view.pin_column(4).unwrap();
assert_eq!(view.get_pinned_columns().len(), 3);
view.clear_pinned_columns();
assert_eq!(view.get_pinned_columns().len(), 0);
assert_eq!(view.column_count(), 6);
}
#[test]
fn test_pinned_columns_with_filtering() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap();
view.pin_column(1).unwrap();
view.apply_text_filter("Item2", false);
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::Integer(2)); assert_eq!(row.values[1], DataValue::String("Item2".to_string()));
assert_eq!(
view.column_names(),
vec!["id", "name", "amount", "category", "status", "date"]
);
}
#[test]
fn test_pinned_columns_with_sorting() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(1).unwrap();
view.apply_sort(2, false).unwrap();
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::String("Item5".to_string())); assert_eq!(row.values[2], DataValue::Float(500.0));
assert_eq!(view.column_names()[0], "name"); }
#[test]
fn test_combined_operations() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column_by_name("id").unwrap();
view.pin_column_by_name("amount").unwrap();
view.hide_column_by_name("date");
view.apply_sort(1, false).unwrap();
view.apply_text_filter("Active", false);
assert_eq!(view.row_count(), 5); assert_eq!(view.column_count(), 5);
let columns = view.column_names();
assert_eq!(columns, vec!["id", "amount", "name", "category", "status"]);
let first_row = view.get_row(0).unwrap();
assert_eq!(first_row.values[0], DataValue::Integer(5)); assert_eq!(first_row.values[1], DataValue::Float(500.0)); }
#[test]
fn test_get_display_columns() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(1).unwrap(); view.pin_column(3).unwrap();
view.hide_column(5);
let display = view.get_display_columns();
assert_eq!(display, vec![1, 3, 0, 2, 4]);
let names = view.get_display_column_names();
assert_eq!(names, vec!["name", "category", "id", "amount", "status"]);
}
#[test]
#[ignore = "Test needs update: pin/hide operations now use display indices, not source indices"]
fn test_export_with_pinned_columns() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(2).unwrap(); view.pin_column(1).unwrap();
view.hide_column(5);
let csv = view.to_csv().unwrap();
let lines: Vec<&str> = csv.lines().collect();
assert_eq!(lines[0], "amount,name,id,category,status");
assert_eq!(lines[1], "100,Item1,1,B,Active");
}
#[test]
fn test_wraparound_navigation() {
let table = create_test_table();
let mut view = DataView::new(table);
view.pin_column(0).unwrap(); view.pin_column(1).unwrap();
view.move_column_left(2);
let names = view.column_names();
assert_eq!(names[names.len() - 1], "amount");
view.move_column_right(names.len() - 1);
let names = view.column_names();
assert_eq!(names[2], "amount"); }