#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_for_i_in_literal_range() {
let src = r#"
pub fn sum_ten() -> i32 {
let mut total = 0
for i in 0..10 {
total = total + i
}
total
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("total + i")
|| result.contains("total = total + i")
|| result.contains("total += i"),
"Should use i directly in arithmetic, got: {}",
result
);
assert!(
!result.contains("*i"),
"Should not dereference loop variable i, got: {}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_for_x_in_param_range() {
let src = r#"
pub fn iterate_range(min: i32, max: i32) -> i32 {
let mut sum = 0
for x in min..max {
sum = sum + x
}
sum
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("sum + x")
|| result.contains("sum = sum + x")
|| result.contains("sum += x"),
"Should use x directly, got: {}",
result
);
assert!(
!result.contains("*x"),
"Should not dereference loop variable x, got: {}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_for_item_in_vec() {
let src = r#"
pub fn sum_vec(items: Vec<i32>) -> i32 {
let mut total = 0
for item in items {
total = total + item
}
total
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("total + item")
|| result.contains("total = total + item")
|| result.contains("total += item"),
"Should use item directly, got: {}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_loop_var_in_arithmetic() {
let src = r#"
pub fn double_range(max: i32) -> i32 {
let mut sum = 0
for i in 0..max {
sum = sum + i * 2
}
sum
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("i * 2"),
"Should multiply i directly, got: {}",
result
);
assert!(
!result.contains("*i"),
"Should not dereference i, got: {}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_loop_var_in_cast() {
let src = r#"
pub fn index_tiles(tiles: Vec<i32>, min: i32, max: i32) -> i32 {
let mut sum = 0
for row in min..max {
let tile = tiles[row as usize]
sum = sum + tile
}
sum
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("row as usize"),
"Should cast row directly to usize, got: {}",
result
);
assert!(
!result.contains("*row"),
"Should not dereference row (would indicate &i32 bug), got: {}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_loop_var_in_function_call() {
let src = r#"
pub fn process_range(min: i32, max: i32) {
for i in min..max {
println!("{}", i)
}
}
"#;
let result = test_utils::compile_single_result(src).expect("compile");
assert!(
result.contains("println!") && result.contains(", i)"),
"Should pass i to println, got: {}",
result
);
}