//! Integration tests for the resolution engine use crate::{ resolve::names::{ DeclKind, NameTable, }, syntax::{ lexer::Lexer, FileParser, }, }; fn parse(source: &str) -> crate::syntax::ast::File { let lexer = Lexer::new(source); let parser = FileParser::new(); parser.parse(lexer).expect("Should parse successfully") } #[test] fn test_name_resolution_example_file() { let source = r#" character Alice { age: 30 } character Bob { age: 35 } template PersonTemplate { age: 18..80 } enum Status { active, inactive } "#; let file = parse(source); let table = NameTable::from_file(&file).expect("Should build name table"); // Verify all names are registered assert!(table.lookup(&["Alice".to_string()]).is_some()); assert!(table.lookup(&["Bob".to_string()]).is_some()); assert!(table.lookup(&["PersonTemplate".to_string()]).is_some()); assert!(table.lookup(&["Status".to_string()]).is_some()); // Verify kind filtering assert_eq!(table.entries_of_kind(DeclKind::Character).count(), 2); assert_eq!(table.entries_of_kind(DeclKind::Template).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Enum).count(), 1); } #[test] fn test_use_statements_are_parsed() { let source = r#" use characters::Martha; use templates::{Person, NPC}; use locations::*; character LocalChar { age: 25 } "#; let file = parse(source); let table = NameTable::from_file(&file).expect("Should build name table"); // Verify imports were collected assert_eq!(table.imports().len(), 3); // Verify local declaration is registered assert!(table.lookup(&["LocalChar".to_string()]).is_some()); } #[test] fn test_duplicate_name_error() { let source = r#" character Martha { age: 30 } character Martha { age: 35 } "#; let file = parse(source); let result = NameTable::from_file(&file); // Should fail with duplicate error assert!(result.is_err()); } #[test] fn test_fuzzy_matching_suggestion() { let source = r#" character Elizabeth { age: 30 } "#; let file = parse(source); let table = NameTable::from_file(&file).expect("Should build name table"); // Typo "Elizabet" should suggest "Elizabeth" let suggestion = table.find_suggestion("Elizabet"); assert_eq!(suggestion, Some("Elizabeth".to_string())); // Typo "Elizabth" should also suggest "Elizabeth" let suggestion = table.find_suggestion("Elizabth"); assert_eq!(suggestion, Some("Elizabeth".to_string())); } #[test] fn test_all_declaration_kinds() { let source = r#" character C { age: 1 } template T { age: 1..2 } life_arc L { state s {} } schedule S { 10:00 -> 11:00: activity { } } behavior B { action } institution I { name: "Test" } relationship R { C { } C { } } location Loc { name: "Place" } species Sp { lifespan: 100 } enum E { a, b } "#; let file = parse(source); let table = NameTable::from_file(&file).expect("Should build name table"); // All 10 declaration kinds should be represented assert_eq!(table.entries_of_kind(DeclKind::Character).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Template).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::LifeArc).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Schedule).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Behavior).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Institution).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Relationship).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Location).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Species).count(), 1); assert_eq!(table.entries_of_kind(DeclKind::Enum).count(), 1); }