use metadol::lexer::{Lexer, TokenKind};
use metadol::parser::Parser;
#[test]
fn error_missing_gene_name() {
let result = Parser::new("gene { }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_gene_brace() {
let result = Parser::new("gene Test").parse_file();
assert!(result.is_err());
}
#[test]
fn error_unclosed_gene() {
let result = Parser::new("gene Test {").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_trait_name() {
let result = Parser::new("trait { }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_constraint_name() {
let result = Parser::new("constraint { }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_function_name() {
let result = Parser::new("fun () { }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_system_name() {
let result = Parser::new("system { }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_unclosed_paren_in_call() {
let result = Parser::new("fun test() { foo(a, b }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_unclosed_bracket_in_list() {
let result = Parser::new("fun test() { [a, b }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_extra_close_brace() {
let result = Parser::new("gene Test { } }").parse_file();
let _ = result;
}
#[test]
fn error_extra_close_paren() {
let result = Parser::new("fun test() { (a)) }").parse_file();
let _ = result;
}
#[test]
fn error_missing_return_keyword() {
let result = Parser::new("fun test() { x }").parse_file();
let _ = result;
}
#[test]
fn error_missing_if_body() {
let result = Parser::new("fun test() { if true }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_match_scrutinee() {
let result = Parser::new("fun test() { match { } }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_field_type() {
let result = Parser::new("gene Test { has x: }").parse_file();
assert!(result.is_err());
}
#[test]
fn error_missing_param_type() {
let result = Parser::new("fun test(x) { }").parse_file();
assert!(result.is_err());
}
#[test]
fn lexer_unknown_char() {
let mut lexer = Lexer::new("$");
let token = lexer.next_token();
assert!(matches!(token.kind, TokenKind::Error | TokenKind::Eof));
}
#[test]
fn lexer_unclosed_string() {
let mut lexer = Lexer::new("\"hello");
let token = lexer.next_token();
let _ = token;
}
#[test]
fn lexer_empty_input() {
let mut lexer = Lexer::new("");
let token = lexer.next_token();
assert_eq!(token.kind, TokenKind::Eof);
}
#[test]
fn error_message_has_span() {
let result = Parser::new("gene { }").parse_file();
if let Err(e) = result {
let msg = format!("{:?}", e);
assert!(msg.contains("span") || msg.contains("line") || msg.contains("Span"));
}
}
#[test]
fn error_message_describes_expected() {
let result = Parser::new("gene { }").parse_file();
if let Err(e) = result {
let msg = format!("{:?}", e);
assert!(msg.contains("expected") || msg.contains("Expected") || msg.contains("identifier"));
}
}
#[test]
fn recover_and_continue_parsing() {
let input = "gene A { gene B { }"; let result = Parser::new(input).parse_file();
let _ = result;
}
#[test]
fn multiple_errors_detected() {
let input = "gene { } trait { }"; let result = Parser::new(input).parse_file();
assert!(result.is_err());
}
#[test]
fn error_only_keyword() {
let result = Parser::new("gene").parse_file();
assert!(result.is_err());
}
#[test]
fn error_only_brace() {
let result = Parser::new("{").parse_file();
assert!(result.is_err());
}
#[test]
fn error_random_tokens() {
let result = Parser::new("+ - * /").parse_file();
assert!(result.is_err());
}
#[test]
fn error_mismatched_braces() {
let result = Parser::new("gene Test { ] }").parse_file();
assert!(result.is_err());
}
#[test]
fn graceful_on_large_error() {
let input = "{{{{{{{{{{";
let result = Parser::new(input).parse_file();
let _ = result;
}
#[test]
fn graceful_on_deep_nesting_error() {
let input = "(((((((((( ))))))))))";
let result = Parser::new(input).parse_expr(0);
let _ = result;
}
#[test]
fn graceful_on_long_input() {
let input = "x ".repeat(10000);
let result = Parser::new(&input).parse_file();
let _ = result;
}