add more tests

This commit is contained in:
JT 2021-07-31 08:02:16 +12:00
parent cdc37bb142
commit 18752672d0
4 changed files with 108 additions and 20 deletions

View File

@ -7,4 +7,10 @@ edition = "2018"
[dependencies] [dependencies]
reedline = {git = "https://github.com/jntrnr/reedline"} reedline = {git = "https://github.com/jntrnr/reedline"}
nu-ansi-term = "0.32.0" 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"

View File

@ -117,24 +117,28 @@ fn main() -> std::io::Result<()> {
let file = std::fs::read(&path)?; let file = std::fs::read(&path)?;
let (block, _err) = working_set.parse_file(&path, &file, false); let (block, err) = working_set.parse_file(&path, &file, false);
println!("{}", block.len());
// println!("{:#?}", output);
// println!("error: {:?}", err);
//println!("working set: {:#?}", working_set); if let Some(err) = err {
eprintln!("Error: {:?}", err);
std::process::exit(1);
}
// println!("{}", size_of::<Statement>()); let state = State {
parser_state: &*parser_state,
};
// let engine = Engine::new(); let stack = Stack::new();
// let result = engine.eval_block(&output);
// println!("{:?}", result);
// let mut buffer = String::new(); match eval_block(&state, stack, &block) {
// let stdin = std::io::stdin(); Ok(value) => {
// let mut handle = stdin.lock(); println!("{}", value);
}
// handle.read_to_string(&mut buffer)?; Err(err) => {
eprintln!("Error: {:?}", err);
std::process::exit(1);
}
}
Ok(()) Ok(())
} else { } else {
@ -181,12 +185,10 @@ fn main() -> std::io::Result<()> {
s.as_bytes(), s.as_bytes(),
false, false,
); );
println!("{:?}", output);
if let Some(err) = err { if let Some(err) = err {
println!("Error: {:?}", err); println!("Error: {:?}", err);
continue; break;
} }
println!("Error: {:?}", err);
(output, working_set.render()) (output, working_set.render())
}; };
@ -196,8 +198,14 @@ fn main() -> std::io::Result<()> {
parser_state: &*parser_state.borrow(), parser_state: &*parser_state.borrow(),
}; };
let output = eval_block(&state, stack.clone(), &block); match eval_block(&state, stack.clone(), &block) {
println!("{:#?}", output); Ok(value) => {
println!("{}", value);
}
Err(err) => {
println!("Error: {:?}", err);
}
}
} }
Signal::CtrlC => { Signal::CtrlC => {
println!("Ctrl-c"); println!("Ctrl-c");

View File

@ -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<dyn std::error::Error>>;
#[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")
}

View File

@ -9,6 +9,18 @@ impl<'a> ParserWorkingSet<'a> {
) -> (Type, Option<ParseError>) { ) -> (Type, Option<ParseError>) {
match &op.expr { match &op.expr {
Expr::Operator(operator) => match operator { 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) { Operator::Plus => match (&lhs.ty, &rhs.ty) {
(Type::Int, Type::Int) => (Type::Int, None), (Type::Int, Type::Int) => (Type::Int, None),
(Type::String, Type::String) => (Type::String, None), (Type::String, Type::String) => (Type::String, None),