mirror of
https://github.com/sagiegurari/duckscript
synced 2024-10-02 22:24:40 +00:00
New random_range and random_text commands #128
This commit is contained in:
parent
fb13d11187
commit
b267106753
|
@ -3,6 +3,7 @@
|
|||
### v0.6.7
|
||||
|
||||
* New --get-exit-code flag for exec command #127
|
||||
* New random_range and random_text commands #128
|
||||
* New semver_parse, semver_is_equal and semver_is_newer commands #129
|
||||
|
||||
### v0.6.6 (2020-08-14)
|
||||
|
|
57
docs/sdk.md
57
docs/sdk.md
|
@ -129,6 +129,8 @@
|
|||
* [std::process::ProcessID (pid, process_id)](#std__process__ProcessID)
|
||||
* [std::process::Spawn (spawn)](#std__process__Spawn)
|
||||
* [std::process::Watchdog (watchdog)](#std__process__Watchdog)
|
||||
* [std::random::Range (random_range, rand_range)](#std__random__Range)
|
||||
* [std::random::Text (random_text, rand_text)](#std__random__Text)
|
||||
* [std::scope::Clear (clear_scope)](#std__scope__Clear)
|
||||
* [std::scope::PopStack (scope_pop_stack)](#std__scope__PopStack)
|
||||
* [std::scope::PushStack (scope_push_stack)](#std__scope__PushStack)
|
||||
|
@ -4800,6 +4802,61 @@ assert_eq ${count} 4
|
|||
#### Aliases:
|
||||
watchdog
|
||||
|
||||
<a name="std__random__Range"></a>
|
||||
## std::random::Range
|
||||
```sh
|
||||
output = random_range min max
|
||||
```
|
||||
|
||||
Generate a random value in the range of min and max values provided, i.e. inclusive of min and exclusive of max.
|
||||
|
||||
#### Parameters
|
||||
|
||||
* min - The min range value (inclusive)
|
||||
* max - The max range value (exclusive)
|
||||
|
||||
#### Return Value
|
||||
|
||||
The generated numeric value.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
value = random_range -10 10
|
||||
echo ${value}
|
||||
```
|
||||
|
||||
|
||||
#### Aliases:
|
||||
random_range, rand_range
|
||||
|
||||
<a name="std__random__Text"></a>
|
||||
## std::random::Text
|
||||
```sh
|
||||
output = random_text [length]
|
||||
```
|
||||
|
||||
Generates random alphanumeric text with the requested length (length is 1 if not provided).
|
||||
|
||||
#### Parameters
|
||||
|
||||
Optional text length. Length is defaulted to 1 if not provided.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The generated alphanumeric value.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
value = random_text 50
|
||||
echo ${value}
|
||||
```
|
||||
|
||||
|
||||
#### Aliases:
|
||||
random_text, rand_text
|
||||
|
||||
<a name="std__scope__Clear"></a>
|
||||
## std::scope::Clear
|
||||
```sh
|
||||
|
|
|
@ -15,6 +15,7 @@ mod noop;
|
|||
mod not;
|
||||
pub(crate) mod on_error;
|
||||
mod process;
|
||||
mod random;
|
||||
mod read;
|
||||
pub(crate) mod release;
|
||||
pub(crate) mod scope;
|
||||
|
@ -51,6 +52,7 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> {
|
|||
net::load(commands, PACKAGE)?;
|
||||
on_error::load(commands, PACKAGE)?;
|
||||
process::load(commands, PACKAGE)?;
|
||||
random::load(commands, PACKAGE)?;
|
||||
scope::load(commands, PACKAGE)?;
|
||||
semver::load(commands, PACKAGE)?;
|
||||
string::load(commands, PACKAGE)?;
|
||||
|
|
17
duckscript_sdk/src/sdk/std/random/mod.rs
Executable file
17
duckscript_sdk/src/sdk/std/random/mod.rs
Executable file
|
@ -0,0 +1,17 @@
|
|||
mod range;
|
||||
mod text;
|
||||
|
||||
use crate::utils::pckg;
|
||||
use duckscript::types::command::Commands;
|
||||
use duckscript::types::error::ScriptError;
|
||||
|
||||
static PACKAGE: &str = "random";
|
||||
|
||||
pub(crate) fn load(commands: &mut Commands, parent: &str) -> Result<(), ScriptError> {
|
||||
let package = pckg::concat(parent, PACKAGE);
|
||||
|
||||
commands.set(range::create(&package))?;
|
||||
commands.set(text::create(&package))?;
|
||||
|
||||
Ok(())
|
||||
}
|
21
duckscript_sdk/src/sdk/std/random/range/help.md
Normal file
21
duckscript_sdk/src/sdk/std/random/range/help.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
```sh
|
||||
output = random_range min max
|
||||
```
|
||||
|
||||
Generate a random value in the range of min and max values provided, i.e. inclusive of min and exclusive of max.
|
||||
|
||||
#### Parameters
|
||||
|
||||
* min - The min range value (inclusive)
|
||||
* max - The max range value (exclusive)
|
||||
|
||||
#### Return Value
|
||||
|
||||
The generated numeric value.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
value = random_range -10 10
|
||||
echo ${value}
|
||||
```
|
69
duckscript_sdk/src/sdk/std/random/range/mod.rs
Executable file
69
duckscript_sdk/src/sdk/std/random/range/mod.rs
Executable file
|
@ -0,0 +1,69 @@
|
|||
use crate::utils::pckg;
|
||||
use duckscript::types::command::{Command, CommandResult};
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "./mod_test.rs"]
|
||||
mod mod_test;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CommandImpl {
|
||||
package: String,
|
||||
}
|
||||
|
||||
impl Command for CommandImpl {
|
||||
fn name(&self) -> String {
|
||||
pckg::concat(&self.package, "Range")
|
||||
}
|
||||
|
||||
fn aliases(&self) -> Vec<String> {
|
||||
vec!["random_range".to_string(), "rand_range".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 {
|
||||
if arguments.len() < 2 {
|
||||
CommandResult::Error("Missing random min/max values.".to_string())
|
||||
} else {
|
||||
match arguments[0].parse() {
|
||||
Ok(min) => match arguments[1].parse() {
|
||||
Ok(max) => {
|
||||
if min > max {
|
||||
CommandResult::Error(
|
||||
format!("Min value: {} bigger than max value: {}", min, max)
|
||||
.to_string(),
|
||||
)
|
||||
} else {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let min_128: i128 = min;
|
||||
let max_128: i128 = max;
|
||||
let rand_value: i128 = rng.gen_range(min_128, max_128);
|
||||
|
||||
CommandResult::Continue(Some(rand_value.to_string()))
|
||||
}
|
||||
}
|
||||
Err(_) => CommandResult::Error(
|
||||
format!("Non numeric max value: {} provided.", &arguments[1]).to_string(),
|
||||
),
|
||||
},
|
||||
Err(_) => CommandResult::Error(
|
||||
format!("Non numeric min value: {} provided.", &arguments[0]).to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create(package: &str) -> Box<dyn Command> {
|
||||
Box::new(CommandImpl {
|
||||
package: package.to_string(),
|
||||
})
|
||||
}
|
32
duckscript_sdk/src/sdk/std/random/range/mod_test.rs
Normal file
32
duckscript_sdk/src/sdk/std/random/range/mod_test.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use super::*;
|
||||
use crate::test;
|
||||
use crate::test::CommandValidation;
|
||||
|
||||
#[test]
|
||||
fn common_functions() {
|
||||
test::test_common_command_functions(create(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_no_args() {
|
||||
test::run_script_and_error(vec![create("")], "out = rand_range", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_single_arg() {
|
||||
test::run_script_and_error(vec![create("")], "out = rand_range 1", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_min_bigger_than_max() {
|
||||
test::run_script_and_error(vec![create("")], "out = rand_range 10 5", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_valid() {
|
||||
test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
"out = rand_range 10 15",
|
||||
CommandValidation::PositiveNumber("out".to_string()),
|
||||
);
|
||||
}
|
20
duckscript_sdk/src/sdk/std/random/text/help.md
Normal file
20
duckscript_sdk/src/sdk/std/random/text/help.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
```sh
|
||||
output = random_text [length]
|
||||
```
|
||||
|
||||
Generates random alphanumeric text with the requested length (length is 1 if not provided).
|
||||
|
||||
#### Parameters
|
||||
|
||||
Optional text length. Length is defaulted to 1 if not provided.
|
||||
|
||||
#### Return Value
|
||||
|
||||
The generated alphanumeric value.
|
||||
|
||||
#### Examples
|
||||
|
||||
```sh
|
||||
value = random_text 50
|
||||
echo ${value}
|
||||
```
|
64
duckscript_sdk/src/sdk/std/random/text/mod.rs
Executable file
64
duckscript_sdk/src/sdk/std/random/text/mod.rs
Executable file
|
@ -0,0 +1,64 @@
|
|||
use crate::utils::pckg;
|
||||
use duckscript::types::command::{Command, CommandResult};
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::iter;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "./mod_test.rs"]
|
||||
mod mod_test;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CommandImpl {
|
||||
package: String,
|
||||
}
|
||||
|
||||
impl Command for CommandImpl {
|
||||
fn name(&self) -> String {
|
||||
pckg::concat(&self.package, "Text")
|
||||
}
|
||||
|
||||
fn aliases(&self) -> Vec<String> {
|
||||
vec!["random_text".to_string(), "rand_text".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 length = if arguments.is_empty() {
|
||||
1
|
||||
} else {
|
||||
match arguments[0].parse() {
|
||||
Ok(value) => {
|
||||
let value_usize: usize = value;
|
||||
value_usize
|
||||
}
|
||||
Err(_) => {
|
||||
return CommandResult::Error(
|
||||
format!("Invalid length provided: {}", &arguments[0]).to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let random_value: String = iter::repeat(())
|
||||
.map(|()| rng.sample(Alphanumeric))
|
||||
.take(length)
|
||||
.collect();
|
||||
|
||||
CommandResult::Continue(Some(random_value))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create(package: &str) -> Box<dyn Command> {
|
||||
Box::new(CommandImpl {
|
||||
package: package.to_string(),
|
||||
})
|
||||
}
|
31
duckscript_sdk/src/sdk/std/random/text/mod_test.rs
Normal file
31
duckscript_sdk/src/sdk/std/random/text/mod_test.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use super::*;
|
||||
use crate::test;
|
||||
use crate::test::CommandValidation;
|
||||
|
||||
#[test]
|
||||
fn common_functions() {
|
||||
test::test_common_command_functions(create(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_no_args() {
|
||||
test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
"out = rand_text",
|
||||
CommandValidation::StringLength("out".to_string(), 1),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_invalid_size() {
|
||||
test::run_script_and_error(vec![create("")], "out = rand_text -10", "out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_valid_size() {
|
||||
test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
"out = rand_text 10",
|
||||
CommandValidation::StringLength("out".to_string(), 10),
|
||||
);
|
||||
}
|
|
@ -186,6 +186,7 @@ impl Command for OnErrorCommand {
|
|||
pub(crate) enum CommandValidation {
|
||||
None,
|
||||
PositiveNumber(String),
|
||||
StringLength(String, usize),
|
||||
Match(String, String),
|
||||
Contains(String, String),
|
||||
Any(String, Vec<String>),
|
||||
|
@ -295,6 +296,12 @@ pub(crate) fn run_script_and_validate(
|
|||
let numeric_value: u128 = var_value.parse().unwrap();
|
||||
assert!(numeric_value > 0)
|
||||
}
|
||||
CommandValidation::StringLength(key, length) => {
|
||||
assert!(!context.variables.is_empty());
|
||||
|
||||
let var_value = context.variables.get(&key).unwrap();
|
||||
assert!(var_value.len() == length)
|
||||
}
|
||||
CommandValidation::Ignore => {
|
||||
assert!(!context.variables.is_empty());
|
||||
}
|
||||
|
|
11
test/std/random/random_range_test.ds
Normal file
11
test/std/random/random_range_test.ds
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
fn test_valid
|
||||
value = random_range -10 10
|
||||
|
||||
in_min = greater_than ${value} -11
|
||||
in_max = greater_than 10 ${value}
|
||||
|
||||
assert ${in_min}
|
||||
assert ${in_max}
|
||||
end
|
||||
|
17
test/std/random/random_text_test.ds
Normal file
17
test/std/random/random_text_test.ds
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
fn test_no_length
|
||||
value = random_text
|
||||
|
||||
len = strlen ${value}
|
||||
|
||||
assert_eq ${len} 1
|
||||
end
|
||||
|
||||
fn test_with_length
|
||||
value = random_text 50
|
||||
|
||||
len = strlen ${value}
|
||||
|
||||
assert_eq ${len} 50
|
||||
end
|
||||
|
Loading…
Reference in a new issue