split condition check to standalone module

This commit is contained in:
sagie gur ari 2019-12-31 19:00:25 +00:00
parent 730d561965
commit f971b6c5bb
5 changed files with 160 additions and 26 deletions

View file

@ -31,7 +31,7 @@ if blocks can be nested in other if blocks (see examples).
#### Parameters
* if/elseif - A command and its arguments to invoke and evaluate its output
* if/elseif - A command and its arguments to invoke and evaluate its output, if a single value is provided an no such command exists, it is evaluated as a value.
* else/end_if - no parameters
#### Return Value
@ -40,7 +40,15 @@ None
#### Examples
Simple example of an if statement that evaluates to true and echos "in if"
Simple example of an if statement that evaluates the argument value as true and echos "in if"
```sh
if true
echo in if
end_if
```
Example of an if statement that evaluates the command as true and echos "in if"
```sh
if set true

View file

@ -6,6 +6,18 @@ use duckscript::types::instruction::Instruction;
use duckscript::types::runtime::{Context, StateValue};
use std::collections::HashMap;
pub(crate) struct ErrorCommand {}
impl Command for ErrorCommand {
fn name(&self) -> String {
"test_error".to_string()
}
fn run(&self, _arguments: Vec<String>) -> CommandResult {
CommandResult::Error("test".to_string())
}
}
pub(crate) struct SetCommand {}
impl Command for SetCommand {

View file

@ -25,33 +25,32 @@ pub(crate) fn eval_condition(
variables: &mut HashMap<String, String>,
commands: &mut Commands,
) -> Result<bool, String> {
let eval_statement = if arguments.len() == 1 {
match commands.get(&arguments[0]) {
Some(_) => true,
None => false,
}
if arguments.is_empty() {
Ok(is_true(None))
} else {
true
};
if eval_statement {
match eval::eval(&arguments, state, variables, commands) {
CommandResult::Continue(value) => {
let passed = is_true(value);
Ok(passed)
let eval_statement = if arguments.len() == 1 {
match commands.get(&arguments[0]) {
Some(_) => true,
None => false,
}
CommandResult::Error(error) => Err(error.to_string()),
_ => Err("Invalid condition evaluation result.".to_string()),
}
} else {
let value = match variables.get(&arguments[0]) {
Some(value) => Some(value.to_string()),
None => None,
} else {
true
};
let passed = is_true(value);
if eval_statement {
match eval::eval(&arguments, state, variables, commands) {
CommandResult::Continue(value) => {
let passed = is_true(value);
Ok(passed)
Ok(passed)
}
CommandResult::Error(error) => Err(error.to_string()),
_ => Err("Invalid condition evaluation result.".to_string()),
}
} else {
let passed = is_true(Some(arguments[0].to_string()));
Ok(passed)
}
}
}

View file

@ -1,4 +1,5 @@
use super::*;
use crate::test::{ErrorCommand, SetCommand};
#[test]
fn is_true_none() {
@ -55,3 +56,113 @@ fn is_true_valid() {
assert!(passed);
}
#[test]
fn eval_condition_empty() {
let result = eval_condition(
vec![],
&mut HashMap::new(),
&mut HashMap::new(),
&mut Commands::new(),
);
assert!(result.is_ok());
let passed = result.unwrap();
assert!(!passed);
}
#[test]
fn eval_condition_value_true() {
let result = eval_condition(
vec!["true".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut Commands::new(),
);
assert!(result.is_ok());
let passed = result.unwrap();
assert!(passed);
}
#[test]
fn eval_condition_value_false() {
let result = eval_condition(
vec!["false".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut Commands::new(),
);
assert!(result.is_ok());
let passed = result.unwrap();
assert!(!passed);
}
#[test]
fn eval_condition_command_true() {
let mut commands = Commands::new();
match commands.set(Box::new(SetCommand {})) {
Ok(_) => (),
_ => panic!("Test error"),
}
let result = eval_condition(
vec!["test_set".to_string(), "true".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
assert!(result.is_ok());
let passed = result.unwrap();
assert!(passed);
}
#[test]
fn eval_condition_command_false() {
let mut commands = Commands::new();
match commands.set(Box::new(SetCommand {})) {
Ok(_) => (),
_ => panic!("Test error"),
}
let result = eval_condition(
vec!["test_set".to_string(), "false".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
assert!(result.is_ok());
let passed = result.unwrap();
assert!(!passed);
}
#[test]
fn eval_condition_command_error() {
let mut commands = Commands::new();
match commands.set(Box::new(ErrorCommand {})) {
Ok(_) => (),
_ => panic!("Test error"),
}
let result = eval_condition(
vec!["test_error".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
assert!(result.is_err());
}

View file

@ -1,6 +1,10 @@
if true
echo in if as value
end_if
if set true
echo in if
echo in if as command
end_if
if set false