use flowcode_core::executor::{ExecuteResult, Executor};
use flowcode_core::parser::ParsedCommand;
use flowcode_core::logger::Logger;
use flowcode_core::error::FCError;
use flowcode_core::ast::ArgValue;
fn pc(name: &str, args: Vec<ArgValue>) -> ParsedCommand {
ParsedCommand { name: name.to_string(), args }
}
#[test]
fn test_execute_combine_success_and_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc("combine", vec![ArgValue::Number(10.0), ArgValue::Number(20.0), ArgValue::Number(30.0)]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Success("60".to_string())
);
assert_eq!(logger.get_logs().len(), 2);
assert_eq!(
logger.get_logs()[0],
"Executing COMBINE"
);
assert_eq!(
logger.get_logs()[1],
"Executed COMBINE with args [TypedValue { kind: Number, value: Number(10.0) }, TypedValue { kind: Number, value: Number(20.0) }, TypedValue { kind: Number, value: Number(30.0) }] -> 60"
);
}
#[test]
fn test_execute_combine_no_args_and_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc("combine", vec![]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Success("-0".to_string())
);
assert_eq!(logger.get_logs().len(), 2);
assert_eq!(
logger.get_logs()[0],
"Executing COMBINE"
);
assert_eq!(
logger.get_logs()[1],
"Executed COMBINE with args [] -> -0"
);
}
#[test]
fn test_execute_combine_invalid_arg_no_log_for_success() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc(
"combine",
vec![ArgValue::Number(10.0), ArgValue::String("abc".to_string()), ArgValue::Number(20.0)],
);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Error(FCError::InvalidArgument("combine command requires numeric arguments".to_string()))
);
assert_eq!(logger.get_logs().len(), 2);
assert_eq!(
logger.get_logs()[0],
"Executing COMBINE"
);
assert_eq!(
logger.get_logs()[1],
"Attempted COMBINE with invalid args: [TypedValue { kind: Number, value: Number(10.0) }, TypedValue { kind: String, value: String(\"abc\") }, TypedValue { kind: Number, value: Number(20.0) }]"
);
}
#[test]
fn test_execute_predict_success_and_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc(
"predict",
vec![
ArgValue::Number(10.0),
ArgValue::Number(20.0),
ArgValue::Number(30.0),
ArgValue::Number(40.0),
],
);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Success(format!("Prediction: {}", 50.0))
);
assert_eq!(logger.get_logs().len(), 2);
assert_eq!(
logger.get_logs()[0],
"Executing PREDICT"
);
assert_eq!(
logger.get_logs()[1],
"Executed PREDICT with args [TypedValue { kind: Number, value: Number(10.0) }, TypedValue { kind: Number, value: Number(20.0) }, TypedValue { kind: Number, value: Number(30.0) }, TypedValue { kind: Number, value: Number(40.0) }] -> Prediction: 50"
);
}
#[test]
fn test_execute_predict_insufficient_data_and_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc("predict", vec![ArgValue::Number(10.0)]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Error(FCError::InsufficientData("predict command requires at least two numeric arguments".to_string()))
);
assert_eq!(logger.get_logs().len(), 2);
assert_eq!(
logger.get_logs()[0],
"Executing PREDICT"
);
assert_eq!(
logger.get_logs()[1],
"Attempted PREDICT with insufficient args: [TypedValue { kind: Number, value: Number(10.0) }]"
);
}
#[test]
fn test_execute_show_no_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc("show", vec![]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Success("Executing SHOW".to_string())
);
assert_eq!(logger.get_logs().len(), 1);
assert_eq!(
logger.get_logs()[0],
"Executing SHOW"
);
}
#[test]
fn test_execute_show_with_logs() {
let executor = Executor::new();
let mut logger = Logger::new(10);
logger.log_action("Log 1".to_string());
logger.log_action("Log 2: another event".to_string());
let command = pc("show", vec![]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Success("Log 1\nLog 2: another event\nExecuting SHOW".to_string())
);
assert_eq!(logger.get_logs().len(), 3);
assert_eq!(
logger.get_logs()[2],
"Executing SHOW"
);
}
#[test]
fn test_execute_show_with_args_error() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc("show", vec![ArgValue::String("unexpected".to_string())]);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Error(FCError::InvalidArgument("show command does not take arguments".to_string()))
);
assert_eq!(logger.get_logs().len(), 1);
assert_eq!(
logger.get_logs()[0],
"Executing SHOW"
);
}
#[test]
fn test_execute_unknown_command() {
let executor = Executor::new();
let mut logger = Logger::new(10);
let command = pc(
"fly",
vec![ArgValue::String("to".to_string()), ArgValue::String("moon".to_string())],
);
assert_eq!(
executor.execute_command(&command, &mut logger),
ExecuteResult::Error(FCError::UnknownCommand("Command 'fly' is recognized but not implemented.".to_string()))
);
assert_eq!(logger.get_logs().len(), 1);
assert_eq!(
logger.get_logs()[0],
"Executing FLY"
);
}