Pull out codegen tests into a separate module

This commit is contained in:
Eugene Rossokha
2023-12-20 00:00:07 +02:00
parent 912815bac3
commit 802d356a35
3 changed files with 371 additions and 367 deletions
-367
View File
@@ -303,370 +303,3 @@ impl<W: Write> Emit<W> for Expression {
} }
} }
} }
#[test]
fn null_emit() {
let null = Expression::Null;
let mut res = String::new();
null.emit(&mut res).unwrap();
assert_eq!(res, "null")
}
#[test]
fn undefined_emit() {
let undefined = Expression::Undefined;
let mut res = String::new();
undefined.emit(&mut res).unwrap();
assert_eq!(res, "undefined")
}
#[test]
fn true_emit() {
let true_ = Expression::Bool(true);
let mut res = String::new();
true_.emit(&mut res).unwrap();
assert_eq!(res, "true")
}
#[test]
fn false_emit() {
let false_ = Expression::Bool(false);
let mut res = String::new();
false_.emit(&mut res).unwrap();
assert_eq!(res, "false")
}
#[test]
fn number_emit() {
let one = Expression::Number(1.0);
let mut res = String::new();
one.emit(&mut res).unwrap();
assert_eq!(res, "1")
}
#[test]
fn negative_number_emit() {
let maybe_one = Expression::Number(-1.5);
let mut res = String::new();
maybe_one.emit(&mut res).unwrap();
assert_eq!(res, "-1.5")
}
#[test]
fn string_emit() {
let string = Expression::String("test".to_owned());
let mut res = String::new();
string.emit(&mut res).unwrap();
assert_eq!(res, "\"test\"")
}
#[test]
fn reference_emit() {
let string = Expression::Reference("x".to_owned());
let mut res = String::new();
string.emit(&mut res).unwrap();
assert_eq!(res, "x")
}
#[test]
fn empty_array_emit() {
let array = Expression::Array(Vec::new());
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[]")
}
#[test]
fn one_elem_array_emit() {
let array = Expression::Array(vec![Expression::Null]);
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[null]")
}
#[test]
fn two_elems_array_emit() {
let array = Expression::Array(vec![Expression::Null, Expression::Undefined]);
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[null, undefined]")
}
#[test]
fn empty_object_emit() {
let object = Expression::Object(Vec::new());
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{}")
}
#[test]
fn one_elem_object_emit() {
let object = Expression::Object(vec![("x".to_owned(), Expression::Null)]);
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{\"x\": null}")
}
#[test]
fn two_elems_object_emit() {
let object = Expression::Object(vec![
("x".to_owned(), Expression::Null),
("y as z".to_owned(), Expression::Undefined),
]);
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{\"x\": null, \"y as z\": undefined}")
}
#[test]
fn unary_plus_emit() {
let unary = Expression::Unary("+".to_owned(), Box::new(Expression::Null));
let mut res = String::new();
unary.emit(&mut res).unwrap();
assert_eq!(res, "(+ null)")
}
#[test]
fn unary_plus_plus_emit() {
let unary = Expression::Unary("++".to_owned(), Box::new(Expression::Null));
let mut res = String::new();
unary.emit(&mut res).unwrap();
assert_eq!(res, "(null ++)")
}
#[test]
fn binary_plus_emit() {
let binary = Expression::Binary(
"+".to_owned(),
Box::new(Expression::Null),
Box::new(Expression::Undefined),
);
let mut res = String::new();
binary.emit(&mut res).unwrap();
assert_eq!(res, "(null + undefined)")
}
#[test]
fn ternary_emit() {
let ternary = Expression::Ternary(
Box::new(Expression::Bool(true)),
Box::new(Expression::Null),
Box::new(Expression::Undefined),
);
let mut res = String::new();
ternary.emit(&mut res).unwrap();
assert_eq!(res, "(true ? null : undefined)")
}
#[test]
fn empty_lambda_emit() {
let lambda = Expression::Lambda {
args: Vec::new(),
body: Vec::new(),
is_async: false,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "() => {}")
}
#[test]
fn empty_async_lambda_emit() {
let lambda = Expression::Lambda {
args: Vec::new(),
body: Vec::new(),
is_async: true,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "async () => {}")
}
#[test]
fn id_lambda_emit() {
let lambda = Expression::Lambda {
args: vec!["x".to_owned()],
body: vec![Statement::Expression(Expression::Reference("x".to_owned()))],
is_async: false,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "(x) => {x}")
}
#[test]
fn return_emit() {
let ret = Statement::Return(Expression::Null);
let mut res = String::new();
ret.emit(&mut res).unwrap();
assert_eq!(res, "return null")
}
#[test]
fn let_declaration_emit() {
let decl = Statement::Declaration {
is_const: false,
is_exported: false,
name: "x".to_owned(),
initial: None,
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "let x")
}
#[test]
fn export_declaration_emit() {
let decl = Statement::Declaration {
is_const: false,
is_exported: true,
name: "x".to_owned(),
initial: None,
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "export let x")
}
#[test]
fn const_declaration_emit() {
let decl = Statement::Declaration {
is_const: true,
is_exported: false,
name: "x".to_owned(),
initial: Some(Expression::Null),
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "const x = null")
}
#[test]
fn throw_emit() {
let throw = Statement::Throw(Expression::Null);
let mut res = String::new();
throw.emit(&mut res).unwrap();
assert_eq!(res, "throw null")
}
#[test]
fn empty_try_emit() {
let try_ = Statement::Try {
body: Vec::new(),
catch_: None,
finally: None,
};
let mut res = String::new();
try_.emit(&mut res).unwrap();
assert_eq!(res, "try {}")
}
#[test]
fn try_emit() {
let try_ = Statement::Try {
body: vec![Statement::Expression(Expression::Null)],
catch_: Some((
"e".to_owned(),
vec![Statement::Expression(Expression::Undefined)],
)),
finally: Some(vec![Statement::Expression(Expression::Null)]),
};
let mut res = String::new();
try_.emit(&mut res).unwrap();
assert_eq!(res, "try {null} catch (e) {undefined} finally {null}")
}
#[test]
fn empty_for_emit() {
let for_ = Statement::For {
init: None,
condition: None,
update: None,
body: Vec::new(),
};
let mut res = String::new();
for_.emit(&mut res).unwrap();
assert_eq!(res, "for (; ; ) {}")
}
#[test]
fn for_emit() {
let for_ = Statement::For {
init: Some(Expression::Null),
condition: Some(Expression::Bool(true)),
update: Some(Expression::Null),
body: vec![Statement::Expression(Expression::Null)],
};
let mut res = String::new();
for_.emit(&mut res).unwrap();
assert_eq!(res, "for (null; true; null) {null}")
}
#[test]
fn empty_while_emit() {
let while_ = Statement::While {
condition: Expression::Bool(true),
body: Vec::new(),
};
let mut res = String::new();
while_.emit(&mut res).unwrap();
assert_eq!(res, "while (true) {}")
}
#[test]
fn while_emit() {
let while_ = Statement::While {
condition: Expression::Bool(true),
body: vec![Statement::Expression(Expression::Null)],
};
let mut res = String::new();
while_.emit(&mut res).unwrap();
assert_eq!(res, "while (true) {null}")
}
#[test]
fn empty_if_emit() {
let if_ = Statement::If {
condition: Expression::Bool(true),
then_: Vec::new(),
else_: None,
};
let mut res = String::new();
if_.emit(&mut res).unwrap();
assert_eq!(res, "if (true) {}")
}
#[test]
fn if_emit() {
let if_ = Statement::If {
condition: Expression::Bool(true),
then_: vec![Statement::Expression(Expression::Null)],
else_: Some(vec![Statement::Expression(Expression::Undefined)]),
};
let mut res = String::new();
if_.emit(&mut res).unwrap();
assert_eq!(res, "if (true) {null} else {undefined}")
}
#[test]
fn empty_import_emit() {
let import = Statement::Import {
names: Vec::new(),
from: "x".to_owned(),
};
let mut res = String::new();
import.emit(&mut res).unwrap();
assert_eq!(res, "import {} from x;")
}
#[test]
fn import_emit() {
let import = Statement::Import {
names: vec!["x".to_owned(), "y".to_owned()],
from: "z".to_owned(),
};
let mut res = String::new();
import.emit(&mut res).unwrap();
assert_eq!(res, "import {x, y} from z;")
}
+368
View File
@@ -0,0 +1,368 @@
use crate::codegen::{Emit, Expression, Statement};
#[test]
fn null_emit() {
let null = Expression::Null;
let mut res = String::new();
null.emit(&mut res).unwrap();
assert_eq!(res, "null")
}
#[test]
fn undefined_emit() {
let undefined = Expression::Undefined;
let mut res = String::new();
undefined.emit(&mut res).unwrap();
assert_eq!(res, "undefined")
}
#[test]
fn true_emit() {
let true_ = Expression::Bool(true);
let mut res = String::new();
true_.emit(&mut res).unwrap();
assert_eq!(res, "true")
}
#[test]
fn false_emit() {
let false_ = Expression::Bool(false);
let mut res = String::new();
false_.emit(&mut res).unwrap();
assert_eq!(res, "false")
}
#[test]
fn number_emit() {
let one = Expression::Number(1.0);
let mut res = String::new();
one.emit(&mut res).unwrap();
assert_eq!(res, "1")
}
#[test]
fn negative_number_emit() {
let maybe_one = Expression::Number(-1.5);
let mut res = String::new();
maybe_one.emit(&mut res).unwrap();
assert_eq!(res, "-1.5")
}
#[test]
fn string_emit() {
let string = Expression::String("test".to_owned());
let mut res = String::new();
string.emit(&mut res).unwrap();
assert_eq!(res, "\"test\"")
}
#[test]
fn reference_emit() {
let string = Expression::Reference("x".to_owned());
let mut res = String::new();
string.emit(&mut res).unwrap();
assert_eq!(res, "x")
}
#[test]
fn empty_array_emit() {
let array = Expression::Array(Vec::new());
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[]")
}
#[test]
fn one_elem_array_emit() {
let array = Expression::Array(vec![Expression::Null]);
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[null]")
}
#[test]
fn two_elems_array_emit() {
let array = Expression::Array(vec![Expression::Null, Expression::Undefined]);
let mut res = String::new();
array.emit(&mut res).unwrap();
assert_eq!(res, "[null, undefined]")
}
#[test]
fn empty_object_emit() {
let object = Expression::Object(Vec::new());
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{}")
}
#[test]
fn one_elem_object_emit() {
let object = Expression::Object(vec![("x".to_owned(), Expression::Null)]);
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{\"x\": null}")
}
#[test]
fn two_elems_object_emit() {
let object = Expression::Object(vec![
("x".to_owned(), Expression::Null),
("y as z".to_owned(), Expression::Undefined),
]);
let mut res = String::new();
object.emit(&mut res).unwrap();
assert_eq!(res, "{\"x\": null, \"y as z\": undefined}")
}
#[test]
fn unary_plus_emit() {
let unary = Expression::Unary("+".to_owned(), Box::new(Expression::Null));
let mut res = String::new();
unary.emit(&mut res).unwrap();
assert_eq!(res, "(+ null)")
}
#[test]
fn unary_plus_plus_emit() {
let unary = Expression::Unary("++".to_owned(), Box::new(Expression::Null));
let mut res = String::new();
unary.emit(&mut res).unwrap();
assert_eq!(res, "(null ++)")
}
#[test]
fn binary_plus_emit() {
let binary = Expression::Binary(
"+".to_owned(),
Box::new(Expression::Null),
Box::new(Expression::Undefined),
);
let mut res = String::new();
binary.emit(&mut res).unwrap();
assert_eq!(res, "(null + undefined)")
}
#[test]
fn ternary_emit() {
let ternary = Expression::Ternary(
Box::new(Expression::Bool(true)),
Box::new(Expression::Null),
Box::new(Expression::Undefined),
);
let mut res = String::new();
ternary.emit(&mut res).unwrap();
assert_eq!(res, "(true ? null : undefined)")
}
#[test]
fn empty_lambda_emit() {
let lambda = Expression::Lambda {
args: Vec::new(),
body: Vec::new(),
is_async: false,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "() => {}")
}
#[test]
fn empty_async_lambda_emit() {
let lambda = Expression::Lambda {
args: Vec::new(),
body: Vec::new(),
is_async: true,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "async () => {}")
}
#[test]
fn id_lambda_emit() {
let lambda = Expression::Lambda {
args: vec!["x".to_owned()],
body: vec![Statement::Expression(Expression::Reference("x".to_owned()))],
is_async: false,
};
let mut res = String::new();
lambda.emit(&mut res).unwrap();
assert_eq!(res, "(x) => {x}")
}
#[test]
fn return_emit() {
let ret = Statement::Return(Expression::Null);
let mut res = String::new();
ret.emit(&mut res).unwrap();
assert_eq!(res, "return null")
}
#[test]
fn let_declaration_emit() {
let decl = Statement::Declaration {
is_const: false,
is_exported: false,
name: "x".to_owned(),
initial: None,
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "let x")
}
#[test]
fn export_declaration_emit() {
let decl = Statement::Declaration {
is_const: false,
is_exported: true,
name: "x".to_owned(),
initial: None,
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "export let x")
}
#[test]
fn const_declaration_emit() {
let decl = Statement::Declaration {
is_const: true,
is_exported: false,
name: "x".to_owned(),
initial: Some(Expression::Null),
};
let mut res = String::new();
decl.emit(&mut res).unwrap();
assert_eq!(res, "const x = null")
}
#[test]
fn throw_emit() {
let throw = Statement::Throw(Expression::Null);
let mut res = String::new();
throw.emit(&mut res).unwrap();
assert_eq!(res, "throw null")
}
#[test]
fn empty_try_emit() {
let try_ = Statement::Try {
body: Vec::new(),
catch_: None,
finally: None,
};
let mut res = String::new();
try_.emit(&mut res).unwrap();
assert_eq!(res, "try {}")
}
#[test]
fn try_emit() {
let try_ = Statement::Try {
body: vec![Statement::Expression(Expression::Null)],
catch_: Some((
"e".to_owned(),
vec![Statement::Expression(Expression::Undefined)],
)),
finally: Some(vec![Statement::Expression(Expression::Null)]),
};
let mut res = String::new();
try_.emit(&mut res).unwrap();
assert_eq!(res, "try {null} catch (e) {undefined} finally {null}")
}
#[test]
fn empty_for_emit() {
let for_ = Statement::For {
init: None,
condition: None,
update: None,
body: Vec::new(),
};
let mut res = String::new();
for_.emit(&mut res).unwrap();
assert_eq!(res, "for (; ; ) {}")
}
#[test]
fn for_emit() {
let for_ = Statement::For {
init: Some(Expression::Null),
condition: Some(Expression::Bool(true)),
update: Some(Expression::Null),
body: vec![Statement::Expression(Expression::Null)],
};
let mut res = String::new();
for_.emit(&mut res).unwrap();
assert_eq!(res, "for (null; true; null) {null}")
}
#[test]
fn empty_while_emit() {
let while_ = Statement::While {
condition: Expression::Bool(true),
body: Vec::new(),
};
let mut res = String::new();
while_.emit(&mut res).unwrap();
assert_eq!(res, "while (true) {}")
}
#[test]
fn while_emit() {
let while_ = Statement::While {
condition: Expression::Bool(true),
body: vec![Statement::Expression(Expression::Null)],
};
let mut res = String::new();
while_.emit(&mut res).unwrap();
assert_eq!(res, "while (true) {null}")
}
#[test]
fn empty_if_emit() {
let if_ = Statement::If {
condition: Expression::Bool(true),
then_: Vec::new(),
else_: None,
};
let mut res = String::new();
if_.emit(&mut res).unwrap();
assert_eq!(res, "if (true) {}")
}
#[test]
fn if_emit() {
let if_ = Statement::If {
condition: Expression::Bool(true),
then_: vec![Statement::Expression(Expression::Null)],
else_: Some(vec![Statement::Expression(Expression::Undefined)]),
};
let mut res = String::new();
if_.emit(&mut res).unwrap();
assert_eq!(res, "if (true) {null} else {undefined}")
}
#[test]
fn empty_import_emit() {
let import = Statement::Import {
names: Vec::new(),
from: "x".to_owned(),
};
let mut res = String::new();
import.emit(&mut res).unwrap();
assert_eq!(res, "import {} from x;")
}
#[test]
fn import_emit() {
let import = Statement::Import {
names: vec!["x".to_owned(), "y".to_owned()],
from: "z".to_owned(),
};
let mut res = String::new();
import.emit(&mut res).unwrap();
assert_eq!(res, "import {x, y} from z;")
}
+3
View File
@@ -1 +1,4 @@
pub mod codegen; pub mod codegen;
#[cfg(test)]
mod codegen_tests;