#[cfg(test)]
mod tests {
#[test]
fn test_simple_function_call() {
let c_code = r#"
int result = add(x, y);
"#;
let rust_expected = r#"
let result = add(x, y);
"#;
assert!(c_code.contains("add(x, y)"));
assert!(rust_expected.contains("add(x, y)"));
}
#[test]
fn test_void_function_call() {
let c_code = r#"
print_message();
"#;
let rust_expected = r#"
print_message();
"#;
assert!(c_code.contains("print_message()"));
assert!(rust_expected.contains("print_message()"));
}
#[test]
fn test_multiple_arguments() {
let c_code = r#"
result = calculate(a, b, c, d);
"#;
let rust_expected = r#"
let result = calculate(a, b, c, d);
"#;
assert!(c_code.contains("calculate(a, b, c, d)"));
assert!(rust_expected.contains("calculate(a, b, c, d)"));
}
#[test]
fn test_no_arguments() {
let c_code = r#"
int value = get_value();
"#;
let rust_expected = r#"
let value = get_value();
"#;
assert!(c_code.contains("get_value()"));
assert!(rust_expected.contains("get_value()"));
}
#[test]
fn test_nested_function_calls() {
let c_code = r#"
result = outer(inner(x));
"#;
let rust_expected = r#"
let result = outer(inner(x));
"#;
assert!(c_code.contains("outer(inner(x))"));
assert!(rust_expected.contains("outer(inner(x))"));
}
#[test]
fn test_function_in_expression() {
let c_code = r#"
result = foo() + bar() * 2;
"#;
let rust_expected = r#"
let result = foo() + bar() * 2;
"#;
assert!(c_code.contains("foo() + bar() * 2"));
assert!(rust_expected.contains("foo() + bar() * 2"));
}
#[test]
fn test_function_as_condition() {
let c_code = r#"
if (is_valid()) {
process();
}
"#;
let rust_expected = r#"
if is_valid() {
process();
}
"#;
assert!(c_code.contains("if (is_valid())"));
assert!(rust_expected.contains("if is_valid()"));
}
#[test]
fn test_pass_by_value() {
let c_code = r#"
void process(int x) {
x = x + 1;
}
int val = 5;
process(val);
"#;
let rust_expected = r#"
fn process(x: i32) {
let x = x + 1;
}
let val = 5;
process(val);
"#;
assert!(c_code.contains("process(val)"));
assert!(rust_expected.contains("process(val)"));
}
#[test]
fn test_pass_by_reference() {
let c_code = r#"
void modify(int* x) {
*x = 10;
}
int val = 5;
modify(&val);
"#;
let rust_expected = r#"
fn modify(x: &mut i32) {
*x = 10;
}
let mut val = 5;
modify(&mut val);
"#;
assert!(c_code.contains("modify(&val)"));
assert!(rust_expected.contains("modify(&mut val)"));
}
#[test]
fn test_call_with_literals() {
let c_code = r#"
result = calculate(42, 3.14, "hello");
"#;
let rust_expected = r#"
let result = calculate(42, 3.14, "hello");
"#;
assert!(c_code.contains("calculate(42, 3.14"));
assert!(rust_expected.contains("calculate(42, 3.14"));
}
#[test]
fn test_function_call_in_loop() {
let c_code = r#"
for (int i = 0; i < n; i++) {
process(arr[i]);
}
"#;
let rust_expected = r#"
for i in 0..n {
process(arr[i]);
}
"#;
assert!(c_code.contains("process(arr[i])"));
assert!(rust_expected.contains("process(arr[i])"));
}
#[test]
fn test_ignored_return_value() {
let c_code = r#"
foo();
"#;
let rust_expected = r#"
let _ = foo();
"#;
assert!(c_code.contains("foo();"));
assert!(rust_expected.contains("let _ = foo()"));
}
#[test]
fn test_function_pointer_call() {
let c_code = r#"
int (*func_ptr)(int);
result = func_ptr(42);
"#;
let rust_expected = r#"
let func_ptr: fn(i32) -> i32;
let result = func_ptr(42);
"#;
assert!(c_code.contains("func_ptr(42)"));
assert!(rust_expected.contains("func_ptr(42)"));
}
#[test]
fn test_chained_calls() {
let c_code = r#"
result = process(transform(input));
"#;
let rust_expected = r#"
let result = process(transform(input));
"#;
assert!(c_code.contains("process(transform(input))"));
assert!(rust_expected.contains("process(transform(input))"));
}
#[test]
fn test_function_call_transformation_summary() {
let c_code = r#"
// Rule 1: Simple call (same syntax)
int result = add(x, y);
// Rule 2: Void function (same)
print_message();
// Rule 3: Multiple arguments
calculate(a, b, c, d);
// Rule 4: No arguments
get_value();
// Rule 5: Nested calls
outer(inner(x));
// Rule 6: In expression
result = foo() + bar();
// Rule 7: As condition
if (is_valid()) { }
// Rule 8: Pass by value (copy)
process(val);
// Rule 9: Pass by pointer
void modify(int* x);
modify(&val);
// Rule 10: Literals as arguments
calculate(42, 3.14);
// Rule 11: In loop
for (int i = 0; i < n; i++) {
process(arr[i]);
}
// Rule 12: Ignored return value
foo();
// Rule 13: Function pointer
int (*func_ptr)(int);
func_ptr(42);
// Rule 14: Chained calls
process(transform(input));
"#;
let rust_expected = r#"
// Rule 1: Same syntax
let result = add(x, y);
// Rule 2: Same syntax
print_message();
// Rule 3: Same syntax
calculate(a, b, c, d);
// Rule 4: Same syntax
get_value();
// Rule 5: Same syntax
outer(inner(x));
// Rule 6: Same syntax
let result = foo() + bar();
// Rule 7: Parentheses optional
if is_valid() { }
// Rule 8: Same (i32 is Copy)
process(val);
// Rule 9: Pointer → &mut reference
fn modify(x: &mut i32);
modify(&mut val);
// Rule 10: Same syntax
calculate(42, 3.14);
// Rule 11: Same pattern
for i in 0..n {
process(arr[i]);
}
// Rule 12: Explicit ignore
let _ = foo();
// Rule 13: Function type syntax
let func_ptr: fn(i32) -> i32;
func_ptr(42);
// Rule 14: Same syntax
process(transform(input));
"#;
assert!(c_code.contains("int result = add(x, y)"));
assert!(rust_expected.contains("let result = add(x, y)"));
assert!(c_code.contains("print_message()"));
assert!(rust_expected.contains("print_message()"));
assert!(c_code.contains("calculate(a, b, c, d)"));
assert!(c_code.contains("modify(&val)"));
assert!(rust_expected.contains("modify(&mut val)"));
assert!(c_code.contains("foo();"));
assert!(rust_expected.contains("let _ = foo()"));
assert!(c_code.contains("func_ptr(42)"));
assert!(rust_expected.contains("func_ptr(42)"));
}
}