add more tests

This commit is contained in:
JT 2021-07-31 09:57:22 +12:00
parent 79a05d63c8
commit 61258d03ad
3 changed files with 58 additions and 10 deletions

View File

@ -9,6 +9,7 @@ pub enum ShellError {
Mismatch(String, Span),
Unsupported(Span),
InternalError(String),
VariableNotFound(Span),
}
#[derive(Debug, Clone)]
@ -98,11 +99,14 @@ impl Stack {
match this.vars.get(&var_id) {
Some(v) => Ok(v.clone()),
_ => {
println!("var_id: {}", var_id);
if let Some(parent) = &this.parent {
parent.get_var(var_id)
} else {
Err(ShellError::InternalError("variable not found".into()))
}
}
}
}
pub fn add_var(&self, var_id: VarId, value: Value) {
let mut this = self.0.borrow_mut();
@ -283,7 +287,9 @@ pub fn eval_expression(
val: *i,
span: expr.span,
}),
Expr::Var(var_id) => stack.get_var(*var_id),
Expr::Var(var_id) => stack
.get_var(*var_id)
.map_err(move |_| ShellError::VariableNotFound(expr.span)),
Expr::Call(call) => eval_call(state, stack, call),
Expr::ExternalCall(_, _) => Err(ShellError::Unsupported(expr.span)),
Expr::Operator(_) => Ok(Value::Unknown),

View File

@ -121,7 +121,7 @@ fn main() -> std::io::Result<()> {
let mut working_set = ParserWorkingSet::new(&*parser_state);
let (output, err) = working_set.parse_file(&path, &file, false);
if let Some(err) = err {
eprintln!("Error: {:?}", err);
eprintln!("Parse Error: {:?}", err);
std::process::exit(1);
}
(output, working_set.render())
@ -140,7 +140,7 @@ fn main() -> std::io::Result<()> {
println!("{}", value);
}
Err(err) => {
eprintln!("Error: {:?}", err);
eprintln!("Eval Error: {:?}", err);
std::process::exit(1);
}
}
@ -191,7 +191,7 @@ fn main() -> std::io::Result<()> {
false,
);
if let Some(err) = err {
println!("Error: {:?}", err);
eprintln!("Parse Error: {:?}", err);
break;
}
(output, working_set.render())
@ -208,7 +208,7 @@ fn main() -> std::io::Result<()> {
println!("{}", value);
}
Err(err) => {
println!("Error: {:?}", err);
eprintln!("Eval Error: {:?}", err);
}
}
}

View File

@ -18,11 +18,15 @@ fn run_test(input: &str, expected: &str) -> TestResult {
let output = cmd.output()?;
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
println!("stdout: {}", stdout);
println!("stderr: {}", stderr);
assert!(output.status.success());
let output = String::from_utf8_lossy(&output.stdout).to_string();
assert_eq!(output.trim(), expected);
assert_eq!(stdout.trim(), expected);
Ok(())
}
@ -40,6 +44,7 @@ fn fail_test(input: &str, expected: &str) -> TestResult {
let output = cmd.output()?;
let output = String::from_utf8_lossy(&output.stderr).to_string();
println!("{}", output);
assert!(output.contains("Error:"));
assert!(output.contains(expected));
@ -71,3 +76,40 @@ fn if_test1() -> TestResult {
fn if_test2() -> TestResult {
run_test("if $false { 10 } else { 20 } ", "20")
}
#[test]
fn no_leak1() -> TestResult {
fail_test(
"if $false { let $x = 10 } else { let $x = 20 }; $x",
"VariableNotFound",
)
}
#[test]
fn no_leak2() -> TestResult {
fail_test(
"def foo [] { $x }; def bar [] { let $x = 10; foo }; bar",
"VariableNotFound",
)
}
#[test]
fn no_leak3() -> TestResult {
run_test(
"def foo [$x] { $x }; def bar [] { let $x = 10; foo 20}; bar",
"20",
)
}
#[test]
fn no_leak4() -> TestResult {
run_test(
"def foo [$x] { $x }; def bar [] { let $x = 10; (foo 20) + $x}; bar",
"30",
)
}
#[test]
fn simple_var_closing() -> TestResult {
run_test("let $x = 10; def foo [] { $x }; foo", "10")
}