#![cfg(not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
fn test_lint_owned_but_not_returned_warns() {
let source = r#"
pub fn smoke_lint_driver() -> i32 {
42
}
"#;
let (_generated, _stderr) = test_utils::compile_via_cli_with_stderr(source);
}
#[test]
fn test_lint_owned_and_returned_no_warning() {
let source = r#"
pub struct Counter {
value: i32,
}
impl Counter {
pub fn increment(self) {
self.value = self.value + 1
}
}
/// This should NOT trigger lint: owned param mutated and returned
pub fn increment_counter(counter: Counter) -> Counter {
counter.increment()
counter
}
"#;
let (_generated, stderr) = test_utils::compile_via_cli_with_stderr(source);
assert!(
!stderr.contains("owned-but-not-returned") && !stderr.contains("mutated but not returned"),
"Should NOT warn for owned param that is returned. Stderr:\n{}",
stderr
);
}
#[test]
fn test_lint_owned_read_only_no_warning() {
let source = r#"
pub struct Data {
value: i32,
}
impl Data {
pub fn get_value(self) -> i32 {
self.value
}
}
/// This should NOT trigger lint: owned param only read (might need ownership)
pub fn process_data(data: Data) -> i32 {
data.get_value()
}
"#;
let (_generated, stderr) = test_utils::compile_via_cli_with_stderr(source);
assert!(
!stderr.contains("owned-but-not-returned"),
"Should NOT warn for owned param that is only read. Stderr:\n{}",
stderr
);
}
#[test]
fn test_consistency_explicit_type_respected() {
let source = r#"
pub fn test() {
let x: i32 = 42 // Explicit i32, even if usize would work
let y: String = "test" // Explicit string, even if &str would work
}
"#;
let (generated, _stderr) = test_utils::compile_via_cli_with_stderr(source);
assert!(
generated.contains(": i32 = 42"),
"Expected explicit i32 type to be preserved. Generated:\n{}",
generated
);
assert!(
generated.contains(": String = "),
"Expected explicit String type to be preserved. Generated:\n{}",
generated
);
}
#[test]
fn test_consistency_explicit_mut_respected() {
let source = r#"
pub fn test() {
let mut x = 42 // Explicit mut, even if never mutated
}
"#;
let (generated, _stderr) = test_utils::compile_via_cli_with_stderr(source);
assert!(
generated.contains("mut") && generated.contains("= 42"),
"Expected explicit mut to be preserved. Generated:\n{}",
generated
);
}
#[test]
fn test_consistency_explicit_ownership_respected() {
let source = r#"
pub struct ResourcePool {
items: Vec<String>,
count: i32,
}
impl ResourcePool {
pub fn new() -> ResourcePool {
ResourcePool { items: Vec::new(), count: 0 }
}
pub fn add(self, item: String) {
self.items.push(item)
self.count = self.count + 1
}
}
pub fn fill_pool(pool: ResourcePool) {
pool.add("water")
pool.add("food")
}
"#;
let (generated, _stderr) = test_utils::compile_via_cli_with_stderr(source);
let ok = generated.contains("pub fn fill_pool(mut pool: ResourcePool)")
|| generated.contains("pub fn fill_pool(pool: &mut ResourcePool)");
assert!(
ok,
"Expected `mut pool: ResourcePool` or inferred `pool: &mut ResourcePool`. Generated:\n{}",
generated
);
}
#[test]
fn test_consistency_user_closure_preserved() {
let source = r#"
pub struct Item {
active: bool,
}
pub struct Inventory {
items: Vec<Item>,
}
impl Inventory {
pub fn count_inactive(self) -> usize {
self.items.filter(|e| !e.active).count()
}
}
"#;
let (generated, _stderr) = test_utils::compile_via_cli_with_stderr(source);
assert!(
generated.contains("filter(|e| !e.active)"),
"Expected user-written closure to be preserved. Generated:\n{}",
generated
);
}