#[cfg(test)]
mod tests {
#[test]
fn test_simple_assignment_statement() {
let c_code = r#"
x = 5;
"#;
let rust_expected = r#"
x = 5;
"#;
assert!(c_code.contains("x = 5;"));
assert!(rust_expected.contains("x = 5;"));
}
#[test]
fn test_function_call_statement() {
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_increment_statement() {
let c_code = r#"
x++;
"#;
let rust_expected = r#"
x += 1;
"#;
assert!(c_code.contains("x++;"));
assert!(rust_expected.contains("x += 1"));
}
#[test]
fn test_decrement_statement() {
let c_code = r#"
count--;
"#;
let rust_expected = r#"
count -= 1;
"#;
assert!(c_code.contains("count--;"));
assert!(rust_expected.contains("count -= 1"));
}
#[test]
fn test_compound_assignment_statement() {
let c_code = r#"
total += amount;
"#;
let rust_expected = r#"
total += amount;
"#;
assert!(c_code.contains("total += amount;"));
assert!(rust_expected.contains("total += amount;"));
}
#[test]
fn test_empty_statement() {
let c_code = r#"
while (*p++)
;
"#;
let _rust_expected = r#"
while { let tmp = *p; p = p.offset(1); tmp != 0 } {
}
"#;
assert!(c_code.contains(";"));
}
#[test]
fn test_multiple_statements() {
let c_code = r#"
x = 1;
y = 2;
z = 3;
"#;
let rust_expected = r#"
x = 1;
y = 2;
z = 3;
"#;
assert!(c_code.contains("x = 1;"));
assert!(c_code.contains("y = 2;"));
assert!(c_code.contains("z = 3;"));
assert!(rust_expected.contains("x = 1;"));
assert!(rust_expected.contains("y = 2;"));
assert!(rust_expected.contains("z = 3;"));
}
#[test]
fn test_expression_statement_in_block() {
let c_code = r#"
{
x = 5;
y = x + 1;
}
"#;
let rust_expected = r#"
{
x = 5;
y = x + 1;
}
"#;
assert!(c_code.contains("x = 5;"));
assert!(rust_expected.contains("x = 5;"));
}
#[test]
fn test_array_assignment_statement() {
let c_code = r#"
arr[i] = 42;
"#;
let rust_expected = r#"
arr[i] = 42;
"#;
assert!(c_code.contains("arr[i] = 42;"));
assert!(rust_expected.contains("arr[i] = 42;"));
}
#[test]
fn test_struct_field_assignment_statement() {
let c_code = r#"
point.x = 10;
point.y = 20;
"#;
let rust_expected = r#"
point.x = 10;
point.y = 20;
"#;
assert!(c_code.contains("point.x = 10;"));
assert!(rust_expected.contains("point.x = 10;"));
}
#[test]
fn test_pointer_dereference_statement() {
let c_code = r#"
*ptr = 100;
"#;
let rust_expected = r#"
*ptr = 100;
"#;
assert!(c_code.contains("*ptr = 100;"));
assert!(rust_expected.contains("*ptr = 100;"));
}
#[test]
fn test_side_effect_statement() {
let c_code = r#"
increment_counter();
update_state();
"#;
let rust_expected = r#"
increment_counter();
update_state();
"#;
assert!(c_code.contains("increment_counter();"));
assert!(rust_expected.contains("increment_counter();"));
}
#[test]
fn test_statement_vs_expression() {
let c_note = "C blocks don't return values";
let rust_code = r#"
let x = {
let a = 5;
a + 1
};
"#;
assert!(c_note.contains("don't return"));
assert!(rust_code.contains("a + 1"));
assert!(!rust_code.contains("a + 1;"));
}
#[test]
fn test_unused_value_warning() {
let c_code = r#"
calculate(); // Return value ignored (no warning)
"#;
let rust_note = r#"
calculate(); // May warn if returns Result or #[must_use]
let _ = calculate(); // OK: explicitly ignored
"#;
assert!(c_code.contains("calculate();"));
assert!(rust_note.contains("let _ = calculate()"));
}
#[test]
fn test_assignment_not_in_condition() {
let c_code = r#"
if ((x = foo()) != 0) {
use_x(x);
}
"#;
let _rust_expected = r#"
x = foo();
if x != 0 {
use_x(x);
}
"#;
assert!(c_code.contains("(x = foo())"));
}
#[test]
fn test_expression_statement_transformation_summary() {
let c_code = r#"
// Rule 1: Simple assignment (same)
x = 5;
// Rule 2: Function call (same)
print_message();
// Rule 3: Increment (x++ → x += 1)
count++;
// Rule 4: Decrement (count-- → count -= 1)
count--;
// Rule 5: Compound assignment (same)
total += 10;
// Rule 6: Empty statement (rare)
;
// Rule 7: Sequential statements (same)
a = 1; b = 2; c = 3;
// Rule 8: In block (same)
{ x = 5; y = x; }
// Rule 9: Array assignment (same)
arr[i] = 42;
// Rule 10: Field assignment (same)
obj.field = 10;
// Rule 11: Pointer dereference (same)
*ptr = 100;
// Rule 12: Side effect only (same)
update();
// Rule 13: Assignment in condition (NOT allowed in Rust)
if ((x = foo()) != 0) { }
"#;
let rust_expected = r#"
// Rule 1: Same
x = 5;
// Rule 2: Same
print_message();
// Rule 3: Compound assignment
count += 1;
// Rule 4: Compound assignment
count -= 1;
// Rule 5: Same
total += 10;
// Rule 6: Empty block preferred
{ }
// Rule 7: Same
a = 1; b = 2; c = 3;
// Rule 8: Same (or can return value)
{ x = 5; y = x; }
// Rule 9: Same
arr[i] = 42;
// Rule 10: Same
obj.field = 10;
// Rule 11: Same
*ptr = 100;
// Rule 12: Same (may warn)
update();
// Rule 13: Must separate
x = foo(); if x != 0 { }
"#;
assert!(c_code.contains("x = 5;"));
assert!(rust_expected.contains("x = 5;"));
assert!(c_code.contains("count++;"));
assert!(rust_expected.contains("count += 1"));
assert!(c_code.contains("count--;"));
assert!(rust_expected.contains("count -= 1"));
assert!(c_code.contains("(x = foo())"));
assert!(rust_expected.contains("x = foo(); if"));
}
}