use decy_core::transpile;
#[test]
fn test_post_increment_basic() {
let c_code = r#"
int main() {
int x = 5;
int y = x++;
return y; // Should return 5 (old value)
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x")
|| rust_code.contains("y")
|| rust_code.contains("5")
|| rust_code.contains("fn main"),
"Expected post-increment or variables"
);
}
#[test]
fn test_pre_increment_basic() {
let c_code = r#"
int main() {
int x = 5;
int y = ++x;
return y; // Should return 6 (new value)
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x") || rust_code.contains("y") || rust_code.contains("fn main"),
"Expected pre-increment or variables"
);
}
#[test]
fn test_post_decrement_basic() {
let c_code = r#"
int main() {
int x = 10;
int y = x--;
return y; // Should return 10 (old value)
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x")
|| rust_code.contains("y")
|| rust_code.contains("10")
|| rust_code.contains("fn main"),
"Expected post-decrement or variables"
);
}
#[test]
fn test_pre_decrement_basic() {
let c_code = r#"
int main() {
int x = 10;
int y = --x;
return y; // Should return 9 (new value)
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x") || rust_code.contains("y") || rust_code.contains("fn main"),
"Expected pre-decrement or variables"
);
}
#[test]
fn test_increment_in_for_loop() {
let c_code = r#"
int main() {
int sum = 0;
for (int i = 0; i < 10; i = i + 1) {
sum = sum + i;
}
return sum;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("for")
|| rust_code.contains("loop")
|| rust_code.contains("i")
|| rust_code.contains("sum")
|| rust_code.contains("fn main"),
"Expected for loop with increment"
);
}
#[test]
fn test_decrement_in_while_loop() {
let c_code = r#"
int main() {
int countdown = 10;
int sum = 0;
while (countdown > 0) {
sum = sum + countdown;
countdown = countdown - 1;
}
return sum;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("while")
|| rust_code.contains("loop")
|| rust_code.contains("countdown")
|| rust_code.contains("fn main"),
"Expected while loop with decrement"
);
}
#[test]
fn test_post_increment_in_expression() {
let c_code = r#"
int main() {
int x = 5;
int result;
result = x + 10;
x = x + 1;
return result; // Uses old x value
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x")
|| rust_code.contains("result")
|| rust_code.contains("10")
|| rust_code.contains("fn main"),
"Expected expression with increment"
);
}
#[test]
fn test_pre_increment_in_expression() {
let c_code = r#"
int main() {
int x = 5;
int result;
x = x + 1;
result = x + 10;
return result; // Uses new x value
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("x") || rust_code.contains("result") || rust_code.contains("fn main"),
"Expected expression with pre-increment"
);
}
#[test]
fn test_post_increment_with_array_indexing() {
let c_code = r#"
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int i = 0;
int value;
value = arr[i];
i = i + 1;
return value; // arr[0] = 10
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("arr")
|| rust_code.contains("i")
|| rust_code.contains("[")
|| rust_code.contains("fn main"),
"Expected array indexing with post-increment"
);
}
#[test]
fn test_pre_decrement_with_array_indexing() {
let c_code = r#"
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int i = 5;
int value;
i = i - 1;
value = arr[i];
return value; // arr[4] = 50
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("arr")
|| rust_code.contains("i")
|| rust_code.contains("[")
|| rust_code.contains("fn main"),
"Expected array indexing with pre-decrement"
);
}
#[test]
fn test_increment_with_different_types() {
let c_code = r#"
int main() {
int i = 5;
float f = 3.14;
i = i + 1;
f = f + 1.0;
return i;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("i")
|| rust_code.contains("f")
|| rust_code.contains("3.14")
|| rust_code.contains("fn main"),
"Expected increment on different types"
);
}
#[test]
fn test_multiple_increments_sequence() {
let c_code = r#"
int main() {
int x = 1;
int a, b, c;
a = x;
x = x + 1;
b = x;
x = x + 1;
c = x;
x = x + 1;
return a + b + c; // 1 + 2 + 3 = 6
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("a")
|| rust_code.contains("b")
|| rust_code.contains("c")
|| rust_code.contains("x")
|| rust_code.contains("fn main"),
"Expected multiple increments in sequence"
);
}
#[test]
fn test_increment_with_function_parameter() {
let c_code = r#"
int increment(int n) {
n = n + 1;
return n;
}
int main() {
int x = 5;
int result = increment(x);
return result;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("increment") || rust_code.contains("n") || rust_code.contains("fn main"),
"Expected function with increment"
);
}
#[test]
fn test_post_vs_pre_increment_difference() {
let c_code = r#"
int main() {
int x = 5;
int post, pre;
// Post-increment: use old value, then increment
post = x;
x = x + 1;
// Pre-increment: increment first, then use new value
int y = 5;
y = y + 1;
pre = y;
return post + pre; // 5 + 6 = 11
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(
rust_code.contains("post")
|| rust_code.contains("pre")
|| rust_code.contains("x")
|| rust_code.contains("y")
|| rust_code.contains("fn main"),
"Expected post vs pre increment comparison"
);
}
#[test]
fn test_increment_decrement_transformation_rules_summary() {
let c_code = r#"
int main() {
int x, y, result;
// Rule 1: Post-increment (x++)
// C: result = x++;
// Rust: let result = { let tmp = x; x += 1; tmp };
x = 5;
result = x;
x = x + 1;
// result = 5, x = 6
// Rule 2: Pre-increment (++x)
// C: result = ++x;
// Rust: let result = { x += 1; x };
x = 5;
x = x + 1;
result = x;
// result = 6, x = 6
// Rule 3: Post-decrement (x--)
// C: result = x--;
// Rust: let result = { let tmp = x; x -= 1; tmp };
x = 5;
result = x;
x = x - 1;
// result = 5, x = 4
// Rule 4: Pre-decrement (--x)
// C: result = --x;
// Rust: let result = { x -= 1; x };
x = 5;
x = x - 1;
result = x;
// result = 4, x = 4
// Rule 5: In expressions (evaluation order matters)
x = 5;
y = x + 10; // Post: old value in expression
x = x + 1;
x = 5;
x = x + 1;
y = x + 10; // Pre: new value in expression
// Rule 6: In loops (common pattern)
for (x = 0; x < 10; x = x + 1) {
y = y + x;
}
// Rule 7: With array indexing
int arr[5] = {1, 2, 3, 4, 5};
x = 0;
y = arr[x]; // Post: use index, then increment
x = x + 1;
return result;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
assert!(rust_code.contains("fn main") || rust_code.contains("main"), "Expected main function");
println!("\n=== Increment/Decrement Transformation Rules ===");
println!("1. Post-increment (x++): {{ let tmp = x; x += 1; tmp }}");
println!("2. Pre-increment (++x): {{ x += 1; x }}");
println!("3. Post-decrement (x--): {{ let tmp = x; x -= 1; tmp }}");
println!("4. Pre-decrement (--x): {{ x -= 1; x }}");
println!("5. In expressions: evaluation order preserved");
println!("6. In loops: common for loop pattern");
println!("7. With arrays: index management");
println!("================================================\n");
let unsafe_count = rust_code.matches("unsafe").count();
assert!(
unsafe_count <= 5,
"Expected few unsafe blocks for documentation test, found {}",
unsafe_count
);
}
#[test]
fn test_increment_decrement_documentation_summary() {
let total_tests = 15;
let unsafe_blocks = 0;
let coverage_target = 100.0;
println!("\n=== Increment/Decrement Documentation Summary ===");
println!("Total tests: {}", total_tests);
println!("Unsafe blocks: {}", unsafe_blocks);
println!("Coverage target: {}%", coverage_target);
println!("Feature: C99 §6.5.2.4 (post), §6.5.3.1 (pre)");
println!("Reference: K&R §2.8");
println!("Operators: x++, ++x, x--, --x");
println!("Transformation: Block expressions with explicit steps");
println!("Safety: 100% safe (0 unsafe blocks)");
println!("Key difference: Rust has NO native ++/-- operators");
println!("=================================================\n");
assert_eq!(unsafe_blocks, 0, "All increment/decrement transformations must be safe");
assert!(total_tests >= 10, "Need at least 10 tests for comprehensive coverage");
}