mirror of
https://github.com/sagiegurari/duckscript
synced 2024-07-01 06:34:19 +00:00
The if/else and not commands now support complex conditions
This commit is contained in:
parent
c54af0f297
commit
4cc8f820b9
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
### v0.1.9
|
### v0.1.9
|
||||||
|
|
||||||
|
* The if/else and not commands now support complex conditions.
|
||||||
* Release command now support recursive option.
|
* Release command now support recursive option.
|
||||||
* New map_clear command.
|
* New map_clear command.
|
||||||
* New map_to_properties command.
|
* New map_to_properties command.
|
||||||
|
|
|
@ -348,12 +348,12 @@ end
|
||||||
value = set false
|
value = set false
|
||||||
if ${value}
|
if ${value}
|
||||||
echo should not be here
|
echo should not be here
|
||||||
elseif true
|
elseif true or false
|
||||||
echo in else if but not done yet
|
echo in else if but not done yet
|
||||||
|
|
||||||
value = set true
|
value = set true
|
||||||
|
|
||||||
if not false
|
if not true and false
|
||||||
echo nested if
|
echo nested if
|
||||||
|
|
||||||
value = set "some text"
|
value = set "some text"
|
||||||
|
|
|
@ -304,12 +304,12 @@ end
|
||||||
value = set false
|
value = set false
|
||||||
if ${value}
|
if ${value}
|
||||||
echo should not be here
|
echo should not be here
|
||||||
elseif true
|
elseif true or false
|
||||||
echo in else if but not done yet
|
echo in else if but not done yet
|
||||||
|
|
||||||
value = set true
|
value = set true
|
||||||
|
|
||||||
if not false
|
if not true and false
|
||||||
echo nested if
|
echo nested if
|
||||||
|
|
||||||
value = set "some text"
|
value = set "some text"
|
||||||
|
|
68
docs/sdk.md
68
docs/sdk.md
|
@ -343,7 +343,7 @@ goto
|
||||||
<a name="std__If"></a>
|
<a name="std__If"></a>
|
||||||
## std::If
|
## std::If
|
||||||
```sh
|
```sh
|
||||||
if command|value
|
if [command|value|condition]
|
||||||
# commands
|
# commands
|
||||||
elseif command|value
|
elseif command|value
|
||||||
# commands
|
# commands
|
||||||
|
@ -363,8 +363,9 @@ if and elseif commands accept either:
|
||||||
|
|
||||||
* A command with optional arguments and invokes it
|
* A command with optional arguments and invokes it
|
||||||
* A single value which doesn't match any known command
|
* A single value which doesn't match any known command
|
||||||
|
* A condition statement
|
||||||
|
|
||||||
If the value or the result of the command is one of the following:
|
If the result is one of the following:
|
||||||
|
|
||||||
* No output
|
* No output
|
||||||
* false (case insensitive)
|
* false (case insensitive)
|
||||||
|
@ -378,6 +379,9 @@ If a truthy (non falsy) output is found, it will invoke the commands of that cod
|
||||||
|
|
||||||
if blocks can be nested in other if blocks (see examples).
|
if blocks can be nested in other if blocks (see examples).
|
||||||
|
|
||||||
|
A condition statement is made up of values, or/and keywords and '('/')' groups.<br>
|
||||||
|
Each must be separated with a space character.
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
* 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.
|
* 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.
|
||||||
|
@ -433,6 +437,16 @@ elseif set true
|
||||||
else
|
else
|
||||||
echo should not be here
|
echo should not be here
|
||||||
end
|
end
|
||||||
|
|
||||||
|
valid = set false
|
||||||
|
if true and false or true and false or ( true and true or false )
|
||||||
|
valid = set true
|
||||||
|
end
|
||||||
|
assert ${valid}
|
||||||
|
|
||||||
|
if true and false or true and false or ( true and true or false ) and false
|
||||||
|
assert_fail
|
||||||
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -469,7 +483,7 @@ is_defined
|
||||||
<a name="std__Not"></a>
|
<a name="std__Not"></a>
|
||||||
## std::Not
|
## std::Not
|
||||||
```sh
|
```sh
|
||||||
output = not command|value
|
output = not [command|value|condition]
|
||||||
```
|
```
|
||||||
|
|
||||||
Enables to switch falsy to true and truthy to false.<br>
|
Enables to switch falsy to true and truthy to false.<br>
|
||||||
|
@ -477,8 +491,9 @@ The **not** commands accept either:
|
||||||
|
|
||||||
* A command with optional arguments and invokes it
|
* A command with optional arguments and invokes it
|
||||||
* A single value which doesn't match any known command
|
* A single value which doesn't match any known command
|
||||||
|
* A condition statement
|
||||||
|
|
||||||
If the value or the result of the command is one of the following:
|
If the result is one of the following:
|
||||||
|
|
||||||
* No output
|
* No output
|
||||||
* false (case insensitive)
|
* false (case insensitive)
|
||||||
|
@ -488,6 +503,9 @@ If the value or the result of the command is one of the following:
|
||||||
|
|
||||||
It will return true, otherwise it will return false.
|
It will return true, otherwise it will return false.
|
||||||
|
|
||||||
|
A condition statement is made up of values, or/and keywords and '('/')' groups.<br>
|
||||||
|
Each must be separated with a space character.
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
@ -499,19 +517,41 @@ The switched value of the input.
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Simple example of converting true/false values
|
fn test_not_true
|
||||||
is_false = not true
|
value = not true
|
||||||
echo is false: ${is_false}
|
|
||||||
|
|
||||||
is_true = not false
|
assert_false ${value}
|
||||||
echo is true: ${is_true}
|
end
|
||||||
|
|
||||||
# Example of converting command output value
|
fn test_not_false
|
||||||
is_false = not set true
|
value = not false
|
||||||
echo is false: ${is_false}
|
|
||||||
|
|
||||||
is_true = not set false
|
assert ${value}
|
||||||
echo is true: ${is_true}
|
end
|
||||||
|
|
||||||
|
fn test_not_command_true
|
||||||
|
value = not set true
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_command_false
|
||||||
|
value = not set false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_true
|
||||||
|
value = not true and false or true and false or ( true and true or false )
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_false
|
||||||
|
value = not true and false or true and false or ( true and true or false ) and false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,18 @@ fn load_valid() {
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
let result = load(&mut context.commands);
|
let result = load(&mut context.commands);
|
||||||
|
|
||||||
match result {
|
assert!(result.is_ok());
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => panic!("{:#?}", e),
|
assert!(!context.commands.get_all_command_names().is_empty());
|
||||||
};
|
}
|
||||||
// assert!(result.is_ok());
|
|
||||||
|
#[test]
|
||||||
|
fn test_scripts() {
|
||||||
|
let mut context = Context::new();
|
||||||
|
let result = load(&mut context.commands);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
assert!(!context.commands.get_all_command_names().is_empty());
|
assert!(!context.commands.get_all_command_names().is_empty());
|
||||||
|
|
||||||
let result = runner::run_script("test_directory ../test", context);
|
let result = runner::run_script("test_directory ../test", context);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
```sh
|
```sh
|
||||||
if command|value
|
if [command|value|condition]
|
||||||
# commands
|
# commands
|
||||||
elseif command|value
|
elseif command|value
|
||||||
# commands
|
# commands
|
||||||
|
@ -19,8 +19,9 @@ if and elseif commands accept either:
|
||||||
|
|
||||||
* A command with optional arguments and invokes it
|
* A command with optional arguments and invokes it
|
||||||
* A single value which doesn't match any known command
|
* A single value which doesn't match any known command
|
||||||
|
* A condition statement
|
||||||
|
|
||||||
If the value or the result of the command is one of the following:
|
If the result is one of the following:
|
||||||
|
|
||||||
* No output
|
* No output
|
||||||
* false (case insensitive)
|
* false (case insensitive)
|
||||||
|
@ -34,6 +35,9 @@ If a truthy (non falsy) output is found, it will invoke the commands of that cod
|
||||||
|
|
||||||
if blocks can be nested in other if blocks (see examples).
|
if blocks can be nested in other if blocks (see examples).
|
||||||
|
|
||||||
|
A condition statement is made up of values, or/and keywords and '('/')' groups.<br>
|
||||||
|
Each must be separated with a space character.
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
* 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.
|
* 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.
|
||||||
|
@ -89,4 +93,14 @@ elseif set true
|
||||||
else
|
else
|
||||||
echo should not be here
|
echo should not be here
|
||||||
end
|
end
|
||||||
|
|
||||||
|
valid = set false
|
||||||
|
if true and false or true and false or ( true and true or false )
|
||||||
|
valid = set true
|
||||||
|
end
|
||||||
|
assert ${valid}
|
||||||
|
|
||||||
|
if true and false or true and false or ( true and true or false ) and false
|
||||||
|
assert_fail
|
||||||
|
end
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
```sh
|
```sh
|
||||||
output = not command|value
|
output = not [command|value|condition]
|
||||||
```
|
```
|
||||||
|
|
||||||
Enables to switch falsy to true and truthy to false.<br>
|
Enables to switch falsy to true and truthy to false.<br>
|
||||||
|
@ -7,8 +7,9 @@ The **not** commands accept either:
|
||||||
|
|
||||||
* A command with optional arguments and invokes it
|
* A command with optional arguments and invokes it
|
||||||
* A single value which doesn't match any known command
|
* A single value which doesn't match any known command
|
||||||
|
* A condition statement
|
||||||
|
|
||||||
If the value or the result of the command is one of the following:
|
If the result is one of the following:
|
||||||
|
|
||||||
* No output
|
* No output
|
||||||
* false (case insensitive)
|
* false (case insensitive)
|
||||||
|
@ -18,6 +19,9 @@ If the value or the result of the command is one of the following:
|
||||||
|
|
||||||
It will return true, otherwise it will return false.
|
It will return true, otherwise it will return false.
|
||||||
|
|
||||||
|
A condition statement is made up of values, or/and keywords and '('/')' groups.<br>
|
||||||
|
Each must be separated with a space character.
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
@ -29,17 +33,39 @@ The switched value of the input.
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Simple example of converting true/false values
|
fn test_not_true
|
||||||
is_false = not true
|
value = not true
|
||||||
echo is false: ${is_false}
|
|
||||||
|
|
||||||
is_true = not false
|
assert_false ${value}
|
||||||
echo is true: ${is_true}
|
end
|
||||||
|
|
||||||
# Example of converting command output value
|
fn test_not_false
|
||||||
is_false = not set true
|
value = not false
|
||||||
echo is false: ${is_false}
|
|
||||||
|
|
||||||
is_true = not set false
|
assert ${value}
|
||||||
echo is true: ${is_true}
|
end
|
||||||
|
|
||||||
|
fn test_not_command_true
|
||||||
|
value = not set true
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_command_false
|
||||||
|
value = not set false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_true
|
||||||
|
value = not true and false or true and false or ( true and true or false )
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_false
|
||||||
|
value = not true and false or true and false or ( true and true or false ) and false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,6 +7,13 @@ use std::collections::HashMap;
|
||||||
#[path = "./condition_test.rs"]
|
#[path = "./condition_test.rs"]
|
||||||
mod condition_test;
|
mod condition_test;
|
||||||
|
|
||||||
|
enum FoundToken {
|
||||||
|
None,
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
|
Value,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn is_true(value: Option<String>) -> bool {
|
pub(crate) fn is_true(value: Option<String>) -> bool {
|
||||||
let failed = match value {
|
let failed = match value {
|
||||||
Some(value_str) => {
|
Some(value_str) => {
|
||||||
|
@ -28,11 +35,7 @@ pub(crate) fn eval_condition(
|
||||||
if arguments.is_empty() {
|
if arguments.is_empty() {
|
||||||
Ok(is_true(None))
|
Ok(is_true(None))
|
||||||
} else {
|
} else {
|
||||||
let eval_statement = if arguments.len() == 1 {
|
let eval_statement = commands.exists(&arguments[0]);
|
||||||
commands.exists(&arguments[0])
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
if eval_statement {
|
if eval_statement {
|
||||||
match eval::eval_with_error(&arguments, state, variables, commands) {
|
match eval::eval_with_error(&arguments, state, variables, commands) {
|
||||||
|
@ -45,9 +48,125 @@ pub(crate) fn eval_condition(
|
||||||
_ => Err("Invalid condition evaluation result.".to_string()),
|
_ => Err("Invalid condition evaluation result.".to_string()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let passed = is_true(Some(arguments[0].to_string()));
|
eval_condition_for_slice(&arguments[..])
|
||||||
|
}
|
||||||
Ok(passed)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn eval_condition_for_slice(arguments: &[String]) -> Result<bool, String> {
|
||||||
|
if arguments.is_empty() {
|
||||||
|
Ok(is_true(None))
|
||||||
|
} else {
|
||||||
|
let mut searching_block_end = false;
|
||||||
|
let mut start_block = 0;
|
||||||
|
let mut counter = 0;
|
||||||
|
let mut index = 0;
|
||||||
|
let mut total_evaluated = None;
|
||||||
|
let mut partial_evaluated = None;
|
||||||
|
let mut found_token = FoundToken::None;
|
||||||
|
for argument in arguments {
|
||||||
|
if argument == "(" {
|
||||||
|
searching_block_end = true;
|
||||||
|
if counter == 0 {
|
||||||
|
start_block = index + 1
|
||||||
|
}
|
||||||
|
counter = counter + 1;
|
||||||
|
} else if argument == ")" {
|
||||||
|
counter = counter - 1;
|
||||||
|
|
||||||
|
if counter == 0 {
|
||||||
|
searching_block_end = false;
|
||||||
|
|
||||||
|
match eval_condition_for_slice(&arguments[start_block..index]) {
|
||||||
|
Ok(evaluated) => {
|
||||||
|
start_block = 0;
|
||||||
|
|
||||||
|
match found_token {
|
||||||
|
FoundToken::None => {
|
||||||
|
total_evaluated = Some(evaluated);
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::And => {
|
||||||
|
partial_evaluated = Some(evaluated);
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::Or => {
|
||||||
|
partial_evaluated =
|
||||||
|
Some(evaluated || partial_evaluated.unwrap_or(false));
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::Value => {
|
||||||
|
return Err(
|
||||||
|
format!("Unexpected value: {}", argument).to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => return Err(error),
|
||||||
|
};
|
||||||
|
} else if counter < 0 {
|
||||||
|
return Err("Unexpected ')'".to_string());
|
||||||
|
}
|
||||||
|
} else if !searching_block_end {
|
||||||
|
if argument == "and" {
|
||||||
|
match found_token {
|
||||||
|
FoundToken::Value => {
|
||||||
|
found_token = FoundToken::And;
|
||||||
|
|
||||||
|
total_evaluated = Some(
|
||||||
|
total_evaluated.unwrap_or(true)
|
||||||
|
&& partial_evaluated.unwrap_or(true),
|
||||||
|
);
|
||||||
|
partial_evaluated = None;
|
||||||
|
|
||||||
|
if !total_evaluated.unwrap() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err("Unexpected 'and'".to_string()),
|
||||||
|
}
|
||||||
|
} else if argument == "or" {
|
||||||
|
match found_token {
|
||||||
|
FoundToken::Value => found_token = FoundToken::Or,
|
||||||
|
_ => return Err("Unexpected 'or'".to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let evaluated = is_true(Some(argument.to_string()));
|
||||||
|
|
||||||
|
match found_token {
|
||||||
|
FoundToken::None => {
|
||||||
|
partial_evaluated = Some(evaluated);
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::And => {
|
||||||
|
partial_evaluated = Some(evaluated);
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::Or => {
|
||||||
|
partial_evaluated =
|
||||||
|
Some(evaluated || partial_evaluated.unwrap_or(false));
|
||||||
|
found_token = FoundToken::Value;
|
||||||
|
}
|
||||||
|
FoundToken::Value => {
|
||||||
|
return Err(format!("Unexpected value: {}", argument).to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if searching_block_end {
|
||||||
|
Err("Missing ')'".to_string())
|
||||||
|
} else {
|
||||||
|
let total_bool = if total_evaluated.is_none() && partial_evaluated.is_none() {
|
||||||
|
is_true(None)
|
||||||
|
} else {
|
||||||
|
partial_evaluated.unwrap_or(true) && total_evaluated.unwrap_or(true)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(total_bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,3 +166,290 @@ fn eval_condition_command_error() {
|
||||||
|
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_empty() {
|
||||||
|
let result = eval_condition_for_slice(&vec![]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(!output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_true() {
|
||||||
|
let result = eval_condition_for_slice(&vec!["true".to_string()]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_false() {
|
||||||
|
let result = eval_condition_for_slice(&vec!["false".to_string()]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(!output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_true_and_false() {
|
||||||
|
let result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(!output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_false_and_true() {
|
||||||
|
let result = eval_condition_for_slice(&vec![
|
||||||
|
"false".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(!output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_true_or_false() {
|
||||||
|
let result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_false_or_true() {
|
||||||
|
let result = eval_condition_for_slice(&vec![
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let output = result.unwrap();
|
||||||
|
assert!(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_complex_no_parts() {
|
||||||
|
let mut result = eval_condition_for_slice(&vec![
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"false".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(!result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(!result.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_complex_with_parts() {
|
||||||
|
let mut result = eval_condition_for_slice(&vec![
|
||||||
|
"(".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"(".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(!result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"(".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(!result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(!result.unwrap());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"(".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"false".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_condition_for_slice_parse_errors() {
|
||||||
|
let mut result = eval_condition_for_slice(&vec!["or".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec!["and".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec!["(".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![")".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec!["(".to_string(), "true".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"false".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
")".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec!["false".to_string(), "true".to_string()]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
result = eval_condition_for_slice(&vec![
|
||||||
|
"true".to_string(),
|
||||||
|
"or".to_string(),
|
||||||
|
"and".to_string(),
|
||||||
|
"true".to_string(),
|
||||||
|
]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ end
|
||||||
|
|
||||||
if set false
|
if set false
|
||||||
echo should not be here
|
echo should not be here
|
||||||
elseif set true
|
elseif true or false
|
||||||
echo in else if but not done yet
|
echo in else if but not done yet
|
||||||
|
|
||||||
if set true
|
if set true
|
||||||
|
@ -49,7 +49,7 @@ elseif true
|
||||||
|
|
||||||
value = set true
|
value = set true
|
||||||
|
|
||||||
if not false
|
if not true and false
|
||||||
echo nested if
|
echo nested if
|
||||||
|
|
||||||
value = set "some text"
|
value = set "some text"
|
||||||
|
|
|
@ -35,6 +35,22 @@ fn test_if_command_returns_true
|
||||||
assert ${valid}
|
assert ${valid}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fn test_if_condition_true
|
||||||
|
valid = set false
|
||||||
|
|
||||||
|
if true and false or true and false or ( true and true or false )
|
||||||
|
valid = set true
|
||||||
|
end
|
||||||
|
|
||||||
|
assert ${valid}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_if_condition_false
|
||||||
|
if true and false or true and false or ( true and true or false ) and false
|
||||||
|
assert_fail
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
fn test_simple_else
|
fn test_simple_else
|
||||||
valid = set false
|
valid = set false
|
||||||
|
|
|
@ -10,3 +10,27 @@ fn test_not_false
|
||||||
|
|
||||||
assert ${value}
|
assert ${value}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fn test_not_command_true
|
||||||
|
value = not set true
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_command_false
|
||||||
|
value = not set false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_true
|
||||||
|
value = not true and false or true and false or ( true and true or false )
|
||||||
|
|
||||||
|
assert_false ${value}
|
||||||
|
end
|
||||||
|
|
||||||
|
fn test_not_condition_false
|
||||||
|
value = not true and false or true and false or ( true and true or false ) and false
|
||||||
|
|
||||||
|
assert ${value}
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user