Fixed end command bug which directed execution to wrong sub command when multiple script contexts are running #110

This commit is contained in:
sagie gur ari 2020-06-05 21:38:28 +00:00
parent 013d20d723
commit 1d8fabb55d
8 changed files with 81 additions and 6 deletions

View file

@ -1,5 +1,9 @@
## CHANGELOG
### v0.4.3
* Fixed end command bug which directed execution to wrong sub command when multiple script contexts are running #110
### v0.4.2 (2020-06-05)
* Fixed parsing issue for commands evaluated by other commands (for example if conditions)

View file

@ -1,3 +1,4 @@
use crate::types::scope::get_line_context_name;
use crate::utils::state::get_core_sub_state_for_command;
use duckscript::runner;
use duckscript::types::command::{Command, CommandResult, Commands};
@ -14,10 +15,18 @@ mod mod_test;
static END_STATE_KEY: &str = "end";
pub(crate) static END_COMMAND_NAME: &str = "end";
fn get_key(line: usize, state: &mut HashMap<String, StateValue>) -> String {
let mut key = get_line_context_name(state);
key.push_str("::");
key.push_str(&line.to_string());
key
}
fn get_command(line: usize, state: &mut HashMap<String, StateValue>) -> Option<String> {
let key = get_key(line, state);
let sub_state = get_core_sub_state_for_command(state, END_STATE_KEY.to_string());
let key = line.to_string();
match sub_state.get(&key) {
Some(state_value) => match state_value {
StateValue::String(command) => Some(command.clone()),
@ -33,9 +42,10 @@ fn get_command(line: usize, state: &mut HashMap<String, StateValue>) -> Option<S
}
pub(crate) fn set_command(line: usize, state: &mut HashMap<String, StateValue>, command: String) {
let key = get_key(line, state);
let sub_state = get_core_sub_state_for_command(state, END_STATE_KEY.to_string());
sub_state.insert(line.to_string(), StateValue::String(command));
sub_state.insert(key, StateValue::String(command));
}
#[derive(Clone)]

View file

@ -21,7 +21,10 @@ fn run_valid() {
CommandValidation::Match("out".to_string(), "false".to_string()),
);
let sub_state_value = context.state.get("duckscriptsdk::on_error").unwrap();
let sub_state_value = context
.state
.get("duckscriptsdk::command::on_error")
.unwrap();
match sub_state_value {
StateValue::SubState(sub_state) => {
match sub_state.get("error").unwrap() {

View file

@ -20,7 +20,10 @@ fn run_valid() {
CommandValidation::None,
);
let sub_state_value = context.state.get("duckscriptsdk::on_error").unwrap();
let sub_state_value = context
.state
.get("duckscriptsdk::command::on_error")
.unwrap();
match sub_state_value {
StateValue::SubState(sub_state) => {
match sub_state.get("error").unwrap() {

View file

@ -1,4 +1,5 @@
use crate::types::scope::clear;
use crate::types::scope::set_line_context_name;
use crate::utils::state::{get_handles_sub_state, put_handle};
use duckscript::types::command::{Command, CommandResult, Commands, GoToValue};
use duckscript::types::error::ScriptError;
@ -91,6 +92,7 @@ impl Command for AliasCommand {
CommandResult::Error("Invalid arguments provided.".to_string())
} else {
let start_count = variables.len();
let line_context_name = set_line_context_name(&self.scope_name, state);
// define script arguments
let mut handle_option = None;
@ -199,6 +201,7 @@ impl Command for AliasCommand {
None => (),
}
clear(&self.scope_name, variables);
set_line_context_name(&line_context_name, state);
let end_count = variables.len();
if start_count < end_count {

View file

@ -1,5 +1,39 @@
use crate::utils::state::get_core_sub_state_for_runtime;
use duckscript::types::runtime::StateValue;
use std::collections::HashMap;
static CONTEXT_NAME_SUB_STATE_KEY: &str = "line_context_name";
static CONTEXT_NAME_STATE_KEY: &str = "name";
pub(crate) fn get_line_context_name(state: &mut HashMap<String, StateValue>) -> String {
let sub_state = get_core_sub_state_for_runtime(state, CONTEXT_NAME_SUB_STATE_KEY.to_string());
match sub_state.get(CONTEXT_NAME_STATE_KEY) {
Some(state_value) => match state_value {
StateValue::String(value) => value.clone(),
_ => {
// remove corrupted data
sub_state.remove(CONTEXT_NAME_STATE_KEY);
"".to_string()
}
},
None => "".to_string(),
}
}
pub(crate) fn set_line_context_name(name: &str, state: &mut HashMap<String, StateValue>) -> String {
let previous_name = get_line_context_name(state);
let sub_state = get_core_sub_state_for_runtime(state, CONTEXT_NAME_SUB_STATE_KEY.to_string());
sub_state.insert(
CONTEXT_NAME_STATE_KEY.to_string(),
StateValue::String(name.to_string()),
);
previous_name
}
pub(crate) fn clear(name: &str, variables: &mut HashMap<String, String>) {
let mut scope_name = name.to_string();
scope_name.push_str("::");

View file

@ -11,11 +11,20 @@ mod state_test;
static HANDLE_SUB_STATE_KEY: &str = "handles";
pub(crate) fn get_core_sub_state_for_runtime(
state: &mut HashMap<String, StateValue>,
name: String,
) -> &mut HashMap<String, StateValue> {
let sub_state_name = pckg::concat("duckscriptsdk::runtime", &name);
get_sub_state(sub_state_name, state)
}
pub(crate) fn get_core_sub_state_for_command(
state: &mut HashMap<String, StateValue>,
name: String,
) -> &mut HashMap<String, StateValue> {
let sub_state_name = pckg::concat("duckscriptsdk", &name);
let sub_state_name = pckg::concat("duckscriptsdk::command", &name);
get_sub_state(sub_state_name, state)
}

View file

@ -1,12 +1,21 @@
use super::*;
#[test]
fn get_core_sub_state_for_runtime_valid() {
let mut state = HashMap::new();
let value = get_core_sub_state_for_runtime(&mut state, "test".to_string());
assert!(value.is_empty());
assert!(state.contains_key("duckscriptsdk::runtime::test"));
}
#[test]
fn get_core_sub_state_for_command_valid() {
let mut state = HashMap::new();
let value = get_core_sub_state_for_command(&mut state, "test".to_string());
assert!(value.is_empty());
assert!(state.contains_key("duckscriptsdk::test"));
assert!(state.contains_key("duckscriptsdk::command::test"));
}
#[test]