mirror of
https://github.com/nushell/nushell
synced 2024-11-10 07:04:13 +00:00
Move command changes. Refactorings. (#2683)
Continuing on anchoring and improvements on Nu's overall internal commands (#2635). `move column` sub command has been turned into the command `move` since we use it to move exclusively columns. Examples added as well. Fixed it to carry along any anchor locations that might be in place if table to be moved originates from other sources.
This commit is contained in:
parent
bc6c884a14
commit
b6d19cc9fa
49 changed files with 516 additions and 625 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -3067,6 +3067,7 @@ dependencies = [
|
|||
"nu-errors",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
"nu-test-support",
|
||||
"nu-value-ext",
|
||||
"num-bigint 0.3.0",
|
||||
"serde 1.0.115",
|
||||
|
@ -3119,6 +3120,7 @@ dependencies = [
|
|||
name = "nu-test-support"
|
||||
version = "0.21.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"chrono",
|
||||
"dunce",
|
||||
"getset",
|
||||
|
@ -3227,6 +3229,7 @@ dependencies = [
|
|||
"nu-plugin",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
"nu-test-support",
|
||||
"nu-value-ext",
|
||||
"semver 0.10.0",
|
||||
]
|
||||
|
|
|
@ -159,7 +159,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
|||
whole_stream_command(Ansi),
|
||||
whole_stream_command(Char),
|
||||
// Column manipulation
|
||||
whole_stream_command(MoveColumn),
|
||||
whole_stream_command(Move),
|
||||
whole_stream_command(Reject),
|
||||
whole_stream_command(Select),
|
||||
whole_stream_command(Get),
|
||||
|
|
|
@ -213,7 +213,7 @@ pub(crate) use math::{
|
|||
};
|
||||
pub(crate) use merge::Merge;
|
||||
pub(crate) use mkdir::Mkdir;
|
||||
pub(crate) use move_::{Move, MoveColumn, Mv};
|
||||
pub(crate) use move_::{Move, Mv};
|
||||
pub(crate) use next::Next;
|
||||
pub(crate) use nth::Nth;
|
||||
pub(crate) use open::Open;
|
||||
|
@ -285,6 +285,7 @@ mod tests {
|
|||
whole_stream_command(Append),
|
||||
whole_stream_command(GroupBy),
|
||||
whole_stream_command(Insert),
|
||||
whole_stream_command(Move),
|
||||
whole_stream_command(Update),
|
||||
whole_stream_command(Empty),
|
||||
]
|
||||
|
|
|
@ -175,8 +175,8 @@ async fn from_yaml(
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::*;
|
||||
use nu_plugin::row;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::row;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -51,30 +51,30 @@ impl WholeStreamCommand for Command {
|
|||
result: Some(vec![UntaggedValue::row(indexmap! {
|
||||
"File".to_string() => UntaggedValue::Table(vec![
|
||||
UntaggedValue::row(indexmap! {
|
||||
"modified".to_string() => date("2019-07-23".tagged_unknown()).unwrap().into(),
|
||||
"name".to_string() => UntaggedValue::string("Andrés.txt").into(),
|
||||
"type".to_string() => UntaggedValue::string("File").into(),
|
||||
"chickens".to_string() => UntaggedValue::int(10).into(),
|
||||
"modified".to_string() => date("2019-07-23".tagged_unknown()).unwrap().into(),
|
||||
}).into(),
|
||||
UntaggedValue::row(indexmap! {
|
||||
"modified".to_string() => date("2019-09-24".tagged_unknown()).unwrap().into(),
|
||||
"name".to_string() => UntaggedValue::string("Andrés.txt").into(),
|
||||
"type".to_string() => UntaggedValue::string("File").into(),
|
||||
"chickens".to_string() => UntaggedValue::int(20).into(),
|
||||
"modified".to_string() => date("2019-09-24".tagged_unknown()).unwrap().into(),
|
||||
}).into(),
|
||||
]).into(),
|
||||
"Dir".to_string() => UntaggedValue::Table(vec![
|
||||
UntaggedValue::row(indexmap! {
|
||||
"modified".to_string() => date("2019-07-23".tagged_unknown()).unwrap().into(),
|
||||
"name".to_string() => UntaggedValue::string("Jonathan").into(),
|
||||
"type".to_string() => UntaggedValue::string("Dir").into(),
|
||||
"chickens".to_string() => UntaggedValue::int(5).into(),
|
||||
"modified".to_string() => date("2019-07-23".tagged_unknown()).unwrap().into(),
|
||||
}).into(),
|
||||
UntaggedValue::row(indexmap! {
|
||||
"modified".to_string() => date("2019-09-24".tagged_unknown()).unwrap().into(),
|
||||
"name".to_string() => UntaggedValue::string("Yehuda").into(),
|
||||
"type".to_string() => UntaggedValue::string("Dir").into(),
|
||||
"chickens".to_string() => UntaggedValue::int(4).into(),
|
||||
"modified".to_string() => date("2019-09-24".tagged_unknown()).unwrap().into(),
|
||||
}).into(),
|
||||
]).into(),
|
||||
})
|
||||
|
@ -278,9 +278,10 @@ pub fn group(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::group;
|
||||
use nu_data::utils::helpers::{committers, date, int, row, string, table};
|
||||
use nu_data::utils::helpers::committers;
|
||||
use nu_errors::ShellError;
|
||||
use nu_source::*;
|
||||
use nu_test_support::value::{date, int, row, string, table};
|
||||
|
||||
#[test]
|
||||
fn groups_table_by_date_column() -> Result<(), ShellError> {
|
||||
|
|
|
@ -38,9 +38,8 @@ mod tests {
|
|||
avg::average, max::maximum, median::median, min::minimum, mode::mode, stddev::stddev,
|
||||
sum::summation, utils::calculate, utils::MathFunction, variance::variance,
|
||||
};
|
||||
use nu_plugin::row;
|
||||
use nu_plugin::test_helpers::value::{decimal, decimal_from_float, int, table};
|
||||
use nu_protocol::Value;
|
||||
use nu_protocol::{row, Value};
|
||||
use nu_test_support::value::{decimal, decimal_from_float, int, table};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
|
@ -71,14 +70,14 @@ mod tests {
|
|||
values: vec![int(10)],
|
||||
expected_err: None,
|
||||
expected_res: vec![
|
||||
Ok(decimal(10)),
|
||||
Ok(decimal_from_float(10.0)),
|
||||
Ok(int(10)),
|
||||
Ok(int(10)),
|
||||
Ok(int(10)),
|
||||
Ok(table(&[int(10)])),
|
||||
Ok(decimal(0)),
|
||||
Ok(decimal_from_float(0.0)),
|
||||
Ok(int(10)),
|
||||
Ok(decimal(0)),
|
||||
Ok(decimal_from_float(0.0)),
|
||||
],
|
||||
},
|
||||
TestCase {
|
||||
|
@ -86,7 +85,7 @@ mod tests {
|
|||
values: vec![int(10), int(20), int(30)],
|
||||
expected_err: None,
|
||||
expected_res: vec![
|
||||
Ok(decimal(20)),
|
||||
Ok(decimal_from_float(20.0)),
|
||||
Ok(int(10)),
|
||||
Ok(int(30)),
|
||||
Ok(int(20)),
|
||||
|
@ -101,13 +100,13 @@ mod tests {
|
|||
values: vec![int(10), decimal_from_float(26.5), decimal_from_float(26.5)],
|
||||
expected_err: None,
|
||||
expected_res: vec![
|
||||
Ok(decimal(21)),
|
||||
Ok(decimal_from_float(21.0)),
|
||||
Ok(int(10)),
|
||||
Ok(decimal_from_float(26.5)),
|
||||
Ok(decimal_from_float(26.5)),
|
||||
Ok(table(&[decimal_from_float(26.5)])),
|
||||
Ok(decimal(BigDecimal::from_str("7.77817459305202276840928798315333943213319531457321440247173855894902863154158871367713143880202865").expect("Could not convert to decimal from string"))),
|
||||
Ok(decimal(63)),
|
||||
Ok(decimal_from_float(63.0)),
|
||||
Ok(decimal_from_float(60.5)),
|
||||
],
|
||||
},
|
||||
|
@ -116,14 +115,14 @@ mod tests {
|
|||
values: vec![int(-14), int(-11), int(10)],
|
||||
expected_err: None,
|
||||
expected_res: vec![
|
||||
Ok(decimal(-5)),
|
||||
Ok(decimal_from_float(-5.0)),
|
||||
Ok(int(-14)),
|
||||
Ok(int(10)),
|
||||
Ok(int(-11)),
|
||||
Ok(table(&[int(-14), int(-11), int(10)])),
|
||||
Ok(decimal(BigDecimal::from_str("10.67707825203131121081152396559571062628228776946058011397810604284900898365140801704064843595778374").expect("Could not convert to decimal from string"))),
|
||||
Ok(int(-15)),
|
||||
Ok(decimal(114)),
|
||||
Ok(decimal_from_float(114.0)),
|
||||
],
|
||||
},
|
||||
TestCase {
|
||||
|
@ -131,13 +130,13 @@ mod tests {
|
|||
values: vec![decimal_from_float(-13.5), decimal_from_float(-11.5), int(10)],
|
||||
expected_err: None,
|
||||
expected_res: vec![
|
||||
Ok(decimal(-5)),
|
||||
Ok(decimal_from_float(-5.0)),
|
||||
Ok(decimal_from_float(-13.5)),
|
||||
Ok(int(10)),
|
||||
Ok(decimal_from_float(-11.5)),
|
||||
Ok(table(&[decimal_from_float(-13.5), decimal_from_float(-11.5), int(10)])),
|
||||
Ok(decimal(BigDecimal::from_str("10.63798226482196513098036125801342585449179971588207816421068645273754903468375890632981926875247027").expect("Could not convert to decimal from string"))),
|
||||
Ok(decimal(-15)),
|
||||
Ok(decimal_from_float(-15.0)),
|
||||
Ok(decimal(BigDecimal::from_str("113.1666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667").expect("Could not convert to decimal from string"))),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,328 +0,0 @@
|
|||
use crate::command_registry::CommandRegistry;
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_data::base::select_fields;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, Value};
|
||||
use nu_source::HasFallibleSpan;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
rest: Vec<ColumnPath>,
|
||||
after: Option<ColumnPath>,
|
||||
before: Option<ColumnPath>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"move column"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("move column")
|
||||
.rest(SyntaxShape::ColumnPath, "the columns to move")
|
||||
.named(
|
||||
"after",
|
||||
SyntaxShape::ColumnPath,
|
||||
"the column that will precede the columns moved",
|
||||
None,
|
||||
)
|
||||
.named(
|
||||
"before",
|
||||
SyntaxShape::ColumnPath,
|
||||
"the column that will be next the columns moved",
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Move columns."
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
operate(args, registry).await
|
||||
}
|
||||
}
|
||||
|
||||
async fn operate(
|
||||
raw_args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let name = raw_args.call_info.name_tag.clone();
|
||||
let registry = registry.clone();
|
||||
let (
|
||||
Arguments {
|
||||
rest: mut columns,
|
||||
before,
|
||||
after,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process(®istry).await?;
|
||||
|
||||
if columns.is_empty() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"expected columns",
|
||||
"expected columns",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
if columns.iter().any(|c| c.members().len() > 1) {
|
||||
return Err(ShellError::labeled_error(
|
||||
"expected columns",
|
||||
"expected columns",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
if vec![&after, &before]
|
||||
.iter()
|
||||
.map(|o| if o.is_some() { 1 } else { 0 })
|
||||
.sum::<usize>()
|
||||
> 1
|
||||
{
|
||||
return Err(ShellError::labeled_error(
|
||||
"can't move column(s)",
|
||||
"pick exactly one (before, after)",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(after) = after {
|
||||
let member = columns.remove(0);
|
||||
|
||||
Ok(input
|
||||
.map(move |item| {
|
||||
let member = vec![member.clone()];
|
||||
let column_paths = vec![&member, &columns]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let after_span = after.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if after.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
.iter()
|
||||
.filter_map(|c| c.last())
|
||||
.map(|c| c.as_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(column) = after.last() {
|
||||
if !keys.contains(&column.as_string()) {
|
||||
ReturnSuccess::value(move_after(&item, &keys, &after, &name)?)
|
||||
} else {
|
||||
let msg =
|
||||
format!("can't move column {} after itself", column.as_string());
|
||||
Err(ShellError::labeled_error(
|
||||
"can't move column",
|
||||
msg,
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
} else if let Some(before) = before {
|
||||
let member = columns.remove(0);
|
||||
|
||||
Ok(input
|
||||
.map(move |item| {
|
||||
let member = vec![member.clone()];
|
||||
let column_paths = vec![&member, &columns]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let before_span = before.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if before.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
.iter()
|
||||
.filter_map(|c| c.last())
|
||||
.map(|c| c.as_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(column) = before.last() {
|
||||
if !keys.contains(&column.as_string()) {
|
||||
ReturnSuccess::value(move_before(&item, &keys, &before, &name)?)
|
||||
} else {
|
||||
let msg =
|
||||
format!("can't move column {} before itself", column.as_string());
|
||||
Err(ShellError::labeled_error(
|
||||
"can't move column",
|
||||
msg,
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"no columns given",
|
||||
"no columns given",
|
||||
name,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn move_after(
|
||||
table: &Value,
|
||||
columns: &[String],
|
||||
from: &ColumnPath,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"unknown column",
|
||||
"unknown column",
|
||||
from_fields,
|
||||
));
|
||||
};
|
||||
|
||||
let columns_moved = table.data_descriptors().into_iter().map(|name| {
|
||||
if columns.contains(&name) {
|
||||
None
|
||||
} else {
|
||||
Some(name)
|
||||
}
|
||||
});
|
||||
|
||||
let mut reordered_columns = vec![];
|
||||
let mut insert = false;
|
||||
let mut inserted = false;
|
||||
|
||||
for name in columns_moved.into_iter() {
|
||||
if let Some(name) = name {
|
||||
reordered_columns.push(Some(name.clone()));
|
||||
|
||||
if !inserted && name == from {
|
||||
insert = true;
|
||||
}
|
||||
} else {
|
||||
reordered_columns.push(None);
|
||||
}
|
||||
|
||||
if insert {
|
||||
for column in columns {
|
||||
reordered_columns.push(Some(column.clone()));
|
||||
}
|
||||
inserted = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&tag,
|
||||
))
|
||||
}
|
||||
|
||||
fn move_before(
|
||||
table: &Value,
|
||||
columns: &[String],
|
||||
from: &ColumnPath,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"unknown column",
|
||||
"unknown column",
|
||||
from_fields,
|
||||
));
|
||||
};
|
||||
|
||||
let columns_moved = table.data_descriptors().into_iter().map(|name| {
|
||||
if columns.contains(&name) {
|
||||
None
|
||||
} else {
|
||||
Some(name)
|
||||
}
|
||||
});
|
||||
|
||||
let mut reordered_columns = vec![];
|
||||
let mut inserted = false;
|
||||
|
||||
for name in columns_moved.into_iter() {
|
||||
if let Some(name) = name {
|
||||
if !inserted && name == from {
|
||||
for column in columns {
|
||||
reordered_columns.push(Some(column.clone()));
|
||||
}
|
||||
|
||||
inserted = true;
|
||||
}
|
||||
|
||||
reordered_columns.push(Some(name.clone()));
|
||||
} else {
|
||||
reordered_columns.push(None);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&tag,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::SubCommand;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
Ok(test_examples(SubCommand {})?)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,20 @@
|
|||
use crate::command_registry::CommandRegistry;
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_data::base::select_fields;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, Value};
|
||||
use nu_source::HasFallibleSpan;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Command;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
rest: Vec<ColumnPath>,
|
||||
after: Option<ColumnPath>,
|
||||
before: Option<ColumnPath>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for Command {
|
||||
fn name(&self) -> &str {
|
||||
|
@ -14,34 +23,318 @@ impl WholeStreamCommand for Command {
|
|||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("move")
|
||||
.rest(SyntaxShape::ColumnPath, "the columns to move")
|
||||
.named(
|
||||
"after",
|
||||
SyntaxShape::ColumnPath,
|
||||
"the column that will precede the columns moved",
|
||||
None,
|
||||
)
|
||||
.named(
|
||||
"before",
|
||||
SyntaxShape::ColumnPath,
|
||||
"the column that will be next the columns moved",
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Moves across desired subcommand."
|
||||
"Move columns."
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
_args: CommandArgs,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
||||
UntaggedValue::string(crate::commands::help::get_help(&Command, ®istry))
|
||||
.into_value(Tag::unknown()),
|
||||
))))
|
||||
operate(args, registry).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
use nu_test_support::value::*;
|
||||
|
||||
vec![
|
||||
Example {
|
||||
description: "Move the column \"type\" before the column \"name\"",
|
||||
example: r#"ls | move type --before name | first"#,
|
||||
result: Some(vec![row! {
|
||||
"type".into() => string("File"),
|
||||
"name".into() => string("Andrés.txt"),
|
||||
"chickens".into() => int(10),
|
||||
"modified".into() => date("2019-07-23")
|
||||
}]),
|
||||
},
|
||||
Example {
|
||||
description: "or move the column \"chickens\" after \"name\"",
|
||||
example: r#"ls | move chickens --after name | first"#,
|
||||
result: Some(vec![row! {
|
||||
"name".into() => string("Andrés.txt"),
|
||||
"chickens".into() => int(10),
|
||||
"type".into() => string("File"),
|
||||
"modified".into() => date("2019-07-23")
|
||||
}]),
|
||||
},
|
||||
Example {
|
||||
description: "you can selectively move many columns in either direction",
|
||||
example: r#"ls | move name chickens --after type | first"#,
|
||||
result: Some(vec![row! {
|
||||
"type".into() => string("File"),
|
||||
"name".into() => string("Andrés.txt"),
|
||||
"chickens".into() => int(10),
|
||||
"modified".into() => date("2019-07-23")
|
||||
}]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Command;
|
||||
use super::ShellError;
|
||||
async fn operate(
|
||||
raw_args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let name = raw_args.call_info.name_tag.clone();
|
||||
let registry = registry.clone();
|
||||
let (
|
||||
Arguments {
|
||||
rest: mut columns,
|
||||
before,
|
||||
after,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process(®istry).await?;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
if columns.is_empty() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"expected columns",
|
||||
"expected columns",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(test_examples(Command {})?)
|
||||
if columns.iter().any(|c| c.members().len() > 1) {
|
||||
return Err(ShellError::labeled_error(
|
||||
"expected columns",
|
||||
"expected columns",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
if vec![&after, &before]
|
||||
.iter()
|
||||
.map(|o| if o.is_some() { 1 } else { 0 })
|
||||
.sum::<usize>()
|
||||
> 1
|
||||
{
|
||||
return Err(ShellError::labeled_error(
|
||||
"can't move column(s)",
|
||||
"pick exactly one (before, after)",
|
||||
name,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(after) = after {
|
||||
let member = columns.remove(0);
|
||||
|
||||
Ok(input
|
||||
.map(move |item| {
|
||||
let member = vec![member.clone()];
|
||||
let column_paths = vec![&member, &columns]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let after_span = after.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if after.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
.iter()
|
||||
.filter_map(|c| c.last())
|
||||
.map(|c| c.as_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(column) = after.last() {
|
||||
if !keys.contains(&column.as_string()) {
|
||||
ReturnSuccess::value(move_after(&item, &keys, &after)?)
|
||||
} else {
|
||||
let msg =
|
||||
format!("can't move column {} after itself", column.as_string());
|
||||
Err(ShellError::labeled_error(
|
||||
"can't move column",
|
||||
msg,
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
after_span,
|
||||
))
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
} else if let Some(before) = before {
|
||||
let member = columns.remove(0);
|
||||
|
||||
Ok(input
|
||||
.map(move |item| {
|
||||
let member = vec![member.clone()];
|
||||
let column_paths = vec![&member, &columns]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let before_span = before.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if before.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
.iter()
|
||||
.filter_map(|c| c.last())
|
||||
.map(|c| c.as_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(column) = before.last() {
|
||||
if !keys.contains(&column.as_string()) {
|
||||
ReturnSuccess::value(move_before(&item, &keys, &before)?)
|
||||
} else {
|
||||
let msg =
|
||||
format!("can't move column {} before itself", column.as_string());
|
||||
Err(ShellError::labeled_error(
|
||||
"can't move column",
|
||||
msg,
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"expected column",
|
||||
"expected column",
|
||||
before_span,
|
||||
))
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"no columns given",
|
||||
"no columns given",
|
||||
name,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn move_after(table: &Value, columns: &[String], from: &ColumnPath) -> Result<Value, ShellError> {
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"unknown column",
|
||||
"unknown column",
|
||||
from_fields,
|
||||
));
|
||||
};
|
||||
|
||||
let columns_moved = table.data_descriptors().into_iter().map(|name| {
|
||||
if columns.contains(&name) {
|
||||
None
|
||||
} else {
|
||||
Some(name)
|
||||
}
|
||||
});
|
||||
|
||||
let mut reordered_columns = vec![];
|
||||
let mut insert = false;
|
||||
let mut inserted = false;
|
||||
|
||||
for name in columns_moved.into_iter() {
|
||||
if let Some(name) = name {
|
||||
reordered_columns.push(Some(name.clone()));
|
||||
|
||||
if !inserted && name == from {
|
||||
insert = true;
|
||||
}
|
||||
} else {
|
||||
reordered_columns.push(None);
|
||||
}
|
||||
|
||||
if insert {
|
||||
for column in columns {
|
||||
reordered_columns.push(Some(column.clone()));
|
||||
}
|
||||
inserted = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&table.tag,
|
||||
))
|
||||
}
|
||||
|
||||
fn move_before(table: &Value, columns: &[String], from: &ColumnPath) -> Result<Value, ShellError> {
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"unknown column",
|
||||
"unknown column",
|
||||
from_fields,
|
||||
));
|
||||
};
|
||||
|
||||
let columns_moved = table.data_descriptors().into_iter().map(|name| {
|
||||
if columns.contains(&name) {
|
||||
None
|
||||
} else {
|
||||
Some(name)
|
||||
}
|
||||
});
|
||||
|
||||
let mut reordered_columns = vec![];
|
||||
let mut inserted = false;
|
||||
|
||||
for name in columns_moved.into_iter() {
|
||||
if let Some(name) = name {
|
||||
if !inserted && name == from {
|
||||
for column in columns {
|
||||
reordered_columns.push(Some(column.clone()));
|
||||
}
|
||||
|
||||
inserted = true;
|
||||
}
|
||||
|
||||
reordered_columns.push(Some(name.clone()));
|
||||
} else {
|
||||
reordered_columns.push(None);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&table.tag,
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
mod column;
|
||||
mod command;
|
||||
pub mod mv;
|
||||
|
||||
pub use column::SubCommand as MoveColumn;
|
||||
pub use command::Command as Move;
|
||||
pub use mv::Mv;
|
||||
|
|
|
@ -101,9 +101,10 @@ pub fn split(
|
|||
mod tests {
|
||||
use super::split;
|
||||
use super::ShellError;
|
||||
use nu_data::utils::helpers::{committers_grouped_by_date, date, int, row, string, table};
|
||||
use nu_data::utils::helpers::committers_grouped_by_date;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::*;
|
||||
use nu_test_support::value::{date, int, row, string, table};
|
||||
|
||||
#[test]
|
||||
fn splits_inner_tables_by_key() {
|
||||
|
|
|
@ -112,8 +112,8 @@ fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -46,8 +46,8 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{to_camel_case, SubCommand};
|
||||
use crate::commands::str_::case::action;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -46,8 +46,8 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{to_kebab_case, SubCommand};
|
||||
use crate::commands::str_::case::action;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -46,8 +46,8 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{to_pascal_case, SubCommand};
|
||||
use crate::commands::str_::case::action;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -46,8 +46,8 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{to_screaming_snake_case, SubCommand};
|
||||
use crate::commands::str_::case::action;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -46,8 +46,8 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{to_snake_case, SubCommand};
|
||||
use crate::commands::str_::case::action;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -130,9 +130,9 @@ fn action(
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -100,8 +100,8 @@ fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -104,9 +104,9 @@ fn action(input: &Value, pattern: &str, tag: impl Into<Tag>) -> Result<Value, Sh
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -149,8 +149,8 @@ fn action(
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, FindReplace, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -248,9 +248,9 @@ fn process_range(input: &Value, range: &Value) -> Result<IndexOfOptionalBounds,
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::{Primitive, UntaggedValue};
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -145,9 +145,9 @@ fn action(
|
|||
mod tests {
|
||||
use super::{action, SubCommand};
|
||||
use nu_errors::ShellError;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -145,9 +145,9 @@ fn action(
|
|||
mod tests {
|
||||
use super::{action, SubCommand};
|
||||
use nu_errors::ShellError;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -101,8 +101,8 @@ fn action(_input: &Value, options: &Replace, tag: impl Into<Tag>) -> Result<Valu
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, Replace, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -104,9 +104,9 @@ fn action(input: &Value, pattern: &str, tag: impl Into<Tag>) -> Result<Value, Sh
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -285,8 +285,8 @@ fn process_arguments(range: Value, name: impl Into<Tag>) -> Result<(isize, isize
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand, Substring};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -176,9 +176,9 @@ fn action(
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, DatetimeFormat, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_protocol::{Primitive, UntaggedValue};
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -114,8 +114,8 @@ fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::{decimal_from_float, string};
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::{decimal_from_float, string};
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -114,8 +114,8 @@ fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::{int, string};
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::{int, string};
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -65,11 +65,9 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{trim, SubCommand};
|
||||
use crate::commands::str_::trim::{action, ActionMode};
|
||||
use nu_plugin::{
|
||||
row,
|
||||
test_helpers::value::{int, string, table},
|
||||
};
|
||||
use nu_protocol::row;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::{int, string, table};
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -66,11 +66,9 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{trim_left, SubCommand};
|
||||
use crate::commands::str_::trim::{action, ActionMode};
|
||||
use nu_plugin::{
|
||||
row,
|
||||
test_helpers::value::{int, string, table},
|
||||
};
|
||||
use nu_protocol::row;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::{int, string, table};
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -66,11 +66,9 @@ mod tests {
|
|||
use super::ShellError;
|
||||
use super::{trim_right, SubCommand};
|
||||
use crate::commands::str_::trim::{action, ActionMode};
|
||||
use nu_plugin::{
|
||||
row,
|
||||
test_helpers::value::{int, string, table},
|
||||
};
|
||||
use nu_protocol::row;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::{int, string, table};
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -100,8 +100,8 @@ fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
|||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::{action, SubCommand};
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
|
|
|
@ -7,11 +7,8 @@ use nu_source::{AnchorLocation, TaggedItem};
|
|||
|
||||
use crate::prelude::*;
|
||||
|
||||
use indexmap::indexmap;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::command_registry::CommandRegistry;
|
||||
use crate::commands::classified::block::run_block;
|
||||
use crate::commands::command::CommandArgs;
|
||||
|
@ -450,10 +447,6 @@ fn string(input: impl Into<String>) -> Value {
|
|||
UntaggedValue::string(input.into()).into_untagged_value()
|
||||
}
|
||||
|
||||
fn row(entries: IndexMap<String, Value>) -> Value {
|
||||
UntaggedValue::row(entries).into_untagged_value()
|
||||
}
|
||||
|
||||
fn date(input: impl Into<String>) -> Value {
|
||||
let key = input.into().tagged_unknown();
|
||||
crate::value::Date::naive_from_str(key.borrow_tagged())
|
||||
|
@ -463,30 +456,30 @@ fn date(input: impl Into<String>) -> Value {
|
|||
|
||||
fn file_listing() -> Vec<Value> {
|
||||
vec![
|
||||
row(indexmap! {
|
||||
"modified".to_string() => date("2019-07-23"),
|
||||
row! {
|
||||
"name".to_string() => string("Andrés.txt"),
|
||||
"type".to_string() => string("File"),
|
||||
"chickens".to_string() => int(10),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"modified".to_string() => date("2019-07-23"),
|
||||
"modified".to_string() => date("2019-07-23")
|
||||
},
|
||||
row! {
|
||||
"name".to_string() => string("Jonathan"),
|
||||
"type".to_string() => string("Dir"),
|
||||
"chickens".to_string() => int(5),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"modified".to_string() => date("2019-09-24"),
|
||||
"modified".to_string() => date("2019-07-23")
|
||||
},
|
||||
row! {
|
||||
"name".to_string() => string("Andrés.txt"),
|
||||
"type".to_string() => string("File"),
|
||||
"chickens".to_string() => int(20),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"modified".to_string() => date("2019-09-24"),
|
||||
"modified".to_string() => date("2019-09-24")
|
||||
},
|
||||
row! {
|
||||
"name".to_string() => string("Yehuda"),
|
||||
"type".to_string() => string("Dir"),
|
||||
"chickens".to_string() => int(4),
|
||||
}),
|
||||
"modified".to_string() => date("2019-09-24")
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ macro_rules! trace_out_stream {
|
|||
}};
|
||||
}
|
||||
|
||||
pub(crate) use nu_protocol::{errln, out, outln};
|
||||
pub(crate) use nu_protocol::{errln, out, outln, row};
|
||||
use nu_source::HasFallibleSpan;
|
||||
|
||||
pub(crate) use crate::command_registry::CommandRegistry;
|
||||
|
|
|
@ -22,7 +22,7 @@ fn moves_a_column_before() {
|
|||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
open sample.csv
|
||||
| move column column99 --before column1
|
||||
| move column99 --before column1
|
||||
| rename chars
|
||||
| get chars
|
||||
| str trim
|
||||
|
@ -57,7 +57,7 @@ fn moves_columns_before() {
|
|||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
open sample.csv
|
||||
| move column column99 column3 --before column2
|
||||
| move column99 column3 --before column2
|
||||
| rename _ chars_1 chars_2
|
||||
| get chars_2 chars_1
|
||||
| str trim
|
||||
|
@ -92,8 +92,8 @@ fn moves_a_column_after() {
|
|||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
open sample.csv
|
||||
| move column letters --after and_more
|
||||
| move column letters and_more --before column2
|
||||
| move letters --after and_more
|
||||
| move letters and_more --before column2
|
||||
| rename _ chars_1 chars_2
|
||||
| get chars_1 chars_2
|
||||
| str trim
|
||||
|
@ -128,7 +128,7 @@ fn moves_columns_after() {
|
|||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
open sample.csv
|
||||
| move column letters and_more --after column1
|
||||
| move letters and_more --after column1
|
||||
| get
|
||||
| nth 1 2
|
||||
| str collect
|
||||
|
|
|
@ -191,7 +191,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn gets_matching_field_from_nested_rows_inside_a_row() -> Result<(), ShellError> {
|
||||
let field_path = column_path("package.version");
|
||||
let field_path = column_path("package.version").as_column_path()?;
|
||||
|
||||
let (version, tag) = string("0.4.0").into_parts();
|
||||
|
||||
|
@ -205,7 +205,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
*value.into_value(tag).get_data_by_column_path(
|
||||
&field_path?.item,
|
||||
&field_path.item,
|
||||
Box::new(error_callback("package.version"))
|
||||
)?,
|
||||
version
|
||||
|
@ -217,7 +217,7 @@ mod tests {
|
|||
#[test]
|
||||
fn gets_first_matching_field_from_rows_with_same_field_inside_a_table() -> Result<(), ShellError>
|
||||
{
|
||||
let field_path = column_path("package.authors.name");
|
||||
let field_path = column_path("package.authors.name").as_column_path()?;
|
||||
|
||||
let (_, tag) = string("Andrés N. Robalino").into_parts();
|
||||
|
||||
|
@ -235,7 +235,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
value.into_value(tag).get_data_by_column_path(
|
||||
&field_path?.item,
|
||||
&field_path.item,
|
||||
Box::new(error_callback("package.authors.name"))
|
||||
)?,
|
||||
table(&[
|
||||
|
@ -250,7 +250,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn column_path_that_contains_just_a_number_gets_a_row_from_a_table() -> Result<(), ShellError> {
|
||||
let field_path = column_path("package.authors.0");
|
||||
let field_path = column_path("package.authors.0").as_column_path()?;
|
||||
|
||||
let (_, tag) = string("Andrés N. Robalino").into_parts();
|
||||
|
||||
|
@ -268,7 +268,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
*value.into_value(tag).get_data_by_column_path(
|
||||
&field_path?.item,
|
||||
&field_path.item,
|
||||
Box::new(error_callback("package.authors.0"))
|
||||
)?,
|
||||
UntaggedValue::row(indexmap! {
|
||||
|
@ -281,7 +281,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn column_path_that_contains_just_a_number_gets_a_row_from_a_row() -> Result<(), ShellError> {
|
||||
let field_path = column_path(r#"package.authors."0""#);
|
||||
let field_path = column_path(r#"package.authors."0""#).as_column_path()?;
|
||||
|
||||
let (_, tag) = string("Andrés N. Robalino").into_parts();
|
||||
|
||||
|
@ -299,7 +299,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
*value.into_value(tag).get_data_by_column_path(
|
||||
&field_path?.item,
|
||||
&field_path.item,
|
||||
Box::new(error_callback("package.authors.\"0\""))
|
||||
)?,
|
||||
UntaggedValue::row(indexmap! {
|
||||
|
@ -312,7 +312,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn replaces_matching_field_from_a_row() -> Result<(), ShellError> {
|
||||
let field_path = column_path("amigos");
|
||||
let field_path = column_path("amigos").as_column_path()?;
|
||||
|
||||
let sample = UntaggedValue::row(indexmap! {
|
||||
"amigos".into() => table(&[
|
||||
|
@ -326,7 +326,7 @@ mod tests {
|
|||
|
||||
let actual = sample
|
||||
.into_untagged_value()
|
||||
.replace_data_at_column_path(&field_path?.item, replacement)
|
||||
.replace_data_at_column_path(&field_path.item, replacement)
|
||||
.ok_or_else(|| ShellError::untagged_runtime_error("Could not replace column"))?;
|
||||
|
||||
assert_eq!(actual, row(indexmap! {"amigos".into() => string("jonas")}));
|
||||
|
@ -336,7 +336,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn replaces_matching_field_from_nested_rows_inside_a_row() -> Result<(), ShellError> {
|
||||
let field_path = column_path(r#"package.authors."los.3.caballeros""#);
|
||||
let field_path = column_path(r#"package.authors."los.3.caballeros""#).as_column_path()?;
|
||||
|
||||
let sample = UntaggedValue::row(indexmap! {
|
||||
"package".into() => row(indexmap! {
|
||||
|
@ -353,7 +353,7 @@ mod tests {
|
|||
|
||||
let actual = sample
|
||||
.into_value(&tag)
|
||||
.replace_data_at_column_path(&field_path?.item, replacement.clone())
|
||||
.replace_data_at_column_path(&field_path.item, replacement.clone())
|
||||
.ok_or_else(|| {
|
||||
ShellError::labeled_error(
|
||||
"Could not replace column",
|
||||
|
@ -377,7 +377,8 @@ mod tests {
|
|||
}
|
||||
#[test]
|
||||
fn replaces_matching_field_from_rows_inside_a_table() -> Result<(), ShellError> {
|
||||
let field_path = column_path(r#"shell_policy.releases."nu.version.arepa""#);
|
||||
let field_path =
|
||||
column_path(r#"shell_policy.releases."nu.version.arepa""#).as_column_path()?;
|
||||
|
||||
let sample = UntaggedValue::row(indexmap! {
|
||||
"shell_policy".into() => row(indexmap! {
|
||||
|
@ -409,7 +410,7 @@ mod tests {
|
|||
|
||||
let actual = sample
|
||||
.into_value(tag.clone())
|
||||
.replace_data_at_column_path(&field_path?.item, replacement.clone())
|
||||
.replace_data_at_column_path(&field_path.item, replacement.clone())
|
||||
.ok_or_else(|| {
|
||||
ShellError::labeled_error(
|
||||
"Could not replace column",
|
||||
|
|
|
@ -97,99 +97,68 @@ pub fn report(
|
|||
}
|
||||
|
||||
pub mod helpers {
|
||||
use super::Model;
|
||||
use indexmap::indexmap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{UntaggedValue, Value};
|
||||
use nu_source::{Span, Tag, TaggedItem};
|
||||
use nu_protocol::{row, Value};
|
||||
use nu_source::{Tag, TaggedItem};
|
||||
use nu_test_support::value::{date, int, string, table};
|
||||
use nu_value_ext::ValueExt;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
pub fn int(s: impl Into<BigInt>) -> Value {
|
||||
UntaggedValue::int(s).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn decimal_from_float(f: f64, span: Span) -> Value {
|
||||
UntaggedValue::decimal_from_float(f, span).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn string(input: impl Into<String>) -> Value {
|
||||
UntaggedValue::string(input.into()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn row(entries: IndexMap<String, Value>) -> Value {
|
||||
UntaggedValue::row(entries).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn table(list: &[Value]) -> Value {
|
||||
UntaggedValue::table(list).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn date(input: impl Into<String>) -> Value {
|
||||
let key = input.into().tagged_unknown();
|
||||
crate::value::Date::naive_from_str(key.borrow_tagged())
|
||||
.expect("date from string failed")
|
||||
.into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn committers() -> Vec<Value> {
|
||||
vec![
|
||||
row(indexmap! {
|
||||
row! {
|
||||
"date".into() => date("2019-07-23"),
|
||||
"name".into() => string("AR"),
|
||||
"country".into() => string("EC"),
|
||||
"chickens".into() => int(10),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(10)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-07-23"),
|
||||
"name".into() => string("JT"),
|
||||
"country".into() => string("NZ"),
|
||||
"chickens".into() => int(5),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(5)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-10-10"),
|
||||
"name".into() => string("YK"),
|
||||
"country".into() => string("US"),
|
||||
"chickens".into() => int(6),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(6)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-09-24"),
|
||||
"name".into() => string("AR"),
|
||||
"country".into() => string("EC"),
|
||||
"chickens".into() => int(20),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(20)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-10-10"),
|
||||
"name".into() => string("JT"),
|
||||
"country".into() => string("NZ"),
|
||||
"chickens".into() => int(15),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(15)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-09-24"),
|
||||
"name".into() => string("YK"),
|
||||
"country".into() => string("US"),
|
||||
"chickens".into() => int(4),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(4)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-10-10"),
|
||||
"name".into() => string("AR"),
|
||||
"country".into() => string("EC"),
|
||||
"chickens".into() => int(30),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(30)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-09-24"),
|
||||
"name".into() => string("JT"),
|
||||
"country".into() => string("NZ"),
|
||||
"chickens".into() => int(10),
|
||||
}),
|
||||
row(indexmap! {
|
||||
"chickens".into() => int(10)
|
||||
},
|
||||
row! {
|
||||
"date".into() => date("2019-07-23"),
|
||||
"name".into() => string("YK"),
|
||||
"country".into() => string("US"),
|
||||
"chickens".into() => int(2),
|
||||
}),
|
||||
"chickens".into() => int(2)
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -217,6 +186,17 @@ pub mod helpers {
|
|||
date.format(&fmt)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::helpers::{committers, date_formatter};
|
||||
use super::{report, Labels, Model, Operation, Range, Reduction};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::Value;
|
||||
use nu_source::{Tag, TaggedItem};
|
||||
use nu_test_support::value::{decimal_from_float, int, table};
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
pub fn assert_without_checking_percentages(report_a: Model, report_b: Model) {
|
||||
assert_eq!(report_a.labels.x, report_b.labels.x);
|
||||
|
@ -224,19 +204,6 @@ pub mod helpers {
|
|||
assert_eq!(report_a.ranges, report_b.ranges);
|
||||
assert_eq!(report_a.data, report_b.data);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::helpers::{
|
||||
assert_without_checking_percentages, committers, date_formatter, decimal_from_float, int,
|
||||
table,
|
||||
};
|
||||
use super::{report, Labels, Model, Operation, Range, Reduction};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::Value;
|
||||
use nu_source::{Span, Tag, TaggedItem};
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
#[test]
|
||||
fn prepares_report_using_counting_value() {
|
||||
|
@ -304,19 +271,19 @@ mod tests {
|
|||
]),
|
||||
percentages: table(&[
|
||||
table(&[
|
||||
decimal_from_float(33.33, Span::unknown()),
|
||||
decimal_from_float(66.66, Span::unknown()),
|
||||
decimal_from_float(99.99, Span::unknown()),
|
||||
decimal_from_float(33.33),
|
||||
decimal_from_float(66.66),
|
||||
decimal_from_float(99.99),
|
||||
]),
|
||||
table(&[
|
||||
decimal_from_float(16.66, Span::unknown()),
|
||||
decimal_from_float(33.33, Span::unknown()),
|
||||
decimal_from_float(49.99, Span::unknown()),
|
||||
decimal_from_float(16.66),
|
||||
decimal_from_float(33.33),
|
||||
decimal_from_float(49.99),
|
||||
]),
|
||||
table(&[
|
||||
decimal_from_float(6.66, Span::unknown()),
|
||||
decimal_from_float(13.33, Span::unknown()),
|
||||
decimal_from_float(19.99, Span::unknown()),
|
||||
decimal_from_float(6.66),
|
||||
decimal_from_float(13.33),
|
||||
decimal_from_float(19.99),
|
||||
]),
|
||||
]),
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ nu-errors = {path = "../nu-errors", version = "0.21.0"}
|
|||
nu-protocol = {path = "../nu-protocol", version = "0.21.0"}
|
||||
nu-source = {path = "../nu-source", version = "0.21.0"}
|
||||
nu-value-ext = {path = "../nu-value-ext", version = "0.21.0"}
|
||||
nu-test-support = {path = "../nu-test-support", version = "0.21.0"}
|
||||
|
||||
bigdecimal = {version = "0.2.0", features = ["serde"]}
|
||||
indexmap = {version = "1.6.0", features = ["serde-1"]}
|
||||
|
@ -21,4 +22,4 @@ num-bigint = {version = "0.3.0", features = ["serde"]}
|
|||
serde = {version = "1.0.115", features = ["derive"]}
|
||||
serde_json = "1.0.57"
|
||||
|
||||
[build-dependencies]
|
||||
[build-dependencies]
|
|
@ -1,8 +1,12 @@
|
|||
use crate::Plugin;
|
||||
use indexmap::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{CallInfo, EvaluatedArgs, ReturnSuccess, ReturnValue, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
CallInfo, EvaluatedArgs, Primitive, ReturnSuccess, ReturnValue, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::column_path;
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
pub struct PluginTest<'a, T: Plugin> {
|
||||
plugin: &'a mut T,
|
||||
|
@ -112,12 +116,12 @@ impl CallStub {
|
|||
}
|
||||
|
||||
pub fn with_parameter(&mut self, name: &str) -> Result<&mut Self, ShellError> {
|
||||
let fields: Vec<Value> = name
|
||||
.split('.')
|
||||
.map(|s| UntaggedValue::string(s.to_string()).into_value(Tag::unknown()))
|
||||
.collect();
|
||||
let cp = column_path(&name)
|
||||
.as_column_path()
|
||||
.expect("Failed! Expected valid column path.");
|
||||
let cp = UntaggedValue::Primitive(Primitive::ColumnPath(cp.item)).into_value(cp.tag);
|
||||
|
||||
self.positionals.push(value::column_path(&fields)?);
|
||||
self.positionals.push(cp);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
|
@ -157,62 +161,3 @@ pub fn expect_return_value_at(
|
|||
return_values.len() - 1
|
||||
))
|
||||
}
|
||||
|
||||
pub mod value {
|
||||
use bigdecimal::BigDecimal;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, TaggedDictBuilder, UntaggedValue, Value};
|
||||
use nu_source::{Span, Tag};
|
||||
use nu_value_ext::ValueExt;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
pub fn get_data(for_value: Value, key: &str) -> Value {
|
||||
for_value.get_data(&key.to_string()).borrow().clone()
|
||||
}
|
||||
|
||||
pub fn int(i: impl Into<BigInt>) -> Value {
|
||||
UntaggedValue::Primitive(Primitive::Int(i.into())).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn decimal(f: impl Into<BigDecimal>) -> Value {
|
||||
UntaggedValue::decimal(f.into()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn decimal_from_float(f: f64) -> Value {
|
||||
UntaggedValue::decimal_from_float(f, Span::unknown()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn string(input: impl Into<String>) -> Value {
|
||||
UntaggedValue::string(input.into()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn structured_sample_record(key: &str, value: &str) -> Value {
|
||||
let mut record = TaggedDictBuilder::new(Tag::unknown());
|
||||
record.insert_untagged(key, UntaggedValue::string(value));
|
||||
record.into_value()
|
||||
}
|
||||
|
||||
pub fn unstructured_sample_record(value: &str) -> Value {
|
||||
UntaggedValue::string(value).into_value(Tag::unknown())
|
||||
}
|
||||
|
||||
pub fn table(list: &[Value]) -> Value {
|
||||
UntaggedValue::table(list).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn column_path(paths: &[Value]) -> Result<Value, ShellError> {
|
||||
Ok(UntaggedValue::Primitive(Primitive::ColumnPath(
|
||||
table(&paths.to_vec()).as_column_path()?.item,
|
||||
))
|
||||
.into_untagged_value())
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! row {
|
||||
($( $key: expr => $val: expr ),*) => {{
|
||||
let mut map = ::indexmap::IndexMap::new();
|
||||
$( map.insert($key, $val); )*
|
||||
::nu_protocol::UntaggedValue::row(map).into_untagged_value()
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,3 +24,12 @@ macro_rules! outln {
|
|||
macro_rules! errln {
|
||||
($($tokens:tt)*) => { eprintln!($($tokens)*) }
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! row {
|
||||
($( $key: expr => $val: expr ),*) => {{
|
||||
let mut map = ::indexmap::IndexMap::new();
|
||||
$( map.insert($key, $val); )*
|
||||
::nu_protocol::UntaggedValue::row(map).into_untagged_value()
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ impl UntaggedValue {
|
|||
}
|
||||
|
||||
/// Helper for creating column-path values
|
||||
pub fn column_path(s: &str) -> UntaggedValue {
|
||||
let s = s.to_string().spanned_unknown();
|
||||
pub fn column_path(s: &str, span: Span) -> UntaggedValue {
|
||||
let s = s.to_string().spanned(span);
|
||||
|
||||
UntaggedValue::Primitive(Primitive::ColumnPath(ColumnPath::build(&s)))
|
||||
}
|
||||
|
@ -196,8 +196,8 @@ impl UntaggedValue {
|
|||
}
|
||||
|
||||
/// Helper for creating decimal values
|
||||
pub fn decimal(s: BigDecimal) -> UntaggedValue {
|
||||
UntaggedValue::Primitive(Primitive::Decimal(s))
|
||||
pub fn decimal(s: impl Into<BigDecimal>) -> UntaggedValue {
|
||||
UntaggedValue::Primitive(Primitive::Decimal(s.into()))
|
||||
}
|
||||
|
||||
/// Helper for creating decimal values
|
||||
|
|
|
@ -21,6 +21,7 @@ getset = "0.1.1"
|
|||
glob = "0.3.0"
|
||||
indexmap = {version = "1.6.0", features = ["serde-1"]}
|
||||
num-bigint = {version = "0.3.0", features = ["serde"]}
|
||||
bigdecimal = {version = "0.2.0", features = ["serde"]}
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
use bigdecimal::BigDecimal;
|
||||
use chrono::{DateTime, NaiveDate, Utc};
|
||||
use indexmap::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, PathMember, Primitive, UntaggedValue, Value};
|
||||
use nu_source::{Span, SpannedItem, Tagged, TaggedItem};
|
||||
use nu_protocol::{PathMember, Primitive, UntaggedValue, Value};
|
||||
use nu_source::{Span, TaggedItem};
|
||||
use num_bigint::BigInt;
|
||||
|
||||
pub fn int(s: impl Into<BigInt>) -> Value {
|
||||
UntaggedValue::int(s).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn decimal_from_float(f: f64, span: Span) -> Value {
|
||||
UntaggedValue::decimal_from_float(f, span).into_untagged_value()
|
||||
pub fn decimal(s: BigDecimal) -> Value {
|
||||
UntaggedValue::Primitive(Primitive::Decimal(s)).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn decimal_from_float(f: f64) -> Value {
|
||||
UntaggedValue::decimal_from_float(f, Span::unknown()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn string(input: impl Into<String>) -> Value {
|
||||
|
@ -42,9 +47,8 @@ pub fn date(input: impl Into<String>) -> Value {
|
|||
.into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn column_path(paths: &str) -> Result<Tagged<ColumnPath>, ShellError> {
|
||||
let paths = paths.to_string().spanned_unknown();
|
||||
Ok(ColumnPath::build(&paths).tagged_unknown())
|
||||
pub fn column_path(paths: &str) -> Value {
|
||||
UntaggedValue::column_path(paths, Span::unknown()).into_untagged_value()
|
||||
}
|
||||
|
||||
pub fn error_callback(
|
||||
|
|
|
@ -5,7 +5,7 @@ use indexmap::indexmap;
|
|||
|
||||
#[test]
|
||||
fn forgiving_insertion_test_1() {
|
||||
let field_path = column_path("crate.version").unwrap();
|
||||
let field_path = column_path("crate.version").as_column_path().unwrap();
|
||||
|
||||
let version = string("nuno");
|
||||
|
||||
|
@ -20,7 +20,7 @@ fn forgiving_insertion_test_1() {
|
|||
assert_eq!(
|
||||
*value
|
||||
.into_untagged_value()
|
||||
.forgiving_insert_data_at_column_path(&field_path, version)
|
||||
.forgiving_insert_data_at_column_path(&field_path.item, version)
|
||||
.unwrap()
|
||||
.get_data_by_column_path(&field_path, Box::new(error_callback("crate.version")))
|
||||
.unwrap(),
|
||||
|
@ -30,7 +30,7 @@ fn forgiving_insertion_test_1() {
|
|||
|
||||
#[test]
|
||||
fn forgiving_insertion_test_2() {
|
||||
let field_path = column_path("things.0").unwrap();
|
||||
let field_path = column_path("things.0").as_column_path().unwrap();
|
||||
|
||||
let version = string("arepas");
|
||||
|
||||
|
@ -47,7 +47,7 @@ fn forgiving_insertion_test_2() {
|
|||
assert_eq!(
|
||||
*value
|
||||
.into_untagged_value()
|
||||
.forgiving_insert_data_at_column_path(&field_path, version)
|
||||
.forgiving_insert_data_at_column_path(&field_path.item, version)
|
||||
.unwrap()
|
||||
.get_data_by_column_path(&field_path, Box::new(error_callback("things.0")))
|
||||
.unwrap(),
|
||||
|
@ -57,8 +57,10 @@ fn forgiving_insertion_test_2() {
|
|||
|
||||
#[test]
|
||||
fn forgiving_insertion_test_3() {
|
||||
let field_path = column_path("color_config.arepa_color").unwrap();
|
||||
let pizza_path = column_path("things.0").unwrap();
|
||||
let field_path = column_path("color_config.arepa_color")
|
||||
.as_column_path()
|
||||
.unwrap();
|
||||
let pizza_path = column_path("things.0").as_column_path().unwrap();
|
||||
|
||||
let entry = string("amarillo");
|
||||
|
||||
|
@ -79,7 +81,7 @@ fn forgiving_insertion_test_3() {
|
|||
.forgiving_insert_data_at_column_path(&field_path, entry.clone())
|
||||
.unwrap()
|
||||
.get_data_by_column_path(
|
||||
&field_path,
|
||||
&field_path.item,
|
||||
Box::new(error_callback("color_config.arepa_color"))
|
||||
)
|
||||
.unwrap(),
|
||||
|
@ -89,7 +91,7 @@ fn forgiving_insertion_test_3() {
|
|||
assert_eq!(
|
||||
*value
|
||||
.into_untagged_value()
|
||||
.forgiving_insert_data_at_column_path(&field_path, entry)
|
||||
.forgiving_insert_data_at_column_path(&field_path.item, entry)
|
||||
.unwrap()
|
||||
.get_data_by_column_path(&pizza_path, Box::new(error_callback("things.0")))
|
||||
.unwrap(),
|
||||
|
|
|
@ -15,6 +15,7 @@ nu-plugin = {path = "../nu-plugin", version = "0.21.0"}
|
|||
nu-protocol = {path = "../nu-protocol", version = "0.21.0"}
|
||||
nu-source = {path = "../nu-source", version = "0.21.0"}
|
||||
nu-value-ext = {path = "../nu-value-ext", version = "0.21.0"}
|
||||
nu-test-support = {path = "../nu-test-support", version = "0.21.0"}
|
||||
|
||||
semver = "0.10.0"
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ mod tests {
|
|||
mod semver {
|
||||
use crate::inc::SemVerAction;
|
||||
use crate::Inc;
|
||||
use nu_plugin::test_helpers::value::string;
|
||||
use nu_test_support::value::string;
|
||||
|
||||
#[test]
|
||||
fn major() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
|
@ -2,8 +2,10 @@ mod integration {
|
|||
use crate::inc::{Action, SemVerAction};
|
||||
use crate::Inc;
|
||||
use nu_errors::ShellError;
|
||||
use nu_plugin::test_helpers::value::{column_path, string};
|
||||
use nu_plugin::test_helpers::{plugin, CallStub};
|
||||
use nu_protocol::{Primitive, UntaggedValue};
|
||||
use nu_test_support::value::column_path;
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
#[test]
|
||||
fn picks_up_one_action_flag_only() {
|
||||
|
@ -58,21 +60,28 @@ mod integration {
|
|||
.args(CallStub::new().with_parameter("package.version")?.create())
|
||||
.setup(|plugin, _| {
|
||||
//FIXME: this will need to be updated
|
||||
if let Ok(column_path) = column_path(&[string("package"), string("version")]) {
|
||||
if let Ok(column_path) = column_path("package.version").as_column_path() {
|
||||
let column_path =
|
||||
UntaggedValue::Primitive(Primitive::ColumnPath(column_path.item))
|
||||
.into_value(column_path.tag);
|
||||
plugin.expect_field(column_path)
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
mod sem_ver {
|
||||
use crate::Inc;
|
||||
use nu_errors::ShellError;
|
||||
use nu_plugin::test_helpers::value::{get_data, string, structured_sample_record};
|
||||
use nu_plugin::test_helpers::{expect_return_value_at, plugin, CallStub};
|
||||
use nu_protocol::TaggedDictBuilder;
|
||||
use nu_source::Tag;
|
||||
use nu_test_support::value::string;
|
||||
use nu_value_ext::get_data;
|
||||
|
||||
fn cargo_sample_record(with_version: &str) -> nu_protocol::Value {
|
||||
structured_sample_record("version", with_version)
|
||||
TaggedDictBuilder::build(Tag::unknown(), |row| {
|
||||
row.insert_value("version".to_string(), string(with_version));
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -90,7 +99,7 @@ mod integration {
|
|||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
|
||||
assert_eq!(get_data(actual, "version"), string("1.0.0"));
|
||||
assert_eq!(get_data(&actual, "version").borrow(), &string("1.0.0"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -109,7 +118,7 @@ mod integration {
|
|||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
|
||||
assert_eq!(get_data(actual, "version"), string("0.2.0"));
|
||||
assert_eq!(get_data(&actual, "version").borrow(), &string("0.2.0"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -128,7 +137,7 @@ mod integration {
|
|||
|
||||
let actual = expect_return_value_at(run, 0);
|
||||
|
||||
assert_eq!(get_data(actual, "version"), string("0.1.4"));
|
||||
assert_eq!(get_data(&actual, "version").borrow(), &string("0.1.4"));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ fn build_xpath(xpath_str: &str) -> Result<sxd_xpath::XPath, ShellError> {
|
|||
mod tests {
|
||||
use super::string_to_value as query;
|
||||
use nu_errors::ShellError;
|
||||
use nu_source::{Span, TaggedItem};
|
||||
use nu_source::TaggedItem;
|
||||
use nu_test_support::value::{decimal_from_float, row};
|
||||
|
||||
use indexmap::indexmap;
|
||||
|
@ -140,9 +140,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
actual[0],
|
||||
row(
|
||||
indexmap! { "count(//a/*[posit...".into() => decimal_from_float(1.0, Span::unknown()) }
|
||||
)
|
||||
row(indexmap! { "count(//a/*[posit...".into() => decimal_from_float(1.0) })
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
@ -156,9 +154,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
actual[0],
|
||||
row(
|
||||
indexmap! { "count(//*[contain...".into() => decimal_from_float(1.0, Span::unknown()) }
|
||||
)
|
||||
row(indexmap! { "count(//*[contain...".into() => decimal_from_float(1.0) })
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue