ruchy 4.2.0

A systems scripting language that transpiles to idiomatic Rust with extreme quality engineering
Documentation
//! Unit tests for backend transpiler DataFrame module
//!
//! Comprehensive unit testing for the zero-coverage DataFrame transpilation module.
//! Covers DataFrame creation, operations, and Rust code generation.

#![allow(warnings)] // Allow all warnings for test files

use ruchy::backend::transpiler::Transpiler;
use ruchy::frontend::ast::{
    AggregateOp, DataFrameColumn, DataFrameOp, Expr, ExprKind, JoinType, Literal, Span,
};

/// Helper to create test expressions
fn create_expr(kind: ExprKind) -> Expr {
    Expr::new(kind, Span::new(0, 10))
}

/// Test DataFrame literal transpilation
#[test]
fn test_dataframe_literal_basic() {
    let mut transpiler = Transpiler::new();

    let df_columns = vec![
        DataFrameColumn {
            name: "id".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::Integer(1))),
                create_expr(ExprKind::Literal(Literal::Integer(2))),
            ],
        },
        DataFrameColumn {
            name: "name".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::String("Alice".to_string()))),
                create_expr(ExprKind::Literal(Literal::String("Bob".to_string()))),
            ],
        },
    ];

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: df_columns,
    });
    let result = transpiler.transpile_expr(&df_expr);

    // Should generate valid Rust code for DataFrame
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame filter operation
#[test]
fn test_dataframe_filter_operation() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "value".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::Integer(10))),
                create_expr(ExprKind::Literal(Literal::Integer(20))),
            ],
        }],
    });

    let filter_condition = create_expr(ExprKind::Binary {
        left: Box::new(create_expr(ExprKind::Identifier("value".to_string()))),
        op: ruchy::frontend::ast::BinaryOp::Greater,
        right: Box::new(create_expr(ExprKind::Literal(Literal::Integer(15)))),
    });

    let filter_op = DataFrameOp::Filter(Box::new(filter_condition));

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: filter_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame select operation
#[test]
fn test_dataframe_select_operation() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![
            DataFrameColumn {
                name: "id".to_string(),
                values: vec![create_expr(ExprKind::Literal(Literal::Integer(1)))],
            },
            DataFrameColumn {
                name: "name".to_string(),
                values: vec![create_expr(ExprKind::Literal(Literal::String(
                    "test".to_string(),
                )))],
            },
        ],
    });

    let select_op = DataFrameOp::Select(vec!["id".to_string(), "name".to_string()]);

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: select_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame groupby operation
#[test]
fn test_dataframe_groupby_operation() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "category".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::String("A".to_string()))),
                create_expr(ExprKind::Literal(Literal::String("B".to_string()))),
            ],
        }],
    });

    let groupby_op = DataFrameOp::GroupBy(vec!["category".to_string()]);

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: groupby_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame join operation
#[test]
fn test_dataframe_join_operation() {
    let mut transpiler = Transpiler::new();

    let left_df = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "id".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::Integer(1)))],
        }],
    });

    let right_df = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "id".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::Integer(1)))],
        }],
    });

    let join_op = DataFrameOp::Join {
        other: Box::new(right_df),
        on: vec!["id".to_string()],
        how: JoinType::Inner,
    };

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(left_df),
        operation: join_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame sort operation
#[test]
fn test_dataframe_sort_operation() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "score".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::Integer(90))),
                create_expr(ExprKind::Literal(Literal::Integer(85))),
            ],
        }],
    });

    let sort_op = DataFrameOp::Sort(vec!["score".to_string()]);

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: sort_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame aggregate operation
#[test]
fn test_dataframe_aggregate_operation() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "values".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::Integer(10))),
                create_expr(ExprKind::Literal(Literal::Integer(20))),
            ],
        }],
    });

    let agg_expr = create_expr(ExprKind::Call {
        func: Box::new(create_expr(ExprKind::Identifier("sum".to_string()))),
        args: vec![create_expr(ExprKind::Identifier("values".to_string()))],
    });

    let aggregate_op = DataFrameOp::Aggregate(vec![AggregateOp::Sum("values".to_string())]);

    let operation_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: aggregate_op,
    });

    let result = transpiler.transpile_expr(&operation_expr);
    assert!(result.is_ok() || result.is_err());
}

/// Test empty DataFrame
#[test]
fn test_empty_dataframe() {
    let mut transpiler = Transpiler::new();

    let empty_df = create_expr(ExprKind::DataFrame { columns: vec![] });
    let result = transpiler.transpile_expr(&empty_df);

    // Should handle empty DataFrame gracefully
    assert!(result.is_ok() || result.is_err());
}

/// Test DataFrame with mixed column types
#[test]
fn test_mixed_column_types() {
    let mut transpiler = Transpiler::new();

    let df_columns = vec![
        DataFrameColumn {
            name: "int_col".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::Integer(42)))],
        },
        DataFrameColumn {
            name: "float_col".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::Float(42.5)))],
        },
        DataFrameColumn {
            name: "bool_col".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::Bool(true)))],
        },
        DataFrameColumn {
            name: "string_col".to_string(),
            values: vec![create_expr(ExprKind::Literal(Literal::String(
                "test".to_string(),
            )))],
        },
    ];

    let mixed_df = create_expr(ExprKind::DataFrame {
        columns: df_columns,
    });
    let result = transpiler.transpile_expr(&mixed_df);

    // Should handle mixed types
    assert!(result.is_ok() || result.is_err());
}

/// Test chained DataFrame operations
#[test]
fn test_chained_dataframe_operations() {
    let mut transpiler = Transpiler::new();

    let df_expr = create_expr(ExprKind::DataFrame {
        columns: vec![DataFrameColumn {
            name: "value".to_string(),
            values: vec![
                create_expr(ExprKind::Literal(Literal::Integer(5))),
                create_expr(ExprKind::Literal(Literal::Integer(15))),
                create_expr(ExprKind::Literal(Literal::Integer(25))),
            ],
        }],
    });

    // First operation: filter
    let filter_op = DataFrameOp::Filter(Box::new(create_expr(ExprKind::Binary {
        left: Box::new(create_expr(ExprKind::Identifier("value".to_string()))),
        op: ruchy::frontend::ast::BinaryOp::Greater,
        right: Box::new(create_expr(ExprKind::Literal(Literal::Integer(10)))),
    })));

    let filtered_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(df_expr),
        operation: filter_op,
    });

    // Second operation: sort
    let sort_op = DataFrameOp::Sort(vec!["value".to_string()]);

    let chained_expr = create_expr(ExprKind::DataFrameOperation {
        source: Box::new(filtered_expr),
        operation: sort_op,
    });

    let result = transpiler.transpile_expr(&chained_expr);
    assert!(result.is_ok() || result.is_err());
}