From 802d356a35232e78635098563604d21df3aa3ddc Mon Sep 17 00:00:00 2001 From: Eugene Rossokha Date: Wed, 20 Dec 2023 00:00:07 +0200 Subject: [PATCH] Pull out codegen tests into a separate module --- backend/src/codegen.rs | 367 ---------------------------------- backend/src/codegen_tests.rs | 368 +++++++++++++++++++++++++++++++++++ backend/src/lib.rs | 3 + 3 files changed, 371 insertions(+), 367 deletions(-) create mode 100644 backend/src/codegen_tests.rs diff --git a/backend/src/codegen.rs b/backend/src/codegen.rs index db507a1..d51cc93 100644 --- a/backend/src/codegen.rs +++ b/backend/src/codegen.rs @@ -303,370 +303,3 @@ impl Emit 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;") -} diff --git a/backend/src/codegen_tests.rs b/backend/src/codegen_tests.rs new file mode 100644 index 0000000..af0f480 --- /dev/null +++ b/backend/src/codegen_tests.rs @@ -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;") +} diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 24ccbdd..015365e 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -1 +1,4 @@ pub mod codegen; + +#[cfg(test)] +mod codegen_tests;