From 18752672d0d12e6269ab24202ac823fd116513d4 Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 31 Jul 2021 08:02:16 +1200 Subject: [PATCH] add more tests --- Cargo.toml | 8 +++++- src/main.rs | 46 ++++++++++++++++++++--------------- src/tests.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++ src/type_check.rs | 12 +++++++++ 4 files changed, 108 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a0a1c6310f..88c3a832a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,10 @@ edition = "2018" [dependencies] reedline = {git = "https://github.com/jntrnr/reedline"} -nu-ansi-term = "0.32.0" \ No newline at end of file +nu-ansi-term = "0.32.0" +# mimalloc = { version = "*", default-features = false } + +[dev-dependencies] +tempfile = "3.2.0" +assert_cmd = "1.0.7" +pretty_assertions = "0.7.2" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 11ba59ecd2..48258983cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -117,24 +117,28 @@ fn main() -> std::io::Result<()> { let file = std::fs::read(&path)?; - let (block, _err) = working_set.parse_file(&path, &file, false); - println!("{}", block.len()); - // println!("{:#?}", output); - // println!("error: {:?}", err); + let (block, err) = working_set.parse_file(&path, &file, false); - //println!("working set: {:#?}", working_set); + if let Some(err) = err { + eprintln!("Error: {:?}", err); + std::process::exit(1); + } - // println!("{}", size_of::()); + let state = State { + parser_state: &*parser_state, + }; - // let engine = Engine::new(); - // let result = engine.eval_block(&output); - // println!("{:?}", result); + let stack = Stack::new(); - // let mut buffer = String::new(); - // let stdin = std::io::stdin(); - // let mut handle = stdin.lock(); - - // handle.read_to_string(&mut buffer)?; + match eval_block(&state, stack, &block) { + Ok(value) => { + println!("{}", value); + } + Err(err) => { + eprintln!("Error: {:?}", err); + std::process::exit(1); + } + } Ok(()) } else { @@ -181,12 +185,10 @@ fn main() -> std::io::Result<()> { s.as_bytes(), false, ); - println!("{:?}", output); if let Some(err) = err { println!("Error: {:?}", err); - continue; + break; } - println!("Error: {:?}", err); (output, working_set.render()) }; @@ -196,8 +198,14 @@ fn main() -> std::io::Result<()> { parser_state: &*parser_state.borrow(), }; - let output = eval_block(&state, stack.clone(), &block); - println!("{:#?}", output); + match eval_block(&state, stack.clone(), &block) { + Ok(value) => { + println!("{}", value); + } + Err(err) => { + println!("Error: {:?}", err); + } + } } Signal::CtrlC => { println!("Ctrl-c"); diff --git a/src/tests.rs b/src/tests.rs index 8b13789179..49e7cdbc26 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1 +1,63 @@ +use assert_cmd::prelude::*; +use pretty_assertions::assert_eq; +use std::io::Write; +use std::process::Command; +use tempfile::NamedTempFile; +type TestResult = Result<(), Box>; + +#[cfg(test)] +fn run_test(input: &str, expected: &str) -> TestResult { + let mut file = NamedTempFile::new()?; + let name = file.path(); + + let mut cmd = Command::cargo_bin("engine-q")?; + cmd.arg(name); + + writeln!(file, "{}", input)?; + + let output = cmd.output()?; + + assert!(output.status.success()); + + let output = String::from_utf8_lossy(&output.stdout).to_string(); + + assert_eq!(output.trim(), expected); + + Ok(()) +} + +#[cfg(test)] +fn fail_test(input: &str, expected: &str) -> TestResult { + let mut file = NamedTempFile::new()?; + let name = file.path(); + + let mut cmd = Command::cargo_bin("engine-q")?; + cmd.arg(name); + + writeln!(file, "{}", input)?; + + let output = cmd.output()?; + + let output = String::from_utf8_lossy(&output.stderr).to_string(); + + assert!(output.contains("Error:")); + assert!(output.contains(expected)); + + Ok(()) +} + +#[test] +fn add_simple() -> TestResult { + run_test("3 + 4", "7") +} + +#[test] +fn add_simple2() -> TestResult { + run_test("3 + 4 + 9", "16") +} + +#[test] +fn broken_math() -> TestResult { + fail_test("3 + ", "Incomplete") +} diff --git a/src/type_check.rs b/src/type_check.rs index c01ad01710..524a58b95b 100644 --- a/src/type_check.rs +++ b/src/type_check.rs @@ -9,6 +9,18 @@ impl<'a> ParserWorkingSet<'a> { ) -> (Type, Option) { match &op.expr { Expr::Operator(operator) => match operator { + Operator::Multiply => match (&lhs.ty, &rhs.ty) { + (Type::Int, Type::Int) => (Type::Int, None), + (Type::Unknown, _) => (Type::Unknown, None), + (_, Type::Unknown) => (Type::Unknown, None), + _ => { + *op = Expression::garbage(op.span); + ( + Type::Unknown, + Some(ParseError::Mismatch("math".into(), op.span)), + ) + } + }, Operator::Plus => match (&lhs.ty, &rhs.ty) { (Type::Int, Type::Int) => (Type::Int, None), (Type::String, Type::String) => (Type::String, None),