use metadol::parser::Parser;
use metadol::validator::validate;
#[test]
fn validate_gene_without_exegesis_fails() {
let file = Parser::new("gene Test { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.is_valid() || result.has_warnings());
}
}
#[test]
fn validate_gene_with_exegesis() {
let input = r#"gene Test { }
exegesis { This is the Test gene documentation. }"#;
let file = Parser::new(input).parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
let _ = result.is_valid();
}
}
#[test]
fn validation_result_has_errors_without_exegesis() {
let file = Parser::new("gene Test { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.errors.is_empty() || !result.warnings.is_empty() || !result.is_valid());
}
}
#[test]
fn validation_result_can_check_valid() {
let file = Parser::new("gene Test { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
let _is_valid: bool = result.is_valid();
}
}
#[test]
fn validation_result_can_check_warnings() {
let file = Parser::new("gene Test { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
let _has_warnings: bool = result.has_warnings();
}
}
#[test]
fn validate_gene_declaration() {
let file = Parser::new("gene Test { has x: Int64 }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_trait_declaration() {
let file = Parser::new("trait Test { entity is active }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_constraint_declaration() {
let file = Parser::new("constraint Test { value is required }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_function_declaration() {
let file = Parser::new("fun test() { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_system_declaration() {
let file = Parser::new("system Test { entity has state }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_pascal_case_gene_name() {
let file = Parser::new("gene MyContainer { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
let has_naming_warning = result
.warnings
.iter()
.any(|w| format!("{:?}", w).contains("Naming"));
assert!(!has_naming_warning);
}
}
#[test]
fn validate_lowercase_gene_name_warns() {
let file = Parser::new("gene mycontainer { }").parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
let _ = result.warnings.len(); }
}
#[test]
fn validate_qualified_name() {
let input = "gene container.exists { }";
let file = Parser::new(input).parse_file();
if let Ok(file) = file {
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
}
#[test]
fn validate_each_declaration_independently() {
let input = "gene A { } gene B { } gene C { }";
let file = Parser::new(input).parse_file().unwrap();
for decl in &file.declarations {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_mixed_declaration_types() {
let input = r#"
gene A { }
trait B { }
constraint C { }
fun d() { }
system E { }
"#;
let file = Parser::new(input).parse_file().unwrap();
assert_eq!(file.declarations.len(), 5);
for decl in &file.declarations {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_gene_with_many_fields() {
let mut input = String::from("gene Test { ");
for i in 0..10 {
input.push_str(&format!("has field{}: Int64 ", i));
}
input.push('}');
let file = Parser::new(&input).parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_trait_with_many_predicates() {
let input = r#"trait Test {
entity is active
entity is running
entity is ready
}"#;
let file = Parser::new(input).parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_int64_type() {
let file = Parser::new("gene Test { has x: Int64 }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_uint64_type() {
let file = Parser::new("gene Test { has x: UInt64 }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_string_type() {
let file = Parser::new("gene Test { has x: String }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_bool_type() {
let file = Parser::new("gene Test { has x: Bool }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_float64_type() {
let file = Parser::new("gene Test { has x: Float64 }")
.parse_file()
.unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_large_file() {
let mut input = String::new();
for i in 0..50 {
input.push_str(&format!("gene Gene{} {{ has x: Int64 }}\n", i));
}
let file = Parser::new(&input).parse_file().unwrap();
assert_eq!(file.declarations.len(), 50);
for decl in &file.declarations {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_complex_file() {
let input = r#"
gene User {
has id: UInt64
has name: String
has active: Bool
}
gene Post {
has id: UInt64
has author: UInt64
has content: String
}
trait Lifecycle {
entity is created
entity is deleted
}
constraint NonEmpty {
value is required
}
fun process(x: Int64) -> Int64 {
return x
}
system API {
request has method
request has path
}
"#;
let file = Parser::new(input).parse_file().unwrap();
for decl in &file.declarations {
let result = validate(decl);
assert!(!result.declaration_name.is_empty());
}
}
#[test]
fn validate_long_name() {
let name = "A".repeat(100);
let input = format!("gene {} {{ }}", name);
let file = Parser::new(&input).parse_file().unwrap();
if let Some(decl) = file.declarations.first() {
let result = validate(decl);
assert_eq!(result.declaration_name.len(), 100);
}
}
#[test]
fn validate_empty_file_no_declarations() {
let file = Parser::new("").parse_file().unwrap();
assert!(file.declarations.is_empty());
}
#[test]
fn validate_whitespace_file_no_declarations() {
let file = Parser::new(" \n\t\n ").parse_file().unwrap();
assert!(file.declarations.is_empty());
}