use decy_core::transpile;
#[test]
fn test_addition_overflow_prevention() {
let c_code = r#"
int main() {
int a = 1000;
int b = 2000;
int sum = a + b;
return sum;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Addition should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_subtraction_underflow_prevention() {
let c_code = r#"
int main() {
int a = 100;
int b = 200;
int diff = a - b;
return diff;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Subtraction should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_multiplication_overflow_prevention() {
let c_code = r#"
int main() {
int a = 10000;
int b = 20000;
int product = a * b;
return product;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Multiplication should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_division_by_zero_check() {
let c_code = r#"
int main() {
int a = 100;
int b = 5;
int quotient;
if (b != 0) {
quotient = a / b;
} else {
quotient = 0;
}
return quotient;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 5,
"Division should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_modulo_by_zero_check() {
let c_code = r#"
int main() {
int a = 100;
int b = 7;
int remainder;
if (b != 0) {
remainder = a % b;
} else {
remainder = 0;
}
return remainder;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 5,
"Modulo should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_negation_overflow() {
let c_code = r#"
int main() {
int a = -100;
int b = -a;
return b;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Negation should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_loop_counter_overflow() {
let c_code = r#"
int main() {
int i;
int sum = 0;
for (i = 0; i < 10; i++) {
sum = sum + i;
}
return sum;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 5,
"Loop counter should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_unsigned_wraparound() {
let c_code = r#"
int main() {
unsigned int a = 10;
unsigned int b = 20;
unsigned int diff = a - b;
return (int)diff;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 5,
"Unsigned wraparound should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_increment_overflow() {
let c_code = r#"
int main() {
int a = 100;
int b;
a = a + 1;
b = a;
return b;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Increment should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_decrement_underflow() {
let c_code = r#"
int main() {
int a = 100;
int b;
a = a - 1;
b = a;
return b;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Decrement should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_compound_addition_overflow() {
let c_code = r#"
int main() {
int a = 1000;
int b = 2000;
a = a + b;
return a;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Compound addition should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_compound_multiplication_overflow() {
let c_code = r#"
int main() {
int a = 100;
int b = 200;
a = a * b;
return a;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Compound multiplication should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_array_index_arithmetic_overflow() {
let c_code = r#"
int main() {
int arr[10];
int index = 5;
int offset = 2;
int final_index = index + offset;
if (final_index >= 0 && final_index < 10) {
arr[final_index] = 42;
}
return 0;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 6,
"Array index arithmetic should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_size_calculation_overflow() {
let c_code = r#"
int main() {
int count = 100;
int item_size = 50;
int total_size = count * item_size;
return total_size;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count <= 4,
"Size calculation should minimize unsafe (found {})",
unsafe_count
);
}
#[test]
fn test_unsafe_block_count_target() {
let c_code = r#"
int main() {
int a = 1000;
int b = 2000;
int c = 3000;
int sum1 = a + b;
int sum2 = sum1 + c;
int product = sum2 * 2;
int diff = product - 1000;
return diff;
}
"#;
let result = transpile(c_code).expect("Should transpile");
let unsafe_count = result.matches("unsafe").count();
let lines_of_code = result.lines().count();
let unsafe_per_1000 = if lines_of_code > 0 {
(unsafe_count as f64 / lines_of_code as f64) * 1000.0
} else {
0.0
};
assert!(
unsafe_per_1000 <= 100.0,
"Integer overflow prevention should minimize unsafe (got {:.2} per 1000 LOC, want <=100)",
unsafe_per_1000
);
assert!(result.contains("fn main"), "Should generate main function");
}
#[test]
fn test_transpiled_code_compiles() {
let c_code = r#"
int main() {
int a = 100;
int b = 200;
int sum = a + b;
return sum;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(!result.is_empty(), "Should generate non-empty code");
assert!(result.contains("fn main"), "Should have main function");
let open_braces = result.matches('{').count();
let close_braces = result.matches('}').count();
assert_eq!(
open_braces, close_braces,
"Braces should be balanced: {} open, {} close",
open_braces, close_braces
);
}
#[test]
fn test_integer_overflow_safety_documentation() {
let c_code = r#"
int main() {
int a = 1000000;
int b = 2000000;
int product = a * b;
return product;
}
"#;
let result = transpile(c_code).expect("Should transpile");
assert!(result.contains("fn main"), "Should have main function");
let unsafe_count = result.matches("unsafe").count();
assert!(
unsafe_count < 10,
"Should have minimal unsafe blocks (found {})",
unsafe_count
);
}