use super::*;
#[test]
fn test_transpile_if_with_else() {
let mut transpiler = create_transpiler();
let code = "if true { 1 } else { 2 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("if"));
assert!(rust_str.contains("else"));
}
#[test]
fn test_transpile_if_without_else() {
let mut transpiler = create_transpiler();
let code = "let x = true; if x { 1 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("if") && rust_str.contains("x"));
assert!(!rust_str.is_empty());
}
#[test]
fn test_transpile_let_binding() {
let mut transpiler = create_transpiler();
let code = "let x = 5; x";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("let"));
assert!(rust_str.contains("x"));
assert!(rust_str.contains("5"));
}
#[test]
fn test_transpile_mutable_let() {
let mut transpiler = create_transpiler();
let code = "let mut x = 5; x";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("mut"));
}
#[test]
fn test_transpile_for_loop() {
let mut transpiler = create_transpiler();
let code = "for x in [1, 2, 3] { x }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("for"));
assert!(rust_str.contains("in"));
}
#[test]
fn test_transpile_while_loop() {
let mut transpiler = create_transpiler();
let code = "while true { }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("while"));
}
#[test]
fn test_function_with_parameters() {
let mut transpiler = create_transpiler();
let code = "fun add(x, y) { x + y }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("fn add"));
assert!(rust_str.contains("x"));
assert!(rust_str.contains("y"));
}
#[test]
fn test_function_without_parameters() {
let mut transpiler = create_transpiler();
let code = "fun hello() { \"world\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("fn hello"));
assert!(rust_str.contains("()"));
}
#[test]
fn test_match_expression() {
let mut transpiler = create_transpiler();
let code = "match x { 1 => \"one\", _ => \"other\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("match"));
}
#[test]
fn test_lambda_expression() {
let mut transpiler = create_transpiler();
let code = "(x) => x + 1";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("|") || rust_str.contains("move"));
}
#[test]
fn test_reserved_keyword_handling() {
let mut transpiler = create_transpiler();
let code = "let move = 5; move"; let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(
rust_str.contains("r#move"),
"Expected r#move in: {rust_str}"
);
}
#[test]
fn test_generic_function() {
let mut transpiler = create_transpiler();
let code = "fun identity<T>(x: T) -> T { x }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("fn identity"));
}
#[test]
fn test_main_function_special_case() {
let mut transpiler = create_transpiler();
let code = "fun main() { println(\"Hello\") }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(!rust_str.contains("fn main() ->"));
assert!(!rust_str.contains("fn main () ->"));
}
#[test]
fn test_dataframe_function_call() {
let mut transpiler = create_transpiler();
let code = "col(\"name\")";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("polars") || rust_str.contains("col"));
}
#[test]
fn test_regular_function_call_string_conversion() {
let mut transpiler = create_transpiler();
let code = "my_func(\"test\")";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("my_func"));
assert!(rust_str.contains("to_string") || rust_str.contains("\"test\""));
}
#[test]
fn test_nested_expressions() {
let mut transpiler = create_transpiler();
let code = "if true { let x = 5; x + 1 } else { 0 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("if"));
assert!(rust_str.contains("let"));
assert!(rust_str.contains("else"));
}
#[test]
fn test_type_inference_integration() {
let mut transpiler = create_transpiler();
let code1 = "fun apply(f, x) { f(x) }";
let mut parser1 = Parser::new(code1);
let ast1 = parser1.parse().expect("Failed to parse");
let result1 = transpiler
.transpile(&ast1)
.expect("operation should succeed in test");
let rust_str1 = result1.to_string();
assert!(rust_str1.contains("impl Fn"));
let code2 = "fun double(n) { n * 2 }";
let mut parser2 = Parser::new(code2);
let ast2 = parser2.parse().expect("Failed to parse");
let result2 = transpiler
.transpile(&ast2)
.expect("operation should succeed in test");
let rust_str2 = result2.to_string();
assert!(rust_str2.contains("n : i32") || rust_str2.contains("n: i32"));
let code3 = "fun greet(name) { \"Hello \" + name }";
let mut parser3 = Parser::new(code3);
let ast3 = parser3.parse().expect("Failed to parse");
let result3 = transpiler
.transpile(&ast3)
.expect("operation should succeed in test");
let rust_str3 = result3.to_string();
assert!(
rust_str3.contains("name : & str") || rust_str3.contains("name: &str"),
"Expected &str parameter type, got: {rust_str3}"
);
}
#[test]
fn test_return_type_inference() {
let mut transpiler = create_transpiler();
let code = "fun double(n) { n * 2 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("-> i32"));
}
#[test]
fn test_void_function_no_return_type() {
let mut transpiler = create_transpiler();
let code = "fun print_hello() { println(\"Hello\") }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(!rust_str.contains("-> "));
}
#[test]
fn test_complex_function_combinations() {
let mut transpiler = create_transpiler();
let code = "fun transform(f, n, m) { f(n + m) * 2 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("impl Fn"));
assert!(rust_str.contains("n : i32") || rust_str.contains("n: i32"));
assert!(rust_str.contains("m : i32") || rust_str.contains("m: i32"));
}
#[test]
fn test_is_variable_mutated() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let assign_expr = Expr::new(
ExprKind::Assign {
target: Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span { start: 0, end: 0 },
)),
value: Box::new(Expr::new(
ExprKind::Literal(crate::frontend::ast::Literal::Integer(42, None)),
Span { start: 0, end: 0 },
)),
},
Span { start: 0, end: 0 },
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&assign_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&assign_expr
));
}
#[test]
fn test_transpile_break_continue() {
let mut transpiler = create_transpiler();
let code = "while true { if x { break } else { continue } }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("break"));
assert!(rust_str.contains("continue"));
}
#[test]
fn test_transpile_match_expression() {
let mut transpiler = create_transpiler();
let code = "match x { 1 => \"one\", 2 => \"two\", _ => \"other\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("match"));
assert!(rust_str.contains("1 =>") || rust_str.contains("1i64 =>"));
assert!(rust_str.contains("2 =>") || rust_str.contains("2i64 =>"));
assert!(rust_str.contains("_ =>"));
}
#[test]
fn test_transpile_struct_declaration() {
let mut transpiler = create_transpiler();
let code = "struct Point { x: i32, y: i32 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("struct Point"));
assert!(rust_str.contains("x : i32") || rust_str.contains("x: i32"));
assert!(rust_str.contains("y : i32") || rust_str.contains("y: i32"));
}
#[test]
fn test_transpile_enum_declaration() {
let mut transpiler = create_transpiler();
let code = "enum Color { Red, Green, Blue }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("enum Color"));
assert!(rust_str.contains("Red"));
assert!(rust_str.contains("Green"));
assert!(rust_str.contains("Blue"));
}
#[test]
fn test_transpile_impl_block() {
let code = "impl Point { fun new(x: i32, y: i32) -> Point { Point { x: x, y: y } } }";
let mut parser = Parser::new(code);
let result = parser.parse();
assert!(
result.is_ok(),
"impl blocks should be supported now (PARSER-009)"
);
let ast = result.expect("parse should succeed in test");
let mut transpiler = Transpiler::new();
let transpile_result = transpiler.transpile_to_program(&ast);
assert!(
transpile_result.is_ok(),
"impl block should transpile successfully"
);
}
#[test]
fn test_transpile_async_function() {
let mut transpiler = create_transpiler();
let code = "async fun fetch_data() { await http_get(\"url\") }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("async fn"));
assert!(rust_str.contains("await"));
}
#[test]
fn test_transpile_try_catch() {
let mut transpiler = create_transpiler();
let code = "try { risky_operation() } catch (e) { handle_error(e) }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("match") || rust_str.contains("risky_operation"));
}
#[test]
fn test_is_variable_mutated_extended() {
use crate::frontend::ast::{Expr, ExprKind, Span};
fn make_ident(name: &str) -> Expr {
Expr::new(ExprKind::Identifier(name.to_string()), Span::new(0, 1))
}
let assign_expr = Expr::new(
ExprKind::Assign {
target: Box::new(make_ident("x")),
value: Box::new(make_ident("y")),
},
Span::new(0, 1),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&assign_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"z",
&assign_expr
));
let compound_expr = Expr::new(
ExprKind::CompoundAssign {
target: Box::new(make_ident("count")),
op: crate::frontend::ast::BinaryOp::Add,
value: Box::new(make_ident("1")),
},
Span::new(0, 1),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"count",
&compound_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"other",
&compound_expr
));
let pre_inc = Expr::new(
ExprKind::PreIncrement {
target: Box::new(make_ident("i")),
},
Span::new(0, 1),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"i", &pre_inc
));
let post_inc = Expr::new(
ExprKind::PostIncrement {
target: Box::new(make_ident("j")),
},
Span::new(0, 1),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"j", &post_inc
));
let block = Expr::new(
ExprKind::Block(vec![assign_expr, make_ident("other")]),
Span::new(0, 1),
);
assert!(super::super::mutation_detection::is_variable_mutated("x", &block));
assert!(!super::super::mutation_detection::is_variable_mutated(
"other", &block
));
}
#[test]
fn test_transpile_return() {
let mut transpiler = create_transpiler();
let code = "fun test() { return 42 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("return"));
assert!(rust_str.contains("42"));
}
#[test]
fn test_transpile_break_continue_extended() {
let mut transpiler = create_transpiler();
let code = "while true { break }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("break"));
let code2 = "for x in [1,2,3] { continue }";
let mut parser2 = Parser::new(code2);
let ast2 = parser2.parse().expect("Failed to parse");
let result2 = transpiler
.transpile(&ast2)
.expect("operation should succeed in test");
let rust_str2 = result2.to_string();
assert!(rust_str2.contains("continue"));
}
#[test]
fn test_transpile_match() {
let mut transpiler = create_transpiler();
let code = "match x { 1 => \"one\", 2 => \"two\", _ => \"other\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("match"));
assert!(rust_str.contains("=>"));
assert!(rust_str.contains("_"));
}
#[test]
fn test_transpile_pattern_matching() {
let mut transpiler = create_transpiler();
let code = "let (a, b) = (1, 2); a + b";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("let"));
let code2 = "match list { [] => 0, [x] => x, _ => -1 }";
let mut parser2 = Parser::new(code2);
if let Ok(ast2) = parser2.parse() {
let result2 = transpiler
.transpile(&ast2)
.expect("operation should succeed in test");
let rust_str2 = result2.to_string();
assert!(rust_str2.contains("match"));
}
}
#[test]
fn test_transpile_loop() {
let mut transpiler = create_transpiler();
let code = "loop { break }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("loop"));
assert!(rust_str.contains("break"));
}
#[test]
fn test_is_variable_mutated_comprehensive() {
let code = "let mut x = 5; x = 10; x";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let is_mutated = super::super::mutation_detection::is_variable_mutated("x", &ast);
assert!(is_mutated);
let code2 = "let y = 5; y + 10";
let mut parser2 = Parser::new(code2);
let ast2 = parser2.parse().expect("Failed to parse");
let is_mutated2 = super::super::mutation_detection::is_variable_mutated("y", &ast2);
assert!(!is_mutated2);
}
#[test]
fn test_compound_assignment() {
let mut transpiler = create_transpiler();
let code = "let mut x = 5; x += 10; x";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("mut"));
assert!(rust_str.contains("+="));
}
#[test]
fn test_increment_operations() {
let mut transpiler = create_transpiler();
let code = "let mut x = 5; ++x";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("mut"));
let code2 = "let mut y = 5; y++";
let mut parser2 = Parser::new(code2);
let ast2 = parser2.parse().expect("Failed to parse");
let result2 = transpiler
.transpile(&ast2)
.expect("operation should succeed in test");
let rust_str2 = result2.to_string();
assert!(rust_str2.contains("mut"));
}
#[test]
fn test_match_expression_transpilation() {
let mut transpiler = create_transpiler();
let code = "match x { 1 => \"one\", 2 => \"two\", _ => \"other\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("match"));
assert!(rust_str.contains("=>"));
assert!(rust_str.contains("_"));
}
#[test]
fn test_pattern_guards() {
let mut transpiler = create_transpiler();
let code = "match x { n if n > 0 => \"positive\", _ => \"non-positive\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("if"));
}
#[test]
fn test_try_catch() {
let mut transpiler = create_transpiler();
let code = "try { risky_op() } catch(e) { handle(e) }";
let mut parser = Parser::new(code);
if let Ok(ast) = parser.parse() {
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
}
#[test]
fn test_async_function() {
let mut transpiler = create_transpiler();
let code = "async fun fetch_data() { await get_data() }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("async"));
}
#[test]
fn test_list_comprehension() {
let mut transpiler = create_transpiler();
let code = "[x * 2 for x in [1, 2, 3]]";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_module_definition() {
let mut transpiler = create_transpiler();
let code = "mod utils { fun helper() { 42 } }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
if let Ok(rust_str) = result {
let str = rust_str.to_string();
assert!(str.contains("mod") || !str.is_empty());
}
}
#[test]
fn test_import_statement() {
let mut transpiler = create_transpiler();
let code = "import \"std::fs\"";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_export_statement() {
let mut transpiler = create_transpiler();
let code = "export fun public_func() { 42 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_return_statement() {
let mut transpiler = create_transpiler();
let code = "fun early_return() { if true { return 42 } 0 }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("return"));
}
#[test]
fn test_break_continue() {
let mut transpiler = create_transpiler();
let code = "while true { if done { break } }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("break"));
let code2 = "for x in items { if skip { continue } }";
let mut parser2 = Parser::new(code2);
let ast2 = parser2.parse().expect("Failed to parse");
let result2 = transpiler
.transpile(&ast2)
.expect("operation should succeed in test");
let rust_str2 = result2.to_string();
assert!(rust_str2.contains("continue"));
}
#[test]
fn test_nested_blocks() {
let mut transpiler = create_transpiler();
let code = "{ let x = 1; { let y = 2; x + y } }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("{"));
assert!(rust_str.contains("}"));
}
#[test]
fn test_method_chaining() {
let mut transpiler = create_transpiler();
let code = "[1, 2, 3].iter().sum()"; let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok(), "Failed to transpile method chaining");
}
#[test]
fn test_string_interpolation() {
let mut transpiler = create_transpiler();
let code = r#"let name = "world"; f"Hello {name}!""#;
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
if let Ok(rust_str) = result {
let str = rust_str.to_string();
assert!(str.contains("format!") || !str.is_empty());
}
}
#[test]
fn test_tuple_destructuring() {
let mut transpiler = create_transpiler();
let code = "let (a, b, c) = (1, 2, 3); a + b + c";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(rust_str.contains("let"));
assert!(rust_str.contains("("));
}
#[test]
fn test_array_destructuring() {
let mut transpiler = create_transpiler();
let code = "let [first, second] = [1, 2]; first + second";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_object_destructuring() {
let mut transpiler = create_transpiler();
let code = "let {x, y} = point; x + y";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_default_parameters() {
let mut transpiler = create_transpiler();
let code = "fun greet(name = \"World\") { f\"Hello {name}\" }";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler.transpile(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_is_variable_mutated_assign() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let value = Box::new(Expr::new(
ExprKind::Literal(crate::frontend::ast::Literal::Integer(5, None)),
Span::default(),
));
let assign_expr = Expr::new(ExprKind::Assign { target, value }, Span::default());
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&assign_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&assign_expr
));
}
#[test]
fn test_is_variable_mutated_compound_assign() {
use crate::frontend::ast::{BinaryOp, Expr, ExprKind, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let value = Box::new(Expr::new(
ExprKind::Literal(crate::frontend::ast::Literal::Integer(5, None)),
Span::default(),
));
let compound_expr = Expr::new(
ExprKind::CompoundAssign {
target,
op: BinaryOp::Add,
value,
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&compound_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&compound_expr
));
}
#[test]
fn test_is_variable_mutated_increment_decrement() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let pre_inc = Expr::new(
ExprKind::PreIncrement {
target: target.clone(),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x", &pre_inc
));
let post_inc = Expr::new(
ExprKind::PostIncrement {
target: target.clone(),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x", &post_inc
));
let pre_dec = Expr::new(
ExprKind::PreDecrement {
target: target.clone(),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x", &pre_dec
));
let post_dec = Expr::new(ExprKind::PostDecrement { target }, Span::default());
assert!(super::super::mutation_detection::is_variable_mutated(
"x", &post_dec
));
}
#[test]
fn test_is_variable_mutated_in_blocks() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let value = Box::new(Expr::new(
ExprKind::Literal(crate::frontend::ast::Literal::Integer(5, None)),
Span::default(),
));
let assign_expr = Expr::new(ExprKind::Assign { target, value }, Span::default());
let block_expr = Expr::new(ExprKind::Block(vec![assign_expr]), Span::default());
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&block_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&block_expr
));
}
#[test]
fn test_is_variable_mutated_in_if_branches() {
use crate::frontend::ast::{Expr, ExprKind, Literal, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let value = Box::new(Expr::new(
ExprKind::Literal(Literal::Integer(5, None)),
Span::default(),
));
let assign_expr = Expr::new(ExprKind::Assign { target, value }, Span::default());
let condition = Box::new(Expr::new(
ExprKind::Literal(Literal::Bool(true)),
Span::default(),
));
let then_branch = Box::new(assign_expr);
let if_expr = Expr::new(
ExprKind::If {
condition,
then_branch,
else_branch: None,
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x", &if_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y", &if_expr
));
}
#[test]
fn test_is_variable_mutated_in_binary_expressions() {
use crate::frontend::ast::{BinaryOp, Expr, ExprKind, Literal, Span};
let target = Box::new(Expr::new(
ExprKind::Identifier("x".to_string()),
Span::default(),
));
let value = Box::new(Expr::new(
ExprKind::Literal(Literal::Integer(5, None)),
Span::default(),
));
let assign_expr = Expr::new(ExprKind::Assign { target, value }, Span::default());
let right = Expr::new(
ExprKind::Literal(Literal::Integer(10, None)),
Span::default(),
);
let binary_expr = Expr::new(
ExprKind::Binary {
left: Box::new(assign_expr),
op: BinaryOp::Add,
right: Box::new(right),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&binary_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&binary_expr
));
}
#[test]
fn test_looks_like_numeric_function() {
let _transpiler = create_transpiler();
assert!(super::super::function_analysis::looks_like_numeric_function("sin"));
assert!(super::super::function_analysis::looks_like_numeric_function("cos"));
assert!(super::super::function_analysis::looks_like_numeric_function("tan"));
assert!(super::super::function_analysis::looks_like_numeric_function(
"sqrt"
));
assert!(super::super::function_analysis::looks_like_numeric_function("abs"));
assert!(super::super::function_analysis::looks_like_numeric_function(
"floor"
));
assert!(super::super::function_analysis::looks_like_numeric_function(
"ceil"
));
assert!(super::super::function_analysis::looks_like_numeric_function(
"round"
));
assert!(super::super::function_analysis::looks_like_numeric_function("pow"));
assert!(super::super::function_analysis::looks_like_numeric_function("log"));
assert!(super::super::function_analysis::looks_like_numeric_function("exp"));
assert!(super::super::function_analysis::looks_like_numeric_function("min"));
assert!(super::super::function_analysis::looks_like_numeric_function("max"));
assert!(!super::super::function_analysis::looks_like_numeric_function(
"println"
));
assert!(!super::super::function_analysis::looks_like_numeric_function(
"assert"
));
assert!(!super::super::function_analysis::looks_like_numeric_function(
"custom_function"
));
assert!(!super::super::function_analysis::looks_like_numeric_function(""));
}
#[test]
fn test_pattern_needs_slice() {
use crate::frontend::ast::Pattern;
let transpiler = create_transpiler();
let list_pattern = Pattern::List(vec![]);
assert!(transpiler.pattern_needs_slice(&list_pattern));
let id_pattern = Pattern::Identifier("x".to_string());
assert!(!transpiler.pattern_needs_slice(&id_pattern));
let wildcard_pattern = Pattern::Wildcard;
assert!(!transpiler.pattern_needs_slice(&wildcard_pattern));
}
#[test]
fn test_value_creates_vec() {
use crate::frontend::ast::{Expr, ExprKind, Literal, Span};
let transpiler = create_transpiler();
let list_expr = Expr::new(ExprKind::List(vec![]), Span::default());
assert!(transpiler.value_creates_vec(&list_expr));
let literal_expr = Expr::new(
ExprKind::Literal(Literal::Integer(42, None)),
Span::default(),
);
assert!(!transpiler.value_creates_vec(&literal_expr));
let id_expr = Expr::new(ExprKind::Identifier("x".to_string()), Span::default());
assert!(!transpiler.value_creates_vec(&id_expr));
}
#[test]
fn test_is_variable_mutated_assignment() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Expr::new(ExprKind::Identifier("x".to_string()), Span::default());
let value = Expr::new(
ExprKind::Literal(Literal::Integer(42, None)),
Span::default(),
);
let assign_expr = Expr::new(
ExprKind::Assign {
target: Box::new(target),
value: Box::new(value),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&assign_expr
));
assert!(!super::super::mutation_detection::is_variable_mutated(
"y",
&assign_expr
));
}
#[test]
fn test_is_variable_mutated_pre_increment() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Expr::new(ExprKind::Identifier("i".to_string()), Span::default());
let inc_expr = Expr::new(
ExprKind::PreIncrement {
target: Box::new(target),
},
Span::default(),
);
assert!(super::super::mutation_detection::is_variable_mutated(
"i", &inc_expr
));
}
#[test]
fn test_is_variable_mutated_block() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let target = Expr::new(ExprKind::Identifier("x".to_string()), Span::default());
let value = Expr::new(
ExprKind::Literal(Literal::Integer(10, None)),
Span::default(),
);
let assign_expr = Expr::new(
ExprKind::Assign {
target: Box::new(target),
value: Box::new(value),
},
Span::default(),
);
let block_expr = Expr::new(ExprKind::Block(vec![assign_expr]), Span::default());
assert!(super::super::mutation_detection::is_variable_mutated(
"x",
&block_expr
));
}
#[test]
fn test_looks_like_numeric_function_arithmetic() {
let _transpiler = create_transpiler();
assert!(super::super::function_analysis::looks_like_numeric_function("add"));
assert!(super::super::function_analysis::looks_like_numeric_function(
"multiply"
));
assert!(super::super::function_analysis::looks_like_numeric_function(
"sqrt"
));
assert!(super::super::function_analysis::looks_like_numeric_function("pow"));
assert!(!super::super::function_analysis::looks_like_numeric_function(
"concat"
));
}
#[test]
fn test_looks_like_numeric_function_trig() {
let _transpiler = create_transpiler();
assert!(super::super::function_analysis::looks_like_numeric_function("sin"));
assert!(super::super::function_analysis::looks_like_numeric_function("cos"));
assert!(super::super::function_analysis::looks_like_numeric_function(
"atan2"
));
assert!(!super::super::function_analysis::looks_like_numeric_function(
"uppercase"
));
}
#[test]
fn test_is_void_function_call_println() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let func = Expr::new(ExprKind::Identifier("println".to_string()), Span::default());
let call_expr = Expr::new(
ExprKind::Call {
func: Box::new(func),
args: vec![],
},
Span::default(),
);
assert!(super::super::function_analysis::is_void_function_call(&call_expr));
}
#[test]
fn test_is_void_function_call_assert() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let func = Expr::new(ExprKind::Identifier("assert".to_string()), Span::default());
let call_expr = Expr::new(
ExprKind::Call {
func: Box::new(func),
args: vec![],
},
Span::default(),
);
assert!(super::super::function_analysis::is_void_function_call(&call_expr));
}
#[test]
fn test_is_void_expression_unit() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let unit_expr = Expr::new(ExprKind::Literal(Literal::Unit), Span::default());
assert!(super::super::function_analysis::is_void_expression(&unit_expr));
}
#[test]
fn test_is_void_expression_assignment() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let target = Expr::new(ExprKind::Identifier("x".to_string()), Span::default());
let value = Expr::new(
ExprKind::Literal(Literal::Integer(5, None)),
Span::default(),
);
let assign_expr = Expr::new(
ExprKind::Assign {
target: Box::new(target),
value: Box::new(value),
},
Span::default(),
);
assert!(super::super::function_analysis::is_void_expression(&assign_expr));
}
#[test]
fn test_returns_closure_false() {
use crate::frontend::ast::{Expr, ExprKind, Literal, Span};
let _transpiler = create_transpiler();
let int_expr = Expr::new(
ExprKind::Literal(Literal::Integer(42, None)),
Span::default(),
);
assert!(!super::super::function_analysis::returns_closure(&int_expr));
}
#[test]
fn test_returns_string_literal_direct() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let string_expr = Expr::new(
ExprKind::Literal(Literal::String("hello".to_string())),
Span::default(),
);
assert!(returns_string_literal(&string_expr));
}
#[test]
fn test_returns_string_literal_in_block() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let string_expr = Expr::new(
ExprKind::Literal(Literal::String("world".to_string())),
Span::default(),
);
let block_expr = Expr::new(ExprKind::Block(vec![string_expr]), Span::default());
assert!(returns_string_literal(&block_expr));
}
#[test]
fn test_returns_boolean_comparison() {
use crate::frontend::ast::{BinaryOp, Expr, ExprKind, Span};
let left = Expr::new(
ExprKind::Literal(Literal::Integer(5, None)),
Span::default(),
);
let right = Expr::new(
ExprKind::Literal(Literal::Integer(10, None)),
Span::default(),
);
let comparison_expr = Expr::new(
ExprKind::Binary {
left: Box::new(left),
op: BinaryOp::Less,
right: Box::new(right),
},
Span::default(),
);
assert!(returns_boolean(&comparison_expr));
}
#[test]
fn test_returns_boolean_unary_not() {
use crate::frontend::ast::{Expr, ExprKind, Span, UnaryOp};
let inner = Expr::new(ExprKind::Literal(Literal::Bool(true)), Span::default());
let not_expr = Expr::new(
ExprKind::Unary {
op: UnaryOp::Not,
operand: Box::new(inner),
},
Span::default(),
);
assert!(returns_boolean(¬_expr));
}
#[test]
fn test_returns_vec_array_literal() {
use crate::frontend::ast::{Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let array_expr = Expr::new(
ExprKind::List(vec![
Expr::new(
ExprKind::Literal(Literal::Integer(1, None)),
Span::default(),
),
Expr::new(
ExprKind::Literal(Literal::Integer(2, None)),
Span::default(),
),
]),
Span::default(),
);
assert!(returns_vec(&array_expr));
}
#[test]
fn test_returns_string_concatenation() {
use crate::frontend::ast::{BinaryOp, Expr, ExprKind, Span};
let _transpiler = create_transpiler();
let left = Expr::new(
ExprKind::Literal(Literal::String("hello".to_string())),
Span::default(),
);
let right = Expr::new(
ExprKind::Literal(Literal::String("world".to_string())),
Span::default(),
);
let concat_expr = Expr::new(
ExprKind::Binary {
left: Box::new(left),
op: BinaryOp::Add,
right: Box::new(right),
},
Span::default(),
);
assert!(returns_string(&concat_expr));
}
#[test]
fn test_value_creates_vec_list() {
use crate::frontend::ast::{Expr, ExprKind, Literal, Span};
let transpiler = create_transpiler();
let elem1 = Expr::new(
ExprKind::Literal(Literal::Integer(1, None)),
Span::default(),
);
let elem2 = Expr::new(
ExprKind::Literal(Literal::Integer(2, None)),
Span::default(),
);
let list_expr = Expr::new(ExprKind::List(vec![elem1, elem2]), Span::default());
assert!(transpiler.value_creates_vec(&list_expr));
}
#[test]
fn test_trueno_sum_transpiles_to_kahan_sum() {
let mut transpiler = create_transpiler();
let code = "let arr = [1.0, 2.0, 3.0]; trueno_sum(arr)";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(
rust_str.contains("trueno_bridge") && rust_str.contains("kahan_sum"),
"trueno_sum should transpile to trueno_bridge::kahan_sum, got: {rust_str}"
);
}
#[test]
fn test_trueno_mean_transpiles_correctly() {
let mut transpiler = create_transpiler();
let code = "let data = [1.0, 2.0, 3.0, 4.0]; trueno_mean(data)";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("Failed to parse");
let result = transpiler
.transpile(&ast)
.expect("transpile should succeed in test");
let rust_str = result.to_string();
assert!(
rust_str.contains("trueno_bridge") && rust_str.contains("mean"),
"trueno_mean should transpile to trueno_bridge::mean, got: {rust_str}"
);
}