mirror of
https://github.com/nushell/nushell
synced 2025-01-15 06:34:15 +00:00
067ceedf79
# Description The intended effect of the `extra` feature has been undermined by introducing the full builds on our release pages and having more activity on some of the extra commands. To simplify the feature matrix let's get rid of it and focus our effort on truly either refining a command to well-specified behavior or discarding it entirely from the `nu` binary and moving it into plugins. ## Details - Remove `--features extra` from CI - Don't explicitly name `extra` in full build wf - Remove feature extra from build-help scripts - Update README in `nu-cmd-extra` - Remove feature `extra` - Fix previously dead `format pattern` tests - Relax signature of `to html` - Fix/ignore `html::test_no_color_flag` - Remove dead features from `version` - Refine `to html` type signature # User-Facing Changes The commands that were previously only available when building with `--features extra` will now be available to everyone. This increases the number of dependencies slightly but has a limited impact on the overall binary size. # Tests + Formatting Some tests that were left in `nu-command` during cratification were dead because the feature was not passed to `nu-command` and only to `nu-cmd-lang` for feature-flag mention in `version`. Those tests have now been either fixed or ignored in one case. # After Submitting There may be places in the documentation where we point to `--features extra` that will now be moot (apart from the generated command help)
441 lines
10 KiB
Rust
441 lines
10 KiB
Rust
use crate::tests::{fail_test, run_test, TestResult};
|
|
use rstest::rstest;
|
|
|
|
#[test]
|
|
fn concrete_variable_assignment() -> TestResult {
|
|
run_test(
|
|
"let x = (1..100 | each { |y| $y + 100 }); let y = ($x | length); $x | length",
|
|
"100",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn proper_shadow() -> TestResult {
|
|
run_test("let x = 10; let x = $x + 9; $x", "19")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_1() -> TestResult {
|
|
run_test(r#"[3] | if $in.0 > 4 { "yay!" } else { "boo" }"#, "boo")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_2() -> TestResult {
|
|
run_test(r#"3 | if $in > 2 { "yay!" } else { "boo" }"#, "yay!")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_3() -> TestResult {
|
|
run_test(r#"3 | if $in > 4 { "yay!" } else { $in }"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_4() -> TestResult {
|
|
run_test(r#"3 | do { $in }"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_5() -> TestResult {
|
|
run_test(r#"3 | if $in > 2 { $in - 10 } else { $in * 10 }"#, "-7")
|
|
}
|
|
|
|
#[test]
|
|
fn in_variable_6() -> TestResult {
|
|
run_test(r#"3 | if $in > 6 { $in - 10 } else { $in * 10 }"#, "30")
|
|
}
|
|
|
|
#[test]
|
|
fn in_and_if_else() -> TestResult {
|
|
run_test(
|
|
r#"[1, 2, 3] | if false {} else if true { $in | length }"#,
|
|
"3",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn help_works_with_missing_requirements() -> TestResult {
|
|
let expected_length = "70";
|
|
run_test(r#"each --help | lines | length"#, expected_length)
|
|
}
|
|
|
|
#[test]
|
|
fn scope_variable() -> TestResult {
|
|
run_test(
|
|
r#"let x = 3; scope variables | where name == "$x" | get type.0"#,
|
|
"int",
|
|
)
|
|
}
|
|
#[rstest]
|
|
#[case("a", "<> nothing")]
|
|
#[case("b", "<1.23> float")]
|
|
#[case("flag1", "<> nothing")]
|
|
#[case("flag2", "<4.56> float")]
|
|
|
|
fn scope_command_defaults(#[case] var: &str, #[case] exp_result: &str) -> TestResult {
|
|
run_test(
|
|
&format!(
|
|
r#"def t1 [a:int b?:float=1.23 --flag1:string --flag2:float=4.56] {{ true }};
|
|
let rslt = (scope commands | where name == 't1' | get signatures.0.any | where parameter_name == '{var}' | get parameter_default.0);
|
|
$"<($rslt)> ($rslt | describe)""#
|
|
),
|
|
exp_result,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn earlier_errors() -> TestResult {
|
|
fail_test(
|
|
r#"[1, "bob"] | each { |it| $it + 3 } | each { |it| $it / $it } | table"#,
|
|
"int",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn missing_flags_are_nothing() -> TestResult {
|
|
run_test(
|
|
r#"def foo [--aaa(-a): int, --bbb(-b): int] { (if $aaa == null { 10 } else { $aaa }) + (if $bbb == null { 100 } else { $bbb }) }; foo"#,
|
|
"110",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn missing_flags_are_nothing2() -> TestResult {
|
|
run_test(
|
|
r#"def foo [--aaa(-a): int, --bbb(-b): int] { (if $aaa == null { 10 } else { $aaa }) + (if $bbb == null { 100 } else { $bbb }) }; foo -a 90"#,
|
|
"190",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn missing_flags_are_nothing3() -> TestResult {
|
|
run_test(
|
|
r#"def foo [--aaa(-a): int, --bbb(-b): int] { (if $aaa == null { 10 } else { $aaa }) + (if $bbb == null { 100 } else { $bbb }) }; foo -b 45"#,
|
|
"55",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn missing_flags_are_nothing4() -> TestResult {
|
|
run_test(
|
|
r#"def foo [--aaa(-a): int, --bbb(-b): int] { (if $aaa == null { 10 } else { $aaa }) + (if $bbb == null { 100 } else { $bbb }) }; foo -a 3 -b 10000"#,
|
|
"10003",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn proper_variable_captures() -> TestResult {
|
|
run_test(
|
|
r#"def foo [x] { let y = 100; { || $y + $x } }; do (foo 23)"#,
|
|
"123",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn proper_variable_captures_with_calls() -> TestResult {
|
|
run_test(
|
|
r#"def foo [] { let y = 60; def bar [] { $y }; {|| bar } }; do (foo)"#,
|
|
"60",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn proper_variable_captures_with_nesting() -> TestResult {
|
|
run_test(
|
|
r#"def foo [x] { let z = 100; def bar [y] { $y - $x + $z } ; { |z| bar $z } }; do (foo 11) 13"#,
|
|
"102",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn divide_duration() -> TestResult {
|
|
run_test(r#"4ms / 4ms"#, "1")
|
|
}
|
|
|
|
#[test]
|
|
fn divide_filesize() -> TestResult {
|
|
run_test(r#"4mb / 4mb"#, "1")
|
|
}
|
|
|
|
#[test]
|
|
fn date_comparison() -> TestResult {
|
|
run_test(r#"(date now) < ((date now) + 2min)"#, "true")
|
|
}
|
|
|
|
#[test]
|
|
fn let_sees_input() -> TestResult {
|
|
run_test(
|
|
r#"def c [] { let x = (str length); $x }; "hello world" | c"#,
|
|
"11",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn let_sees_in_variable() -> TestResult {
|
|
run_test(
|
|
r#"def c [] { let x = $in.name; $x | str length }; {name: bob, size: 100 } | c"#,
|
|
"3",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn let_sees_in_variable2() -> TestResult {
|
|
run_test(
|
|
r#"def c [] { let x = ($in | str length); $x }; 'bob' | c"#,
|
|
"3",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn def_env() -> TestResult {
|
|
run_test(
|
|
r#"def --env bob [] { $env.BAR = "BAZ" }; bob; $env.BAR"#,
|
|
"BAZ",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn not_def_env() -> TestResult {
|
|
fail_test(r#"def bob [] { $env.BAR = "BAZ" }; bob; $env.BAR"#, "")
|
|
}
|
|
|
|
#[test]
|
|
fn def_env_hiding_something() -> TestResult {
|
|
fail_test(
|
|
r#"$env.FOO = "foo"; def --env bob [] { hide-env FOO }; bob; $env.FOO"#,
|
|
"",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn def_env_then_hide() -> TestResult {
|
|
fail_test(
|
|
r#"def --env bob [] { $env.BOB = "bob" }; def --env un-bob [] { hide-env BOB }; bob; un-bob; $env.BOB"#,
|
|
"",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn export_def_env() -> TestResult {
|
|
run_test(
|
|
r#"module foo { export def --env bob [] { $env.BAR = "BAZ" } }; use foo bob; bob; $env.BAR"#,
|
|
"BAZ",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn dynamic_load_env() -> TestResult {
|
|
run_test(r#"let x = "FOO"; load-env {$x: "BAZ"}; $env.FOO"#, "BAZ")
|
|
}
|
|
|
|
#[test]
|
|
fn reduce_spans() -> TestResult {
|
|
fail_test(
|
|
r#"let x = ([1, 2, 3] | reduce --fold 0 { $it.item + 2 * $it.acc }); error make {msg: "oh that hurts", label: {text: "right here", start: (metadata $x).span.start, end: (metadata $x).span.end } }"#,
|
|
"right here",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn with_env_shorthand_nested_quotes() -> TestResult {
|
|
run_test(
|
|
r#"FOO='-arg "hello world"' echo $env | get FOO"#,
|
|
"-arg \"hello world\"",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn test_redirection_stderr() -> TestResult {
|
|
// try a nonsense binary
|
|
run_test(r#"do -i { asdjw4j5cnaabw44rd }; echo done"#, "done")
|
|
}
|
|
|
|
#[test]
|
|
fn datetime_literal() -> TestResult {
|
|
run_test(r#"(date now) - 2019-08-23 > 1hr"#, "true")
|
|
}
|
|
|
|
#[test]
|
|
fn shortcircuiting_and() -> TestResult {
|
|
run_test(r#"false and (5 / 0; false)"#, "false")
|
|
}
|
|
|
|
#[test]
|
|
fn shortcircuiting_or() -> TestResult {
|
|
run_test(r#"true or (5 / 0; false)"#, "true")
|
|
}
|
|
|
|
#[test]
|
|
fn nonshortcircuiting_xor() -> TestResult {
|
|
run_test(r#"true xor (print "hello"; false) | ignore"#, "hello")
|
|
}
|
|
|
|
#[test]
|
|
fn open_ended_range() -> TestResult {
|
|
run_test(r#"1.. | first 100000 | length"#, "100000")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value1() -> TestResult {
|
|
run_test(r#"def foo [x = 3] { $x }; foo"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value2() -> TestResult {
|
|
run_test(r#"def foo [x: int = 3] { $x }; foo"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value3() -> TestResult {
|
|
run_test(r#"def foo [--x = 3] { $x }; foo"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value4() -> TestResult {
|
|
run_test(r#"def foo [--x: int = 3] { $x }; foo"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value5() -> TestResult {
|
|
run_test(r#"def foo [x = 3] { $x }; foo 10"#, "10")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value6() -> TestResult {
|
|
run_test(r#"def foo [x: int = 3] { $x }; foo 10"#, "10")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value7() -> TestResult {
|
|
run_test(r#"def foo [--x = 3] { $x }; foo --x 10"#, "10")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value8() -> TestResult {
|
|
run_test(r#"def foo [--x: int = 3] { $x }; foo --x 10"#, "10")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value9() -> TestResult {
|
|
fail_test(r#"def foo [--x = 3] { $x }; foo --x a"#, "expected int")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value10() -> TestResult {
|
|
fail_test(r#"def foo [x = 3] { $x }; foo a"#, "expected int")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value11() -> TestResult {
|
|
fail_test(
|
|
r#"def foo [x = 3, y] { $x }; foo a"#,
|
|
"after optional parameter",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn default_value12() -> TestResult {
|
|
fail_test(
|
|
r#"def foo [--x:int = "a"] { $x }"#,
|
|
"expected default value to be `int`",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn default_value_constant1() -> TestResult {
|
|
run_test(r#"def foo [x = "foo"] { $x }; foo"#, "foo")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value_constant2() -> TestResult {
|
|
run_test(r#"def foo [secs = 1sec] { $secs }; foo"#, "1sec")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value_constant3() -> TestResult {
|
|
run_test(r#"def foo [x = ("foo" | str length)] { $x }; foo"#, "3")
|
|
}
|
|
|
|
#[test]
|
|
fn default_value_not_constant2() -> TestResult {
|
|
fail_test(
|
|
r#"def foo [x = (loop { break })] { $x }; foo"#,
|
|
"expected a constant",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn loose_each() -> TestResult {
|
|
run_test(
|
|
r#"[[1, 2, 3], [4, 5, 6]] | each {|| $in.1 } | math sum"#,
|
|
"7",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn in_means_input() -> TestResult {
|
|
run_test(r#"def shl [] { $in * 2 }; 2 | shl"#, "4")
|
|
}
|
|
|
|
#[test]
|
|
fn in_iteration() -> TestResult {
|
|
run_test(
|
|
r#"[3, 4, 5] | each {|| echo $"hi ($in)" } | str join"#,
|
|
"hi 3hi 4hi 5",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn reusable_in() -> TestResult {
|
|
run_test(
|
|
r#"[1, 2, 3, 4] | take (($in | length) - 1) | math sum"#,
|
|
"6",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn better_operator_spans() -> TestResult {
|
|
run_test(
|
|
r#"metadata ({foo: 10} | (20 - $in.foo)) | get span | $in.start < $in.end"#,
|
|
"true",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn range_right_exclusive() -> TestResult {
|
|
run_test(r#"[1, 4, 5, 8, 9] | range 1..<3 | math sum"#, "9")
|
|
}
|
|
|
|
/// Issue #7872
|
|
#[test]
|
|
fn assignment_to_in_var_no_panic() -> TestResult {
|
|
fail_test(r#"$in = 3"#, "needs to be a mutable variable")
|
|
}
|
|
|
|
#[test]
|
|
fn assignment_to_env_no_panic() -> TestResult {
|
|
fail_test(r#"$env = 3"#, "cannot_replace_env")
|
|
}
|
|
|
|
#[test]
|
|
fn short_flags() -> TestResult {
|
|
run_test(
|
|
r#"def foobar [-a: int, -b: string, -c: string] { echo $'($a) ($c) ($b)' }; foobar -b "balh balh" -a 1543 -c "FALSE123""#,
|
|
"1543 FALSE123 balh balh",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn short_flags_1() -> TestResult {
|
|
run_test(
|
|
r#"def foobar [-a: string, -b: string, -s: int] { if ( $s == 0 ) { echo $'($b)($a)' }}; foobar -a test -b case -s 0 "#,
|
|
"casetest",
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn short_flags_2() -> TestResult {
|
|
run_test(
|
|
r#"def foobar [-a: int, -b: string, -c: int] { $a + $c };foobar -b "balh balh" -a 10 -c 1 "#,
|
|
"11",
|
|
)
|
|
}
|