Skip to content

Commit

Permalink
Merge pull request #194 from lilopkins/develop
Browse files Browse the repository at this point in the history
0.21.0-rc.6
  • Loading branch information
lilopkins authored Apr 30, 2024
2 parents 7813af1 + 99b3aab commit 2000b2e
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 42 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/rust-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ jobs:
cargo build -p testangel --bin testangel --release
cargo build -p testangel --bin testangel-executor --no-default-features --features cli --release
cargo build -p testangel-evidence --release
cargo build -p testangel-rand --release
cargo build -p testangel-user-interaction --release
# Prepare output dir
mkdir -p build || exit 1
Expand All @@ -106,6 +107,7 @@ jobs:
# Prepare engines
mkdir -p build/engines || exit 1
cp target/release/libtestangel_evidence.so build/engines
cp target/release/libtestangel_rand.so build/engines
cp target/release/libtestangel_user_interaction.so build/engines
- name: Save Cargo cache
Expand Down Expand Up @@ -217,6 +219,7 @@ jobs:
cargo build -p testangel --bin testangel --release
cargo build -p testangel --bin testangel-executor --no-default-features --features cli --release
cargo build -p testangel-evidence --release
cargo build -p testangel-rand --release
cargo build -p testangel-user-interaction --release
mkdir build
copy target/release/testangel.exe build/
Expand All @@ -226,6 +229,7 @@ jobs:
copy C:\gtk-build\gtk\x64\release\bin\*.dll build/
mkdir build/engines
copy target/release/testangel_evidence.dll build/engines/
copy target/release/testangel_rand.dll build/engines/
copy target/release/testangel_user_interaction.dll build/engines/
# GSchemas for FileChooser
Expand Down
42 changes: 36 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace.package]
version = "0.21.0-pre.5"
version = "0.21.0-rc.6"
edition = "2021"

[workspace]
Expand All @@ -9,6 +9,8 @@ members = [
"testangel-engine",
"testangel-engine-macros",
"testangel-evidence",
"testangel-rand",
"testangel-time",
"testangel-ipc",
"testangel-user-interaction",
]
18 changes: 18 additions & 0 deletions testangel-rand/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "testangel-rand"
authors = ["Lily Hopkins <[email protected]>"]
description = "A randomisation engine plugin for testangel."
version.workspace = true
edition.workspace = true

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lazy_static = "1.4.0"
rand = "0.8.5"
rand_regex = "0.17.0"
testangel-engine = { path = "../testangel-engine" }
thiserror = "1.0"
41 changes: 41 additions & 0 deletions testangel-rand/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::sync::Mutex;

use lazy_static::lazy_static;
use rand::Rng;
use testangel_engine::*;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum EngineError {
#[error("Couldn't build expression.")]
CouldntBuildExpression(#[from] rand_regex::Error),
}

lazy_static! {
static ref ENGINE: Mutex<Engine<'static, ()>> = Mutex::new(
Engine::new("Random", "Random", env!("CARGO_PKG_VERSION")).with_instruction(
Instruction::new(
"rand-string",
"StringByRegex",
"Random String by Regex",
"Generate a random string given the regular expression-like format you provide.",
)
.with_parameter("regex", "Regular Expression", ParameterKind::String)
.with_output("result", "Result", ParameterKind::String),
|_state, params, output, _evidence| {
let regex = params["regex"].value_string();

let expr = rand_regex::Regex::compile(&regex, 32)
.map_err(EngineError::CouldntBuildExpression)?;
output.insert(
"result".to_string(),
ParameterValue::String(rand::thread_rng().sample(&expr)),
);

Ok(())
}
)
);
}

expose_engine!(ENGINE);
16 changes: 16 additions & 0 deletions testangel-time/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "testangel-time"
authors = ["Lily Hopkins <[email protected]>"]
description = "A time engine plugin for testangel."
version.workspace = true
edition.workspace = true

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lazy_static = "1.4.0"
testangel-engine = { path = "../testangel-engine" }
thiserror = "1.0"
35 changes: 35 additions & 0 deletions testangel-time/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::{sync::Mutex, thread::sleep, time::Duration};

use lazy_static::lazy_static;
use testangel_engine::*;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum EngineError {
#[error("Duration cannot be negative.")]
CantWaitNegative,
}

lazy_static! {
static ref ENGINE: Mutex<Engine<'static, ()>> = Mutex::new(
Engine::new("Time", "Time", env!("CARGO_PKG_VERSION")).with_instruction(
Instruction::new(
"time-wait",
"Wait",
"Wait",
"Wait for a specified number of milliseconds.",
)
.with_parameter("duration", "Duration (ms)", ParameterKind::Decimal),
|_state, params, _output, _evidence| {
let duration = params["duration"].value_i32();
if duration < 0 {
return Err(Box::new(EngineError::CantWaitNegative));
}
sleep(Duration::from_millis(duration as u64));
Ok(())
}
)
);
}

expose_engine!(ENGINE);
2 changes: 1 addition & 1 deletion testangel/src/types/action_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl ActionV1 {
line.push_str(&match &step.run_if {
InstructionParameterSource::Literal => String::new(),
InstructionParameterSource::FromOutput(step, name) => {
format!("if s{step}_{} then ", name.to_case(Case::Snake))
format!("if s{}_{} then ", step + 1, name.to_case(Case::Snake))
}
InstructionParameterSource::FromParameter(param) => format!(
"if {} then ",
Expand Down
93 changes: 60 additions & 33 deletions testangel/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ pub enum FlowError {
IPCFailure(IpcError),
ActionDidntReturnCorrectArgumentCount,
ActionDidntReturnValidArguments,
InstructionCalledWithUnsupportedVarType,
InstructionCalledWithWrongNumberOfParams,
InstructionCalledWithInvalidParamType,
}
Expand All @@ -152,10 +151,6 @@ impl fmt::Display for FlowError {
Self::ActionDidntReturnValidArguments => {
write!(f, "The action didn't return valid values.")
}
Self::InstructionCalledWithUnsupportedVarType => write!(
f,
"An instruction was called with an unsupported variable type."
),
Self::InstructionCalledWithWrongNumberOfParams => write!(
f,
"An instruction was called with the wrong number of parameters."
Expand Down Expand Up @@ -258,37 +253,65 @@ impl ActionConfiguration {
));
}

// Convert to TA params
let mut params = vec![];
for param in &args {
match param {
mlua::Value::Boolean(b) => params.push(ParameterValue::Boolean(*b)),
mlua::Value::String(s) => params
.push(ParameterValue::String(s.to_str().unwrap().to_owned())),
mlua::Value::Integer(i) => params.push(ParameterValue::Integer(*i)),
mlua::Value::Number(n) => {
params.push(ParameterValue::Decimal(*n as f32))
}
_ => {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithUnsupportedVarType,
))
}
}
}

// Check we have the correct parameter types and convert to parameter map
let mut param_map = HashMap::new();
for (value, param_id) in
std::iter::zip(params, instruction.parameter_order())
{
for (idx, param_id) in instruction.parameter_order().iter().enumerate() {
if let Some((_name, kind)) = instruction.parameters().get(param_id) {
if *kind != value.kind() {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithInvalidParamType,
));
// Get argument and coerce
let arg = args[idx].clone();
match kind {
ParameterKind::Boolean => {
if let mlua::Value::Boolean(b) = arg {
param_map.insert(
param_id.clone(),
ParameterValue::Boolean(b),
);
} else {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithInvalidParamType,
));
}
}
ParameterKind::String => {
let maybe_str = lua.coerce_string(arg)?;
if let Some(s) = maybe_str {
param_map.insert(
param_id.clone(),
ParameterValue::String(s.to_str()?.to_string()),
);
} else {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithInvalidParamType,
));
}
}
ParameterKind::Decimal => {
let maybe_dec = lua.coerce_number(arg)?;
if let Some(d) = maybe_dec {
param_map.insert(
param_id.clone(),
ParameterValue::Decimal(d as f32),
);
} else {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithInvalidParamType,
));
}
}
ParameterKind::Integer => {
let maybe_int = lua.coerce_integer(arg)?;
if let Some(i) = maybe_int {
param_map.insert(
param_id.clone(),
ParameterValue::Integer(i),
);
} else {
return Err(mlua::Error::external(
FlowError::InstructionCalledWithInvalidParamType,
));
}
}
}
param_map.insert(param_id.clone(), value);
}
}

Expand Down Expand Up @@ -318,21 +341,25 @@ impl ActionConfiguration {
let o = output[0][output_id].clone();
match o {
ParameterValue::Boolean(b) => {
log::debug!("Boolean {b} returned to Lua");
outputs.push(mlua::Value::Boolean(b))
}
ParameterValue::String(s) => {
log::debug!("String {s:?} returned to Lua");
outputs.push(mlua::Value::String(lua.create_string(s)?))
}
ParameterValue::Integer(i) => {
log::debug!("Integer {i} returned to Lua");
outputs.push(mlua::Value::Integer(i))
}
ParameterValue::Decimal(n) => {
log::debug!("Decimal {n} returned to Lua");
outputs.push(mlua::Value::Number(n as f64))
}
}
}

Ok(outputs)
Ok(mlua::MultiValue::from_vec(outputs))
}
Response::Error { kind, reason } => {
Err(mlua::Error::external(FlowError::FromInstruction {
Expand Down
Loading

0 comments on commit 2000b2e

Please sign in to comment.