From 9945241b77e893a0637d2d92b5245cec45703e69 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 3 Feb 2023 08:59:58 +1000 Subject: [PATCH] Remove deprecated `--numbered` flag from four commands (#7777) # Description Remove `--numbered` from ~~`for`~~, `each`, `par-each`, `reduce` and `each while`. These all provide indexes (numbering) via the optional second param to their closures. EDIT: Closes #6986. # User-Facing Changes Every command that had `--numbered` listed as "deprecated" in their help docs is affected. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> --- crates/nu-command/src/core_commands/for_.rs | 2 +- crates/nu-command/src/example_test.rs | 51 +++--- crates/nu-command/src/filters/all.rs | 21 +-- crates/nu-command/src/filters/any.rs | 21 +-- crates/nu-command/src/filters/each.rs | 80 ++------- crates/nu-command/src/filters/each_while.rs | 87 ++------- crates/nu-command/src/filters/filter.rs | 30 +--- crates/nu-command/src/filters/insert.rs | 30 ++-- crates/nu-command/src/filters/par_each.rs | 190 ++++---------------- crates/nu-command/src/filters/reduce.rs | 92 ++-------- crates/nu-command/src/filters/update.rs | 12 +- crates/nu-command/src/filters/upsert.rs | 27 +-- crates/nu-command/src/filters/where_.rs | 20 +-- crates/nu-command/tests/commands/all.rs | 4 +- crates/nu-command/tests/commands/any.rs | 4 +- crates/nu-command/tests/commands/each.rs | 8 +- crates/nu-command/tests/commands/insert.rs | 6 +- crates/nu-command/tests/commands/reduce.rs | 23 ++- crates/nu-command/tests/commands/roll.rs | 3 +- crates/nu-command/tests/commands/update.rs | 6 +- crates/nu-command/tests/commands/upsert.rs | 12 +- crates/nu-command/tests/commands/where_.rs | 6 +- src/tests/test_iteration.rs | 4 +- src/tests/test_parser.rs | 4 +- 24 files changed, 202 insertions(+), 541 deletions(-) diff --git a/crates/nu-command/src/core_commands/for_.rs b/crates/nu-command/src/core_commands/for_.rs index f6193263c8..e8c82627eb 100644 --- a/crates/nu-command/src/core_commands/for_.rs +++ b/crates/nu-command/src/core_commands/for_.rs @@ -34,7 +34,7 @@ impl Command for For { .required("block", SyntaxShape::Block, "the block to run") .switch( "numbered", - "returned a numbered item ($it.index and $it.item)", + "return a numbered item ($it.index and $it.item)", Some('n'), ) .creates_scope() diff --git a/crates/nu-command/src/example_test.rs b/crates/nu-command/src/example_test.rs index 81f0919182..0c7a5f347f 100644 --- a/crates/nu-command/src/example_test.rs +++ b/crates/nu-command/src/example_test.rs @@ -9,9 +9,9 @@ pub fn test_examples(cmd: impl Command + 'static) { #[cfg(test)] mod test_examples { use super::super::{ - Ansi, Date, Echo, From, If, Into, IntoString, Let, LetEnv, Math, MathEuler, MathPi, - MathRound, Path, Random, Split, SplitColumn, SplitRow, Str, StrJoin, StrLength, StrReplace, - Url, Values, Wrap, + Ansi, Date, Echo, Enumerate, Flatten, From, Get, If, Into, IntoString, Let, LetEnv, Math, + MathEuler, MathPi, MathRound, ParEach, Path, Random, Sort, SortBy, Split, SplitColumn, + SplitRow, Str, StrJoin, StrLength, StrReplace, Update, Url, Values, Wrap, }; use crate::{Break, Each, Mut, To}; use itertools::Itertools; @@ -61,35 +61,42 @@ mod test_examples { // Base functions that are needed for testing // Try to keep this working set small to keep tests running as fast as possible let mut working_set = StateWorkingSet::new(&engine_state); + working_set.add_decl(Box::new(Ansi)); + working_set.add_decl(Box::new(Break)); + working_set.add_decl(Box::new(Date)); working_set.add_decl(Box::new(Each)); + working_set.add_decl(Box::new(Echo)); + working_set.add_decl(Box::new(Enumerate)); + working_set.add_decl(Box::new(Flatten)); + working_set.add_decl(Box::new(From)); + working_set.add_decl(Box::new(Get)); + working_set.add_decl(Box::new(If)); + working_set.add_decl(Box::new(Into)); + working_set.add_decl(Box::new(IntoString)); working_set.add_decl(Box::new(Let)); + working_set.add_decl(Box::new(LetEnv)); + working_set.add_decl(Box::new(Math)); + working_set.add_decl(Box::new(MathEuler)); + working_set.add_decl(Box::new(MathPi)); + working_set.add_decl(Box::new(MathRound)); + working_set.add_decl(Box::new(Mut)); + working_set.add_decl(Box::new(Path)); + working_set.add_decl(Box::new(ParEach)); + working_set.add_decl(Box::new(Random)); + working_set.add_decl(Box::new(Sort)); + working_set.add_decl(Box::new(SortBy)); + working_set.add_decl(Box::new(Split)); + working_set.add_decl(Box::new(SplitColumn)); + working_set.add_decl(Box::new(SplitRow)); working_set.add_decl(Box::new(Str)); working_set.add_decl(Box::new(StrJoin)); working_set.add_decl(Box::new(StrLength)); working_set.add_decl(Box::new(StrReplace)); - working_set.add_decl(Box::new(From)); - working_set.add_decl(Box::new(If)); working_set.add_decl(Box::new(To)); - working_set.add_decl(Box::new(Into)); - working_set.add_decl(Box::new(IntoString)); - working_set.add_decl(Box::new(Random)); - working_set.add_decl(Box::new(Split)); - working_set.add_decl(Box::new(SplitColumn)); - working_set.add_decl(Box::new(SplitRow)); - working_set.add_decl(Box::new(Math)); - working_set.add_decl(Box::new(Path)); - working_set.add_decl(Box::new(Date)); working_set.add_decl(Box::new(Url)); + working_set.add_decl(Box::new(Update)); working_set.add_decl(Box::new(Values)); - working_set.add_decl(Box::new(Ansi)); working_set.add_decl(Box::new(Wrap)); - working_set.add_decl(Box::new(LetEnv)); - working_set.add_decl(Box::new(Echo)); - working_set.add_decl(Box::new(Break)); - working_set.add_decl(Box::new(Mut)); - working_set.add_decl(Box::new(MathEuler)); - working_set.add_decl(Box::new(MathPi)); - working_set.add_decl(Box::new(MathRound)); // Adding the command that is being tested to the working set working_set.add_decl(cmd); diff --git a/crates/nu-command/src/filters/all.rs b/crates/nu-command/src/filters/all.rs index 2e9016ccf5..13abfdd511 100644 --- a/crates/nu-command/src/filters/all.rs +++ b/crates/nu-command/src/filters/all.rs @@ -43,9 +43,14 @@ impl Command for All { example: "[[status]; [UP] [UP]] | all {|el| $el.status == UP }", result: Some(Value::test_bool(true)), }, + Example { + description: "Check that each item is a string", + example: "[foo bar 2 baz] | all { ($in | describe) == 'string' }", + result: Some(Value::test_bool(false)), + }, Example { description: "Check that all values are equal to twice their index", - example: "[0 2 4 6] | all {|el ind| $el == $ind * 2 }", + example: "[0 2 4 6] | enumerate | all {|i| $i.item == $i.index * 2 }", result: Some(Value::test_bool(true)), }, Example { @@ -80,7 +85,7 @@ impl Command for All { let ctrlc = engine_state.ctrlc.clone(); let engine_state = engine_state.clone(); - for (idx, value) in input.into_interruptible_iter(ctrlc).enumerate() { + for value in input.into_interruptible_iter(ctrlc) { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -89,18 +94,6 @@ impl Command for All { if let Some(var_id) = var_id { stack.add_var(var_id, value.clone()); } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } let eval = eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/any.rs b/crates/nu-command/src/filters/any.rs index 6834b46bd7..654a551d54 100644 --- a/crates/nu-command/src/filters/any.rs +++ b/crates/nu-command/src/filters/any.rs @@ -43,9 +43,14 @@ impl Command for Any { example: "[[status]; [UP] [DOWN] [UP]] | any {|el| $el.status == DOWN }", result: Some(Value::test_bool(true)), }, + Example { + description: "Check that any item is a string", + example: "[1 2 3 4] | any { ($in | describe) == 'string' }", + result: Some(Value::test_bool(false)), + }, Example { description: "Check if any value is equal to twice its own index", - example: "[9 8 7 6] | any {|el ind| $el == $ind * 2 }", + example: "[9 8 7 6] | enumerate | any {|i| $i.item == $i.index * 2 }", result: Some(Value::test_bool(true)), }, Example { @@ -80,7 +85,7 @@ impl Command for Any { let ctrlc = engine_state.ctrlc.clone(); let engine_state = engine_state.clone(); - for (idx, value) in input.into_interruptible_iter(ctrlc).enumerate() { + for value in input.into_interruptible_iter(ctrlc) { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -89,18 +94,6 @@ impl Command for Any { if let Some(var_id) = var_id { stack.add_var(var_id, value.clone()); } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } let eval = eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 6490424276..d1e5ea2ef1 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -35,21 +35,19 @@ with 'transpose' first."# fn signature(&self) -> nu_protocol::Signature { Signature::build("each") - .input_output_types(vec![( - Type::List(Box::new(Type::Any)), - Type::List(Box::new(Type::Any)), - )]) + .input_output_types(vec![ + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + (Type::Table(vec![]), Type::List(Box::new(Type::Any))), + ]) .required( "closure", SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), "the closure to run", ) .switch("keep-empty", "keep empty result cells", Some('k')) - .switch( - "numbered", - "iterate with an index (deprecated; use a two-parameter closure instead)", - Some('n'), - ) .category(Category::Filters) } @@ -96,7 +94,7 @@ with 'transpose' first."# }), }, Example { - example: r#"[1 2 3] | each {|el ind| if $el == 2 { $"found 2 at ($ind)!"} }"#, + example: r#"[1 2 3] | enumerate | each {|e| if $e.item == 2 { $"found 2 at ($e.index)!"} }"#, description: "Iterate over each element, producing a list showing indexes of any 2s", result: Some(Value::List { @@ -106,7 +104,7 @@ with 'transpose' first."# }, Example { example: r#"[1 2 3] | each --keep-empty {|e| if $e == 2 { "found 2!"} }"#, - description: "Iterate over each element, keeping all results", + description: "Iterate over each element, keeping null results", result: Some(Value::List { vals: stream_test_2, span: Span::test_data(), @@ -124,7 +122,6 @@ with 'transpose' first."# ) -> Result { let capture_block: Closure = call.req(engine_state, stack, 0)?; - let numbered = call.has_flag("numbered"); let keep_empty = call.has_flag("keep-empty"); let metadata = input.metadata(); @@ -144,11 +141,8 @@ with 'transpose' first."# PipelineData::Value(Value::Range { .. }, ..) | PipelineData::Value(Value::List { .. }, ..) | PipelineData::ListStream { .. } => Ok(input - // To enumerate over the input (for the index argument), - // it must be converted into an iterator using into_iter(). .into_iter() - .enumerate() - .map_while(move |(idx, x)| { + .map_while(move |x| { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -156,37 +150,7 @@ with 'transpose' first."# if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - // -n changes the first argument into an {index, item} record. - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -214,8 +178,7 @@ with 'transpose' first."# .. } => Ok(stream .into_iter() - .enumerate() - .map_while(move |(idx, x)| { + .map_while(move |x| { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -229,24 +192,7 @@ with 'transpose' first."# if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } + stack.add_var(*var_id, x.clone()); } } diff --git a/crates/nu-command/src/filters/each_while.rs b/crates/nu-command/src/filters/each_while.rs index bc04b3de45..fa64d8c4b7 100644 --- a/crates/nu-command/src/filters/each_while.rs +++ b/crates/nu-command/src/filters/each_while.rs @@ -24,20 +24,18 @@ impl Command for EachWhile { fn signature(&self) -> nu_protocol::Signature { Signature::build(self.name()) - .input_output_types(vec![( - Type::List(Box::new(Type::Any)), - Type::List(Box::new(Type::Any)), - )]) + .input_output_types(vec![ + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + (Type::Table(vec![]), Type::List(Box::new(Type::Any))), + ]) .required( "closure", SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), "the closure to run", ) - .switch( - "numbered", - "iterate with an index (deprecated; use a two-parameter closure instead)", - Some('n'), - ) .category(Category::Filters) } @@ -66,7 +64,7 @@ impl Command for EachWhile { }), }, Example { - example: r#"[1 2 3] | each while {|el ind| if $el < 2 { $"value ($el) at ($ind)!"} }"#, + example: r#"[1 2 3] | enumerate | each while {|e| if $e.item < 2 { $"value ($e.item) at ($e.index)!"} }"#, description: "Iterate over each element, printing the matching value and its index", result: Some(Value::List { vals: vec![Value::test_string("value 1 at 0!")], @@ -84,7 +82,6 @@ impl Command for EachWhile { input: PipelineData, ) -> Result { let capture_block: Closure = call.req(engine_state, stack, 0)?; - let numbered = call.has_flag("numbered"); let metadata = input.metadata(); let ctrlc = engine_state.ctrlc.clone(); @@ -102,12 +99,9 @@ impl Command for EachWhile { PipelineData::Value(Value::Range { .. }, ..) | PipelineData::Value(Value::List { .. }, ..) | PipelineData::ListStream { .. } => Ok(input - // To enumerate over the input (for the index argument), - // it must be converted into an iterator using into_iter(). // TODO: Could this be changed to .into_interruptible_iter(ctrlc) ? .into_iter() - .enumerate() - .map_while(move |(idx, x)| { + .map_while(move |x| { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -115,36 +109,7 @@ impl Command for EachWhile { if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -175,8 +140,7 @@ impl Command for EachWhile { .. } => Ok(stream .into_iter() - .enumerate() - .map_while(move |(idx, x)| { + .map_while(move |x| { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -189,24 +153,7 @@ impl Command for EachWhile { if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } + stack.add_var(*var_id, x.clone()); } } @@ -257,17 +204,7 @@ impl Command for EachWhile { #[cfg(test)] mod test { use super::*; - use nu_test_support::{nu, pipeline}; - #[test] - fn uses_optional_index_argument() { - let actual = nu!( - cwd: ".", pipeline( - r#"[7 8 9 10] | each while {|el ind| $el + $ind } | to nuon"# - )); - - assert_eq!(actual.out, "[7, 9, 11, 13]"); - } #[test] fn test_examples() { use crate::test_examples; diff --git a/crates/nu-command/src/filters/filter.rs b/crates/nu-command/src/filters/filter.rs index ae9d471106..2e516de4e8 100644 --- a/crates/nu-command/src/filters/filter.rs +++ b/crates/nu-command/src/filters/filter.rs @@ -72,8 +72,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# // To enumerate over the input (for the index argument), // it must be converted into an iterator using into_iter(). .into_iter() - .enumerate() - .filter_map(move |(idx, x)| { + .filter_map(move |x| { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -84,18 +83,6 @@ a variable. On the other hand, the "row condition" syntax is not supported."# stack.add_var(*var_id, x.clone()); } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } match eval_block( &engine_state, @@ -125,8 +112,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# .. } => Ok(stream .into_iter() - .enumerate() - .filter_map(move |(idx, x)| { + .filter_map(move |x| { // see note above about with_env() stack.with_env(&orig_env_vars, &orig_env_hidden); @@ -140,18 +126,6 @@ a variable. On the other hand, the "row condition" syntax is not supported."# stack.add_var(*var_id, x.clone()); } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } match eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/insert.rs b/crates/nu-command/src/filters/insert.rs index 703a6fd254..3a6d7ab03b 100644 --- a/crates/nu-command/src/filters/insert.rs +++ b/crates/nu-command/src/filters/insert.rs @@ -64,27 +64,37 @@ impl Command for Insert { ], span: Span::test_data(), }), - }, Example { + }, + Example { + description: "Insert a new column into a table, populating all rows", + example: "[[project, lang]; ['Nushell', 'Rust']] | insert type 'shell'", + result: Some(Value::List { vals: vec![Value::Record { cols: vec!["project".into(), "lang".into(), "type".into()], + vals: vec![Value::test_string("Nushell"), Value::test_string("Rust"), Value::test_string("shell")], span: Span::test_data()}], span: Span::test_data()}), + }, + Example { description: "Insert a column with values equal to their row index, plus the value of 'foo' in each row", - example: "[[foo]; [7] [8] [9]] | insert bar {|el ind| $el.foo + $ind }", + example: "[[foo]; [7] [8] [9]] | enumerate | insert bar {|e| $e.item.foo + $e.index } | flatten", result: Some(Value::List { vals: vec![Value::Record { - cols: vec!["foo".into(), "bar".into()], + cols: vec!["index".into(), "foo".into(), "bar".into()], vals: vec![ + Value::test_int(0), Value::test_int(7), Value::test_int(7), ], span: Span::test_data(), }, Value::Record { - cols: vec!["foo".into(), "bar".into()], + cols: vec!["index".into(),"foo".into(), "bar".into()], vals: vec![ + Value::test_int(1), Value::test_int(8), Value::test_int(9), ], span: Span::test_data(), }, Value::Record { - cols: vec!["foo".into(), "bar".into()], + cols: vec!["index".into(), "foo".into(), "bar".into()], vals: vec![ + Value::test_int(2), Value::test_int(9), Value::test_int(11), ], @@ -122,9 +132,6 @@ fn insert( let orig_env_vars = stack.env_vars.clone(); let orig_env_hidden = stack.env_hidden.clone(); - // enumerate() can't be used here because it converts records into tables - // when combined with into_pipeline_data(). Hence, the index is tracked manually like so. - let mut idx: i64 = 0; input.map( move |mut input| { // with_env() is used here to ensure that each iteration uses @@ -138,13 +145,6 @@ fn insert( stack.add_var(*var_id, input.clone()) } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, Value::Int { val: idx, span }); - } - idx += 1; - } let output = eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index 8d561bccce..8bb373dea8 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -23,20 +23,18 @@ impl Command for ParEach { fn signature(&self) -> nu_protocol::Signature { Signature::build("par-each") - .input_output_types(vec![( - Type::List(Box::new(Type::Any)), - Type::List(Box::new(Type::Any)), - )]) + .input_output_types(vec![ + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + (Type::Table(vec![]), Type::List(Box::new(Type::Any))), + ]) .required( "closure", SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), "the closure to run", ) - .switch( - "numbered", - "iterate with an index (deprecated; use a two-parameter closure instead)", - Some('n'), - ) .category(Category::Filters) } @@ -49,8 +47,29 @@ impl Command for ParEach { result: None, }, Example { - example: r#"[1 2 3] | par-each -n { |it| if $it.item == 2 { $"found 2 at ($it.index)!"} }"#, - description: "Iterate over each element, print the matching value and its index", + example: r#"[foo bar baz] | par-each {|e| $e + '!' } | sort"#, + description: "Output can still be sorted afterward", + result: Some(Value::List { + vals: vec![ + Value::test_string("bar!"), + Value::test_string("baz!"), + Value::test_string("foo!"), + ], + span: Span::test_data(), + }), + }, + Example { + example: r#"1..3 | enumerate | par-each {|p| update item ($p.item * 2)} | sort-by item | get item"#, + description: "Enumerate and sort-by can be used to reconstruct the original order", + result: Some(Value::List { + vals: vec![Value::test_int(2), Value::test_int(4), Value::test_int(6)], + span: Span::test_data(), + }), + }, + Example { + example: r#"[1 2 3] | enumerate | par-each { |e| if $e.item == 2 { $"found 2 at ($e.index)!"} }"#, + description: + "Iterate over each element, producing a list showing indexes of any 2s", result: Some(Value::List { vals: vec![Value::test_string("found 2 at 1!")], span: Span::test_data(), @@ -68,12 +87,10 @@ impl Command for ParEach { ) -> Result { let capture_block: Closure = call.req(engine_state, stack, 0)?; - let numbered = call.has_flag("numbered"); let metadata = input.metadata(); let ctrlc = engine_state.ctrlc.clone(); let block_id = capture_block.block_id; let mut stack = stack.captures_to_stack(&capture_block.captures); - let span = call.head; let redirect_stdout = call.redirect_stdout; let redirect_stderr = call.redirect_stderr; @@ -81,45 +98,15 @@ impl Command for ParEach { PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val .into_range_iter(ctrlc.clone())? - .enumerate() .par_bridge() - .map(move |(idx, x)| { + .map(move |x| { let block = engine_state.get_block(block_id); let mut stack = stack.clone(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -145,45 +132,15 @@ impl Command for ParEach { .into_pipeline_data(ctrlc)), PipelineData::Value(Value::List { vals: val, .. }, ..) => Ok(val .into_iter() - .enumerate() .par_bridge() - .map(move |(idx, x)| { + .map(move |x| { let block = engine_state.get_block(block_id); let mut stack = stack.clone(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -208,45 +165,15 @@ impl Command for ParEach { .flatten() .into_pipeline_data(ctrlc)), PipelineData::ListStream(stream, ..) => Ok(stream - .enumerate() .par_bridge() - .map(move |(idx, x)| { + .map(move |x| { let block = engine_state.get_block(block_id); let mut stack = stack.clone(); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -275,9 +202,8 @@ impl Command for ParEach { stdout: Some(stream), .. } => Ok(stream - .enumerate() .par_bridge() - .map(move |(idx, x)| { + .map(move |x| { let x = match x { Ok(x) => x, Err(err) => return Value::Error { error: err }.into_pipeline_data(), @@ -289,36 +215,7 @@ impl Command for ParEach { if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { - if numbered { - stack.add_var( - *var_id, - Value::Record { - cols: vec!["index".into(), "item".into()], - vals: vec![ - Value::Int { - val: idx as i64, - span, - }, - x.clone(), - ], - span, - }, - ); - } else { - stack.add_var(*var_id, x.clone()); - } - } - } - // Optional second index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); + stack.add_var(*var_id, x.clone()); } } @@ -366,17 +263,6 @@ impl Command for ParEach { #[cfg(test)] mod test { use super::*; - use nu_test_support::{nu, pipeline}; - - #[test] - fn uses_optional_index_argument() { - let actual = nu!( - cwd: ".", pipeline( - r#"[7,8,9,10] | par-each {|el ind| $ind } | describe"# - )); - - assert_eq!(actual.out, "list (stream)"); - } #[test] fn test_examples() { diff --git a/crates/nu-command/src/filters/reduce.rs b/crates/nu-command/src/filters/reduce.rs index 4d81360126..11da4dfbe4 100644 --- a/crates/nu-command/src/filters/reduce.rs +++ b/crates/nu-command/src/filters/reduce.rs @@ -16,7 +16,10 @@ impl Command for Reduce { fn signature(&self) -> Signature { Signature::build("reduce") - .input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Any)]) + .input_output_types(vec![ + (Type::List(Box::new(Type::Any)), Type::Any), + (Type::Table(vec![]), Type::Any), + ]) .named( "fold", SyntaxShape::Any, @@ -32,11 +35,6 @@ impl Command for Reduce { ])), "reducing function", ) - .switch( - "numbered", - "iterate with an index (deprecated; use a 3-parameter closure instead)", - Some('n'), - ) } fn usage(&self) -> &str { @@ -55,9 +53,10 @@ impl Command for Reduce { result: Some(Value::test_int(10)), }, Example { - example: "[ 8 7 6 ] | reduce {|it, acc, ind| $acc + $it + $ind }", + example: + "[ 8 7 6 ] | enumerate | reduce -f 0 {|it, acc| $acc + $it.item + $it.index }", description: "Sum values of a list, plus their indexes", - result: Some(Value::test_int(22)), + result: Some(Value::test_int(24)), }, Example { example: "[ 1 2 3 4 ] | reduce -f 10 {|it, acc| $acc + $it }", @@ -70,7 +69,7 @@ impl Command for Reduce { result: Some(Value::test_string("ArXhur, KXng Xf Xhe BrXXXns")), }, Example { - example: r#"['foo.gz', 'bar.gz', 'baz.gz'] | reduce -f '' {|str all ind| $"($all)(if $ind != 0 {'; '})($ind + 1)-($str)" }"#, + example: r#"['foo.gz', 'bar.gz', 'baz.gz'] | enumerate | reduce -f '' {|str all| $"($all)(if $str.index != 0 {'; '})($str.index + 1)-($str.item)" }"#, description: "Add ascending numbers to each of the filenames, and join with semicolons.", result: Some(Value::test_string("1-foo.gz; 2-bar.gz; 3-baz.gz")), @@ -88,7 +87,6 @@ impl Command for Reduce { let span = call.head; let fold: Option = call.get_flag(engine_state, stack, "fold")?; - let numbered = call.has_flag("numbered"); let capture_block: Closure = call.req(engine_state, stack, 0)?; let mut stack = stack.captures_to_stack(&capture_block.captures); let block = engine_state.get_block(capture_block.block_id); @@ -104,10 +102,10 @@ impl Command for Reduce { // it must be converted into an iterator using into_iter(). let mut input_iter = input.into_iter(); - let (off, start_val) = if let Some(val) = fold { - (0, val) + let start_val = if let Some(val) = fold { + val } else if let Some(val) = input_iter.next() { - (1, val) + val } else { return Err(ShellError::GenericError( "Expected input".to_string(), @@ -118,41 +116,11 @@ impl Command for Reduce { )); }; - let mut acc = if numbered { - Value::Record { - cols: vec!["index".to_string(), "item".to_string()], - vals: vec![Value::Int { val: 0, span }, start_val], - span, - } - } else { - start_val - }; + let mut acc = start_val; - let mut input_iter = input_iter - .enumerate() - .map(|(idx, x)| { - if numbered { - ( - idx, - Value::Record { - cols: vec!["index".to_string(), "item".to_string()], - vals: vec![ - Value::Int { - val: idx as i64 + off, - span, - }, - x, - ], - span, - }, - ) - } else { - (idx, x) - } - }) - .peekable(); + let mut input_iter = input_iter.peekable(); - while let Some((idx, x)) = input_iter.next() { + while let Some(x) = input_iter.next() { // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. @@ -168,41 +136,9 @@ impl Command for Reduce { // Accumulator argument if let Some(var) = block.signature.get_positional(1) { if let Some(var_id) = &var.var_id { - acc = if numbered { - if let Value::Record { .. } = &acc { - acc - } else { - Value::Record { - cols: vec!["index".to_string(), "item".to_string()], - vals: vec![ - Value::Int { - val: idx as i64 + off, - span, - }, - acc, - ], - span, - } - } - } else { - acc - }; - stack.add_var(*var_id, acc); } } - // Optional third index argument - if let Some(var) = block.signature.get_positional(2) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } acc = eval_block( engine_state, diff --git a/crates/nu-command/src/filters/update.rs b/crates/nu-command/src/filters/update.rs index 9d2fb1536c..6c1db87c99 100644 --- a/crates/nu-command/src/filters/update.rs +++ b/crates/nu-command/src/filters/update.rs @@ -60,7 +60,7 @@ impl Command for Update { }, Example { description: "Use in closure form for more involved updating logic", - example: "[[count fruit]; [1 'apple']] | update count {|row index| ($row.fruit | str length) + $index }", + example: "[[count fruit]; [1 'apple']] | enumerate | update item.count {|e| ($e.item.fruit | str length) + $e.index } | get item", result: Some(Value::List { vals: vec![Value::Record { cols: vec!["count".into(), "fruit".into()], @@ -105,9 +105,6 @@ fn update( let orig_env_vars = stack.env_vars.clone(); let orig_env_hidden = stack.env_hidden.clone(); - // enumerate() can't be used here because it converts records into tables - // when combined with into_pipeline_data(). Hence, the index is tracked manually like so. - let mut idx: i64 = 0; input.map( move |mut input| { // with_env() is used here to ensure that each iteration uses @@ -120,13 +117,6 @@ fn update( stack.add_var(*var_id, input.clone()) } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, Value::Int { val: idx, span }); - } - idx += 1; - } let output = eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/upsert.rs b/crates/nu-command/src/filters/upsert.rs index 1a044fe98c..fea8d2b28d 100644 --- a/crates/nu-command/src/filters/upsert.rs +++ b/crates/nu-command/src/filters/upsert.rs @@ -56,14 +56,25 @@ impl Command for Upsert { description: "Update a record's value", example: "{'name': 'nu', 'stars': 5} | upsert name 'Nushell'", result: Some(Value::Record { cols: vec!["name".into(), "stars".into()], vals: vec![Value::test_string("Nushell"), Value::test_int(5)], span: Span::test_data()}), - }, Example { + }, + Example { + description: "Update each row of a table", + example: "[[name lang]; [Nushell ''] [Reedline '']] | upsert lang 'Rust'", + result: Some(Value::List { vals: vec![ + Value::Record { cols: vec!["name".into(), "lang".into()], vals: vec![Value::test_string("Nushell"), Value::test_string("Rust")], span: Span::test_data()}, + Value::Record { cols: vec!["name".into(), "lang".into()], vals: vec![Value::test_string("Reedline"), Value::test_string("Rust")], span: Span::test_data()} + ], span: Span::test_data()}), + }, + Example { description: "Insert a new entry into a single record", example: "{'name': 'nu', 'stars': 5} | upsert language 'Rust'", result: Some(Value::Record { cols: vec!["name".into(), "stars".into(), "language".into()], vals: vec![Value::test_string("nu"), Value::test_int(5), Value::test_string("Rust")], span: Span::test_data()}), }, Example { description: "Use in closure form for more involved updating logic", - example: "[[count fruit]; [1 'apple']] | upsert count {|row index| ($row.fruit | str length) + $index }", - result: Some(Value::List { vals: vec![Value::Record { cols: vec!["count".into(), "fruit".into()], vals: vec![Value::test_int(5), Value::test_string("apple")], span: Span::test_data()}], span: Span::test_data()}), + example: "[[count fruit]; [1 'apple']] | enumerate | upsert item.count {|e| ($e.item.fruit | str length) + $e.index } | get item", + result: Some(Value::List { vals: vec![ + Value::Record { cols: vec!["count".into(), "fruit".into()], vals: vec![Value::test_int(5), Value::test_string("apple")], span: Span::test_data()}], + span: Span::test_data()}), }, Example { description: "Upsert an int into a list, updating an existing value based on the index", @@ -116,9 +127,6 @@ fn upsert( let orig_env_vars = stack.env_vars.clone(); let orig_env_hidden = stack.env_hidden.clone(); - // enumerate() can't be used here because it converts records into tables - // when combined with into_pipeline_data(). Hence, the index is tracked manually like so. - let mut idx: i64 = 0; input.map( move |mut input| { // with_env() is used here to ensure that each iteration uses @@ -131,13 +139,6 @@ fn upsert( stack.add_var(*var_id, input.clone()) } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, Value::Int { val: idx, span }); - } - idx += 1; - } let output = eval_block( &engine_state, diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index d705bbdf8f..74c0849dc2 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -70,8 +70,7 @@ not supported."# let redirect_stderr = call.redirect_stderr; Ok(input .into_iter_strict(span)? - .enumerate() - .filter_map(move |(idx, value)| { + .filter_map(move |value| { stack.with_env(&orig_env_vars, &orig_env_hidden); if let Some(var) = block.signature.get_positional(0) { @@ -79,18 +78,6 @@ not supported."# stack.add_var(*var_id, value.clone()); } } - // Optional index argument - if let Some(var) = block.signature.get_positional(1) { - if let Some(var_id) = &var.var_id { - stack.add_var( - *var_id, - Value::Int { - val: idx as i64, - span, - }, - ); - } - } let result = eval_block( &engine_state, &mut stack, @@ -159,6 +146,11 @@ not supported."# example: "ls | where modified >= (date now) - 2wk", result: None, }, + Example { + description: "Find files whose filenames don't begin with the correct sequential number", + example: "ls | where type == file | sort-by name -n | enumerate | where {|e| $e.item.name !~ $'^($e.index + 1)' } | each { get item }", + result: None, + }, ] } } diff --git a/crates/nu-command/tests/commands/all.rs b/crates/nu-command/tests/commands/all.rs index 24a3530cb7..451df526ad 100644 --- a/crates/nu-command/tests/commands/all.rs +++ b/crates/nu-command/tests/commands/all.rs @@ -109,10 +109,10 @@ fn early_exits_with_0_param_blocks() { } #[test] -fn uses_optional_index_argument() { +fn all_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[7 8 9] | all {|el ind| print $ind | true }"# + r#"[7 8 9] | enumerate | all {|el| print $el.index | true }"# )); assert_eq!(actual.out, "012true"); diff --git a/crates/nu-command/tests/commands/any.rs b/crates/nu-command/tests/commands/any.rs index 3a06d73c0e..170aecd19c 100644 --- a/crates/nu-command/tests/commands/any.rs +++ b/crates/nu-command/tests/commands/any.rs @@ -85,10 +85,10 @@ fn early_exits_with_0_param_blocks() { } #[test] -fn uses_optional_index_argument() { +fn any_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[7 8 9] | any {|el ind| print $ind | false }"# + r#"[7 8 9] | enumerate | any {|el| print $el.index | false }"# )); assert_eq!(actual.out, "012false"); diff --git a/crates/nu-command/tests/commands/each.rs b/crates/nu-command/tests/commands/each.rs index deb07c910b..50dd8c6b30 100644 --- a/crates/nu-command/tests/commands/each.rs +++ b/crates/nu-command/tests/commands/each.rs @@ -73,20 +73,20 @@ fn each_implicit_it_in_block() { } #[test] -fn uses_optional_index_argument() { +fn each_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[7 8 9 10] | each {|el ind| $ind } | to nuon"# + r#"[7 8 9 10] | enumerate | each {|el| $el.index } | to nuon"# )); assert_eq!(actual.out, "[0, 1, 2, 3]"); } #[test] -fn each_while_uses_optional_index_argument() { +fn each_while_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[7 8 9 10] | each while {|el ind| $ind } | to nuon"# + r#"[7 8 9 10] | enumerate | each while {|el| $el.index } | to nuon"# )); assert_eq!(actual.out, "[0, 1, 2, 3]"); diff --git a/crates/nu-command/tests/commands/insert.rs b/crates/nu-command/tests/commands/insert.rs index c8c36fc049..3aed2f92c9 100644 --- a/crates/nu-command/tests/commands/insert.rs +++ b/crates/nu-command/tests/commands/insert.rs @@ -87,11 +87,11 @@ fn insert_past_end_list() { } #[test] -fn uses_optional_index_argument() { +fn insert_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[[a]; [7] [6]] | insert b {|el ind| $ind + 1 + $el.a } | to nuon"# + r#"[[a]; [7] [6]] | enumerate | insert b {|el| $el.index + 1 + $el.item.a } | flatten | to nuon"# )); - assert_eq!(actual.out, "[[a, b]; [7, 8], [6, 8]]"); + assert_eq!(actual.out, "[[index, a, b]; [0, 7, 8], [1, 6, 8]]"); } diff --git a/crates/nu-command/tests/commands/reduce.rs b/crates/nu-command/tests/commands/reduce.rs index ccb1e0bdbb..b87d6af196 100644 --- a/crates/nu-command/tests/commands/reduce.rs +++ b/crates/nu-command/tests/commands/reduce.rs @@ -47,12 +47,12 @@ fn reduce_rows_example() { } #[test] -fn reduce_numbered_example() { +fn reduce_enumerate_example() { let actual = nu!( cwd: ".", pipeline( r#" - echo one longest three bar - | reduce -n { |it, acc| if ($it.item | str length) > ($acc.item | str length) {echo $it} else {echo $acc}} + echo one longest three bar | enumerate + | reduce { |it, acc| if ($it.item | str length) > ($acc.item | str length) {echo $it} else {echo $acc}} | get index "# ) @@ -62,12 +62,14 @@ fn reduce_numbered_example() { } #[test] -fn reduce_numbered_integer_addition_example() { +fn reduce_enumerate_integer_addition_example() { let actual = nu!( cwd: ".", pipeline( r#" echo [1 2 3 4] - | reduce -n { |it, acc| $acc.item + $it.item } + | enumerate + | reduce { |it, acc| { index: ($it.index) item: ($acc.item + $it.item)} } + | get item "# ) ); @@ -121,11 +123,14 @@ fn error_reduce_empty() { } #[test] -fn uses_optional_index_argument() { +fn enumerate_reduce_example() { let actual = nu!( cwd: ".", pipeline( - r#"[18 19 20] | reduce -f 0 {|elem accum index| $accum + $index } | to nuon"# - )); + r#" + [one longest three bar] | enumerate | reduce {|it, acc| if ($it.item | str length) > ($acc.item | str length) { $it } else { $acc }} | get index + "# + ) + ); - assert_eq!(actual.out, "3"); + assert_eq!(actual.out, "1"); } diff --git a/crates/nu-command/tests/commands/roll.rs b/crates/nu-command/tests/commands/roll.rs index e59b70b9d3..26f5b767b0 100644 --- a/crates/nu-command/tests/commands/roll.rs +++ b/crates/nu-command/tests/commands/roll.rs @@ -135,7 +135,8 @@ mod columns { transpose bit --ignore-titles | get bit | reverse - | each --numbered { |it| + | enumerate + | each { |it| $it.item * (2 ** $it.index) } | math sum diff --git a/crates/nu-command/tests/commands/update.rs b/crates/nu-command/tests/commands/update.rs index f30235bc92..86d43aa6a1 100644 --- a/crates/nu-command/tests/commands/update.rs +++ b/crates/nu-command/tests/commands/update.rs @@ -116,11 +116,11 @@ fn update_nonexistent_column() { } #[test] -fn uses_optional_index_argument() { +fn update_uses_enumerate_index() { let actual = nu!( cwd: ".", pipeline( - r#"[[a]; [7] [6]] | update a {|el ind| $ind + 1 + $el.a } | to nuon"# + r#"[[a]; [7] [6]] | enumerate | update item.a {|el| $el.index + 1 + $el.item.a } | flatten | to nuon"# )); - assert_eq!(actual.out, "[[a]; [8], [8]]"); + assert_eq!(actual.out, "[[index, a]; [0, 8], [1, 8]]"); } diff --git a/crates/nu-command/tests/commands/upsert.rs b/crates/nu-command/tests/commands/upsert.rs index e1d14e9348..73197e3d57 100644 --- a/crates/nu-command/tests/commands/upsert.rs +++ b/crates/nu-command/tests/commands/upsert.rs @@ -69,23 +69,23 @@ fn sets_the_column_from_a_subexpression() { } #[test] -fn uses_optional_index_argument_inserting() { +fn upsert_uses_enumerate_index_inserting() { let actual = nu!( cwd: ".", pipeline( - r#"[[a]; [7] [6]] | upsert b {|el ind| $ind + 1 + $el.a } | to nuon"# + r#"[[a]; [7] [6]] | enumerate | upsert b {|el| $el.index + 1 + $el.item.a } | flatten | to nuon"# )); - assert_eq!(actual.out, "[[a, b]; [7, 8], [6, 8]]"); + assert_eq!(actual.out, "[[index, a, b]; [0, 7, 8], [1, 6, 8]]"); } #[test] -fn uses_optional_index_argument_updating() { +fn upsert_uses_enumerate_index_updating() { let actual = nu!( cwd: ".", pipeline( - r#"[[a]; [7] [6]] | upsert a {|el ind| $ind + 1 + $el.a } | to nuon"# + r#"[[a]; [7] [6]] | enumerate | upsert a {|el| $el.index + 1 + $el.item.a } | flatten | to nuon"# )); - assert_eq!(actual.out, "[[a]; [8], [8]]"); + assert_eq!(actual.out, "[[index, a]; [0, 8], [1, 8]]"); } #[test] diff --git a/crates/nu-command/tests/commands/where_.rs b/crates/nu-command/tests/commands/where_.rs index 11915aec84..d9e0feca50 100644 --- a/crates/nu-command/tests/commands/where_.rs +++ b/crates/nu-command/tests/commands/where_.rs @@ -82,13 +82,13 @@ fn where_not_in_table() { } #[test] -fn uses_optional_index_argument() { +fn where_uses_enumerate_index() { let actual = nu!( cwd: ".", - r#"[7 8 9 10] | where {|el ind| $ind < 2 } | to nuon"# + r#"[7 8 9 10] | enumerate | where {|el| $el.index < 2 } | to nuon"# ); - assert_eq!(actual.out, "[7, 8]"); + assert_eq!(actual.out, "[[index, item]; [0, 7], [1, 8]]"); } #[cfg(feature = "sqlite")] diff --git a/src/tests/test_iteration.rs b/src/tests/test_iteration.rs index 645105857d..da3eef9ce2 100644 --- a/src/tests/test_iteration.rs +++ b/src/tests/test_iteration.rs @@ -3,7 +3,7 @@ use crate::tests::{run_test, TestResult}; #[test] fn better_block_types() -> TestResult { run_test( - r#"([1, 2, 3] | each -n { |it| $"($it.index) is ($it.item)" }).1"#, + r#"([1, 2, 3] | enumerate | each { |e| $"($e.index) is ($e.item)" }).1"#, "1 is 2", ) } @@ -35,7 +35,7 @@ fn row_condition2() -> TestResult { #[test] fn par_each() -> TestResult { run_test( - r#"1..10 | par-each --numbered { |it| ([[index, item]; [$it.index, ($it.item > 5)]]).0 } | where index == 4 | get item.0"#, + r#"1..10 | enumerate | par-each { |it| ([[index, item]; [$it.index, ($it.item > 5)]]).0 } | where index == 4 | get item.0"#, "false", ) } diff --git a/src/tests/test_parser.rs b/src/tests/test_parser.rs index 21e2ff0182..8edf3a5fa1 100644 --- a/src/tests/test_parser.rs +++ b/src/tests/test_parser.rs @@ -147,8 +147,8 @@ fn bad_var_name2() -> TestResult { #[test] fn long_flag() -> TestResult { run_test( - r#"([a, b, c] | each --numbered { |it| if $it.index == 1 { 100 } else { 0 } }).1"#, - "100", + r#"([a, b, c] | enumerate | each --keep-empty { |e| if $e.index != 1 { 100 }}).1 | to nuon"#, + "null", ) }