Skip to content

merge more tests into rstest cases - #15538

Merged
sylvestre merged 6 commits into
mainfrom
tests-rstest-dedup-2
Oct 21, 2026
Merged

sylvestre merged 6 commits into
mainfrom
tests-rstest-dedup-2

Conversation

@sylvestre

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 21:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

4 open issues
What changed in this PR

Consolidates multiple single-case tests into parameterized rstest cases across several utility test suites to reduce duplication and centralize fixture-driven assertions.

Changes:

  • Merged many individual #[test] functions into grouped #[rstest] case tables.
  • Standardized several assertions to use shared helper-style flows (stdout_only, fixture checks).
  • Added rstest imports to the affected test modules.
File Description
tests/​by-util/​test_unexpand.rs Replaces multiple stdin-based tests with a single rstest-parameterized test.
tests/​by-util/​test_sort.rs Consolidates many fixture tests into one parameterized rstest function calling test_helper.
tests/​by-util/​test_numfmt.rs Collapses many argument/stdin tests into two large rstest suites with case tables.
tests/​by-util/​test_expand.rs Converts multiple stdin tab-spec tests into one parameterized rstest.
tests/​by-util/​test_dd.rs Merges multiple dd conversion fixture tests into a single rstest function.
tests/​by-util/​test_basenc.rs Consolidates multiple encoding/decoding stdin tests into one rstest suite.

Review effort: Lite

Comment on lines +16 to +74
#[rstest]
// This test failed when fixing #11653.
// Add a `--` separator to ensure floats are not rounded(it match the gnu pattern).
#[test]
fn test_should_not_round_floats() {
new_ucmd!()
.args(&["--", "0.99", "1.01", "1.1", "1.22", ".1", "-0.1"])
.succeeds()
.stdout_is("0.99\n1.01\n1.1\n1.22\n0.1\n-0.1\n");
}

#[test]
fn test_should_preserve_trailing_zeros() {
new_ucmd!()
.args(&["0.1000", "10.00"])
.succeeds()
.stdout_is("0.1000\n10.00\n");
}

#[test]
fn test_from_si() {
new_ucmd!()
.args(&["--from=si"])
.pipe_in("1000\n1.1M\n0.1G")
.succeeds()
.stdout_is("1000\n1100000\n100000000");
}

#[test]
fn test_from_iec() {
new_ucmd!()
.args(&["--from=iec"])
.pipe_in("1024\n1.1M\n0.1G")
.succeeds()
.stdout_is("1024\n1153434\n107374183");
}

#[test]
fn test_from_iec_i() {
new_ucmd!()
.args(&["--from=iec-i"])
.pipe_in("1.1Mi\n0.1Gi")
.succeeds()
.stdout_is("1153434\n107374183");
#[case::should_not_round_floats(&["--", "0.99", "1.01", "1.1", "1.22", ".1", "-0.1"], "0.99\n1.01\n1.1\n1.22\n0.1\n-0.1\n")]
#[case::should_preserve_trailing_zeros(&["0.1000", "10.00"], "0.1000\n10.00\n")]
#[case::from_iec_i_without_suffix_are_bytes(&["--from=iec-i", "1024"], "1024\n")]
#[case::input_from_free_arguments(&["--from=si", "1K", "1.1M", "0.1G"], "1000\n1100000\n100000000\n")]
#[case::si_to_iec(&["--from=si", "--to=iec", "15334263563K"], "14T\n")]
#[case::leading_whitespace_in_free_argument_should_imply_padding(&["--from=auto", " 1Ki"], " 1024\n")]
#[case::should_calculate_implicit_padding_per_free_argument(&["--from=auto", " 1Ki", " 2K"], " 1024\n 2000\n")]
#[case::format_implied_range_and_field(&["--from=auto", "--field", "-2,4", "1K 2K 3K 4K 5K 6K"], "1000 2000 3K 4000 5K 6K\n")]
#[case::should_succeed_if_selected_field_out_of_range(&["--from=auto", "--field", "9", "1K 2K 3K"], "1K 2K 3K\n")]
#[case::format_selected_field_range(&["--from=auto", "--field", "2-5", "1K 2K 3K 4K 5K 6K"], "1K 2000 3000 4000 5000 6K\n")]
#[case::should_succeed_if_range_out_of_bounds(&["--from=auto", "--field", "5-10", "1K 2K 3K 4K 5K 6K"], "1K 2K 3K 4K 5000 6000\n")]
#[case::to_unitless_small_values_use_display_rounding(&["--to=si", "--", "0.4", "0.5", "0.6", "1.4", "3.14", "-0.4", "-0.5", "-0.6", "-1.4"], "0\n0\n1\n1\n3\n-0\n-0\n-1\n-1\n")]
#[case::invalid_arg_number_with_ignore_returns_status_0(&["--invalid=ignore", "4Q"], "4Q\n")]
#[case::from_unit(&["--from-unit=512", "4"], "2048\n")]
#[case::to_unit(&["--to-unit=512", "2048"], "4\n")]
#[case::format(&["--format=--%f--", "50"], "--50--\n")]
#[case::format_with_separate_value(&["--format", "--%f--", "50"], "--50--\n")]
#[case::format_padding_with_prefix_and_suffix(&["--format=--%6f--", "50"], "-- 50--\n")]
#[case::format_negative_padding_with_prefix_and_suffix(&["--format=--%-6f--", "50"], "--50 --\n")]
#[case::format_with_format_padding_overriding_padding_option(&["--format=%6f", "--padding=10", "1234"], " 1234\n")]
#[case::format_with_format_padding_overriding_implicit_padding(&["--format=%6f", " 1234"], " 1234\n")]
#[case::format_with_negative_format_padding_and_suffix(&["--format=%-6f", "1234 ?"], "1234 ?\n")]
#[case::format_with_zero_padding_and_padding_option(&["--format=%06f", "--padding=8", "1234"], " 001234\n")]
#[case::format_with_zero_padding_and_negative_padding_option(&["--format=%06f", "--padding=-8", "1234"], "001234 \n")]
#[case::format_with_zero_padding_and_implicit_padding(&["--format=%06f", " 1234"], " 001234\n")]
#[case::format_with_zero_padding_and_suffix(&["--format=%06f", "1234 ?"], "001234 ?\n")]
// https://github.com/uutils/coreutils/issues/11653
// GNU rejects `-9923868` as an invalid short option (leading `-9`) and
// requires `--` separator; uutils accepts it as a negative positional number.
#[case::numfmt_negative_after_double_dash_ok(&["--to=iec", "--", "-8765432"], "-8.4M\n")]
// https://github.com/uutils/coreutils/issues/11654
// uutils parses large integers through f64, losing precision past 2^53.
#[case::large_integer_precision_loss_issue_11654(&["--from=iec", "9153396227555392131"], "9153396227555392131\n")]
// https://github.com/uutils/coreutils/issues/11663
// `--from-unit` multiplication with fractional input rounds to an integer;
// GNU preserves the fractional digits.
#[case::from_unit_fractional_precision_issue_11663(&["--from=iec", "--from-unit=959", "--", "-615484.454"], "-590249591.386\n")]
// https://github.com/uutils/coreutils/issues/11664
// Zero-padded `--format` places padding zeros before the sign for negative
// numbers; GNU (and C printf) puts the sign first.
#[case::zero_pad_sign_order_issue_11664(&["--from=none", "--format=%018.2f", "--", "-9869647"], "-00000009869647.00\n")]
#[case::to_unit_prefix_selection(&["--to=iec-i", "--to-unit=885", "100000"], "113\n")]
// https://github.com/uutils/coreutils/issues/11667
// `--format='%.0f'` with `--to=<scale>` still prints one fractional digit;
// the precision specifier `.0` is ignored.
#[case::format_precision_zero_with_to_scale_issue_11667(&["--to=iec", "--format=%.0f", "5183776"], "5M\n")]
// https://github.com/uutils/coreutils/issues/11937
// numfmt: --format width accounting diverges from GNU for multi-byte --suffix
#[case::multibyte_suffix_issue11937(&["--suffix=€", "--format=%10.2f", "692"], " 692.00€\n")]
#[case::float_precision_greater_than_16bits(&["--to=iec", "--format=%.65536f", "1"], "1\n")]
#[case::float_precision_greater_than_16bits_without_scaling(&["--format=%.65536f", "1.5"], "2\n")]
#[case::float_precision_greater_than_16bits_with_suffix(&["--to=si", "--format=%.65536f", "1000000"], "1M\n")]
// https://github.com/uutils/coreutils/issues/13272
// argument following `--header` must not be interpreted as the option's value
#[case::header_detached(&["--header", "1", "2"], "1\n2\n")]
fn test_numfmt_args(#[case] args: &[&str], #[case] expected: &str) {
Comment thread tests/by-util/test_sort.rs Outdated
Comment on lines +208 to +248
#[rstest]
#[case::months_whitespace("months-whitespace", &["-M", "--month-sort", "--sort=month", "--sort=mont", "--sort=m"])]
#[case::version_empty_lines("version-empty-lines", &["-V", "--version-sort"])]
#[case::multiple_decimals_numeric("multiple_decimals_numeric", &["-n", "--numeric-sort", "--sort=numeric", "--sort=n"])]
#[case::multiple_groupings_numeric("multiple_groupings_numeric", &["-n", "--numeric-sort", "--sort=numeric", "--sort=n"])]
#[case::numeric_with_trailing_invalid_chars("numeric_trailing_chars", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_floats_and_ints("numeric_floats_and_ints", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_floats("numeric_floats", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_floats_with_nan("numeric_floats_with_nan", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_unfixed_floats("numeric_unfixed_floats", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_fixed_floats("numeric_fixed_floats", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::numeric_unsorted_ints("numeric_unsorted_ints", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::human_block_sizes("human_block_sizes", &["-h", "--human-numeric-sort", "--sort=human-numeric"])]
#[case::month_default("month_default", &["-M", "--month-sort", "--sort=month"])]
#[case::month_stable("month_stable", &["-Ms"])]
#[case::default_unsorted_ints("default_unsorted_ints", &[""])]
#[case::numeric_unique_ints("numeric_unsorted_ints_unique", &["-nu"])]
#[case::version("version", &["-V"])]
#[case::ignore_case("ignore_case", &["-f"])]
#[case::dictionary_order("dictionary_order", &["-d"])]
#[case::exponents_general("exponents_general", &["-g"])]
#[case::exponents_positive_numeric("exponents-positive-numeric", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::months_dedup("months-dedup", &["-Mu"])]
#[case::mixed_floats_ints_chars_numeric("mixed_floats_ints_chars_numeric", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::mixed_floats_ints_chars_numeric_unique("mixed_floats_ints_chars_numeric_unique", &["-nu"])]
#[case::words_unique("words_unique", &["-u"])]
#[case::numeric_unique("numeric_unique", &["-nu"])]
#[case::mixed_floats_ints_chars_numeric_reverse("mixed_floats_ints_chars_numeric_unique_reverse", &["-nur"])]
#[case::mixed_floats_ints_chars_numeric_stable("mixed_floats_ints_chars_numeric_stable", &["-ns"])]
#[case::numeric_floats_with_nan2("numeric-floats-with-nan2", &["-n", "--numeric-sort", "--sort=numeric"])]
#[case::keys_open_ended("keys_open_ended", &["-k 2.3"])]
#[case::keys_closed_range("keys_closed_range", &["-k 2.2,2.2"])]
#[case::keys_multiple_ranges("keys_multiple_ranges", &["-k 2,2 -k 3,3"])]
#[case::keys_no_field_match("keys_no_field_match", &["-k 4,4"])]
#[case::keys_no_char_match("keys_no_char_match", &["-k 1.2"])]
#[case::keys_custom_separator("keys_custom_separator", &["-k 2.2,2.2 -t x"])]
#[case::keys_blanks_with_char_idx("keys_blanks", &["-k 1.2b"])]
#[case::keys_ignore_flag("keys_ignore_flag", &["-k 1n -b"])]
#[case::zero_terminated("zero-terminated", &["-z"])]
#[case::blanks("blanks", &["-b", "--ignore-leading-blanks"])]
fn test_sort_fixtures(#[case] fixture_stem: &str, #[case] args: &[&str]) {
Comment thread tests/by-util/test_numfmt.rs Outdated
Comment thread tests/by-util/test_sort.rs Outdated
Copilot AI balanced review requested due to automatic review settings October 20, 2026 07:31
@sylvestre
sylvestre force-pushed the tests-rstest-dedup-2 branch from 536dcb0 to 8ab1a74 Compare October 20, 2026 07:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread tests/by-util/test_sort.rs Outdated
Comment thread tests/by-util/test_sort.rs
@sylvestre
sylvestre force-pushed the tests-rstest-dedup-2 branch from 8ab1a74 to 22d89be Compare October 21, 2026 09:17
Copilot AI balanced review requested due to automatic review settings October 21, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@sylvestre
sylvestre enabled auto-merge (rebase) October 21, 2026 09:51
@sylvestre
sylvestre merged commit ba62e8f into main Oct 21, 2026
177 checks passed
@sylvestre
sylvestre deleted the tests-rstest-dedup-2 branch October 21, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants