#[cfg(test)]
mod tests {
#[test]
fn test_simple_if_comparison() {
let c_code = r#"
if (x > 0) {
printf("positive\n");
}
"#;
let rust_expected = r#"
if x > 0 {
println!("positive");
}
"#;
assert!(c_code.contains("if (x > 0)"));
assert!(rust_expected.contains("if x > 0"));
}
#[test]
fn test_if_implicit_bool() {
let c_code = r#"
if (x) {
do_something();
}
"#;
let rust_expected = r#"
if x != 0 {
do_something();
}
"#;
assert!(c_code.contains("if (x)"));
assert!(rust_expected.contains("if x != 0"));
}
#[test]
fn test_if_else() {
let c_code = r#"
if (x > 0) {
y = 1;
} else {
y = -1;
}
"#;
let rust_expected = r#"
if x > 0 {
y = 1;
} else {
y = -1;
}
"#;
assert!(c_code.contains("if (x > 0)"));
assert!(c_code.contains("else"));
assert!(rust_expected.contains("if x > 0"));
assert!(rust_expected.contains("else"));
}
#[test]
fn test_if_else_if_chain() {
let c_code = r#"
if (x > 0) {
result = 1;
} else if (x < 0) {
result = -1;
} else {
result = 0;
}
"#;
let rust_expected = r#"
if x > 0 {
result = 1;
} else if x < 0 {
result = -1;
} else {
result = 0;
}
"#;
assert!(c_code.contains("else if"));
assert!(rust_expected.contains("else if"));
}
#[test]
fn test_if_as_expression() {
let c_code = r#"
int y;
if (x > 0) {
y = 1;
} else {
y = -1;
}
"#;
let rust_expected = r#"
let y = if x > 0 { 1 } else { -1 };
"#;
assert!(c_code.contains("int y;"));
assert!(rust_expected.contains("let y = if"));
}
#[test]
fn test_nested_if() {
let c_code = r#"
if (x > 0) {
if (y > 0) {
printf("both positive\n");
}
}
"#;
let rust_expected = r#"
if x > 0 {
if y > 0 {
println!("both positive");
}
}
"#;
assert!(c_code.contains("if (x > 0)"));
assert!(c_code.contains("if (y > 0)"));
assert!(rust_expected.contains("if x > 0"));
assert!(rust_expected.contains("if y > 0"));
}
#[test]
fn test_if_early_return() {
let c_code = r#"
if (x <= 0) {
return -1;
}
"#;
let rust_expected = r#"
if x <= 0 {
return -1;
}
"#;
assert!(c_code.contains("if (x <= 0)"));
assert!(c_code.contains("return -1"));
assert!(rust_expected.contains("if x <= 0"));
}
#[test]
fn test_if_logical_and() {
let c_code = r#"
if (x > 0 && y > 0) {
printf("both positive\n");
}
"#;
let rust_expected = r#"
if x > 0 && y > 0 {
println!("both positive");
}
"#;
assert!(c_code.contains("x > 0 && y > 0"));
assert!(rust_expected.contains("x > 0 && y > 0"));
}
#[test]
fn test_if_logical_or() {
let c_code = r#"
if (x < 0 || y < 0) {
printf("at least one negative\n");
}
"#;
let rust_expected = r#"
if x < 0 || y < 0 {
println!("at least one negative");
}
"#;
assert!(c_code.contains("x < 0 || y < 0"));
assert!(rust_expected.contains("x < 0 || y < 0"));
}
#[test]
fn test_if_negation() {
let c_code = r#"
if (!(x > 0)) {
printf("not positive\n");
}
"#;
let rust_expected = r#"
if !(x > 0) {
println!("not positive");
}
"#;
assert!(c_code.contains("!(x > 0)"));
assert!(rust_expected.contains("!(x > 0)"));
}
#[test]
fn test_if_pointer_check() {
let c_code = r#"
if (ptr != NULL) {
use_ptr(ptr);
}
"#;
let rust_expected = r#"
if !ptr.is_null() {
use_ptr(ptr);
}
"#;
assert!(c_code.contains("ptr != NULL"));
assert!(rust_expected.contains("!ptr.is_null()"));
}
#[test]
fn test_if_single_statement_c() {
let c_code = r#"
if (x > 0)
printf("positive\n");
"#;
let rust_expected = r#"
if x > 0 {
println!("positive");
}
"#;
assert!(c_code.contains("if (x > 0)"));
assert!(rust_expected.contains("if x > 0 {"));
}
#[test]
fn test_if_equality() {
let c_code = r#"
if (x == 0) {
printf("zero\n");
}
"#;
let rust_expected = r#"
if x == 0 {
println!("zero");
}
"#;
assert!(c_code.contains("if (x == 0)"));
assert!(rust_expected.contains("if x == 0"));
}
#[test]
fn test_if_inequality() {
let c_code = r#"
if (x != 0) {
process(x);
}
"#;
let rust_expected = r#"
if x != 0 {
process(x);
}
"#;
assert!(c_code.contains("if (x != 0)"));
assert!(rust_expected.contains("if x != 0"));
}
#[test]
fn test_if_multiple_statements() {
let c_code = r#"
if (x > 0) {
y = x * 2;
z = x + 1;
printf("%d %d\n", y, z);
}
"#;
let rust_expected = r#"
if x > 0 {
y = x * 2;
z = x + 1;
println!("{} {}", y, z);
}
"#;
assert!(c_code.contains("y = x * 2;"));
assert!(c_code.contains("z = x + 1;"));
assert!(rust_expected.contains("y = x * 2;"));
assert!(rust_expected.contains("z = x + 1;"));
}
#[test]
fn test_if_expression_with_types() {
let c_note = "C if is statement, cannot return value directly";
let rust_code = r#"
let result: i32 = if condition { 42 } else { 0 };
"#;
assert!(c_note.contains("statement"));
assert!(rust_code.contains("let result: i32 = if"));
}
#[test]
fn test_if_transformation_summary() {
let c_code = r#"
// Rule 1: Simple if (remove parens, keep comparison)
if (x > 0) { printf("positive\n"); }
// Rule 2: Implicit bool (add explicit comparison)
if (x) { do_something(); }
// Rule 3: If-else (same structure)
if (x > 0) { y = 1; } else { y = -1; }
// Rule 4: If-else if-else (same)
if (x > 0) { r = 1; } else if (x < 0) { r = -1; } else { r = 0; }
// Rule 5: If as expression (Rust can assign from if)
int y;
if (x > 0) { y = 1; } else { y = -1; }
// Rule 6: Nested if (braces clarify)
if (x > 0) { if (y > 0) { printf("both\n"); } }
// Rule 7: Early return (same)
if (x <= 0) { return -1; }
// Rule 8: Logical AND (same)
if (x > 0 && y > 0) { printf("both\n"); }
// Rule 9: Logical OR (same)
if (x < 0 || y < 0) { printf("one\n"); }
// Rule 10: Negation (same)
if (!(x > 0)) { printf("not pos\n"); }
// Rule 11: Pointer check (NULL → is_null())
if (ptr != NULL) { use_ptr(ptr); }
// Rule 12: Single statement (add braces in Rust)
if (x > 0) printf("pos\n");
// Rule 13: Equality (same)
if (x == 0) { printf("zero\n"); }
// Rule 14: Inequality (same)
if (x != 0) { process(x); }
"#;
let rust_expected = r#"
// Rule 1: Remove parentheses
if x > 0 { println!("positive"); }
// Rule 2: Explicit comparison
if x != 0 { do_something(); }
// Rule 3: Same
if x > 0 { y = 1; } else { y = -1; }
// Rule 4: Same
if x > 0 { r = 1; } else if x < 0 { r = -1; } else { r = 0; }
// Rule 5: Expression form (more idiomatic)
let y = if x > 0 { 1 } else { -1 };
// Rule 6: Braces required
if x > 0 { if y > 0 { println!("both"); } }
// Rule 7: Same
if x <= 0 { return -1; }
// Rule 8: Same
if x > 0 && y > 0 { println!("both"); }
// Rule 9: Same
if x < 0 || y < 0 { println!("one"); }
// Rule 10: Same (parens optional)
if !(x > 0) { println!("not pos"); }
// Rule 11: Method call
if !ptr.is_null() { use_ptr(ptr); }
// Rule 12: Braces required
if x > 0 { println!("pos"); }
// Rule 13: Same
if x == 0 { println!("zero"); }
// Rule 14: Same
if x != 0 { process(x); }
"#;
assert!(c_code.contains("if (x > 0)"));
assert!(rust_expected.contains("if x > 0"));
assert!(c_code.contains("if (x)"));
assert!(rust_expected.contains("if x != 0"));
assert!(c_code.contains("else if"));
assert!(rust_expected.contains("else if"));
assert!(c_code.contains("ptr != NULL"));
assert!(rust_expected.contains("!ptr.is_null()"));
}
}