#![cfg(not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)))]
use std::fs;
use std::process::Command;
use tempfile::TempDir;
#[test]
fn test_nested_field_borrowed_param() {
let source = r#"
struct Item {
id: string
name: string
}
struct Stack {
item: Item
quantity: i32
}
fn has_item(item_id: string, quantity: i32) -> bool {
true
}
fn check_stacks(stacks: Vec<Stack>) -> bool {
for stack in &stacks {
if !has_item(stack.item.id, stack.quantity) {
return false
}
}
true
}
fn main() {
let stacks = Vec::new()
let result = check_stacks(stacks)
}
"#;
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let wj_file = temp_dir.path().join("test.wj");
fs::write(&wj_file, source).unwrap();
let out_dir = temp_dir.path().join("out");
let wj_binary = env!("CARGO_BIN_EXE_wj");
let _output = Command::new(wj_binary)
.arg("build")
.arg("--no-cargo")
.arg(&wj_file)
.arg("--target")
.arg("rust")
.arg("--output")
.arg(&out_dir)
.output()
.expect("Failed to run wj compiler");
let rust_file = out_dir.join("test.rs");
let generated = fs::read_to_string(&rust_file).expect("Failed to read generated Rust file");
println!("Generated Rust code:\n{}", generated);
let rustc_output = Command::new("rustc")
.arg(&rust_file)
.arg("--crate-type")
.arg("bin")
.arg("--edition")
.arg("2021")
.arg("--out-dir")
.arg(temp_dir.path())
.output()
.expect("Failed to run rustc");
if !rustc_output.status.success() {
let stderr = String::from_utf8_lossy(&rustc_output.stderr);
panic!(
"Rustc compilation failed:\n{}\n\nGenerated code:\n{}",
stderr, generated
);
}
assert!(
generated.contains("&stack.item.id") || generated.contains("stack.item.id.clone()"),
"Should add & or .clone() for nested field access through borrowed iterator"
);
}
#[test]
fn test_nested_field_owned_param() {
let source = r#"
struct Item {
id: string
}
struct Stack {
item: Item
}
fn remove_item(item_id: string) {
let mut removed: Vec<string> = Vec::new()
removed.push(item_id)
}
fn process(stacks: Vec<Stack>) {
for stack in &stacks {
remove_item(stack.item.id) // Should clone for owned param
}
}
fn main() {}
"#;
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let wj_file = temp_dir.path().join("test.wj");
fs::write(&wj_file, source).unwrap();
let out_dir = temp_dir.path().join("out");
let wj_binary = env!("CARGO_BIN_EXE_wj");
let _output = Command::new(wj_binary)
.arg("build")
.arg("--no-cargo")
.arg(&wj_file)
.arg("--target")
.arg("rust")
.arg("--output")
.arg(&out_dir)
.output()
.expect("Failed to run wj compiler");
let rust_file = out_dir.join("test.rs");
let generated = fs::read_to_string(&rust_file).expect("Failed to read generated Rust file");
println!("Generated Rust code:\n{}", generated);
let rustc_output = Command::new("rustc")
.arg(&rust_file)
.arg("--crate-type")
.arg("bin")
.arg("--edition")
.arg("2021")
.arg("--out-dir")
.arg(temp_dir.path())
.output()
.expect("Failed to run rustc");
if !rustc_output.status.success() {
let stderr = String::from_utf8_lossy(&rustc_output.stderr);
panic!(
"Rustc compilation failed:\n{}\n\nGenerated code:\n{}",
stderr, generated
);
}
assert!(
generated.contains("stack.item.id.clone()"),
"Should add .clone() for nested field when parameter expects owned"
);
}