forked from extern/nushell
Merge pull request #1016 from andrasio/str
replace and find-replace str plugin additions.
This commit is contained in:
commit
186b75a848
@ -263,6 +263,10 @@ impl Value {
|
|||||||
Ok(ColumnPath::new(out).tagged(&self.tag))
|
Ok(ColumnPath::new(out).tagged(&self.tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UntaggedValue::Primitive(Primitive::String(s)) => {
|
||||||
|
Ok(ColumnPath::new(vec![PathMember::string(s, &self.tag.span)]).tagged(&self.tag))
|
||||||
|
}
|
||||||
|
|
||||||
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
|
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
|
||||||
Ok(path.clone().tagged(self.tag.clone()))
|
Ok(path.clone().tagged(self.tag.clone()))
|
||||||
}
|
}
|
||||||
@ -299,6 +303,9 @@ impl Value {
|
|||||||
UntaggedValue::Primitive(Primitive::Int(x)) => Ok(format!("{}", x)),
|
UntaggedValue::Primitive(Primitive::Int(x)) => Ok(format!("{}", x)),
|
||||||
UntaggedValue::Primitive(Primitive::Bytes(x)) => Ok(format!("{}", x)),
|
UntaggedValue::Primitive(Primitive::Bytes(x)) => Ok(format!("{}", x)),
|
||||||
UntaggedValue::Primitive(Primitive::Path(x)) => Ok(format!("{}", x.display())),
|
UntaggedValue::Primitive(Primitive::Path(x)) => Ok(format!("{}", x.display())),
|
||||||
|
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
|
||||||
|
Ok(path.iter().map(|member| member.display()).join("."))
|
||||||
|
}
|
||||||
// TODO: this should definitely be more general with better errors
|
// TODO: this should definitely be more general with better errors
|
||||||
other => Err(ShellError::labeled_error(
|
other => Err(ShellError::labeled_error(
|
||||||
"Expected string",
|
"Expected string",
|
||||||
|
@ -4,6 +4,7 @@ use nu::{
|
|||||||
};
|
};
|
||||||
use nu_source::{span_for_spanned_list, Tagged};
|
use nu_source::{span_for_spanned_list, Tagged};
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@ -12,11 +13,17 @@ enum Action {
|
|||||||
Upcase,
|
Upcase,
|
||||||
ToInteger,
|
ToInteger,
|
||||||
Substring(usize, usize),
|
Substring(usize, usize),
|
||||||
|
Replace(ReplaceAction),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
enum ReplaceAction {
|
||||||
|
Direct(String),
|
||||||
|
FindAndReplace(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Str {
|
struct Str {
|
||||||
field: Option<Tagged<ColumnPath>>,
|
field: Option<Tagged<ColumnPath>>,
|
||||||
params: Option<Vec<String>>,
|
|
||||||
error: Option<String>,
|
error: Option<String>,
|
||||||
action: Option<Action>,
|
action: Option<Action>,
|
||||||
}
|
}
|
||||||
@ -25,7 +32,6 @@ impl Str {
|
|||||||
fn new() -> Str {
|
fn new() -> Str {
|
||||||
Str {
|
Str {
|
||||||
field: None,
|
field: None,
|
||||||
params: Some(Vec::<String>::new()),
|
|
||||||
error: None,
|
error: None,
|
||||||
action: None,
|
action: None,
|
||||||
}
|
}
|
||||||
@ -50,6 +56,19 @@ impl Str {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(Action::Replace(mode)) => match mode {
|
||||||
|
ReplaceAction::Direct(replacement) => UntaggedValue::string(replacement.as_str()),
|
||||||
|
ReplaceAction::FindAndReplace(find, replacement) => {
|
||||||
|
let regex = Regex::new(find.as_str());
|
||||||
|
|
||||||
|
match regex {
|
||||||
|
Ok(re) => UntaggedValue::string(
|
||||||
|
re.replace(input, replacement.as_str()).to_owned(),
|
||||||
|
),
|
||||||
|
Err(_) => UntaggedValue::string(input),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(Action::ToInteger) => match input.trim() {
|
Some(Action::ToInteger) => match input.trim() {
|
||||||
other => match other.parse::<i64>() {
|
other => match other.parse::<i64>() {
|
||||||
Ok(v) => UntaggedValue::int(v),
|
Ok(v) => UntaggedValue::int(v),
|
||||||
@ -117,8 +136,16 @@ impl Str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn for_replace(&mut self, mode: ReplaceAction) {
|
||||||
|
if self.permit() {
|
||||||
|
self.action = Some(Action::Replace(mode));
|
||||||
|
} else {
|
||||||
|
self.log_error("can only apply one");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn usage() -> &'static str {
|
pub fn usage() -> &'static str {
|
||||||
"Usage: str field [--downcase|--upcase|--to-int|--substring \"start,end\"]"
|
"Usage: str field [--downcase|--upcase|--to-int|--substring \"start,end\"|--replace|--find-replace [pattern replacement]]]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +213,12 @@ impl Plugin for Str {
|
|||||||
.switch("downcase", "convert string to lowercase")
|
.switch("downcase", "convert string to lowercase")
|
||||||
.switch("upcase", "convert string to uppercase")
|
.switch("upcase", "convert string to uppercase")
|
||||||
.switch("to-int", "convert string to integer")
|
.switch("to-int", "convert string to integer")
|
||||||
|
.named("replace", SyntaxShape::String, "replaces the string")
|
||||||
|
.named(
|
||||||
|
"find-replace",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"finds and replaces [pattern replacement]",
|
||||||
|
)
|
||||||
.named(
|
.named(
|
||||||
"substring",
|
"substring",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
@ -226,21 +259,33 @@ impl Plugin for Str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if args.has("replace") {
|
||||||
|
if let Some(Value {
|
||||||
|
value: UntaggedValue::Primitive(Primitive::String(replacement)),
|
||||||
|
..
|
||||||
|
}) = args.get("replace")
|
||||||
|
{
|
||||||
|
self.for_replace(ReplaceAction::Direct(replacement.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.has("find-replace") {
|
||||||
|
if let Some(Value {
|
||||||
|
value: UntaggedValue::Table(arguments),
|
||||||
|
..
|
||||||
|
}) = args.get("find-replace")
|
||||||
|
{
|
||||||
|
self.for_replace(ReplaceAction::FindAndReplace(
|
||||||
|
arguments.get(0).unwrap().as_string()?,
|
||||||
|
arguments.get(1).unwrap().as_string()?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(possible_field) = args.nth(0) {
|
if let Some(possible_field) = args.nth(0) {
|
||||||
let possible_field = possible_field.as_column_path()?;
|
let possible_field = possible_field.as_column_path()?;
|
||||||
|
|
||||||
self.for_field(possible_field);
|
self.for_field(possible_field);
|
||||||
}
|
}
|
||||||
for param in args.positional_iter() {
|
|
||||||
match param {
|
|
||||||
Value {
|
|
||||||
value: UntaggedValue::Primitive(Primitive::String(s)),
|
|
||||||
..
|
|
||||||
} => self.params.as_mut().unwrap().push(String::from(s)),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match &self.error {
|
match &self.error {
|
||||||
Some(reason) => {
|
Some(reason) => {
|
||||||
@ -265,15 +310,32 @@ fn main() {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Action, Str};
|
use super::{Action, ReplaceAction, Str};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu::{
|
use nu::{
|
||||||
CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, TaggedDictBuilder,
|
CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, TaggedDictBuilder,
|
||||||
UnspannedPathMember, UntaggedValue, Value,
|
UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
|
fn string(input: impl Into<String>) -> Value {
|
||||||
|
UntaggedValue::string(input.into()).into_untagged_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table(list: &Vec<Value>) -> Value {
|
||||||
|
UntaggedValue::table(list).into_untagged_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn column_path(paths: &Vec<Value>) -> Value {
|
||||||
|
UntaggedValue::Primitive(Primitive::ColumnPath(
|
||||||
|
table(&paths.iter().cloned().collect())
|
||||||
|
.as_column_path()
|
||||||
|
.unwrap()
|
||||||
|
.item,
|
||||||
|
))
|
||||||
|
.into_untagged_value()
|
||||||
|
}
|
||||||
struct CallStub {
|
struct CallStub {
|
||||||
positionals: Vec<Value>,
|
positionals: Vec<Value>,
|
||||||
flags: IndexMap<String, Value>,
|
flags: IndexMap<String, Value>,
|
||||||
@ -287,11 +349,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_named_parameter(&mut self, name: &str, value: &str) -> &mut Self {
|
fn with_named_parameter(&mut self, name: &str, value: Value) -> &mut Self {
|
||||||
self.flags.insert(
|
self.flags.insert(name.to_string(), value);
|
||||||
name.to_string(),
|
|
||||||
UntaggedValue::string(value).into_value(Tag::unknown()),
|
|
||||||
);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +368,7 @@ mod tests {
|
|||||||
.map(|s| UntaggedValue::string(s.to_string()).into_value(Tag::unknown()))
|
.map(|s| UntaggedValue::string(s.to_string()).into_value(Tag::unknown()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.positionals
|
self.positionals.push(column_path(&fields));
|
||||||
.push(UntaggedValue::Table(fields).into_value(Tag::unknown()));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +396,14 @@ mod tests {
|
|||||||
|
|
||||||
let configured = plugin.config().unwrap();
|
let configured = plugin.config().unwrap();
|
||||||
|
|
||||||
for action_flag in &["downcase", "upcase", "to-int"] {
|
for action_flag in &[
|
||||||
|
"downcase",
|
||||||
|
"upcase",
|
||||||
|
"to-int",
|
||||||
|
"substring",
|
||||||
|
"replace",
|
||||||
|
"find-replace",
|
||||||
|
] {
|
||||||
assert!(configured.named.get(*action_flag).is_some());
|
assert!(configured.named.get(*action_flag).is_some());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,6 +437,55 @@ mod tests {
|
|||||||
.is_ok());
|
.is_ok());
|
||||||
assert_eq!(plugin.action.unwrap(), Action::ToInteger);
|
assert_eq!(plugin.action.unwrap(), Action::ToInteger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_accepts_replace() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
let argument = String::from("replace_text");
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_named_parameter("replace", string(&argument))
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
match plugin.action {
|
||||||
|
Some(Action::Replace(ReplaceAction::Direct(replace_with))) => {
|
||||||
|
assert_eq!(replace_with, argument)
|
||||||
|
}
|
||||||
|
Some(_) | None => panic!("Din't accept."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_accepts_find_replace() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
let search_argument = String::from("kittens");
|
||||||
|
let replace_argument = String::from("jotandrehuda");
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_named_parameter(
|
||||||
|
"find-replace",
|
||||||
|
table(&vec![string(&search_argument), string(&replace_argument)])
|
||||||
|
)
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
match plugin.action {
|
||||||
|
Some(Action::Replace(ReplaceAction::FindAndReplace(find_with, replace_with))) => {
|
||||||
|
assert_eq!(find_with, search_argument);
|
||||||
|
assert_eq!(replace_with, replace_argument);
|
||||||
|
}
|
||||||
|
Some(_) | None => panic!("Din't accept."),
|
||||||
|
}
|
||||||
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn str_plugin_accepts_field() {
|
fn str_plugin_accepts_field() {
|
||||||
let mut plugin = Str::new();
|
let mut plugin = Str::new();
|
||||||
@ -384,14 +498,13 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
|
|
||||||
|
let actual = &*plugin.field.unwrap();
|
||||||
|
let actual = UntaggedValue::Primitive(Primitive::ColumnPath(actual.clone()));
|
||||||
|
let actual = actual.into_value(Tag::unknown());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
plugin
|
actual,
|
||||||
.field
|
column_path(&vec![string("package"), string("description")])
|
||||||
.map(|f| f.iter().cloned().map(|f| f.unspanned).collect()),
|
|
||||||
Some(vec![
|
|
||||||
UnspannedPathMember::String("package".to_string()),
|
|
||||||
UnspannedPathMember::String("description".to_string())
|
|
||||||
])
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,6 +555,30 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_replace() {
|
||||||
|
let mut strutils = Str::new();
|
||||||
|
strutils.for_replace(ReplaceAction::Direct("robalino".to_string()));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
strutils.apply("andres").unwrap(),
|
||||||
|
UntaggedValue::string("robalino")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_find_replace() {
|
||||||
|
let mut strutils = Str::new();
|
||||||
|
strutils.for_replace(ReplaceAction::FindAndReplace(
|
||||||
|
"kittens".to_string(),
|
||||||
|
"jotandrehuda".to_string(),
|
||||||
|
));
|
||||||
|
assert_eq!(
|
||||||
|
strutils.apply("wykittens").unwrap(),
|
||||||
|
UntaggedValue::string("wyjotandrehuda")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn str_plugin_applies_upcase_with_field() {
|
fn str_plugin_applies_upcase_with_field() {
|
||||||
let mut plugin = Str::new();
|
let mut plugin = Str::new();
|
||||||
@ -593,7 +730,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", "0,1")
|
.with_named_parameter("substring", string("0,1"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
@ -617,7 +754,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", "0,11")
|
.with_named_parameter("substring", string("0,11"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
@ -641,7 +778,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", "20,30")
|
.with_named_parameter("substring", string("20,30"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
@ -665,7 +802,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", ",5")
|
.with_named_parameter("substring", string(",5"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
@ -689,7 +826,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", "2,")
|
.with_named_parameter("substring", string("2,"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
@ -713,7 +850,7 @@ mod tests {
|
|||||||
assert!(plugin
|
assert!(plugin
|
||||||
.begin_filter(
|
.begin_filter(
|
||||||
CallStub::new()
|
CallStub::new()
|
||||||
.with_named_parameter("substring", "3,1")
|
.with_named_parameter("substring", string("3,1"))
|
||||||
.create()
|
.create()
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
@ -722,4 +859,120 @@ mod tests {
|
|||||||
Some("End must be greater than or equal to Start".to_string())
|
Some("End must be greater than or equal to Start".to_string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_applies_replace_with_field() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_parameter("rustconf")
|
||||||
|
.with_named_parameter("replace", string("22nd August 2019"))
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let subject = structured_sample_record("rustconf", "1st January 1970");
|
||||||
|
let output = plugin.filter(subject).unwrap();
|
||||||
|
|
||||||
|
match output[0].as_ref().unwrap() {
|
||||||
|
ReturnSuccess::Value(Value {
|
||||||
|
value: UntaggedValue::Row(o),
|
||||||
|
..
|
||||||
|
}) => assert_eq!(
|
||||||
|
*o.get_data(&String::from("rustconf")).borrow(),
|
||||||
|
Value {
|
||||||
|
value: UntaggedValue::string(String::from("22nd August 2019")),
|
||||||
|
tag: Tag::unknown()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_applies_replace_without_field() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_named_parameter("replace", string("22nd August 2019"))
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let subject = unstructured_sample_record("1st January 1970");
|
||||||
|
let output = plugin.filter(subject).unwrap();
|
||||||
|
|
||||||
|
match output[0].as_ref().unwrap() {
|
||||||
|
ReturnSuccess::Value(Value {
|
||||||
|
value: UntaggedValue::Primitive(Primitive::String(s)),
|
||||||
|
..
|
||||||
|
}) => assert_eq!(*s, String::from("22nd August 2019")),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_applies_find_replace_with_field() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_parameter("staff")
|
||||||
|
.with_named_parameter(
|
||||||
|
"find-replace",
|
||||||
|
table(&vec![string("kittens"), string("jotandrehuda")])
|
||||||
|
)
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let subject = structured_sample_record("staff", "wykittens");
|
||||||
|
let output = plugin.filter(subject).unwrap();
|
||||||
|
|
||||||
|
match output[0].as_ref().unwrap() {
|
||||||
|
ReturnSuccess::Value(Value {
|
||||||
|
value: UntaggedValue::Row(o),
|
||||||
|
..
|
||||||
|
}) => assert_eq!(
|
||||||
|
*o.get_data(&String::from("staff")).borrow(),
|
||||||
|
Value {
|
||||||
|
value: UntaggedValue::string(String::from("wyjotandrehuda")),
|
||||||
|
tag: Tag::unknown()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn str_plugin_applies_find_replace_without_field() {
|
||||||
|
let mut plugin = Str::new();
|
||||||
|
|
||||||
|
assert!(plugin
|
||||||
|
.begin_filter(
|
||||||
|
CallStub::new()
|
||||||
|
.with_named_parameter(
|
||||||
|
"find-replace",
|
||||||
|
table(&vec![string("kittens"), string("jotandrehuda")])
|
||||||
|
)
|
||||||
|
.create()
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let subject = unstructured_sample_record("wykittens");
|
||||||
|
let output = plugin.filter(subject).unwrap();
|
||||||
|
|
||||||
|
match output[0].as_ref().unwrap() {
|
||||||
|
ReturnSuccess::Value(Value {
|
||||||
|
value: UntaggedValue::Primitive(Primitive::String(s)),
|
||||||
|
..
|
||||||
|
}) => assert_eq!(*s, String::from("wyjotandrehuda")),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ fn can_only_apply_one() {
|
|||||||
"open caco3_plastics.csv | first 1 | str origin --downcase --upcase"
|
"open caco3_plastics.csv | first 1 | str origin --downcase --upcase"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(actual.contains("Usage: str field [--downcase|--upcase|--to-int"));
|
assert!(actual.contains(r#"--downcase|--upcase|--to-int|--substring "start,end"|--replace|--find-replace [pattern replacement]]"#));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -90,3 +90,78 @@ fn converts_to_int() {
|
|||||||
|
|
||||||
assert_eq!(actual, "2509000000");
|
assert_eq!(actual, "2509000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn replaces() {
|
||||||
|
Playground::setup("plugin_str_test_4", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContent(
|
||||||
|
"sample.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "nushell"
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), h::pipeline(
|
||||||
|
r#"
|
||||||
|
open sample.toml
|
||||||
|
| str package.name --replace wykittenshell
|
||||||
|
| get package.name
|
||||||
|
| echo $it
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual, "wykittenshell");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_and_replaces() {
|
||||||
|
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContent(
|
||||||
|
"sample.toml",
|
||||||
|
r#"
|
||||||
|
[fortune.teller]
|
||||||
|
phone = "1-800-KATZ"
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), h::pipeline(
|
||||||
|
r#"
|
||||||
|
open sample.toml
|
||||||
|
| str fortune.teller.phone --find-replace [KATZ 5289]
|
||||||
|
| get fortune.teller.phone
|
||||||
|
| echo $it
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual, "1-800-5289");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_and_replaces_without_passing_field() {
|
||||||
|
Playground::setup("plugin_str_test_6", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContent(
|
||||||
|
"sample.toml",
|
||||||
|
r#"
|
||||||
|
[fortune.teller]
|
||||||
|
phone = "1-800-KATZ"
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), h::pipeline(
|
||||||
|
r#"
|
||||||
|
open sample.toml
|
||||||
|
| get fortune.teller.phone
|
||||||
|
| str --find-replace [KATZ 5289]
|
||||||
|
| echo $it
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual, "1-800-5289");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user