Fix: if/else condition with a command that accepts empty values

This commit is contained in:
sagie gur ari 2024-01-19 07:33:48 +00:00
parent 6c63263c38
commit 48ae088b99
10 changed files with 236 additions and 92 deletions

View file

@ -1,5 +1,10 @@
## CHANGELOG
### v0.9.3
* Fix: if/else condition with a command that accepts empty values
* Enhancement: dump commands will print to output if no output variable is defined
### v0.9.2 (2023-11-18)
* Enhancement: \[Breaking Change\] add support for renaming directories via mv command #374

View file

@ -42,7 +42,7 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> {
commands.set(noop::create(PACKAGE))?;
commands.set(not::create(PACKAGE))?;
commands.set(print::create(PACKAGE))?;
commands.set(println::create(PACKAGE)?)?;
commands.set(println::create(PACKAGE))?;
commands.set(read::create(PACKAGE))?;
commands.set(release::create(PACKAGE))?;

View file

@ -134,6 +134,64 @@ fn add_color(
}
}
pub(crate) fn run_print(arguments: Vec<String>) -> CommandResult {
// collect options
let mut styles = vec![];
let mut text_color = None;
let mut background_color = None;
let mut index = 0;
let mut looking_for = LookingFor::Flag;
for argument in &arguments {
index = index + 1;
match looking_for {
LookingFor::Flag => match argument.as_str() {
"--style" | "-s" => looking_for = LookingFor::Style,
"--color" | "-c" => looking_for = LookingFor::TextColor,
"--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor,
_ => break,
},
LookingFor::Style => {
styles.push(argument.to_string());
looking_for = LookingFor::Flag;
}
LookingFor::TextColor => {
text_color = Some(argument.to_string());
looking_for = LookingFor::Flag;
}
LookingFor::BackgroundColor => {
background_color = Some(argument.to_string());
looking_for = LookingFor::Flag;
}
}
}
if index > 0 {
index = index - 1;
}
// generate whole string
let mut string = String::new();
let mut count = 0;
for argument in &arguments[index..] {
count = count + 1;
string.push_str(argument);
string.push(' ');
}
if count > 0 {
string.remove(string.len() - 1);
}
// add colors
let mut styled_string = string.normal();
styled_string = add_color(styled_string, text_color, false);
styled_string = add_color(styled_string, background_color, true);
styled_string = add_styles(styled_string, styles);
print!("{}", styled_string);
CommandResult::Continue(Some(count.to_string()))
}
#[derive(Clone)]
pub(crate) struct CommandImpl {
package: String,
@ -157,61 +215,7 @@ impl Command for CommandImpl {
}
fn run(&self, arguments: Vec<String>) -> CommandResult {
// collect options
let mut styles = vec![];
let mut text_color = None;
let mut background_color = None;
let mut index = 0;
let mut looking_for = LookingFor::Flag;
for argument in &arguments {
index = index + 1;
match looking_for {
LookingFor::Flag => match argument.as_str() {
"--style" | "-s" => looking_for = LookingFor::Style,
"--color" | "-c" => looking_for = LookingFor::TextColor,
"--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor,
_ => break,
},
LookingFor::Style => {
styles.push(argument.to_string());
looking_for = LookingFor::Flag;
}
LookingFor::TextColor => {
text_color = Some(argument.to_string());
looking_for = LookingFor::Flag;
}
LookingFor::BackgroundColor => {
background_color = Some(argument.to_string());
looking_for = LookingFor::Flag;
}
}
}
if index > 0 {
index = index - 1;
}
// generate whole string
let mut string = String::new();
let mut count = 0;
for argument in &arguments[index..] {
count = count + 1;
string.push_str(argument);
string.push(' ');
}
if count > 0 {
string.remove(string.len() - 1);
}
// add colors
let mut styled_string = string.normal();
styled_string = add_color(styled_string, text_color, false);
styled_string = add_color(styled_string, background_color, true);
styled_string = add_styles(styled_string, styles);
print!("{}", styled_string);
CommandResult::Continue(Some(count.to_string()))
run_print(arguments)
}
}

View file

@ -1,22 +1,47 @@
use crate::types::command::create_alias_command;
use crate::sdk::std::print::run_print;
use crate::utils::pckg;
use duckscript::types::command::Command;
use duckscript::types::error::ScriptError;
use duckscript::types::command::{Command, CommandResult};
#[cfg(test)]
#[path = "./mod_test.rs"]
mod mod_test;
pub(crate) fn create(package: &str) -> Result<Box<dyn Command>, ScriptError> {
let name = pckg::concat(package, "Println");
let command = create_alias_command(
name,
vec!["println".to_string()],
include_str!("help.md").to_string(),
"println".to_string(),
include_str!("script.ds").to_string(),
0,
)?;
Ok(Box::new(command))
#[derive(Clone)]
pub(crate) struct CommandImpl {
package: String,
}
impl Command for CommandImpl {
fn name(&self) -> String {
pckg::concat(&self.package, "Println")
}
fn aliases(&self) -> Vec<String> {
vec!["println".to_string()]
}
fn help(&self) -> String {
include_str!("help.md").to_string()
}
fn clone_and_box(&self) -> Box<dyn Command> {
Box::new((*self).clone())
}
fn run(&self, arguments: Vec<String>) -> CommandResult {
let result = run_print(arguments);
match result {
CommandResult::Continue(_) => println!(""),
_ => (),
};
return result;
}
}
pub(crate) fn create(package: &str) -> Box<dyn Command> {
Box::new(CommandImpl {
package: package.to_string(),
})
}

View file

@ -1,7 +1,26 @@
use super::*;
use crate::test;
use crate::test::CommandValidation;
#[test]
fn common_functions() {
test::test_common_command_functions(create("").unwrap());
test::test_common_command_functions(create(""));
}
#[test]
fn run_no_args() {
test::run_script_and_validate(
vec![create("")],
"out = println",
CommandValidation::Match("out".to_string(), "0".to_string()),
);
}
#[test]
fn run_multiple_args() {
test::run_script_and_validate(
vec![create("")],
"out = println 1 2 \"3 4\"",
CommandValidation::Match("out".to_string(), "3".to_string()),
);
}

View file

@ -1,13 +0,0 @@
scope::println::count = set 0
if not array_is_empty ${scope::println::arguments}
scope::println::commandline = array_join ${scope::println::arguments} "\" \""
scope::println::commandline = set "\"${scope::println::commandline}"
scope::println::commandline = substring ${scope::println::commandline} -2
scope::println::count = print %{scope::println::commandline}
end
echo
set ${scope::println::count}

View file

@ -12,12 +12,20 @@ mod eval_test;
fn parse(arguments: &Vec<String>) -> Result<Instruction, String> {
let mut line_buffer = String::new();
for argument in arguments {
if argument.contains(" ") {
line_buffer.push('"');
}
line_buffer.push_str(argument);
if argument.contains(" ") {
line_buffer.push('"');
if argument.is_empty() {
line_buffer.push_str("\"\"");
} else if argument.starts_with("\"") && argument.ends_with("\"") {
line_buffer.push('\\');
line_buffer.push_str(argument);
line_buffer.push('\\');
} else {
if argument.contains(" ") {
line_buffer.push('"');
}
line_buffer.push_str(argument);
if argument.contains(" ") {
line_buffer.push('"');
}
}
line_buffer.push(' ');
}

View file

@ -1,4 +1,5 @@
use super::*;
use crate::sdk::std::string::equals::create as EqCreate;
use crate::test::SetCommand;
#[test]
@ -143,3 +144,66 @@ fn eval_with_error_parse_error() {
_ => panic!("invalid result type."),
};
}
#[test]
fn eval_with_eq_empty_args() {
let mut commands = Commands::new();
match commands.set(EqCreate("")) {
Err(error) => panic!("{}", error),
_ => (),
};
let result = eval_with_error(
&vec!["eq".to_string(), "".to_string(), "".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
match result {
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"),
_ => panic!("invalid result type."),
};
}
#[test]
fn eval_with_eq_true_args() {
let mut commands = Commands::new();
match commands.set(EqCreate("")) {
Err(error) => panic!("{}", error),
_ => (),
};
let result = eval_with_error(
&vec!["eq".to_string(), "true".to_string(), "true".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
match result {
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"),
_ => panic!("invalid result type."),
};
}
#[test]
fn eval_with_eq_true_and_false_args() {
let mut commands = Commands::new();
match commands.set(EqCreate("")) {
Err(error) => panic!("{}", error),
_ => (),
};
let result = eval_with_error(
&vec!["eq".to_string(), "true".to_string(), "false".to_string()],
&mut HashMap::new(),
&mut HashMap::new(),
&mut commands,
);
match result {
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "false"),
_ => panic!("invalid result type."),
};
}

View file

@ -163,6 +163,38 @@ fn test_if_call_to_functions
assert ${valid}
end
fn test_eq_empty_strings
valid = set false
if eq "" ""
valid = set true
end
assert ${valid}
end
fn test_eq_different_strings
valid = set true
if eq "1 2" "1 3"
valid = set false
end
assert ${valid}
end
fn test_not_is_array_empty
valid = set false
array = array 1 2 3
if not array_is_empty ${array}
valid = set true
end
release ${array}
assert ${valid}
end
fn _test_return_true
return true
end

View file

@ -6,7 +6,7 @@ fn test_no_style
end
fn test_with_style
count = print -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red
count = println -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red
assert_eq ${count} 2
colors = array black red green yellow blue magenta cyan white