Select Git revision
test_parser.rs
test_parser.rs 4.67 KiB
// This will also allow us to change all tests when syntax changes.
use erode::ast::*;
use erode::grammar::*;
#[test]
fn test_path() {
// path cannot be empty
assert!(PathParser::new().parse("").is_err());
// path cannot hold a singe Id
assert!(PathParser::new().parse("A").is_err());
// path Id::Id is ok
assert!(PathParser::new().parse("A::B_").is_ok());
println!("{:?}", PathParser::new().parse("A::B_"));
println!("{}", PathParser::new().parse("A::B_").unwrap());
}
#[test]
fn test_expr() {
// unary op
let expr = ExprParser::new().parse("- (+ 3)").unwrap();
assert_eq!(&format!("{}", expr), "(- (+ 3))");
let expr = ExprParser::new().parse("true").unwrap();
assert_eq!(*expr, Expr::Bool(true));
// ref
let expr = ExprParser::new().parse("& (1 + 2)").unwrap();
assert_eq!(&format!("{}", expr), "&(1 + 2)");
// mutable reference
assert!(ExprParser::new().parse("- *&mut 3 + 1 + 5").is_ok());
// convert as
assert!(ExprParser::new().parse("a as u32").is_ok());
// call in expression
assert!(ExprParser::new().parse("a(1,2,3)").is_ok());
// call in expression
assert!(ExprParser::new().parse("a(1,2,3,)").is_err());
}
#[test]
fn test_exprs() {
// comma separated expression sequence
assert!(ExprsParser::new().parse("(1, 2, a(1,2,3))").is_ok());
// comma separated expression sequence, is_err
assert!(ExprsParser::new().parse("1, 2, a(1,2,3),").is_err());
}
#[test]
fn test_stmts() {
// test empty sequence
assert!(BlockParser::new().parse("{}").is_ok());
// test let with no assignment and inferred type
assert!(BlockParser::new().parse("{ let a }").is_ok());
// test let with no assignment and excplicit type
assert!(BlockParser::new().parse("{ let a : u32 }").is_ok());
// test let with inferred type
assert!(BlockParser::new().parse("{ let a = 0 }").is_ok());
// test let with explicit type
assert!(BlockParser::new().parse("{ let a : u16 = 1 + 2 }").is_ok());
// test assignment
assert!(BlockParser::new().parse("{ a = 1 + 2 }").is_ok());
// test assignment
assert!(BlockParser::new().parse("{ *a = 1 + 2}").is_ok());
// test if then
assert!(BlockParser::new().parse("{ if a { b = 5 } }").is_ok());
// test if then else
assert!(BlockParser::new()
.parse("{ if a { b = 5 } else { b = 7 } }")
.is_ok());
// test hello
assert!(BlockParser::new()
.parse("{ while hello(b) { b = b - 5 } }")
.is_ok());
}
#[test]
fn test_fn_explicit_return_type() {
// test FnDecl with explicit return value
assert!(FnDeclParser::new().parse("fn main() -> u32 {}").is_ok());
}
#[test]
fn test_fn_no_arg_implicit_return_type() {
// test FnDecl with explicit return value
assert!(FnDeclParser::new().parse("fn main() {}").is_ok());
}
#[test]
fn test_fn_arg_implicit_return_type() {
// test FnDecl with explicit return value
assert!(FnDeclParser::new().parse("fn main(a:u32) {}").is_ok());
}
#[test]
fn test_fn_arg_explict_return_type() {
// test FnDecl with unit return value
assert!(FnDeclParser::new()
.parse("fn a(x:u8, y:u8) -> u8 {}")
.is_ok());
}
#[test]
fn test_fn_with_all_statements() {
// test FnDecl with unit return value
assert!(FnDeclParser::new()
.parse(
"
fn a(x:u8, y:u8) -> u8 {
let a;
let b = 5;
let mut a : u8 = 0;
let c : u8;
{
c = 5;
};
while true {
let v: u8 = 0;
}
}
"
)
.is_ok());
}
#[test]
fn test_types() {
assert!(TypeDeclParser::new()
.parse("struct A { x: u32, b: nisse }")
.is_ok());
assert!(TypeDeclParser::new()
.parse("enum Greetings { Hello, Goodbye(u32) }")
.is_ok());
}
#[test]
fn test_programs() {
// simple program with only main
assert!(ProgramParser::new().parse("fn main() {}").is_ok());
// program with multiple types and FnDecls
assert!(ProgramParser::new()
.parse(
"enum Stmt {
Let(String, id),
Plepps(u8),
Hej
}
fn main() {
hello = 7;
}
fn main() -> u8 {
hello(5);
if hello(7) {
let a = 5;
} else {
let b = 8;
}
}
enum Tjong {
Let(String, id),
Plepps(u8),
Hej
}
",
)
.is_ok());
}