mirror of
https://github.com/nushell/nushell.git
synced 2025-03-25 14:07:26 +01:00
str plugin can capitalize and trim strings. (#1652)
* Str plugin can capitalize. * Str plugin can trim.
This commit is contained in:
parent
716c4def03
commit
10768b6ecf
@ -15,9 +15,11 @@ impl Plugin for Str {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
Ok(Signature::build("str")
|
||||
.desc("Apply string function. Optional use the column of a table")
|
||||
.switch("capitalize", "capitalizes the string", Some('c'))
|
||||
.switch("downcase", "convert string to lowercase", Some('d'))
|
||||
.switch("upcase", "convert string to uppercase", Some('U'))
|
||||
.switch("to-int", "convert string to integer", Some('i'))
|
||||
.switch("trim", "trims the string", Some('t'))
|
||||
.named(
|
||||
"replace",
|
||||
SyntaxShape::String,
|
||||
@ -49,6 +51,12 @@ impl Plugin for Str {
|
||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
||||
let args = call_info.args;
|
||||
|
||||
if args.has("trim") {
|
||||
self.for_trim();
|
||||
}
|
||||
if args.has("capitalize") {
|
||||
self.for_capitalize();
|
||||
}
|
||||
if args.has("downcase") {
|
||||
self.for_downcase();
|
||||
}
|
||||
|
@ -56,6 +56,20 @@ mod integration {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_up_trim_flag() {
|
||||
plugin(&mut Str::new())
|
||||
.args(CallStub::new().with_long_flag("trim").create())
|
||||
.setup(|plugin, _| plugin.expect_action(Action::Trim));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_up_capitalize_flag() {
|
||||
plugin(&mut Str::new())
|
||||
.args(CallStub::new().with_long_flag("capitalize").create())
|
||||
.setup(|plugin, _| plugin.expect_action(Action::Capitalize));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_up_downcase_flag() {
|
||||
plugin(&mut Str::new())
|
||||
@ -169,6 +183,44 @@ mod integration {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trims_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(
|
||||
CallStub::new()
|
||||
.with_long_flag("trim")
|
||||
.with_parameter("name")?
|
||||
.create(),
|
||||
)
|
||||
.input(structured_sample_record("name", "andres "))
|
||||
.setup(|_, _| {})
|
||||
.test();
|
||||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
|
||||
assert_eq!(get_data(actual, "name"), string("andres"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capitalizes_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(
|
||||
CallStub::new()
|
||||
.with_long_flag("capitalize")
|
||||
.with_parameter("name")?
|
||||
.create(),
|
||||
)
|
||||
.input(structured_sample_record("name", "andres"))
|
||||
.setup(|_, _| {})
|
||||
.test();
|
||||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
|
||||
assert_eq!(get_data(actual, "name"), string("Andres"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn downcases_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||
let run = plugin(&mut Str::new())
|
||||
@ -261,6 +313,30 @@ mod integration {
|
||||
assert_eq!(actual, string("JOANDREHUDA"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trims_the_input() {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(CallStub::new().with_long_flag("trim").create())
|
||||
.input(unstructured_sample_record("andres "))
|
||||
.setup(|_, _| {})
|
||||
.test();
|
||||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
assert_eq!(actual, string("andres"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capitalizes_the_input() {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(CallStub::new().with_long_flag("capitalize").create())
|
||||
.input(unstructured_sample_record("andres"))
|
||||
.setup(|_, _| {})
|
||||
.test();
|
||||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
assert_eq!(actual, string("Andres"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn downcases_the_input() {
|
||||
let run = plugin(&mut Str::new())
|
||||
|
@ -10,12 +10,14 @@ use std::cmp;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum Action {
|
||||
Capitalize,
|
||||
Downcase,
|
||||
Upcase,
|
||||
ToInteger,
|
||||
Substring(usize, usize),
|
||||
Replace(ReplaceAction),
|
||||
ToDateTime(String),
|
||||
Trim,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
@ -38,6 +40,22 @@ impl Str {
|
||||
|
||||
fn apply(&self, input: &str) -> Result<UntaggedValue, ShellError> {
|
||||
let applied = match self.action.as_ref() {
|
||||
Some(Action::Trim) => UntaggedValue::string(input.trim()),
|
||||
Some(Action::Capitalize) => {
|
||||
let mut capitalized = String::new();
|
||||
|
||||
for (idx, character) in input.chars().enumerate() {
|
||||
let out = if idx == 0 {
|
||||
character.to_uppercase().to_string()
|
||||
} else {
|
||||
character.to_lowercase().to_string()
|
||||
};
|
||||
|
||||
capitalized.push_str(&out);
|
||||
}
|
||||
|
||||
UntaggedValue::string(capitalized)
|
||||
}
|
||||
Some(Action::Downcase) => UntaggedValue::string(input.to_ascii_lowercase()),
|
||||
Some(Action::Upcase) => UntaggedValue::string(input.to_ascii_uppercase()),
|
||||
Some(Action::Substring(s, e)) => {
|
||||
@ -101,6 +119,14 @@ impl Str {
|
||||
self.add_action(Action::ToInteger);
|
||||
}
|
||||
|
||||
pub fn for_capitalize(&mut self) {
|
||||
self.add_action(Action::Capitalize);
|
||||
}
|
||||
|
||||
pub fn for_trim(&mut self) {
|
||||
self.add_action(Action::Trim);
|
||||
}
|
||||
|
||||
pub fn for_downcase(&mut self) {
|
||||
self.add_action(Action::Downcase);
|
||||
}
|
||||
@ -151,7 +177,7 @@ impl Str {
|
||||
}
|
||||
|
||||
pub fn usage() -> &'static str {
|
||||
"Usage: str field [--downcase|--upcase|--to-int|--substring \"start,end\"|--replace|--find-replace [pattern replacement]]]"
|
||||
"Usage: str field [--capitalize|--downcase|--upcase|--to-int|--substring \"start,end\"|--replace|--find-replace [pattern replacement]|to-date-time|--trim]"
|
||||
}
|
||||
|
||||
pub fn strutils(&self, value: Value) -> Result<Value, ShellError> {
|
||||
@ -216,6 +242,22 @@ pub mod tests {
|
||||
use super::Str;
|
||||
use nu_plugin::test_helpers::value::{int, string};
|
||||
|
||||
#[test]
|
||||
fn trim() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut strutils = Str::new();
|
||||
strutils.for_trim();
|
||||
assert_eq!(strutils.apply("andres ")?, string("andres").value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capitalize() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut strutils = Str::new();
|
||||
strutils.for_capitalize();
|
||||
assert_eq!(strutils.apply("andres")?, string("Andres").value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn downcases() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut strutils = Str::new();
|
||||
|
@ -47,4 +47,18 @@ Consumes either a single value or a table and converts the provided data to a st
|
||||
─────────
|
||||
6
|
||||
━━━━━━━━━
|
||||
```
|
||||
|
||||
> echo "nu" | str --capitalize
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
Nu
|
||||
━━━━━━━━━
|
||||
|
||||
> echo "Nu " | str --trim
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
Nu
|
||||
━━━━━━━━━
|
||||
```
|
@ -9,7 +9,7 @@ fn can_only_apply_one() {
|
||||
"open caco3_plastics.csv | first 1 | str origin --downcase --upcase"
|
||||
);
|
||||
|
||||
assert!(actual.contains(r#"--downcase|--upcase|--to-int|--substring "start,end"|--replace|--find-replace [pattern replacement]]"#));
|
||||
assert!(actual.contains(r#"--capitalize|--downcase|--upcase|--to-int|--substring "start,end"|--replace|--find-replace [pattern replacement]|to-date-time|--trim]"#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -34,8 +34,48 @@ fn acts_without_passing_field() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn downcases() {
|
||||
fn trims() {
|
||||
Playground::setup("plugin_str_test_2", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
[dependency]
|
||||
name = "nu "
|
||||
"#,
|
||||
)]);
|
||||
|
||||
let actual = nu!(
|
||||
cwd: dirs.test(),
|
||||
"open sample.toml | str dependency.name --trim | get dependency.name | echo $it"
|
||||
);
|
||||
|
||||
assert_eq!(actual, "nu");
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capitalizes() {
|
||||
Playground::setup("plugin_str_test_3", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
[dependency]
|
||||
name = "nu"
|
||||
"#,
|
||||
)]);
|
||||
|
||||
let actual = nu!(
|
||||
cwd: dirs.test(),
|
||||
"open sample.toml | str dependency.name --capitalize | get dependency.name | echo $it"
|
||||
);
|
||||
|
||||
assert_eq!(actual, "Nu");
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn downcases() {
|
||||
Playground::setup("plugin_str_test_4", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
@ -55,7 +95,7 @@ fn downcases() {
|
||||
|
||||
#[test]
|
||||
fn upcases() {
|
||||
Playground::setup("plugin_str_test_3", |dirs, sandbox| {
|
||||
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
@ -93,7 +133,7 @@ fn converts_to_int() {
|
||||
|
||||
#[test]
|
||||
fn replaces() {
|
||||
Playground::setup("plugin_str_test_4", |dirs, sandbox| {
|
||||
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
@ -118,7 +158,7 @@ fn replaces() {
|
||||
|
||||
#[test]
|
||||
fn find_and_replaces() {
|
||||
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||
Playground::setup("plugin_str_test_6", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
@ -143,7 +183,7 @@ fn find_and_replaces() {
|
||||
|
||||
#[test]
|
||||
fn find_and_replaces_without_passing_field() {
|
||||
Playground::setup("plugin_str_test_6", |dirs, sandbox| {
|
||||
Playground::setup("plugin_str_test_7", |dirs, sandbox| {
|
||||
sandbox.with_files(vec![FileWithContent(
|
||||
"sample.toml",
|
||||
r#"
|
||||
|
Loading…
Reference in New Issue
Block a user