#[cfg(test)]
mod tests {
#[test]
fn test_while_loop_simple() {
let c_code = r#"
int x = 0;
while (x < 10) {
x++;
}
"#;
let rust_expected = r#"
let mut x = 0;
while x < 10 {
x += 1;
}
"#;
assert!(c_code.contains("while (x < 10)"));
assert!(rust_expected.contains("while x < 10"));
}
#[test]
fn test_while_loop_boolean() {
let c_code = r#"
int running = 1;
while (running) {
// Do work
running = 0;
}
"#;
let rust_expected = r#"
let mut running = true;
while running {
// Do work
running = false;
}
"#;
assert!(c_code.contains("while (running)"));
assert!(rust_expected.contains("while running"));
}
#[test]
fn test_while_loop_with_break() {
let c_code = r#"
while (x < 100) {
if (x == 50) {
break;
}
x++;
}
"#;
let rust_expected = r#"
while x < 100 {
if x == 50 {
break;
}
x += 1;
}
"#;
assert!(c_code.contains("break;"));
assert!(rust_expected.contains("break;"));
}
#[test]
fn test_while_loop_with_continue() {
let c_code = r#"
while (x < 10) {
x++;
if (x % 2 == 0) {
continue;
}
printf("%d\n", x);
}
"#;
let rust_expected = r#"
while x < 10 {
x += 1;
if x % 2 == 0 {
continue;
}
println!("{}", x);
}
"#;
assert!(c_code.contains("continue;"));
assert!(rust_expected.contains("continue;"));
}
#[test]
fn test_while_loop_infinite() {
let c_code = r#"
while (1) {
// Do work
if (done) break;
}
"#;
let rust_expected = r#"
loop {
// Do work
if done { break; }
}
"#;
assert!(c_code.contains("while (1)"));
assert!(rust_expected.contains("loop"));
}
#[test]
fn test_while_loop_complex_condition() {
let c_code = r#"
while (x < 10 && y > 0) {
x++;
y--;
}
"#;
let rust_expected = r#"
while x < 10 && y > 0 {
x += 1;
y -= 1;
}
"#;
assert!(c_code.contains("while (x < 10 && y > 0)"));
assert!(rust_expected.contains("while x < 10 && y > 0"));
}
#[test]
fn test_while_loop_nested_if() {
let c_code = r#"
while (x < 10) {
if (x % 2 == 0) {
even++;
} else {
odd++;
}
x++;
}
"#;
let rust_expected = r#"
while x < 10 {
if x % 2 == 0 {
even += 1;
} else {
odd += 1;
}
x += 1;
}
"#;
assert!(c_code.contains("if (x % 2 == 0)"));
assert!(rust_expected.contains("if x % 2 == 0"));
}
#[test]
fn test_while_loop_sentinel() {
let c_code = r#"
char c;
while ((c = getchar()) != EOF) {
putchar(c);
}
"#;
let rust_expected = r#"
loop {
let c = getchar();
if c == EOF {
break;
}
putchar(c);
}
"#;
assert!(c_code.contains("while ((c = getchar()) != EOF)"));
assert!(rust_expected.contains("loop"));
assert!(rust_expected.contains("if c == EOF"));
}
#[test]
fn test_while_loop_countdown() {
let c_code = r#"
int n = 10;
while (n > 0) {
printf("%d\n", n);
n--;
}
"#;
let rust_expected = r#"
let mut n = 10;
while n > 0 {
println!("{}", n);
n -= 1;
}
"#;
assert!(c_code.contains("while (n > 0)"));
assert!(rust_expected.contains("while n > 0"));
}
#[test]
fn test_while_loop_multiple_updates() {
let c_code = r#"
while (i < n && j > 0) {
i++;
j--;
sum += i + j;
}
"#;
let rust_expected = r#"
while i < n && j > 0 {
i += 1;
j -= 1;
sum += i + j;
}
"#;
assert!(c_code.contains("i++"));
assert!(c_code.contains("j--"));
assert!(rust_expected.contains("i += 1"));
assert!(rust_expected.contains("j -= 1"));
}
#[test]
fn test_while_loop_nested() {
let c_code = r#"
int i = 0;
while (i < rows) {
int j = 0;
while (j < cols) {
printf("%d ", matrix[i][j]);
j++;
}
i++;
}
"#;
let rust_expected = r#"
let mut i = 0;
while i < rows {
let mut j = 0;
while j < cols {
print!("{} ", matrix[i][j]);
j += 1;
}
i += 1;
}
"#;
assert!(c_code.contains("while (i < rows)"));
assert!(c_code.contains("while (j < cols)"));
assert!(rust_expected.contains("while i < rows"));
assert!(rust_expected.contains("while j < cols"));
}
#[test]
fn test_while_loop_pointer_check() {
let c_code = r#"
Node* current = head;
while (current) {
process(current);
current = current->next;
}
"#;
let rust_expected = r#"
let mut current = head;
while current.is_some() {
process(¤t);
current = current.next;
}
"#;
assert!(c_code.contains("while (current)"));
assert!(rust_expected.contains("while current.is_some()"));
}
#[test]
fn test_while_loop_do_while_pattern() {
let c_code = r#"
// C do-while (not while, but related):
// do {
// process();
// } while (x < 10);
// While equivalent (pre-test):
process();
while (x < 10) {
process();
}
"#;
let rust_expected = r#"
// Rust loop with break (do-while equivalent):
// loop {
// process();
// if !(x < 10) { break; }
// }
// While (pre-test):
process();
while x < 10 {
process();
}
"#;
assert!(c_code.contains("while (x < 10)"));
assert!(rust_expected.contains("while x < 10"));
}
#[test]
fn test_while_loop_empty_body() {
let c_code = r#"
while (is_busy()); // Spin until not busy
"#;
let rust_expected = r#"
while is_busy() {} // Spin until not busy
"#;
assert!(c_code.contains("while (is_busy())"));
assert!(rust_expected.contains("while is_busy()"));
}
#[test]
fn test_while_loop_not_condition() {
let c_code = r#"
while (!done) {
work();
}
"#;
let rust_expected = r#"
while !done {
work();
}
"#;
assert!(c_code.contains("while (!done)"));
assert!(rust_expected.contains("while !done"));
}
#[test]
fn test_while_loop_string_processing() {
let c_code = r#"
int i = 0;
while (str[i] != '\0') {
process(str[i]);
i++;
}
"#;
let rust_expected = r#"
let mut i = 0;
while str[i] != '\0' {
process(str[i]);
i += 1;
}
// Or idiomatic: for ch in str.chars() { process(ch); }
"#;
assert!(c_code.contains("while (str[i] != '\\0')"));
assert!(rust_expected.contains("while str[i] != '\\0'"));
}
#[test]
fn test_while_loop_transformation_summary() {
let c_code = r#"
// Rule 1: Basic while
while (x < 10) { x++; }
// Rule 2: Scalar condition → explicit comparison
while (x) { x--; }
// Rule 3: Infinite loop
while (1) { if (done) break; }
// Rule 4: Assignment in condition
while ((c = getchar()) != EOF) { }
// Rule 5: Complex condition
while (x < 10 && y > 0) { }
// Rule 6: Pointer check
while (ptr) { ptr = ptr->next; }
// Rule 7: Logical NOT
while (!done) { }
"#;
let rust_expected = r#"
// Rule 1: Remove parentheses
while x < 10 { x += 1; }
// Rule 2: Explicit comparison
while x != 0 { x -= 1; }
// Rule 3: Use loop keyword
loop { if done { break; } }
// Rule 4: loop + break
loop { let c = getchar(); if c == EOF { break; } }
// Rule 5: Same complex conditions
while x < 10 && y > 0 { }
// Rule 6: Option::is_some()
while ptr.is_some() { ptr = ptr.next; }
// Rule 7: Same NOT operator
while !done { }
"#;
assert!(c_code.contains("while (x < 10)"));
assert!(rust_expected.contains("while x < 10"));
assert!(c_code.contains("while (x)"));
assert!(rust_expected.contains("while x != 0"));
assert!(c_code.contains("while (1)"));
assert!(rust_expected.contains("loop"));
assert!(c_code.contains("while ((c = getchar())"));
assert!(c_code.contains("while (!done)"));
assert!(rust_expected.contains("while !done"));
}
}