use sql_cli::data::data_view::DataView;
use sql_cli::data::datatable::{DataColumn, DataRow, DataTable, DataValue};
use sql_cli::data::query_engine::QueryEngine;
use std::sync::Arc;
fn create_test_table() -> Arc<DataTable> {
let mut table = DataTable::new("users");
table.add_column(DataColumn::new("id"));
table.add_column(DataColumn::new("name"));
table.add_column(DataColumn::new("age"));
table.add_column(DataColumn::new("city"));
table
.add_row(DataRow::new(vec![
DataValue::Integer(1),
DataValue::String("Alice".to_string()),
DataValue::Integer(30),
DataValue::String("New York".to_string()),
]))
.unwrap();
table
.add_row(DataRow::new(vec![
DataValue::Integer(2),
DataValue::String("Bob".to_string()),
DataValue::Integer(25),
DataValue::String("London".to_string()),
]))
.unwrap();
table
.add_row(DataRow::new(vec![
DataValue::Integer(3),
DataValue::String("Charlie".to_string()),
DataValue::Integer(35),
DataValue::String("Paris".to_string()),
]))
.unwrap();
table
.add_row(DataRow::new(vec![
DataValue::Integer(4),
DataValue::String("David".to_string()),
DataValue::Integer(28),
DataValue::String("London".to_string()),
]))
.unwrap();
table
.add_row(DataRow::new(vec![
DataValue::Integer(5),
DataValue::String("Eve".to_string()),
DataValue::Integer(32),
DataValue::String("New York".to_string()),
]))
.unwrap();
Arc::new(table)
}
#[test]
fn test_select_all() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users")
.unwrap();
assert_eq!(view.row_count(), 5);
assert_eq!(view.column_count(), 4);
let columns = view.column_names();
assert_eq!(columns, vec!["id", "name", "age", "city"]);
}
#[test]
fn test_select_specific_columns() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT name, age FROM users")
.unwrap();
assert_eq!(view.row_count(), 5);
assert_eq!(view.column_count(), 2);
let columns = view.column_names();
assert_eq!(columns, vec!["name", "age"]);
let row = view.get_row(0).unwrap();
assert_eq!(row.values.len(), 2);
assert_eq!(row.values[0], DataValue::String("Alice".to_string()));
assert_eq!(row.values[1], DataValue::Integer(30));
}
#[test]
fn test_select_with_limit() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users LIMIT 3")
.unwrap();
assert_eq!(view.row_count(), 3);
assert_eq!(view.column_count(), 4);
}
#[test]
fn test_select_with_limit_offset() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users LIMIT 2 OFFSET 2")
.unwrap();
assert_eq!(view.row_count(), 2);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[1], DataValue::String("Charlie".to_string()));
let row = view.get_row(1).unwrap();
assert_eq!(row.values[1], DataValue::String("David".to_string()));
}
#[test]
fn test_data_view_direct_usage() {
let table = create_test_table();
let view = DataView::new(table.clone());
assert_eq!(view.row_count(), 5);
assert_eq!(view.column_count(), 4);
let view = view.with_columns(vec![1, 2]); assert_eq!(view.column_count(), 2);
let view = view.with_limit(2, 0);
assert_eq!(view.row_count(), 2);
}
#[test]
fn test_data_view_sorting() {
let table = create_test_table();
let view = DataView::new(table.clone())
.sort_by(2, true) .unwrap();
let row = view.get_row(0).unwrap();
assert_eq!(row.values[2], DataValue::Integer(25));
let row = view.get_row(4).unwrap();
assert_eq!(row.values[2], DataValue::Integer(35)); }
#[test]
fn test_select_with_where_equals() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users WHERE city = 'London'")
.unwrap();
assert_eq!(view.row_count(), 2);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[1], DataValue::String("Bob".to_string()));
let row = view.get_row(1).unwrap();
assert_eq!(row.values[1], DataValue::String("David".to_string()));
}
#[test]
fn test_select_with_where_greater_than() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users WHERE age > 30")
.unwrap();
assert_eq!(view.row_count(), 2); }
#[test]
fn test_select_columns_with_where() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT name, age FROM users WHERE age >= 30")
.unwrap();
assert_eq!(view.row_count(), 3); assert_eq!(view.column_count(), 2);
let columns = view.column_names();
assert_eq!(columns, vec!["name", "age"]);
}
#[test]
fn test_select_with_like() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT * FROM users WHERE name LIKE '%e%'")
.unwrap();
assert_eq!(view.row_count(), 3);
}
#[test]
fn test_select_with_in() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT * FROM users WHERE city IN ('London', 'Paris')",
)
.unwrap();
assert_eq!(view.row_count(), 3);
}
#[test]
fn test_select_with_between() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT * FROM users WHERE age BETWEEN 28 AND 32",
)
.unwrap();
assert_eq!(view.row_count(), 3);
}
#[test]
fn test_select_with_and_condition() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT * FROM users WHERE age > 25 AND city = 'London'",
)
.unwrap();
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[1], DataValue::String("David".to_string()));
}
#[test]
fn test_select_with_or_condition() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT * FROM users WHERE city = 'Paris' OR age = 25",
)
.unwrap();
assert_eq!(view.row_count(), 2);
}
#[test]
#[ignore = "Complex WHERE with parentheses not yet implemented"]
fn test_complex_where_and_or() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT * FROM users WHERE (age > 30 AND city = 'New York') OR city = 'Paris'",
)
.unwrap();
assert_eq!(view.row_count(), 2);
}
#[test]
fn test_string_literal_with_aggregates_single_row() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT 'User Count', COUNT(id), 'Average Age', AVG(age) FROM users",
)
.unwrap();
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::String("User Count".to_string()));
assert_eq!(row.values[1], DataValue::Integer(5)); assert_eq!(row.values[2], DataValue::String("Average Age".to_string()));
if let DataValue::Float(avg) = &row.values[3] {
assert!((avg - 30.0).abs() < 0.001);
} else {
panic!("Expected float for AVG(age), got {:?}", row.values[3]);
}
}
#[test]
fn test_number_literal_with_aggregates_single_row() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT 42, COUNT(id), 3.14, MIN(age) FROM users",
)
.unwrap();
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::Integer(42));
assert_eq!(row.values[1], DataValue::Integer(5));
assert_eq!(row.values[2], DataValue::Float(3.14));
assert_eq!(row.values[3], DataValue::Integer(25)); }
#[test]
fn test_boolean_null_literal_with_aggregates_single_row() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(
table.clone(),
"SELECT TRUE, COUNT(id), NULL, MAX(age) FROM users",
)
.unwrap();
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::Boolean(true));
assert_eq!(row.values[1], DataValue::Integer(5));
assert_eq!(row.values[2], DataValue::Null);
assert_eq!(row.values[3], DataValue::Integer(35)); }
#[test]
fn test_column_with_aggregates_multiple_rows() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT name, COUNT(id) FROM users")
.unwrap();
assert_eq!(view.row_count(), 5);
for i in 0..5 {
let row = view.get_row(i).unwrap();
assert_eq!(row.values[1], DataValue::Integer(5));
}
}
#[test]
fn test_constant_arithmetic_with_aggregates_single_row() {
let table = create_test_table();
let engine = QueryEngine::new();
let view = engine
.execute(table.clone(), "SELECT 1 + 2, COUNT(id), 10 * 5 FROM users")
.unwrap();
assert_eq!(view.row_count(), 1);
let row = view.get_row(0).unwrap();
assert_eq!(row.values[0], DataValue::Integer(3)); assert_eq!(row.values[1], DataValue::Integer(5)); assert_eq!(row.values[2], DataValue::Integer(50)); }