151 líneas
5.0 KiB
Rust
151 líneas
5.0 KiB
Rust
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use alecc::lexer::{Lexer, TokenType};
|
|
use alecc::parser::Parser;
|
|
use alecc::codegen::CodeGenerator;
|
|
use alecc::targets::Target;
|
|
use alecc::compiler::Compiler;
|
|
use alecc::cli::Args;
|
|
use std::path::PathBuf;
|
|
|
|
#[test]
|
|
fn test_lexer_basic() {
|
|
let input = "int main() { return 0; }".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
|
|
assert!(!tokens.is_empty());
|
|
assert!(matches!(tokens[0].token_type, TokenType::Int));
|
|
}
|
|
|
|
#[test]
|
|
fn test_lexer_numbers() {
|
|
let input = "42 3.14 'a' \"hello\"".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
|
|
assert!(matches!(tokens[0].token_type, TokenType::IntegerLiteral(42)));
|
|
assert!(matches!(tokens[1].token_type, TokenType::FloatLiteral(_)));
|
|
assert!(matches!(tokens[2].token_type, TokenType::CharLiteral('a')));
|
|
assert!(matches!(tokens[3].token_type, TokenType::StringLiteral(_)));
|
|
}
|
|
|
|
#[test]
|
|
fn test_lexer_operators() {
|
|
let input = "+ - * / == != < > <= >=".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
|
|
assert!(matches!(tokens[0].token_type, TokenType::Plus));
|
|
assert!(matches!(tokens[1].token_type, TokenType::Minus));
|
|
assert!(matches!(tokens[2].token_type, TokenType::Multiply));
|
|
assert!(matches!(tokens[3].token_type, TokenType::Divide));
|
|
assert!(matches!(tokens[4].token_type, TokenType::Equal));
|
|
assert!(matches!(tokens[5].token_type, TokenType::NotEqual));
|
|
}
|
|
|
|
#[test]
|
|
fn test_lexer_comments() {
|
|
let input = "int x; // comment\n/* block comment */ int y;".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
|
|
// Comments should be filtered out
|
|
let identifier_count = tokens.iter()
|
|
.filter(|t| matches!(t.token_type, TokenType::Identifier(_)))
|
|
.count();
|
|
assert_eq!(identifier_count, 2); // x and y
|
|
}
|
|
|
|
#[test]
|
|
fn test_parser_simple_function() {
|
|
let input = "int main() { return 0; }".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
let mut parser = Parser::new(tokens);
|
|
let program = parser.parse().unwrap();
|
|
|
|
assert_eq!(program.functions.len(), 1);
|
|
assert_eq!(program.functions[0].name, "main");
|
|
}
|
|
|
|
#[test]
|
|
fn test_target_from_string() {
|
|
assert_eq!(Target::from_string("i386"), Some(Target::I386));
|
|
assert_eq!(Target::from_string("amd64"), Some(Target::Amd64));
|
|
assert_eq!(Target::from_string("arm64"), Some(Target::Arm64));
|
|
assert_eq!(Target::from_string("x86_64"), Some(Target::Amd64));
|
|
assert_eq!(Target::from_string("invalid"), None);
|
|
}
|
|
|
|
#[test]
|
|
fn test_target_properties() {
|
|
assert_eq!(Target::I386.pointer_size(), 4);
|
|
assert_eq!(Target::Amd64.pointer_size(), 8);
|
|
assert_eq!(Target::Arm64.pointer_size(), 8);
|
|
}
|
|
|
|
#[test]
|
|
fn test_codegen_simple() {
|
|
let input = "int main() { return 42; }".to_string();
|
|
let mut lexer = Lexer::new(input);
|
|
let tokens = lexer.tokenize().unwrap();
|
|
let mut parser = Parser::new(tokens);
|
|
let program = parser.parse().unwrap();
|
|
|
|
let mut codegen = CodeGenerator::new(Target::Amd64);
|
|
let assembly = codegen.generate(&program).unwrap();
|
|
|
|
assert!(assembly.contains("main:"));
|
|
assert!(assembly.contains("ret"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_compiler_invalid_target() {
|
|
let args = Args {
|
|
input_files: vec![PathBuf::from("test.c")],
|
|
target: "invalid_target".to_string(),
|
|
output: None,
|
|
compile_only: false,
|
|
assembly_only: false,
|
|
preprocess_only: false,
|
|
optimization: "0".to_string(),
|
|
debug: false,
|
|
warnings: vec![],
|
|
include_dirs: vec![],
|
|
library_dirs: vec![],
|
|
libraries: vec![],
|
|
defines: vec![],
|
|
undefines: vec![],
|
|
standard: None,
|
|
verbose: false,
|
|
pic: false,
|
|
pie: false,
|
|
static_link: false,
|
|
shared: false,
|
|
thread_model: "posix".to_string(),
|
|
lto: false,
|
|
sysroot: None,
|
|
extra_flags: vec![],
|
|
};
|
|
|
|
let result = Compiler::new(args);
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_types() {
|
|
use alecc::error::AleccError;
|
|
|
|
let lex_error = AleccError::LexError {
|
|
line: 1,
|
|
column: 5,
|
|
message: "Unexpected character".to_string(),
|
|
};
|
|
|
|
assert!(format!("{}", lex_error).contains("line 1"));
|
|
assert!(format!("{}", lex_error).contains("column 5"));
|
|
}
|
|
}
|