use super::*;
use crate::frontend::ast::{Literal, UnaryOp};
#[test]
fn test_parser_basic_literals() {
let mut state = ParserState::new("42");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Literal(Literal::Integer(42, None))
));
let mut state = ParserState::new("3.15");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Literal(Literal::Float(f)) = expr.kind {
assert!((f - 3.15).abs() < 0.001);
} else {
panic!("Expected float literal");
}
let mut state = ParserState::new("true");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Literal(Literal::Bool(true))));
let mut state = ParserState::new("false");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Literal(Literal::Bool(false))));
}
#[test]
fn test_parser_string_literals() {
let mut state = ParserState::new(r#""hello world""#);
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Literal(Literal::String(s)) = expr.kind {
assert_eq!(s, "hello world");
} else {
panic!("Expected string literal");
}
let mut state = ParserState::new(r#""""#);
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Literal(Literal::String(s)) = expr.kind {
assert_eq!(s, "");
} else {
panic!("Expected empty string literal");
}
}
#[test]
fn test_parser_identifiers() {
let mut state = ParserState::new("variable");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Identifier(name) = expr.kind {
assert_eq!(name, "variable");
} else {
panic!("Expected identifier");
}
let mut state = ParserState::new("_underscore");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Identifier(name) = expr.kind {
assert_eq!(name, "_underscore");
} else {
panic!("Expected identifier with underscore");
}
}
#[test]
fn test_parser_binary_operations() {
let mut state = ParserState::new("1 + 2");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Add,
..
}
));
let mut state = ParserState::new("10 - 5");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Subtract,
..
}
));
let mut state = ParserState::new("3 * 4");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Multiply,
..
}
));
let mut state = ParserState::new("8 / 2");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Divide,
..
}
));
}
#[test]
fn test_parser_comparison_operations() {
let mut state = ParserState::new("5 > 3");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Greater,
..
}
));
let mut state = ParserState::new("3 < 5");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Less,
..
}
));
let mut state = ParserState::new("5 == 5");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Equal,
..
}
));
let mut state = ParserState::new("5 != 3");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::NotEqual,
..
}
));
}
#[test]
fn test_parser_logical_operations() {
let mut state = ParserState::new("true && false");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::And,
..
}
));
let mut state = ParserState::new("true || false");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Or,
..
}
));
}
#[test]
fn test_parser_unary_operations() {
let mut state = ParserState::new("-42");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Unary {
op: UnaryOp::Negate,
..
}
));
let mut state = ParserState::new("!true");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Unary {
op: UnaryOp::Not,
..
}
));
}
#[test]
fn test_parser_parenthesized_expression() {
let mut state = ParserState::new("(42)");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Literal(Literal::Integer(42, None))
));
let mut state = ParserState::new("(1 + 2) * 3");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Multiply,
..
}
));
}
#[test]
fn test_parser_list_literal() {
let mut state = ParserState::new("[1, 2, 3]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::List(items) = expr.kind {
assert_eq!(items.len(), 3);
} else {
panic!("Expected list literal");
}
let mut state = ParserState::new("[]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::List(items) = expr.kind {
assert_eq!(items.len(), 0);
} else {
panic!("Expected empty list");
}
}
#[test]
fn test_parser_tuple_literal() {
let mut state = ParserState::new("(1, 2)");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Tuple(items) = expr.kind {
assert_eq!(items.len(), 2);
} else {
panic!("Expected tuple literal");
}
let mut state = ParserState::new("(1,)");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Tuple(items) = expr.kind {
assert_eq!(items.len(), 1);
} else {
panic!("Expected single-element tuple");
}
}
#[test]
fn test_parser_range_expressions() {
let mut state = ParserState::new("1..10");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Range { inclusive, .. } = expr.kind {
assert!(!inclusive);
} else {
panic!("Expected range expression");
}
let mut state = ParserState::new("1..=10");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Range { inclusive, .. } = expr.kind {
assert!(inclusive);
} else {
panic!("Expected inclusive range");
}
}
#[test]
fn test_parser_state_creation() {
let state = ParserState::new("test input");
assert_eq!(state.get_errors().len(), 0);
let (allocated, items) = state.arena_stats();
assert_eq!(allocated, 0);
assert_eq!(items, 0);
let (strings, bytes) = state.interner_stats();
assert_eq!(strings, 0);
assert_eq!(bytes, 0);
}
#[test]
fn test_parser_precedence_levels() {
let mut state = ParserState::new("1 + 2 * 3");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Add,
..
}
));
}
#[test]
fn test_parser_assignment_operators() {
let mut state = ParserState::new("x = 5");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(
matches!(expr.kind, ExprKind::Let { .. })
|| matches!(expr.kind, ExprKind::Binary { .. })
|| matches!(expr.kind, ExprKind::Assign { .. })
);
let mut state = ParserState::new("x += 5");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::CompoundAssign { .. }));
}
#[test]
fn test_parser_pipeline_operator() {
let mut state = ParserState::new("data >> transform");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::RightShift,
..
}
));
}
#[test]
fn test_parser_try_operator() {
let mut state = ParserState::new("result?");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Try { .. }));
}
#[test]
fn test_parser_index_access() {
let mut state = ParserState::new("array[0]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::IndexAccess { .. }));
}
#[test]
fn test_parser_slice_expressions() {
let mut state = ParserState::new("array[1:5]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Slice { .. }));
let mut state = ParserState::new("array[:5]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Slice { .. }));
let mut state = ParserState::new("array[1:]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::Slice { .. }));
}
#[test]
fn test_parser_postfix_increment() {
}
#[test]
fn test_parser_postfix_decrement() {
}
#[test]
fn test_parser_complex_expression() {
let mut state = ParserState::new("(a + b) * (c - d) / 2");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Divide,
..
}
));
}
#[test]
fn test_parser_character_literal() {
let mut state = ParserState::new("'a'");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Literal(Literal::Char(c)) = expr.kind {
assert_eq!(c, 'a');
} else {
panic!("Expected character literal");
}
}
#[test]
fn test_parser_method_call_chain() {
let mut state = ParserState::new("obj.method1().method2()");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::MethodCall { .. }));
}
#[test]
fn test_parser_safe_navigation() {
let mut state = ParserState::new("obj?.method()");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(
matches!(expr.kind, ExprKind::OptionalFieldAccess { .. })
|| matches!(expr.kind, ExprKind::MethodCall { .. })
|| matches!(expr.kind, ExprKind::OptionalMethodCall { .. })
);
}
#[test]
#[ignore = "Macro syntax not fully implemented"]
fn test_parser_macro_call() {
let mut state = ParserState::new("println!(\"hello\")");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::Call { func, args } = expr.kind {
if let ExprKind::Identifier(name) = func.kind {
assert_eq!(name, "println");
assert_eq!(args.len(), 1);
} else {
panic!("Expected function name");
}
} else {
panic!("Expected function call");
}
}
#[test]
fn test_parser_bitwise_operations() {
let mut state = ParserState::new("a & b");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::BitwiseAnd,
..
}
));
let mut state = ParserState::new("a | b");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::BitwiseOr,
..
}
));
let mut state = ParserState::new("a ^ b");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::BitwiseXor,
..
}
));
}
#[test]
fn test_parser_shift_operations() {
let mut state = ParserState::new("a << 2");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::LeftShift,
..
}
));
}
#[test]
fn test_parser_modulo_operation() {
let mut state = ParserState::new("10 % 3");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Modulo,
..
}
));
}
#[test]
fn test_parser_type_cast() {
let mut state = ParserState::new("x as i32");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(expr.kind, ExprKind::TypeCast { .. }));
}
#[test]
fn test_parser_power_operation() {
let mut state = ParserState::new("2 ** 8");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
assert!(matches!(
expr.kind,
ExprKind::Binary {
op: BinaryOp::Power,
..
}
));
}
#[test]
fn test_parser_prefix_increment() {
}
#[test]
fn test_parser_prefix_decrement() {
}
#[test]
fn test_parser_empty_input() {
let mut state = ParserState::new("");
let result = parse_expr_recursive(&mut state);
assert!(result.is_err());
}
#[test]
fn test_parser_nested_lists() {
let mut state = ParserState::new("[[1, 2], [3, 4]]");
let expr =
parse_expr_recursive(&mut state).expect("parse_expr_recursive should succeed in test");
if let ExprKind::List(outer) = expr.kind {
assert_eq!(outer.len(), 2);
for item in outer {
assert!(matches!(item.kind, ExprKind::List(_)));
}
} else {
panic!("Expected nested list");
}
}
#[test]
fn test_ternary_operator_precedence_boundary() {
let mut state = ParserState::new("true ? 1 : 2");
let result = parse_expr_recursive(&mut state);
assert!(
result.is_ok(),
"Ternary with default precedence should work"
);
}
#[test]
fn test_ternary_precedence_calculation() {
let mut state = ParserState::new("1 + 1 ? 10 : 20");
let result = parse_expr_recursive(&mut state);
assert!(
result.is_ok(),
"Ternary with addition should parse correctly"
);
}
#[test]
fn test_assignment_operator_precedence_boundary_less_than() {
let mut state = ParserState::new("x = 42");
let result = parse_expr_with_precedence_recursive(&mut state, 0);
assert!(
result.is_ok(),
"Assignment with min_prec=0 should work (prec < min_prec is false)"
);
}
#[test]
fn test_range_operator_precedence_boundary() {
let mut state = ParserState::new("1..10");
let result = parse_expr_with_precedence_recursive(&mut state, 0);
assert!(result.is_ok(), "Range with low min_prec should work");
}
#[test]
fn test_range_precedence_calculation() {
let mut state = ParserState::new("1..10");
let result = parse_expr_recursive(&mut state);
assert!(
result.is_ok(),
"Range precedence calculation should use + not *"
);
}
#[test]
fn test_pipeline_precedence_calculation() {
let mut state = ParserState::new("x |> f");
let result = parse_expr_recursive(&mut state);
assert!(
result.is_ok(),
"Pipeline precedence should use + for right recursion"
);
}
#[test]
fn test_macro_call_returns_some() {
let mut state = ParserState::new("vec![1, 2, 3]");
let result = parse_expr_recursive(&mut state);
assert!(result.is_ok(), "Macro call should parse successfully");
if let Ok(expr) = result {
assert!(
matches!(expr.kind, ExprKind::MacroInvocation { .. }),
"Should parse as MacroInvocation expression (macro CALL, not definition)"
);
}
}