mirror of
https://github.com/nushell/nushell.git
synced 2025-05-05 23:42:56 +00:00
In my view we should revert nushell/nushell#8395 for now ## Potentially inconsistent application of semantic change #8395 (1d5e7b441b9564b7ee9fe822d908b20fbf4b8682) was loosening the type coercion rules significantly, to let missing data / void returns that were either expressed by `PipelineData::Empty` or the `Value::nothing` be accept by specifically those commands/operations that made use of `PipelineData::into_iter_strict()`. This could apply the new rules inconsistently. ## Turning explicit failures into silent continuations Furthermore the effect of this breaking change to the missing data semantics could make previous errors into silent failures. This could either just reduce the effectiveness of teaching error messages in interactive use: ### Contrived example before ```bash > cd . | where blah Error: nu:🐚:only_supports_this_input_type × Input type not supported. ╭─[entry #13:1:1] 1 │ cd . | where blah · ──┬──┬ · │ ╰── input type: null · ╰── only list, binary, raw data or range input data is supported ╰──── ``` ### ...after, with #8395 ```bash > cd . | where blah ╭────────────╮ │ empty list │ ╰────────────╯ ``` In rare cases people could already try to rely on catching an error of a downstream command to actually deal with the missing data, so it would be a breaking change for their existing code. ## Problem with `PipelineData::into_iter_strict()` Maybe this makes `_strict` a bit of a misnomer for this particular iterator construction. Further we did not actively test the `PipelineData::empty` branch before  ## Parsimonious solution exists For the motivating issue https://github.com/nushell/nushell/issues/8393 there already exists a fix that makes `ls` more consistent with the type system by returning an empty `Value::List` https://github.com/nushell/nushell/pull/8439
192 lines
4.2 KiB
Rust
192 lines
4.2 KiB
Rust
use nu_test_support::nu;
|
|
use nu_test_support::pipeline;
|
|
|
|
#[test]
|
|
fn filters_by_unit_size_comparison() {
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats",
|
|
"ls | where size > 1kib | sort-by size | get name | first | str trim"
|
|
);
|
|
|
|
assert_eq!(actual.out, "cargo_sample.toml");
|
|
}
|
|
|
|
#[test]
|
|
fn filters_with_nothing_comparison() {
|
|
let actual = nu!(
|
|
r#"'[{"foo": 3}, {"foo": null}, {"foo": 4}]' | from json | get foo | compact | where $it > 1 | math sum"#
|
|
);
|
|
|
|
assert_eq!(actual.out, "7");
|
|
}
|
|
|
|
#[test]
|
|
fn where_inside_block_works() {
|
|
let actual = nu!(
|
|
cwd: ".",
|
|
"{|x| ls | where $it =~ 'foo' } | describe"
|
|
);
|
|
|
|
assert_eq!(actual.out, "closure");
|
|
}
|
|
|
|
#[test]
|
|
fn filters_with_0_arity_block() {
|
|
let actual = nu!("[1 2 3 4] | where {|| $in < 3 } | to nuon");
|
|
|
|
assert_eq!(actual.out, "[1, 2]");
|
|
}
|
|
|
|
#[test]
|
|
fn filters_with_1_arity_block() {
|
|
let actual = nu!("[1 2 3 6 7 8] | where {|e| $e < 5 } | to nuon");
|
|
|
|
assert_eq!(actual.out, "[1, 2, 3]");
|
|
}
|
|
|
|
#[test]
|
|
fn unique_env_each_iteration() {
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats",
|
|
"[1 2] | where {|| print ($env.PWD | str ends-with 'formats') | cd '/' | true } | to nuon"
|
|
);
|
|
|
|
assert_eq!(actual.out, "truetrue[1, 2]");
|
|
}
|
|
|
|
#[test]
|
|
fn where_in_table() {
|
|
let actual = nu!(
|
|
r#"'[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from json | where name in ["foo"] | get size | math sum"#
|
|
);
|
|
|
|
assert_eq!(actual.out, "5");
|
|
}
|
|
|
|
#[test]
|
|
fn where_not_in_table() {
|
|
let actual = nu!(
|
|
r#"'[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from json | where name not-in ["foo"] | get size | math sum"#
|
|
);
|
|
|
|
assert_eq!(actual.out, "4");
|
|
}
|
|
|
|
#[test]
|
|
fn where_uses_enumerate_index() {
|
|
let actual = nu!("[7 8 9 10] | enumerate | where {|el| $el.index < 2 } | to nuon");
|
|
|
|
assert_eq!(actual.out, "[[index, item]; [0, 7], [1, 8]]");
|
|
}
|
|
|
|
#[cfg(feature = "sqlite")]
|
|
#[test]
|
|
fn binary_operator_comparisons() {
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get ints
|
|
| first 4
|
|
| where z > 4200
|
|
| get z.0
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "4253");
|
|
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get ints
|
|
| first 4
|
|
| where z >= 4253
|
|
| get z.0
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "4253");
|
|
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get ints
|
|
| first 4
|
|
| where z < 10
|
|
| get z.0
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "1");
|
|
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get ints
|
|
| first 4
|
|
| where z <= 1
|
|
| get z.0
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "1");
|
|
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get ints
|
|
| where z != 1
|
|
| first
|
|
| get z
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "42");
|
|
}
|
|
|
|
#[cfg(feature = "sqlite")]
|
|
#[test]
|
|
fn contains_operator() {
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get strings
|
|
| where x =~ ell
|
|
| length
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "4");
|
|
|
|
let actual = nu!(
|
|
cwd: "tests/fixtures/formats", pipeline(
|
|
r#"
|
|
open sample.db
|
|
| get strings
|
|
| where x !~ ell
|
|
| length
|
|
"#
|
|
));
|
|
|
|
assert_eq!(actual.out, "2");
|
|
}
|
|
|
|
#[test]
|
|
fn fail_on_non_iterator() {
|
|
let actual = nu!(cwd: ".", pipeline(r#"{"name": "foo", "size": 3} | where name == "foo""#));
|
|
|
|
assert!(actual.err.contains("only_supports_this_input_type"));
|
|
}
|
|
|
|
// Test that filtering on columns that might be missing/null works
|
|
#[test]
|
|
fn where_gt_null() {
|
|
let actual = nu!("[{foo: 123} {}] | where foo? > 10 | to nuon");
|
|
assert_eq!(actual.out, "[[foo]; [123]]");
|
|
}
|