diff --git a/src/engine.rs b/src/engine.rs index 5bb26d2c..c4c68b87 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1314,405 +1314,3 @@ impl Engine { engine } } - - -#[test] -fn test_number_literal() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("65") { - assert_eq!(result, 65); - } else { - assert!(false); - } -} - -#[test] -fn test_chars() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("'y'") { - assert_eq!(result, 'y'); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("'\\u2764'") { - assert_eq!(result, '❤'); - } else { - assert!(false); - } - - match engine.eval::("''") { - Err(_) => (), - _ => assert!(false), - } -} - -#[test] -fn test_ops() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("60 + 5") { - assert_eq!(result, 65); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("(1 + 2) * (6 - 4) / 2") { - assert_eq!(result, 3); - } else { - assert!(false); - } -} - -#[test] -fn test_mismatched_op() { - let mut engine = Engine::new(); - - match engine.eval::("60 + \"hello\"") { - Err(EvalAltResult::ErrorFunctionArgMismatch) => (), - _ => assert!(false), - } -} - -#[test] -fn test_bool_op1() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("true && (false || true)") { - assert_eq!(result, true); - } else { - assert!(false); - } -} - -#[test] -fn test_bool_op2() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("false && (false || true)") { - assert_eq!(result, false); - } else { - assert!(false); - } -} - -#[test] -fn test_op_prec() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("let x = 0; if x == 10 || true { x = 1} x") { - assert_eq!(result, 1); - } else { - assert!(false); - } -} - -#[test] -fn test_if() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("if true { 55 }") { - assert_eq!(result, 55); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("if false { 55 } else { 44 }") { - assert_eq!(result, 44); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("if true { 55 } else { 44 }") { - assert_eq!(result, 55); - } else { - assert!(false); - } -} - -#[test] -fn test_while() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("let x = 0; while x < 10 { x = x + 1; if x > 5 { \ - break } } x") { - assert_eq!(result, 6); - } else { - assert!(false); - } -} - -#[test] -fn test_var_scope() { - let mut engine = Engine::new(); - let mut scope: Scope = Vec::new(); - - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5") { - } else { - assert!(false); - } - - if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { - assert_eq!(result, 9); - } else { - assert!(false); - } - - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "x = x + 1; x = x + 2;") { - } else { - assert!(false); - } - - if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { - assert_eq!(result, 12); - } else { - assert!(false); - } - - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "{let x = 3}") { - } else { - assert!(false); - } - - if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { - assert_eq!(result, 12); - } else { - assert!(false); - } -} - -#[test] -fn test_method_call() { - #[derive(Clone)] - struct TestStruct { - x: i64, - } - - impl TestStruct { - fn update(&mut self) { - self.x += 1000; - } - - fn new() -> TestStruct { - TestStruct { x: 1 } - } - } - - let mut engine = Engine::new(); - - engine.register_type::(); - - engine.register_fn("update", TestStruct::update); - engine.register_fn("new_ts", TestStruct::new); - - if let Ok(result) = engine.eval::("let x = new_ts(); x.update(); x") { - assert_eq!(result.x, 1001); - } else { - assert!(false); - } - -} - -#[test] -fn test_get_set() { - #[derive(Clone)] - struct TestStruct { - x: i64, - } - - impl TestStruct { - fn get_x(&mut self) -> i64 { - self.x - } - - fn set_x(&mut self, new_x: i64) { - self.x = new_x; - } - - fn new() -> TestStruct { - TestStruct { x: 1 } - } - } - - let mut engine = Engine::new(); - - engine.register_type::(); - - engine.register_get_set("x", TestStruct::get_x, TestStruct::set_x); - engine.register_fn("new_ts", TestStruct::new); - - if let Ok(result) = engine.eval::("let a = new_ts(); a.x = 500; a.x") { - assert_eq!(result, 500); - } else { - assert!(false); - } -} - -#[test] -fn test_big_get_set() { - #[derive(Clone)] - struct TestChild { - x: i64, - } - - impl TestChild { - fn get_x(&mut self) -> i64 { - self.x - } - - fn set_x(&mut self, new_x: i64) { - self.x = new_x; - } - - fn new() -> TestChild { - TestChild { x: 1 } - } - } - - #[derive(Clone)] - struct TestParent { - child: TestChild, - } - - impl TestParent { - fn get_child(&mut self) -> TestChild { - self.child.clone() - } - - fn set_child(&mut self, new_child: TestChild) { - self.child = new_child; - } - - fn new() -> TestParent { - TestParent { child: TestChild::new() } - } - } - - let mut engine = Engine::new(); - - engine.register_type::(); - engine.register_type::(); - - engine.register_get_set("x", TestChild::get_x, TestChild::set_x); - engine.register_get_set("child", TestParent::get_child, TestParent::set_child); - - engine.register_fn("new_tp", TestParent::new); - - if let Ok(result) = engine.eval::("let a = new_tp(); a.child.x = 500; a.child.x") { - assert_eq!(result, 500); - } else { - assert!(false); - } -} - -#[test] -fn test_internal_fn() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("fn addme(a, b) { a+b } addme(3, 4)") { - assert_eq!(result, 7); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("fn bob() { return 4; 5 } bob()") { - assert_eq!(result, 4); - } else { - assert!(false); - } -} - -#[test] -fn test_big_internal_fn() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f \ - } mathme(100, 5, 2, 9, 6, 32)") { - assert_eq!(result, 112); - } else { - assert!(false); - } -} - -#[test] -fn test_string() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("\"Test string: \\u2764\"") { - assert_eq!(result, "Test string: ❤"); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("\"foo\" + \"bar\"") { - assert_eq!(result, "foobar"); - } else { - assert!(false); - } -} - -#[test] -fn test_arrays() { - let mut engine = Engine::new(); - - if let Ok(result) = engine.eval::("let x = [1, 2, 3]; x[1]") { - assert_eq!(result, 2); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("let y = [1, 2, 3]; y[1] = 5; y[1]") { - assert_eq!(result, 5); - } else { - assert!(false); - } -} - -#[test] -fn test_array_with_structs() { - #[derive(Clone)] - struct TestStruct { - x: i64, - } - - impl TestStruct { - fn update(&mut self) { - self.x += 1000; - } - - fn get_x(&mut self) -> i64 { - self.x - } - - fn set_x(&mut self, new_x: i64) { - self.x = new_x; - } - - fn new() -> TestStruct { - TestStruct { x: 1 } - } - } - - let mut engine = Engine::new(); - - engine.register_type::(); - - engine.register_get_set("x", TestStruct::get_x, TestStruct::set_x); - engine.register_fn("update", TestStruct::update); - engine.register_fn("new_ts", TestStruct::new); - - if let Ok(result) = engine.eval::("let a = [new_ts()]; a[0].x") { - assert_eq!(result, 1); - } else { - assert!(false); - } - - if let Ok(result) = engine.eval::("let a = [new_ts()]; a[0].x = 100; a[0].update(); \ - a[0].x") { - assert_eq!(result, 1100); - } else { - assert!(false); - } -} diff --git a/src/lib.rs b/src/lib.rs index 1dbf3a78..0b9cc5ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,5 +11,8 @@ mod engine; mod fn_register; mod parser; +#[cfg(test)] +mod tests; + pub use engine::{Engine, Scope}; pub use fn_register::FnRegister; diff --git a/src/tests.rs b/src/tests.rs new file mode 100644 index 00000000..dffed5d7 --- /dev/null +++ b/src/tests.rs @@ -0,0 +1,400 @@ +#[test] +fn test_number_literal() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("65") { + assert_eq!(result, 65); + } else { + assert!(false); + } +} + +#[test] +fn test_chars() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("'y'") { + assert_eq!(result, 'y'); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("'\\u2764'") { + assert_eq!(result, '❤'); + } else { + assert!(false); + } + + match engine.eval::("''") { + Err(_) => (), + _ => assert!(false), + } +} + +#[test] +fn test_ops() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("60 + 5") { + assert_eq!(result, 65); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("(1 + 2) * (6 - 4) / 2") { + assert_eq!(result, 3); + } else { + assert!(false); + } +} + +#[test] +fn test_mismatched_op() { + let mut engine = Engine::new(); + + match engine.eval::("60 + \"hello\"") { + Err(EvalAltResult::ErrorFunctionArgMismatch) => (), + _ => assert!(false), + } +} + +#[test] +fn test_bool_op1() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("true && (false || true)") { + assert_eq!(result, true); + } else { + assert!(false); + } +} + +#[test] +fn test_bool_op2() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("false && (false || true)") { + assert_eq!(result, false); + } else { + assert!(false); + } +} + +#[test] +fn test_op_prec() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = 0; if x == 10 || true { x = 1} x") { + assert_eq!(result, 1); + } else { + assert!(false); + } +} + +#[test] +fn test_if() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("if true { 55 }") { + assert_eq!(result, 55); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("if false { 55 } else { 44 }") { + assert_eq!(result, 44); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("if true { 55 } else { 44 }") { + assert_eq!(result, 55); + } else { + assert!(false); + } +} + +#[test] +fn test_while() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = 0; while x < 10 { x = x + 1; if x > 5 { \ + break } } x") { + assert_eq!(result, 6); + } else { + assert!(false); + } +} + +#[test] +fn test_var_scope() { + let mut engine = Engine::new(); + let mut scope: Scope = Vec::new(); + + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5") { + } else { + assert!(false); + } + + if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { + assert_eq!(result, 9); + } else { + assert!(false); + } + + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "x = x + 1; x = x + 2;") { + } else { + assert!(false); + } + + if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { + assert_eq!(result, 12); + } else { + assert!(false); + } + + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "{let x = 3}") { + } else { + assert!(false); + } + + if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { + assert_eq!(result, 12); + } else { + assert!(false); + } +} + +#[test] +fn test_method_call() { + #[derive(Clone)] + struct TestStruct { + x: i64, + } + + impl TestStruct { + fn update(&mut self) { + self.x += 1000; + } + + fn new() -> TestStruct { + TestStruct { x: 1 } + } + } + + let mut engine = Engine::new(); + + engine.register_type::(); + + engine.register_fn("update", TestStruct::update); + engine.register_fn("new_ts", TestStruct::new); + + if let Ok(result) = engine.eval::("let x = new_ts(); x.update(); x") { + assert_eq!(result.x, 1001); + } else { + assert!(false); + } + +} + +#[test] +fn test_get_set() { + #[derive(Clone)] + struct TestStruct { + x: i64, + } + + impl TestStruct { + fn get_x(&mut self) -> i64 { + self.x + } + + fn set_x(&mut self, new_x: i64) { + self.x = new_x; + } + + fn new() -> TestStruct { + TestStruct { x: 1 } + } + } + + let mut engine = Engine::new(); + + engine.register_type::(); + + engine.register_get_set("x", TestStruct::get_x, TestStruct::set_x); + engine.register_fn("new_ts", TestStruct::new); + + if let Ok(result) = engine.eval::("let a = new_ts(); a.x = 500; a.x") { + assert_eq!(result, 500); + } else { + assert!(false); + } +} + +#[test] +fn test_big_get_set() { + #[derive(Clone)] + struct TestChild { + x: i64, + } + + impl TestChild { + fn get_x(&mut self) -> i64 { + self.x + } + + fn set_x(&mut self, new_x: i64) { + self.x = new_x; + } + + fn new() -> TestChild { + TestChild { x: 1 } + } + } + + #[derive(Clone)] + struct TestParent { + child: TestChild, + } + + impl TestParent { + fn get_child(&mut self) -> TestChild { + self.child.clone() + } + + fn set_child(&mut self, new_child: TestChild) { + self.child = new_child; + } + + fn new() -> TestParent { + TestParent { child: TestChild::new() } + } + } + + let mut engine = Engine::new(); + + engine.register_type::(); + engine.register_type::(); + + engine.register_get_set("x", TestChild::get_x, TestChild::set_x); + engine.register_get_set("child", TestParent::get_child, TestParent::set_child); + + engine.register_fn("new_tp", TestParent::new); + + if let Ok(result) = engine.eval::("let a = new_tp(); a.child.x = 500; a.child.x") { + assert_eq!(result, 500); + } else { + assert!(false); + } +} + +#[test] +fn test_internal_fn() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("fn addme(a, b) { a+b } addme(3, 4)") { + assert_eq!(result, 7); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("fn bob() { return 4; 5 } bob()") { + assert_eq!(result, 4); + } else { + assert!(false); + } +} + +#[test] +fn test_big_internal_fn() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f \ + } mathme(100, 5, 2, 9, 6, 32)") { + assert_eq!(result, 112); + } else { + assert!(false); + } +} + +#[test] +fn test_string() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("\"Test string: \\u2764\"") { + assert_eq!(result, "Test string: ❤"); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("\"foo\" + \"bar\"") { + assert_eq!(result, "foobar"); + } else { + assert!(false); + } +} + +#[test] +fn test_arrays() { + let mut engine = Engine::new(); + + if let Ok(result) = engine.eval::("let x = [1, 2, 3]; x[1]") { + assert_eq!(result, 2); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("let y = [1, 2, 3]; y[1] = 5; y[1]") { + assert_eq!(result, 5); + } else { + assert!(false); + } +} + +#[test] +fn test_array_with_structs() { + #[derive(Clone)] + struct TestStruct { + x: i64, + } + + impl TestStruct { + fn update(&mut self) { + self.x += 1000; + } + + fn get_x(&mut self) -> i64 { + self.x + } + + fn set_x(&mut self, new_x: i64) { + self.x = new_x; + } + + fn new() -> TestStruct { + TestStruct { x: 1 } + } + } + + let mut engine = Engine::new(); + + engine.register_type::(); + + engine.register_get_set("x", TestStruct::get_x, TestStruct::set_x); + engine.register_fn("update", TestStruct::update); + engine.register_fn("new_ts", TestStruct::new); + + if let Ok(result) = engine.eval::("let a = [new_ts()]; a[0].x") { + assert_eq!(result, 1); + } else { + assert!(false); + } + + if let Ok(result) = engine.eval::("let a = [new_ts()]; a[0].x = 100; a[0].update(); \ + a[0].x") { + assert_eq!(result, 1100); + } else { + assert!(false); + } +}