nushell/crates/nu-command/tests/commands/parse.rs

230 lines
6.5 KiB
Rust
Raw Normal View History

2020-05-22 16:13:58 +02:00
use nu_test_support::fs::Stub;
use nu_test_support::playground::Playground;
2019-12-17 19:54:39 +01:00
use nu_test_support::{nu, pipeline};
mod simple {
use super::*;
#[test]
fn extracts_fields_from_the_given_the_pattern() {
Playground::setup("parse_test_1", |dirs, sandbox| {
sandbox.with_files(vec![Stub::FileWithContentToBeTrimmed(
"key_value_separated_arepa_ingredients.txt",
r#"
VAR1=Cheese
VAR2=JTParsed
VAR3=NushellSecretIngredient
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open key_value_separated_arepa_ingredients.txt
| lines
| each { |it| echo $it | parse "{Name}={Value}" }
| flatten
| get 1
| get Value
"#
));
assert_eq!(actual.out, "JTParsed");
})
}
#[test]
fn double_open_curly_evaluates_to_a_single_curly() {
Playground::setup("parse_test_regex_2", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "{abc}123"
| parse "{{abc}{name}"
| get name.0
"#
));
assert_eq!(actual.out, "123");
})
}
#[test]
fn properly_escapes_text() {
Playground::setup("parse_test_regex_3", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "(abc)123"
| parse "(abc){name}"
| get name.0
"#
));
assert_eq!(actual.out, "123");
})
}
#[test]
fn properly_captures_empty_column() {
Playground::setup("parse_test_regex_4", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo ["1:INFO:component:all is well" "2:ERROR::something bad happened"]
| parse "{timestamp}:{level}:{tag}:{entry}"
| get entry
| get 1
"#
));
assert_eq!(actual.out, "something bad happened");
})
}
#[test]
fn errors_when_missing_closing_brace() {
Playground::setup("parse_test_regex_5", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "(abc)123"
| parse "(abc){name"
| get name
"#
));
assert!(actual
.err
.contains("Found opening `{` without an associated closing `}`"));
})
}
}
2020-05-22 16:13:58 +02:00
mod regex {
use super::*;
fn nushell_git_log_oneline<'a>() -> Vec<Stub<'a>> {
vec![Stub::FileWithContentToBeTrimmed(
"nushell_git_log_oneline.txt",
r#"
ae87582c Fix missing invocation errors (#1846)
b89976da let format access variables also (#1842)
"#,
)]
}
#[test]
fn extracts_fields_with_all_named_groups() {
Playground::setup("parse_test_regex_1", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\\w+) (?P<Message>.+) \\(#(?P<PR>\\d+)\\)"
| get 1
| get PR
"#
2020-05-22 16:13:58 +02:00
));
assert_eq!(actual.out, "1842");
})
}
#[test]
fn extracts_fields_with_all_unnamed_groups() {
Playground::setup("parse_test_regex_2", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(\\w+) (.+) \\(#(\\d+)\\)"
| get 1
| get capture0
"#
2020-05-22 16:13:58 +02:00
));
assert_eq!(actual.out, "b89976da");
})
}
#[test]
fn extracts_fields_with_named_and_unnamed_groups() {
Playground::setup("parse_test_regex_3", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\\w+) (.+) \\(#(?P<PR>\\d+)\\)"
| get 1
| get capture1
"#
2020-05-22 16:13:58 +02:00
));
assert_eq!(actual.out, "let format access variables also");
})
}
#[test]
fn errors_with_invalid_regex() {
Playground::setup("parse_test_regex_1", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\\w+ unfinished capture group"
"#
));
assert!(actual
.err
.contains("Opening parenthesis without closing parenthesis"));
})
}
allow `parse` to work better with streams (#7870) # Description Fixes #7864. Haven't removed redundant code yet; and there's also a weird visual bug, but I'm not sure if that's the fault of this PR or just a quirk of how tabling works: ``` /home/gabriel/CodingProjects/nushell〉ping 1.1.1.1 | parse -r '(?P<num>\d+) ttl' 01/27/2023 11:28:31 AM ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 0 │ 1 │ │ 1 │ 2 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 2 │ 3 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 3 │ 4 │ │ 4 │ 5 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 5 │ 6 │ │ 6 │ 7 │ ╰───┴─────╯ ^C /home/gabriel/CodingProjects/nushell〉 01/27/2023 11:28:59 AM ``` # User-Facing Changes _(List of all changes that impact the user experience here. This helps us keep track of breaking changes.)_ # 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.
2023-02-09 03:59:02 +01:00
#[test]
fn parse_works_with_streaming() {
let actual =
nu!(r#"seq char a z | each {|c| $c + " a"} | parse '{letter} {a}' | describe"#);
allow `parse` to work better with streams (#7870) # Description Fixes #7864. Haven't removed redundant code yet; and there's also a weird visual bug, but I'm not sure if that's the fault of this PR or just a quirk of how tabling works: ``` /home/gabriel/CodingProjects/nushell〉ping 1.1.1.1 | parse -r '(?P<num>\d+) ttl' 01/27/2023 11:28:31 AM ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 0 │ 1 │ │ 1 │ 2 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 2 │ 3 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 3 │ 4 │ │ 4 │ 5 │ ╰───┴─────╯ ╭───┬─────╮ │ # │ num │ ├───┼─────┤ │ 5 │ 6 │ │ 6 │ 7 │ ╰───┴─────╯ ^C /home/gabriel/CodingProjects/nushell〉 01/27/2023 11:28:59 AM ``` # User-Facing Changes _(List of all changes that impact the user experience here. This helps us keep track of breaking changes.)_ # 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.
2023-02-09 03:59:02 +01:00
assert_eq!(actual.out, "table<letter: string, a: string> (stream)")
}
do not emit None mid-stream during parse (#9925) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #issue you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Currently `parse` acts like a `.filter` over an iterator, except that it emits `None` for elements that can't be parsed. This causes consumers of the adapted iterator to stop iterating too early. The correct behaviour is to keep pulling the inner iterator until either the end of it is reached or an element can be parsed. - this PR should close #9906 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> List streams won't be truncated anymore after the first parse failure. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - [x] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - [-] `cargo test --workspace` to check that all tests pass - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> - [x] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - [x] `cargo test --workspace` to check that all tests pass - 11 tests fail, but the same 11 tests fail on main as well - [x] `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library # 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. -->
2023-08-06 13:17:03 +02:00
#[test]
fn parse_does_not_truncate_list_streams() {
let actual = nu!(pipeline(
r#"
[a b c]
| each {|x| $x}
| parse --regex "[ac]"
| length
"#
));
assert_eq!(actual.out, "2");
}
parse: collect external stream chunks before matching (#9950) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx --> # Description This PR implements the workaround discussed in #9795, i.e. having `parse` collect an external stream before operating on it with a regex. - Should close #9795 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> - `parse` will give the correct output for external streams - increased memory and time overhead due to collecting the entire stream (no short-circuiting) # 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 -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> - formatting is checked - clippy is happy - no tests that weren't already broken fail - added test case # 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. -->
2023-08-08 13:48:13 +02:00
#[test]
fn parse_handles_external_stream_chunking() {
Playground::setup("parse_test_streaming_1", |dirs, sandbox| {
let data: String = "abcdefghijklmnopqrstuvwxyz".repeat(1000);
sandbox.with_files(vec![Stub::FileWithContent("data.txt", &data)]);
parse: collect external stream chunks before matching (#9950) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx --> # Description This PR implements the workaround discussed in #9795, i.e. having `parse` collect an external stream before operating on it with a regex. - Should close #9795 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> - `parse` will give the correct output for external streams - increased memory and time overhead due to collecting the entire stream (no short-circuiting) # 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 -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> - formatting is checked - clippy is happy - no tests that weren't already broken fail - added test case # 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. -->
2023-08-08 13:48:13 +02:00
let actual = nu!(
cwd: dirs.test(),
r#"open data.txt | parse --regex "(abcdefghijklmnopqrstuvwxyz)" | length"#
);
parse: collect external stream chunks before matching (#9950) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx --> # Description This PR implements the workaround discussed in #9795, i.e. having `parse` collect an external stream before operating on it with a regex. - Should close #9795 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> - `parse` will give the correct output for external streams - increased memory and time overhead due to collecting the entire stream (no short-circuiting) # 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 -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> - formatting is checked - clippy is happy - no tests that weren't already broken fail - added test case # 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. -->
2023-08-08 13:48:13 +02:00
assert_eq!(actual.out, "1000");
})
}
2020-05-22 16:13:58 +02:00
}