nushell/crates/nu-protocol/tests/test_value.rs

49 lines
1.3 KiB
Rust
Raw Normal View History

Fix duration type to not report months or years (#9632) <!-- 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 you can also mention related issues, PRs or discussions! --> This PR should close #8036, #9028 (in the negative) and #9118. Fix for #9118 is a bit pedantic. As reported, the issue is: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 3yr 12month 2day 18hr 9min 33sec ``` with this PR, you now get: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 208wk 1day 18hr 9min 33sec ``` Which is strictly correct, but could still fairly be called "weird date arithmetic". # Description * [x] Abide by constraint that Value::Duration remains a number of nanoseconds with no additional fields. * [x] `to_string()` only displays weeks .. nanoseconds. Duration doesn't have base date to compute months or years from. * [x] `duration | into record` likewise only has fields for weeks .. nanoseconds. * [x] `string | into duration` now accepts compound form of duration to_string() (e.g '2day 3hr`, not just '2day') * [x] `duration | into string` now works (and produces the same representation as to_string(), which may be compound). # User-Facing Changes ## duration -> string -> duration Now you can "round trip" an arbitrary duration value: convert it to a string that may include multiple time units (a "compound" value), then convert that string back into a duration. This required changes to `string | into duration` and the addition of `duration | into string'. ``` > 2day + 3hr 2day 3hr # the "to_string()" representation (in this case, a compound value) > 2day + 3hr | into string 2day 3hr # string value > 2day + 3hr | into string | into duration 2day 3hr # round-trip duration -> string -> duration ``` Note that `to nuon` and `from nuon` already round-tripped durations, but use a different string representation. ## potentially breaking changes * string rendering of a duration no longer has 'yr' or 'month' phrases. * record from `duration | into record` no longer has 'year' or 'month' fields. The excess duration is all lumped into the `week` field, which is the largest time unit you can convert to without knowing the datetime from which the duration was calculated. Scripts that depended on month or year time units on output will need to be changed. ### Examples ``` > 365day 52wk 1day ## Used to be: ## 1yr > 365day | into record ╭──────┬────╮ │ week │ 52 │ │ day │ 1 │ │ sign │ + │ ╰──────┴────╯ ## used to be: ##╭──────┬───╮ ##│ year │ 1 │ ##│ sign │ + │ ##╰──────┴───╯ > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) 56wk 6day 6hr 7min 8sec 9ms 10µs 11ns ## used to be: ## 1yr 1month 3day 6hr 7min 8sec 9ms 10µs 11ns ## which looks reasonable, but was actually only correct in 75% of the years and 25% of the months in the last 4 years. > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) | into record ╭─────────────┬────╮ │ week │ 56 │ │ day │ 6 │ │ hour │ 6 │ │ minute │ 7 │ │ second │ 8 │ │ millisecond │ 9 │ │ microsecond │ 10 │ │ nanosecond │ 11 │ │ sign │ + │ ╰─────────────┴────╯ ``` Strictly speaking, these changes could break an existing user script. Losing years and months as time units is arguably a regression in behavior. Also, the corrected duration calculation could break an existing script that was calibrated using the old algorithm. # Tests + Formatting ``` > toolkit check pr ``` - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `toolkit test stdlib` # 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: Bob Hyman <bobhy@localhost.localdomain>
2023-08-08 11:24:09 +00:00
use nu_protocol::{Config, Span, Value};
use rstest::rstest;
#[test]
fn test_comparison_nothing() {
let values = vec![
Value::test_int(1),
Value::test_string("string"),
Value::test_float(1.0),
];
Move Value to helpers, separate span call (#10121) # Description As part of the refactor to split spans off of Value, this moves to using helper functions to create values, and using `.span()` instead of matching span out of Value directly. Hoping to get a few more helping hands to finish this, as there are a lot of commands to update :) # 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` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `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 > ``` --> # 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> Co-authored-by: WindSoilder <windsoilder@outlook.com>
2023-09-03 14:27:29 +00:00
let nothing = Value::nothing(Span::test_data());
for value in values {
assert!(matches!(
value.eq(Span::test_data(), &nothing, Span::test_data()),
Ok(Value::Bool { val: false, .. })
));
assert!(matches!(
value.ne(Span::test_data(), &nothing, Span::test_data()),
Ok(Value::Bool { val: true, .. })
));
assert!(matches!(
nothing.eq(Span::test_data(), &value, Span::test_data()),
Ok(Value::Bool { val: false, .. })
));
assert!(matches!(
nothing.ne(Span::test_data(), &value, Span::test_data()),
Ok(Value::Bool { val: true, .. })
));
}
}
Fix duration type to not report months or years (#9632) <!-- 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 you can also mention related issues, PRs or discussions! --> This PR should close #8036, #9028 (in the negative) and #9118. Fix for #9118 is a bit pedantic. As reported, the issue is: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 3yr 12month 2day 18hr 9min 33sec ``` with this PR, you now get: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 208wk 1day 18hr 9min 33sec ``` Which is strictly correct, but could still fairly be called "weird date arithmetic". # Description * [x] Abide by constraint that Value::Duration remains a number of nanoseconds with no additional fields. * [x] `to_string()` only displays weeks .. nanoseconds. Duration doesn't have base date to compute months or years from. * [x] `duration | into record` likewise only has fields for weeks .. nanoseconds. * [x] `string | into duration` now accepts compound form of duration to_string() (e.g '2day 3hr`, not just '2day') * [x] `duration | into string` now works (and produces the same representation as to_string(), which may be compound). # User-Facing Changes ## duration -> string -> duration Now you can "round trip" an arbitrary duration value: convert it to a string that may include multiple time units (a "compound" value), then convert that string back into a duration. This required changes to `string | into duration` and the addition of `duration | into string'. ``` > 2day + 3hr 2day 3hr # the "to_string()" representation (in this case, a compound value) > 2day + 3hr | into string 2day 3hr # string value > 2day + 3hr | into string | into duration 2day 3hr # round-trip duration -> string -> duration ``` Note that `to nuon` and `from nuon` already round-tripped durations, but use a different string representation. ## potentially breaking changes * string rendering of a duration no longer has 'yr' or 'month' phrases. * record from `duration | into record` no longer has 'year' or 'month' fields. The excess duration is all lumped into the `week` field, which is the largest time unit you can convert to without knowing the datetime from which the duration was calculated. Scripts that depended on month or year time units on output will need to be changed. ### Examples ``` > 365day 52wk 1day ## Used to be: ## 1yr > 365day | into record ╭──────┬────╮ │ week │ 52 │ │ day │ 1 │ │ sign │ + │ ╰──────┴────╯ ## used to be: ##╭──────┬───╮ ##│ year │ 1 │ ##│ sign │ + │ ##╰──────┴───╯ > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) 56wk 6day 6hr 7min 8sec 9ms 10µs 11ns ## used to be: ## 1yr 1month 3day 6hr 7min 8sec 9ms 10µs 11ns ## which looks reasonable, but was actually only correct in 75% of the years and 25% of the months in the last 4 years. > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) | into record ╭─────────────┬────╮ │ week │ 56 │ │ day │ 6 │ │ hour │ 6 │ │ minute │ 7 │ │ second │ 8 │ │ millisecond │ 9 │ │ microsecond │ 10 │ │ nanosecond │ 11 │ │ sign │ + │ ╰─────────────┴────╯ ``` Strictly speaking, these changes could break an existing user script. Losing years and months as time units is arguably a regression in behavior. Also, the corrected duration calculation could break an existing script that was calibrated using the old algorithm. # Tests + Formatting ``` > toolkit check pr ``` - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `toolkit test stdlib` # 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: Bob Hyman <bobhy@localhost.localdomain>
2023-08-08 11:24:09 +00:00
#[rstest]
#[case(365 * 24 * 3600 * 1_000_000_000, "52wk 1day")]
Spanned Value step 1: span all value cases (#10042) # Description This doesn't really do much that the user could see, but it helps get us ready to do the steps of the refactor to split the span off of Value, so that values can be spanless. This allows us to have top-level values that can hold both a Value and a Span, without requiring that all values have them. We expect to see significant memory reduction by removing so many unnecessary spans from values. For example, a table of 100,000 rows and 5 columns would have a savings of ~8megs in just spans that are almost always duplicated. # User-Facing Changes Nothing yet # 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 > ``` --> # 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-24 20:48:05 +00:00
#[case( (((((((7 + 2) * 24 + 3) * 60 + 4) * 60) + 5) * 1000 + 6) * 1000 + 7) * 1000 + 8,
Fix duration type to not report months or years (#9632) <!-- 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 you can also mention related issues, PRs or discussions! --> This PR should close #8036, #9028 (in the negative) and #9118. Fix for #9118 is a bit pedantic. As reported, the issue is: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 3yr 12month 2day 18hr 9min 33sec ``` with this PR, you now get: ``` > 2023-05-07T04:08:45+12:00 - 2019-05-10T09:59:12+12:00 208wk 1day 18hr 9min 33sec ``` Which is strictly correct, but could still fairly be called "weird date arithmetic". # Description * [x] Abide by constraint that Value::Duration remains a number of nanoseconds with no additional fields. * [x] `to_string()` only displays weeks .. nanoseconds. Duration doesn't have base date to compute months or years from. * [x] `duration | into record` likewise only has fields for weeks .. nanoseconds. * [x] `string | into duration` now accepts compound form of duration to_string() (e.g '2day 3hr`, not just '2day') * [x] `duration | into string` now works (and produces the same representation as to_string(), which may be compound). # User-Facing Changes ## duration -> string -> duration Now you can "round trip" an arbitrary duration value: convert it to a string that may include multiple time units (a "compound" value), then convert that string back into a duration. This required changes to `string | into duration` and the addition of `duration | into string'. ``` > 2day + 3hr 2day 3hr # the "to_string()" representation (in this case, a compound value) > 2day + 3hr | into string 2day 3hr # string value > 2day + 3hr | into string | into duration 2day 3hr # round-trip duration -> string -> duration ``` Note that `to nuon` and `from nuon` already round-tripped durations, but use a different string representation. ## potentially breaking changes * string rendering of a duration no longer has 'yr' or 'month' phrases. * record from `duration | into record` no longer has 'year' or 'month' fields. The excess duration is all lumped into the `week` field, which is the largest time unit you can convert to without knowing the datetime from which the duration was calculated. Scripts that depended on month or year time units on output will need to be changed. ### Examples ``` > 365day 52wk 1day ## Used to be: ## 1yr > 365day | into record ╭──────┬────╮ │ week │ 52 │ │ day │ 1 │ │ sign │ + │ ╰──────┴────╯ ## used to be: ##╭──────┬───╮ ##│ year │ 1 │ ##│ sign │ + │ ##╰──────┴───╯ > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) 56wk 6day 6hr 7min 8sec 9ms 10µs 11ns ## used to be: ## 1yr 1month 3day 6hr 7min 8sec 9ms 10µs 11ns ## which looks reasonable, but was actually only correct in 75% of the years and 25% of the months in the last 4 years. > (365day + 4wk + 5day + 6hr + 7min + 8sec + 9ms + 10us + 11ns) | into record ╭─────────────┬────╮ │ week │ 56 │ │ day │ 6 │ │ hour │ 6 │ │ minute │ 7 │ │ second │ 8 │ │ millisecond │ 9 │ │ microsecond │ 10 │ │ nanosecond │ 11 │ │ sign │ + │ ╰─────────────┴────╯ ``` Strictly speaking, these changes could break an existing user script. Losing years and months as time units is arguably a regression in behavior. Also, the corrected duration calculation could break an existing script that was calibrated using the old algorithm. # Tests + Formatting ``` > toolkit check pr ``` - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `toolkit test stdlib` # 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: Bob Hyman <bobhy@localhost.localdomain>
2023-08-08 11:24:09 +00:00
"1wk 2day 3hr 4min 5sec 6ms 7µs 8ns")]
fn test_duration_to_string(#[case] in_ns: i64, #[case] expected: &str) {
let dur = Value::test_duration(in_ns);
assert_eq!(
expected,
dur.into_string("", &Config::default()),
"expected != observed"
);
}