Experiment: Allow both $true/true and $false/false (#4696)

* Change true/false to keywords

* oops, clippy

* Both kinds of bools

* Add in some boolean variables

* disable py virtualenv test for now
This commit is contained in:
JT 2022-03-02 19:55:03 -05:00 committed by GitHub
parent fd88920a9d
commit 96a1bf5f8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 173 additions and 100 deletions

View File

@ -73,8 +73,8 @@ jobs:
platform: [ubuntu-latest, macos-latest, windows-latest] platform: [ubuntu-latest, macos-latest, windows-latest]
rust: rust:
- stable - stable
py: # py:
- py # - py
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
@ -95,20 +95,20 @@ jobs:
command: install command: install
args: --path=. --no-default-features args: --path=. --no-default-features
- name: Setup Python # - name: Setup Python
uses: actions/setup-python@v2 # uses: actions/setup-python@v2
with: # with:
python-version: "3.10" # python-version: "3.10"
- run: python -m pip install tox # - run: python -m pip install tox
- name: Install virtualenv # - name: Install virtualenv
run: | # run: |
git clone https://github.com/kubouch/virtualenv.git && \ # git clone https://github.com/kubouch/virtualenv.git && \
cd virtualenv && \ # cd virtualenv && \
git checkout engine-q-update # git checkout engine-q-update
shell: bash # shell: bash
- name: Test Nushell in virtualenv # - name: Test Nushell in virtualenv
run: cd virtualenv && tox -e ${{ matrix.py }} -- -k nushell # run: cd virtualenv && tox -e ${{ matrix.py }} -- -k nushell
shell: bash # shell: bash

View File

@ -70,9 +70,7 @@ impl NuCompleter {
) -> Vec<(reedline::Span, String)> { ) -> Vec<(reedline::Span, String)> {
let mut output = vec![]; let mut output = vec![];
let builtins = [ let builtins = ["$nu", "$scope", "$in", "$config", "$env", "$nothing"];
"$nu", "$scope", "$in", "$config", "$env", "$true", "$false", "$nothing",
];
for builtin in builtins { for builtin in builtins {
if builtin.as_bytes().starts_with(prefix) { if builtin.as_bytes().starts_with(prefix) {

View File

@ -61,7 +61,7 @@ impl Command for SubCommand {
}, },
Example { Example {
description: "convert a boolean to a nushell binary primitive", description: "convert a boolean to a nushell binary primitive",
example: "$true | into binary", example: "true | into binary",
result: Some(Value::Binary { result: Some(Value::Binary {
val: i64::from(1).to_le_bytes().to_vec(), val: i64::from(1).to_le_bytes().to_vec(),
span: Span::test_data(), span: Span::test_data(),

View File

@ -42,7 +42,7 @@ impl Command for SubCommand {
vec![ vec![
Example { Example {
description: "Convert value to boolean in table", description: "Convert value to boolean in table",
example: "echo [[value]; ['false'] ['1'] [0] [1.0] [$true]] | into bool value", example: "echo [[value]; ['false'] ['1'] [0] [1.0] [true]] | into bool value",
result: Some(Value::List { result: Some(Value::List {
vals: vec![ vals: vec![
Value::Record { Value::Record {
@ -76,7 +76,7 @@ impl Command for SubCommand {
}, },
Example { Example {
description: "Convert bool to boolean", description: "Convert bool to boolean",
example: "$true | into bool", example: "true | into bool",
result: Some(Value::boolean(true, span)), result: Some(Value::boolean(true, span)),
}, },
Example { Example {

View File

@ -75,7 +75,7 @@ impl Command for SubCommand {
}, },
Example { Example {
description: "Convert bool to integer", description: "Convert bool to integer",
example: "[$false, $true] | into int", example: "[false, true] | into int",
result: Some(Value::List { result: Some(Value::List {
vals: vec![Value::test_int(0), Value::test_int(1)], vals: vec![Value::test_int(0), Value::test_int(1)],
span: Span::test_data(), span: Span::test_data(),

View File

@ -103,7 +103,7 @@ impl Command for SubCommand {
}, },
Example { Example {
description: "convert boolean to string", description: "convert boolean to string",
example: "$true | into string", example: "true | into string",
result: Some(Value::String { result: Some(Value::String {
val: "true".to_string(), val: "true".to_string(),
span: Span::test_data(), span: Span::test_data(),

View File

@ -60,8 +60,7 @@ impl Command for Debug {
}, },
Example { Example {
description: "Print the value of a table", description: "Print the value of a table",
example: example: "echo [[version patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | debug",
"echo [[version patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | debug",
result: Some(Value::List { result: Some(Value::List {
vals: vec![ vals: vec![
Value::test_string("{version: 0.1.0, patch: false}"), Value::test_string("{version: 0.1.0, patch: false}"),

View File

@ -70,7 +70,7 @@ impl Command for Let {
}, },
Example { Example {
description: "Set a variable based on the condition", description: "Set a variable based on the condition",
example: "let x = if $false { -1 } else { 1 }", example: "let x = if false { -1 } else { 1 }",
result: None, result: None,
}, },
] ]

View File

@ -351,7 +351,7 @@ ls | each {|x| $x.name}
``` ```
The above will create a list of the filenames in the directory. The above will create a list of the filenames in the directory.
``` ```
if $true { echo "it's true" } { echo "it's not true" } if true { echo "it's true" } { echo "it's not true" }
``` ```
This `if` call will run the first block if the expression is true, or the This `if` call will run the first block if the expression is true, or the
second block if the expression is false. second block if the expression is false.

View File

@ -28,7 +28,7 @@ impl Command for FilterWith {
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![Example {
description: "Filter dataframe using a bool mask", description: "Filter dataframe using a bool mask",
example: r#"let mask = ([$true $false] | dfr to-df); example: r#"let mask = ([true false] | dfr to-df);
[[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask"#, [[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask"#,
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![ NuDataFrame::try_from_columns(vec![

View File

@ -86,7 +86,7 @@ impl Command for ToDataFrame {
}, },
Example { Example {
description: "Takes a list of booleans and creates a dataframe", description: "Takes a list of booleans and creates a dataframe",
example: "[$true $true $false] | dfr to-df", example: "[true true false] | dfr to-df",
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![Column::new( NuDataFrame::try_from_columns(vec![Column::new(
"0".to_string(), "0".to_string(),

View File

@ -26,7 +26,7 @@ impl Command for AllFalse {
vec![ vec![
Example { Example {
description: "Returns true if all values are false", description: "Returns true if all values are false",
example: "[$false $false $false] | dfr to-df | dfr all-false", example: "[false false false] | dfr to-df | dfr all-false",
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![Column::new( NuDataFrame::try_from_columns(vec![Column::new(
"all_false".to_string(), "all_false".to_string(),

View File

@ -26,7 +26,7 @@ impl Command for AllTrue {
vec![ vec![
Example { Example {
description: "Returns true if all values are true", description: "Returns true if all values are true",
example: "[$true $true $true] | dfr to-df | dfr all-true", example: "[true true true] | dfr to-df | dfr all-true",
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![Column::new( NuDataFrame::try_from_columns(vec![Column::new(
"all_true".to_string(), "all_true".to_string(),

View File

@ -26,7 +26,7 @@ impl Command for ArgTrue {
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![Example {
description: "Returns indexes where values are true", description: "Returns indexes where values are true",
example: "[$false $true $false] | dfr to-df | dfr arg-true", example: "[false true false] | dfr to-df | dfr arg-true",
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![Column::new( NuDataFrame::try_from_columns(vec![Column::new(
"arg_true".to_string(), "arg_true".to_string(),

View File

@ -28,7 +28,7 @@ impl Command for NotSeries {
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![Example {
description: "Inverts boolean mask", description: "Inverts boolean mask",
example: "[$true $false $true] | dfr to-df | dfr not", example: "[true false true] | dfr to-df | dfr not",
result: Some( result: Some(
NuDataFrame::try_from_columns(vec![Column::new( NuDataFrame::try_from_columns(vec![Column::new(
"0".to_string(), "0".to_string(),

View File

@ -91,7 +91,7 @@ impl Command for Find {
}, },
Example { Example {
description: "Find if a service is not running", description: "Find if a service is not running",
example: "[[version patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | find -p { |it| $it.patch }", example: "[[version patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | find -p { |it| $it.patch }",
result: Some(Value::List { result: Some(Value::List {
vals: vec![Value::test_record( vals: vec![Value::test_record(
vec!["version", "patch"], vec!["version", "patch"],

View File

@ -38,7 +38,7 @@ impl Command for Shuffle {
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![Example {
description: "Shuffle rows randomly (execute it several times and see the difference)", description: "Shuffle rows randomly (execute it several times and see the difference)",
example: r#"echo [[version patch]; [1.0.0 $false] [3.0.1 $true] [2.0.0 $false]] | shuffle"#, example: r#"echo [[version patch]; [1.0.0 false] [3.0.1 true] [2.0.0 false]] | shuffle"#,
result: None, result: None,
}] }]
} }

View File

@ -65,9 +65,9 @@ fn value_to_string(v: &Value, span: Span) -> Result<String, ShellError> {
)), )),
Value::Bool { val, .. } => { Value::Bool { val, .. } => {
if *val { if *val {
Ok("$true".to_string()) Ok("true".to_string())
} else { } else {
Ok("$false".to_string()) Ok("false".to_string())
} }
} }
Value::CellPath { .. } => Err(ShellError::UnsupportedInput( Value::CellPath { .. } => Err(ShellError::UnsupportedInput(

View File

@ -79,7 +79,7 @@ impl Command for Shells {
}, },
Example { Example {
description: "Show currently active shell", description: "Show currently active shell",
example: r#"shells | where active == $true"#, example: r#"shells | where active == true"#,
result: None, result: None,
}, },
] ]

View File

@ -169,7 +169,7 @@ prints out the list properly."#
}, },
Example { Example {
description: "Render a table with 'name' column in it to a grid", description: "Render a table with 'name' column in it to a grid",
example: "[[name patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | grid", example: "[[name patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | grid",
result: Some(Value::String { result: Some(Value::String {
val: "0.1.0 │ 0.1.1 │ 0.2.0".to_string(), val: "0.1.0 │ 0.1.1 │ 0.2.0".to_string(),
span: Span::test_data(), span: Span::test_data(),

View File

@ -45,7 +45,7 @@ fn from_boolean() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo $true | into string echo true | into string
"# "#
) )
); );

View File

@ -65,7 +65,7 @@ fn to_nuon_bool() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
$false false
| to nuon | to nuon
| from nuon | from nuon
"# "#

View File

@ -49,6 +49,10 @@ pub fn is_math_expression_like(bytes: &[u8]) -> bool {
return false; return false;
} }
if bytes == b"true" || bytes == b"false" {
return true;
}
let b = bytes[0]; let b = bytes[0];
b == b'0' b == b'0'
@ -3258,6 +3262,41 @@ pub fn parse_value(
return parse_variable_expr(working_set, span); return parse_variable_expr(working_set, span);
} }
if bytes == b"true" {
if matches!(shape, SyntaxShape::Boolean) || matches!(shape, SyntaxShape::Any) {
return (
Expression {
expr: Expr::Bool(true),
span,
ty: Type::Bool,
custom_completion: None,
},
None,
);
} else {
return (
Expression::garbage(span),
Some(ParseError::Expected("non-boolean value".into(), span)),
);
}
} else if bytes == b"false" {
if matches!(shape, SyntaxShape::Boolean) || matches!(shape, SyntaxShape::Any) {
return (
Expression {
expr: Expr::Bool(false),
span,
ty: Type::Bool,
custom_completion: None,
},
None,
);
} else {
return (
Expression::garbage(span),
Some(ParseError::Expected("non-boolean value".into(), span)),
);
}
}
match bytes[0] { match bytes[0] {
b'$' => return parse_dollar_expr(working_set, span), b'$' => return parse_dollar_expr(working_set, span),
b'(' => { b'(' => {
@ -3381,7 +3420,7 @@ pub fn parse_value(
} }
SyntaxShape::Boolean => { SyntaxShape::Boolean => {
// Redundant, though we catch bad boolean parses here // Redundant, though we catch bad boolean parses here
if bytes == b"$true" || bytes == b"$false" { if bytes == b"true" || bytes == b"false" {
( (
Expression { Expression {
expr: Expr::Bool(true), expr: Expr::Bool(true),
@ -3603,6 +3642,7 @@ pub fn parse_expression(
while pos < spans.len() { while pos < spans.len() {
// Check if there is any environment shorthand // Check if there is any environment shorthand
let name = working_set.get_span_contents(spans[pos]); let name = working_set.get_span_contents(spans[pos]);
let split = name.split(|x| *x == b'='); let split = name.split(|x| *x == b'=');
let split: Vec<_> = split.collect(); let split: Vec<_> = split.collect();
if split.len() == 2 && !split[0].is_empty() { if split.len() == 2 && !split[0].is_empty() {

View File

@ -459,15 +459,15 @@ let base16_theme = {
# now let's apply our regular config settings but also apply the "color_config:" theme that we specified above. # now let's apply our regular config settings but also apply the "color_config:" theme that we specified above.
let config = { let config = {
filesize_metric: $true filesize_metric: true
table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
use_ls_colors: $true use_ls_colors: true
color_config: $base16_theme # <-- this is the theme color_config: $base16_theme # <-- this is the theme
use_grid_icons: $true use_grid_icons: true
footer_mode: always #always, never, number_of_rows, auto footer_mode: always #always, never, number_of_rows, auto
animate_prompt: $false animate_prompt: false
float_precision: 2 float_precision: 2
without_color: $false without_color: false
filesize_format: "b" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto filesize_format: "b" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
edit_mode: emacs # vi edit_mode: emacs # vi
max_history_size: 10000 max_history_size: 10000

View File

@ -23,5 +23,5 @@ Print the value of a string
Print the value of a table Print the value of a table
```shell ```shell
> echo [[version patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | debug > echo [[version patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | debug
``` ```

View File

@ -14,7 +14,7 @@ Returns true if all values are false
Returns true if all values are false Returns true if all values are false
```shell ```shell
> [$false $false $false] | dfr to-df | dfr all-false > [false false false] | dfr to-df | dfr all-false
``` ```
Checks the result from a comparison Checks the result from a comparison

View File

@ -14,7 +14,7 @@ Returns true if all values are true
Returns true if all values are true Returns true if all values are true
```shell ```shell
> [$true $true $true] | dfr to-df | dfr all-true > [true true true] | dfr to-df | dfr all-true
``` ```
Checks the result from a comparison Checks the result from a comparison

View File

@ -14,5 +14,5 @@ Returns indexes where values are true
Returns indexes where values are true Returns indexes where values are true
```shell ```shell
> [$false $true $false] | dfr to-df | dfr arg-true > [false true false] | dfr to-df | dfr arg-true
``` ```

View File

@ -18,6 +18,6 @@ Filters dataframe using a mask as reference
Filter dataframe using a bool mask Filter dataframe using a bool mask
```shell ```shell
> let mask = ([$true $false] | dfr to-df); > let mask = ([true false] | dfr to-df);
[[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask [[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask
``` ```

View File

@ -14,5 +14,5 @@ Inverts boolean mask
Inverts boolean mask Inverts boolean mask
```shell ```shell
> [$true $false $true] | dfr to-df | dfr not > [true false true] | dfr to-df | dfr not
``` ```

View File

@ -29,5 +29,5 @@ Takes a list and creates a dataframe
Takes a list of booleans and creates a dataframe Takes a list of booleans and creates a dataframe
```shell ```shell
> [$true $true $false] | dfr to-df > [true true false] | dfr to-df
``` ```

View File

@ -49,7 +49,7 @@ Find odd values
Find if a service is not running Find if a service is not running
```shell ```shell
> [[version patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | find -p { |it| $it.patch } > [[version patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | find -p { |it| $it.patch }
``` ```
Find using regex Find using regex

View File

@ -40,5 +40,5 @@ Render a list of records to a grid
Render a table with 'name' column in it to a grid Render a table with 'name' column in it to a grid
```shell ```shell
> [[name patch]; [0.1.0 $false] [0.1.1 $true] [0.2.0 $false]] | grid > [[name patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | grid
``` ```

View File

@ -28,7 +28,7 @@ convert a number to a nushell binary primitive
convert a boolean to a nushell binary primitive convert a boolean to a nushell binary primitive
```shell ```shell
> $true | into binary > true | into binary
``` ```
convert a filesize to a nushell binary primitive convert a filesize to a nushell binary primitive

View File

@ -18,12 +18,12 @@ Convert value to boolean
Convert value to boolean in table Convert value to boolean in table
```shell ```shell
> echo [[value]; ['false'] ['1'] [0] [1.0] [$true]] | into bool value > echo [[value]; ['false'] ['1'] [0] [1.0] [true]] | into bool value
``` ```
Convert bool to boolean Convert bool to boolean
```shell ```shell
> $true | into bool > true | into bool
``` ```
convert integer to boolean convert integer to boolean

View File

@ -44,7 +44,7 @@ Convert file size to integer
Convert bool to integer Convert bool to integer
```shell ```shell
> [$false, $true] | into int > [false, true] | into int
``` ```
Convert to integer from binary Convert to integer from binary

View File

@ -49,7 +49,7 @@ convert string to string
convert boolean to string convert boolean to string
```shell ```shell
> $true | into string > true | into string
``` ```
convert date to string convert date to string

View File

@ -29,5 +29,5 @@ Set a variable to the result of an expression
Set a variable based on the condition Set a variable based on the condition
```shell ```shell
> let x = if $false { -1 } else { 1 } > let x = if false { -1 } else { 1 }
``` ```

View File

@ -19,5 +19,5 @@ Enter a new shell at parent path '..' and show all opened shells
Show currently active shell Show currently active shell
```shell ```shell
> shells | where active == $true > shells | where active == true
``` ```

View File

@ -14,5 +14,5 @@ Shuffle rows randomly.
Shuffle rows randomly (execute it several times and see the difference) Shuffle rows randomly (execute it several times and see the difference)
```shell ```shell
> echo [[version patch]; [1.0.0 $false] [3.0.1 $true] [2.0.0 $false]] | shuffle > echo [[version patch]; [1.0.0 false] [3.0.1 true] [2.0.0 false]] | shuffle
``` ```

View File

@ -1,6 +1,6 @@
let vers = (version).version let vers = (version).version
for command in ($scope.commands | where is_custom == $false && is_extern == $false) { for command in ($scope.commands | where is_custom == false && is_extern == false) {
let top = $"--- let top = $"---
title: ($command.command) title: ($command.command)
layout: command layout: command

View File

@ -139,9 +139,9 @@ function end_filter {
function Write-TraceMessage { function Write-TraceMessage {
Param Param
( (
[Parameter(Mandatory = $false, Position = 0)] [Parameter(Mandatory = false, Position = 0)]
[string] $label, [string] $label,
[Parameter(Mandatory = $false, Position = 1)] [Parameter(Mandatory = false, Position = 1)]
[string] $message [string] $message
) )
@ -196,9 +196,9 @@ function Get-PipedData {
param( param(
[Parameter( [Parameter(
Position = 0, Position = 0,
Mandatory = $true, Mandatory = true,
ValueFromPipeline = $true, ValueFromPipeline = true,
ValueFromPipelineByPropertyName = $true) ValueFromPipelineByPropertyName = true)
] ]
[Alias('piped')] [Alias('piped')]
[String]$piped_input [String]$piped_input

View File

@ -162,17 +162,17 @@ let default_theme = {
# The default config record. This is where much of your global configuration is setup. # The default config record. This is where much of your global configuration is setup.
let $config = { let $config = {
filesize_metric: $false filesize_metric: false
table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
use_ls_colors: $true use_ls_colors: true
rm_always_trash: $false rm_always_trash: false
color_config: $default_theme color_config: $default_theme
use_grid_icons: $true use_grid_icons: true
footer_mode: "25" # always, never, number_of_rows, auto footer_mode: "25" # always, never, number_of_rows, auto
quick_completions: $true # set this to $false to prevent auto-selecting completions when only one remains quick_completions: true # set this to false to prevent auto-selecting completions when only one remains
animate_prompt: $false # redraw the prompt every second animate_prompt: false # redraw the prompt every second
float_precision: 2 float_precision: 2
use_ansi_coloring: $true use_ansi_coloring: true
filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
edit_mode: emacs # emacs, vi edit_mode: emacs # emacs, vi
max_history_size: 10000 max_history_size: 10000

View File

@ -2,22 +2,22 @@ use crate::tests::{run_test, TestResult};
#[test] #[test]
fn if_test1() -> TestResult { fn if_test1() -> TestResult {
run_test("if $true { 10 } else { 20 } ", "10") run_test("if true { 10 } else { 20 } ", "10")
} }
#[test] #[test]
fn if_test2() -> TestResult { fn if_test2() -> TestResult {
run_test("if $false { 10 } else { 20 } ", "20") run_test("if false { 10 } else { 20 } ", "20")
} }
#[test] #[test]
fn simple_if() -> TestResult { fn simple_if() -> TestResult {
run_test("if $true { 10 } ", "10") run_test("if true { 10 } ", "10")
} }
#[test] #[test]
fn simple_if2() -> TestResult { fn simple_if2() -> TestResult {
run_test("if $false { 10 } ", "") run_test("if false { 10 } ", "")
} }
#[test] #[test]

View File

@ -3,7 +3,7 @@ use crate::tests::{fail_test, run_test, TestResult};
#[test] #[test]
fn no_scope_leak1() -> TestResult { fn no_scope_leak1() -> TestResult {
fail_test( fail_test(
"if $false { let $x = 10 } else { let $x = 20 }; $x", "if false { let $x = 10 } else { let $x = 20 }; $x",
"Variable not found", "Variable not found",
) )
} }

View File

@ -17,7 +17,7 @@ fn proper_shadow() -> TestResult {
fn config_filesize_format_with_metric_true() -> TestResult { fn config_filesize_format_with_metric_true() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block // Note: this tests both the config variable and that it is properly captured into a block
run_test( run_test(
r#"let config = {"filesize_metric": $true "filesize_format": "kib" }; do { 40kb | into string } "#, r#"let config = {"filesize_metric": true "filesize_format": "kib" }; do { 40kb | into string } "#,
"39.1 KiB", "39.1 KiB",
) )
} }
@ -26,7 +26,7 @@ fn config_filesize_format_with_metric_true() -> TestResult {
fn config_filesize_format_with_metric_false_kib() -> TestResult { fn config_filesize_format_with_metric_false_kib() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block // Note: this tests both the config variable and that it is properly captured into a block
run_test( run_test(
r#"let config = {"filesize_metric": $false "filesize_format": "kib" }; do { 40kb | into string } "#, r#"let config = {"filesize_metric": false "filesize_format": "kib" }; do { 40kb | into string } "#,
"39.1 KiB", "39.1 KiB",
) )
} }
@ -35,7 +35,7 @@ fn config_filesize_format_with_metric_false_kib() -> TestResult {
fn config_filesize_format_with_metric_false_kb() -> TestResult { fn config_filesize_format_with_metric_false_kb() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block // Note: this tests both the config variable and that it is properly captured into a block
run_test( run_test(
r#"let config = {"filesize_metric": $false "filesize_format": "kb" }; do { 40kb | into string } "#, r#"let config = {"filesize_metric": false "filesize_format": "kb" }; do { 40kb | into string } "#,
"40.0 KB", "40.0 KB",
) )
} }
@ -265,15 +265,25 @@ fn datetime_literal() -> TestResult {
#[test] #[test]
fn shortcircuiting_and() -> TestResult { fn shortcircuiting_and() -> TestResult {
run_test(r#"$false && (5 / 0; $false)"#, "false") run_test(r#"false && (5 / 0; false)"#, "false")
} }
#[test] #[test]
fn shortcircuiting_or() -> TestResult { fn shortcircuiting_or() -> TestResult {
run_test(r#"$true || (5 / 0; $false)"#, "true") run_test(r#"true || (5 / 0; false)"#, "true")
} }
#[test] #[test]
fn open_ended_range() -> TestResult { fn open_ended_range() -> TestResult {
run_test(r#"1.. | first 100000 | length"#, "100000") run_test(r#"1.. | first 100000 | length"#, "100000")
} }
#[test]
fn bool_variable() -> TestResult {
run_test(r#"$true"#, "true")
}
#[test]
fn bool_variable2() -> TestResult {
run_test(r#"$false"#, "false")
}

View File

@ -27,12 +27,12 @@ fn modulo2() -> TestResult {
#[test] #[test]
fn and() -> TestResult { fn and() -> TestResult {
run_test("$true && $false", "false") run_test("true && false", "false")
} }
#[test] #[test]
fn or() -> TestResult { fn or() -> TestResult {
run_test("$true || $false", "true") run_test("true || false", "true")
} }
#[test] #[test]

View File

@ -4,7 +4,7 @@ use super::run_test_contains;
#[test] #[test]
fn env_shorthand() -> TestResult { fn env_shorthand() -> TestResult {
run_test("FOO=BAR if $false { 3 } else { 4 }", "4") run_test("FOO=BAR if false { 3 } else { 4 }", "4")
} }
#[test] #[test]

View File

@ -284,6 +284,32 @@ pub(crate) fn eval_source(
true true
} }
fn seems_like_number(bytes: &[u8]) -> bool {
if bytes.is_empty() {
false
} else {
let b = bytes[0];
b == b'0'
|| b == b'1'
|| b == b'2'
|| b == b'3'
|| b == b'4'
|| b == b'5'
|| b == b'6'
|| b == b'7'
|| b == b'8'
|| b == b'9'
|| b == b'('
|| b == b'{'
|| b == b'['
|| b == b'$'
|| b == b'"'
|| b == b'\''
|| b == b'-'
}
}
/// Finds externals that have names that look like math expressions /// Finds externals that have names that look like math expressions
pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec<u8>> { pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec<u8>> {
let mut executables = vec![]; let mut executables = vec![];
@ -299,16 +325,16 @@ pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec
while let Some(Ok(item)) = contents.next() { while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) { if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() { if let Ok(name) = item.file_name().into_string() {
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec(); let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name); executables.push(name);
} }
} }
if let Some(name) = item.path().file_stem() { if let Some(name) = item.path().file_stem() {
let name = name.to_string_lossy(); let name = name.to_string_lossy();
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec(); let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name); executables.push(name);
} }
} }
@ -326,15 +352,15 @@ pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec
while let Some(Ok(item)) = contents.next() { while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) { if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() { if let Ok(name) = item.file_name().into_string() {
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec(); let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name); executables.push(name);
} }
} }
if let Some(name) = item.path().file_stem() { if let Some(name) = item.path().file_stem() {
let name = name.to_string_lossy(); let name = name.to_string_lossy();
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec(); let name = name.as_bytes().to_vec();
if nu_parser::is_math_expression_like(&name) {
executables.push(name); executables.push(name);
} }
} }

View File

@ -563,7 +563,7 @@ fn proper_shadow_let_aliases() {
let actual = nu!( let actual = nu!(
cwd: ".", cwd: ".",
r#" r#"
let DEBUG = $false; echo $DEBUG | table; do { let DEBUG = $true; echo $DEBUG } | table; echo $DEBUG let DEBUG = false; echo $DEBUG | table; do { let DEBUG = true; echo $DEBUG } | table; echo $DEBUG
"# "#
); );
assert_eq!(actual.out, "falsetruefalse"); assert_eq!(actual.out, "falsetruefalse");