#![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_dialog_pattern_string_to_str_match_arms() {
let code = r#"
pub struct Inventory {
items: Vec<(string, i32)>,
}
impl Inventory {
pub fn has_item(self, item_id: string, min_qty: i32) -> bool {
for (id, qty) in self.items {
if id == item_id && qty >= min_qty {
return true
}
}
false
}
}
pub enum Condition {
HasItem(string, i32),
}
impl Condition {
pub fn evaluate(self, inv: Inventory) -> bool {
match self {
Condition::HasItem(item_id, qty) => {
inv.has_item(item_id, qty) // Should auto-convert string → &string
}
}
}
}
pub fn main() {
let inv = Inventory { items: Vec::new() }
let cond = Condition::HasItem("sword", 1)
let result = cond.evaluate(inv)
}
"#;
let (_, cargo_stderr) = test_utils::compile_via_cli_with_stderr(code);
assert!(
!cargo_stderr.contains("error[E0308]"),
"Should not have E0308 String vs &str error:\n{}",
cargo_stderr
);
}
#[test]
fn test_dialog_pattern_primitive_match_deref() {
let code = r#"
pub struct Player {
pub gold: i32,
}
pub enum Cost {
Gold(i32),
}
impl Cost {
pub fn can_afford(self, player: Player) -> bool {
match self {
Cost::Gold(amount) => {
player.gold >= amount // Should NOT deref amount
}
}
}
}
pub fn main() {
let player = Player { gold: 100 }
let cost = Cost::Gold(50)
let can = cost.can_afford(player)
}
"#;
let (_, cargo_stderr) = test_utils::compile_via_cli_with_stderr(code);
assert!(
!cargo_stderr.contains("error[E0614]"),
"Should not have E0614 cannot dereference error:\n{}",
cargo_stderr
);
}
#[test]
fn test_dialog_pattern_option_return_ownership() {
let code = r#"
pub struct Node {
pub id: string,
}
pub struct Tree {
nodes: Vec<Node>,
current_id: string,
}
impl Tree {
pub fn get_current_node(self) -> Option<Node> {
for node in self.nodes {
if node.id == self.current_id {
return Some(node)
}
}
None
}
pub fn process(self) {
if let Some(node) = self.get_current_node() {
println!("{}", node.id)
}
}
}
pub fn main() {
let tree = Tree {
nodes: Vec::new(),
current_id: "start",
}
tree.process()
}
"#;
let (_, cargo_stderr) = test_utils::compile_via_cli_with_stderr(code);
assert!(
!cargo_stderr.contains("error[E0507]"),
"Should not have E0507 cannot move error:\n{}",
cargo_stderr
);
}
#[test]
fn test_dialog_pattern_mutable_tuple_elements() {
let code = r#"
pub struct Inventory {
items: Vec<(string, i32)>,
}
impl Inventory {
pub fn add_item(self, item_id: string, quantity: i32) {
for (id, qty) in self.items {
if id == item_id {
qty = qty + quantity // Should infer &mut qty
return
}
}
self.items.push((item_id, quantity))
}
}
pub fn main() {
let mut inv = Inventory { items: Vec::new() }
inv.add_item("sword", 1)
}
"#;
let (_, cargo_stderr) = test_utils::compile_via_cli_with_stderr(code);
assert!(
!cargo_stderr.contains("error[E0594]"),
"Should not have E0594 cannot assign error:\n{}",
cargo_stderr
);
}
#[test]
fn test_dialog_full_integration() {
let code = r#"
pub struct Player {
pub gold: i32,
attributes: Vec<(string, i32)>,
}
impl Player {
pub fn get_attribute(self, name: string) -> i32 {
for (attr, val) in self.attributes {
if attr == name {
return val
}
}
0
}
pub fn set_attribute(self, name: string, value: i32) {
for (attr, val) in self.attributes {
if attr == name {
val = value
return
}
}
self.attributes.push((name, value))
}
}
pub struct GameState {
pub player: Player,
}
pub enum Condition {
AttributeCheck(string, i32),
HasGold(i32),
}
impl Condition {
pub fn evaluate(self, state: GameState) -> bool {
match self {
Condition::AttributeCheck(attr, min) => {
state.player.get_attribute(attr) >= min
},
Condition::HasGold(amount) => {
state.player.gold >= amount
},
}
}
}
pub fn main() {
let player = Player {
gold: 100,
attributes: Vec::new(),
}
let state = GameState { player: player }
let cond = Condition::HasGold(50)
let result = cond.evaluate(state)
}
"#;
let (_, cargo_stderr) = test_utils::compile_via_cli_with_stderr(code);
assert!(
!cargo_stderr.contains("error[E"),
"Should have no compilation errors:\n{}",
cargo_stderr
);
}