#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "codegen_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
fn test_single_element_tuple_enum_match() {
let code = r#"
pub struct Checker {
pub expected: string,
}
impl Checker {
pub fn check(self, value: string) -> bool {
self.expected == value
}
}
pub enum Event {
QuestComplete(string),
}
impl Event {
pub fn matches(self, checker: Checker) -> bool {
match self {
Event::QuestComplete(quest_id) => {
// quest_id should be owned string
// With proper type inference, this should auto-add &
checker.check(quest_id)
}
}
}
}
pub fn main() {
let checker = Checker { expected: "main_quest" }
let event = Event::QuestComplete("main_quest")
let result = event.matches(checker)
}
"#;
let rust_code = test_utils::compile_single(code);
assert!(
rust_code.contains("checker.check(&quest_id)")
|| rust_code.contains("checker.check(quest_id)"),
"Should auto-convert String to &str:\n{}",
rust_code
);
let temp_dir = tempfile::tempdir().unwrap();
let rs_file = temp_dir.path().join("test.rs");
std::fs::write(&rs_file, &rust_code).unwrap();
let rustc_output = std::process::Command::new("rustc")
.arg("--crate-type=lib")
.arg(&rs_file)
.arg("--out-dir")
.arg(temp_dir.path())
.output()
.unwrap();
let rustc_stderr = String::from_utf8_lossy(&rustc_output.stderr);
assert!(
!rustc_stderr.contains("error[E"),
"Generated Rust should compile:\n{}",
rustc_stderr
);
}
#[test]
fn test_multi_element_tuple_enum_match() {
let code = r#"
pub struct Checker {
pub expected_id: string,
pub min_level: i32,
}
impl Checker {
pub fn check(self, id: string, level: i32) -> bool {
self.expected_id == id && self.min_level <= level
}
}
pub enum Event {
RelationshipLevel(string, i32),
}
impl Event {
pub fn matches(self, checker: Checker) -> bool {
match self {
Event::RelationshipLevel(char_id, min_level) => {
// Both should be owned, auto-convert string → &string
checker.check(char_id, min_level)
}
}
}
}
pub fn main() {
let checker = Checker { expected_id: "npc1", min_level: 3 }
let event = Event::RelationshipLevel("npc1", 5)
let result = event.matches(checker)
}
"#;
let rust_code = test_utils::compile_single(code);
assert!(
rust_code.contains("&char_id") || rust_code.contains("char_id"),
"Should handle multi-element tuple:\n{}",
rust_code
);
}
#[test]
fn test_mixed_single_and_multi_tuple_variants() {
let code = r#"
pub struct Checker {
pub id_field: string,
}
impl Checker {
pub fn matches_id(self, id: string) -> bool {
self.id_field == id
}
}
pub enum Condition {
HasItem(string, i32), // 2 elements → EnumPatternBinding::Tuple
HasGold(i32), // 1 element → EnumPatternBinding::Single
QuestComplete(string), // 1 element → EnumPatternBinding::Single
RelationshipLevel(string, i32), // 2 elements → EnumPatternBinding::Tuple
}
impl Condition {
pub fn check(self, checker: Checker) -> bool {
match self {
Condition::HasItem(item_id, _qty) => {
checker.matches_id(item_id)
},
Condition::HasGold(_amount) => true,
Condition::QuestComplete(quest_id) => {
// CRITICAL: quest_id uses EnumPatternBinding::Single
// This should be tracked in local_var_types!
checker.matches_id(quest_id)
},
Condition::RelationshipLevel(char_id, _level) => {
checker.matches_id(char_id)
},
}
}
}
pub fn main() {
let checker = Checker { id_field: "test" }
let c1 = Condition::HasItem("sword", 1)
let c2 = Condition::QuestComplete("main_quest")
let r1 = c1.check(checker)
}
"#;
let rust_code = test_utils::compile_single(code);
assert!(
rust_code.contains("&quest_id")
|| rust_code.contains("&item_id")
|| rust_code.contains("&char_id"),
"Should auto-convert String → &str for all variants:\n{}",
rust_code
);
}