SeraphScript/src/parsing/parser/parser_tests.rs

210 lines
6.2 KiB
Rust

use super::parse;
use super::parsed_statement::ParsedStatement;
use crate::modifiers::TypeModifier;
use crate::parsing::lexer::lex_tokens::{LexToken, TokenType};
use crate::span::Span;
use enumflags2::BitFlags;
fn create_tokens(types: Vec<TokenType>) -> Vec<LexToken> {
let mut v = Vec::with_capacity(types.len());
for t in types {
v.push(LexToken {
token_type: t,
span: Span::new(0, 0),
});
}
v
}
#[test]
fn test_empty_namespace() {
let script = parse(
create_tokens(vec![
TokenType::NamespaceKeyword,
TokenType::WhiteSpace,
TokenType::Identifier("foo".to_string()),
TokenType::WhiteSpace,
TokenType::OpenCurlyBracket,
TokenType::CloseCurlyBracket,
TokenType::EndOfFile,
]),
&mut |_message, _span| {
std::panic::panic_any(_message.stringify());
},
);
if let ParsedStatement::Script { statements } = script.as_ref() {
assert_eq!(1, statements.len());
if let ParsedStatement::Namespace { identifier, script } = &statements[0] {
assert_eq!(identifier, "foo");
if let ParsedStatement::Script { statements } = script.as_ref() {
assert_eq!(0, statements.len());
} else {
unreachable!();
}
} else {
unreachable!()
}
} else {
unreachable!();
}
}
#[test]
fn test_empty_interface() {
let script = parse(
create_tokens(vec![
TokenType::InterfaceKeyword,
TokenType::WhiteSpace,
TokenType::Identifier("foo".to_string()),
TokenType::WhiteSpace,
TokenType::OpenCurlyBracket,
TokenType::CloseCurlyBracket,
TokenType::EndOfFile,
]),
&mut |_message, _span| {
std::panic::panic_any(_message.stringify());
},
);
if let ParsedStatement::Script { statements } = script.as_ref() {
assert_eq!(1, statements.len());
if let ParsedStatement::Interface {
type_mod,
identifier,
inherits,
statements,
} = &statements[0]
{
assert!(type_mod.is_empty());
assert_eq!(identifier, "foo");
assert_eq!(inherits.len(), 0);
assert_eq!(statements.len(), 0);
} else {
unreachable!()
}
} else {
unreachable!();
}
}
#[test]
fn test_empty_external_shared_interface() {
let script = parse(
create_tokens(vec![
TokenType::ExternalKeyword,
TokenType::SharedKeyword,
TokenType::InterfaceKeyword,
TokenType::WhiteSpace,
TokenType::Identifier("foo".to_string()),
TokenType::WhiteSpace,
TokenType::OpenCurlyBracket,
TokenType::CloseCurlyBracket,
TokenType::EndOfFile,
]),
&mut |_message, _span| {
std::panic::panic_any(_message.stringify());
},
);
if let ParsedStatement::Script { statements } = script.as_ref() {
assert_eq!(1, statements.len());
if let ParsedStatement::Interface {
type_mod,
identifier,
inherits,
statements,
} = &statements[0]
{
assert!(!type_mod.is_empty());
assert!(type_mod.contains(TypeModifier::External));
assert!(type_mod.contains(TypeModifier::Shared));
assert_eq!(identifier, "foo");
assert_eq!(inherits.len(), 0);
assert_eq!(statements.len(), 0);
} else {
unreachable!()
}
} else {
unreachable!();
}
}
#[test]
fn test_interface_with_virtprop() {
let script = parse(
create_tokens(vec![
TokenType::InterfaceKeyword,
TokenType::WhiteSpace,
TokenType::Identifier("foo".to_string()),
TokenType::WhiteSpace,
TokenType::OpenCurlyBracket,
TokenType::Identifier("bar".to_string()),
TokenType::Identifier("get_bar".to_string()),
TokenType::OpenCurlyBracket,
TokenType::GetKeyword,
TokenType::Semicolon,
TokenType::SetKeyword,
TokenType::Semicolon,
TokenType::CloseCurlyBracket,
TokenType::CloseCurlyBracket,
TokenType::EndOfFile,
]),
&mut |_message, _span| {
std::panic::panic_any(_message.stringify());
},
);
if let ParsedStatement::Script { statements } = script.as_ref() {
assert_eq!(1, statements.len());
if let ParsedStatement::Interface {
type_mod,
identifier,
inherits,
statements,
} = &statements[0]
{
assert!(type_mod.is_empty());
assert_eq!(identifier, "foo");
assert_eq!(inherits.len(), 0);
assert_eq!(statements.len(), 1);
if let ParsedStatement::VirtProp {
field_mod,
property_type,
identifier,
is_handle,
has_get,
is_get_const,
get_statement,
has_set,
is_set_const,
set_statement,
} = &statements[0]
{
assert_eq!(*field_mod, BitFlags::empty());
if let ParsedStatement::Type {
is_const,
identifier,
..
} = property_type.as_ref()
{
assert!(!is_const);
assert_eq!(identifier, "bar");
} else {
unreachable!()
}
assert_eq!(identifier, "get_bar");
assert!(has_get);
assert!(!is_get_const);
assert!(has_set);
assert!(!is_set_const);
assert!(get_statement.is_none());
assert!(set_statement.is_none());
assert!(!is_handle);
} else {
unreachable!()
}
} else {
unreachable!()
}
} else {
unreachable!();
}
}