1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

test_seq: Add a few more tests for corner cases

Some of these tests are not completely defined behavior, but
in many cases they make sense (or at least one can find some
consistent logic to it).

However, there are 2 edge cases that are more dubious IMHO.
One of them has been reported on list a while back, and I
just reported another.
This commit is contained in:
Nicolas Boichat 2025-03-22 13:44:09 +01:00 committed by Sylvestre Ledru
parent 59cd6e5e41
commit 596ea0a694

View file

@ -936,3 +936,111 @@ fn test_parse_valid_hexadecimal_float_format_issues() {
.succeeds()
.stdout_only("9.92804e-09\n1\n");
}
// GNU `seq` manual states that, when the parameters "all use a fixed point
// decimal representation", the format should be `%.pf`, where the precision
// is inferred from parameters. Else, `%g` is used.
//
// This is understandable, as translating hexadecimal precision to decimal precision
// is not straightforward or intuitive to the user. There are some exceptions though,
// if a mix of hexadecimal _integers_ and decimal floats are provided.
//
// The way precision is inferred is said to be able to "represent the output numbers
// exactly". In practice, this means that trailing zeros in first/increment number are
// considered, but not in the last number. This makes sense if we take that last number
// as a "bound", and not really part of input/output.
#[test]
fn test_precision_corner_cases() {
// Mixed input with integer hex still uses precision in decimal float
new_ucmd!()
.args(&["0x1", "0.90", "3"])
.succeeds()
.stdout_is("1.00\n1.90\n2.80\n");
// Mixed input with hex float reverts to %g
new_ucmd!()
.args(&["0x1.00", "0.90", "3"])
.succeeds()
.stdout_is("1\n1.9\n2.8\n");
// Even if it's the last number.
new_ucmd!()
.args(&["1", "1.20", "0x3.000000"])
.succeeds()
.stdout_is("1\n2.2\n");
// Otherwise, precision in last number is ignored.
new_ucmd!()
.args(&["1", "1.20", "3.000000"])
.succeeds()
.stdout_is("1.00\n2.20\n");
// Infinity is ignored
new_ucmd!()
.args(&["1", "1.2", "inf"])
.run_stdout_starts_with(b"1.0\n2.2\n3.4\n")
.success();
}
// GNU `seq` manual only makes guarantees about `-w` working if the
// provided numbers "all use a fixed point decimal representation",
// and guides the user to use `-f` for other cases.
#[test]
fn test_equalize_widths_corner_cases() {
// Mixed input with hexadecimal does behave as expected
new_ucmd!()
.args(&["-w", "0x1", "5.2", "9"])
.succeeds()
.stdout_is("1.0\n6.2\n");
// Confusingly, the number of integral digits in the last number is
// used to pad the output numbers, while it is ignored for precision
// computation.
//
// This problem has been reported on list here:
// "bug#77179: seq incorrectly(?) pads output when last parameter magnitude"
// https://lists.gnu.org/archive/html/bug-coreutils/2025-03/msg00028.html
//
// TODO: This case could be handled correctly, consider fixing this in
// `uutils` implementation. Output should probably be "1.0\n6.2\n".
new_ucmd!()
.args(&["-w", "0x1", "5.2", "10.0000"])
.succeeds()
.stdout_is("01.0\n06.2\n");
// But if we fixed the case above, we need to make sure we still pad
// if the last number in the output requires an extra digit.
new_ucmd!()
.args(&["-w", "0x1", "5.2", "15.0000"])
.succeeds()
.stdout_is("01.0\n06.2\n11.4\n");
// GNU `seq` bails out if any hex float is in the output.
// Unlike the precision corner cases above, it is harder to justify
// this behavior for hexadecimal float inputs, as it is always be
// possible to output numbers with a fixed width.
//
// This problem has been reported on list here:
// "bug#76070: Subject: seq, hexadecimal args and equal width"
// https://lists.gnu.org/archive/html/bug-coreutils/2025-02/msg00007.html
//
// TODO: These cases could be handled correctly, consider fixing this in
// `uutils` implementation.
// If we ignore hexadecimal precision, the output should be "1.0\n6.2\n".
new_ucmd!()
.args(&["-w", "0x1.0000", "5.2", "10"])
.succeeds()
.stdout_is("1\n6.2\n");
// The equivalent `seq -w 1.0625 1.00002 3` correctly pads the first number: "1.06250\n2.06252\n"
new_ucmd!()
.args(&["-w", "0x1.1", "1.00002", "3"])
.succeeds()
.stdout_is("1.0625\n2.06252\n");
// We can't really pad with infinite number of zeros, so `-w` is ignored.
// (there is another test with infinity as an increment above)
new_ucmd!()
.args(&["-w", "1", "1.2", "inf"])
.run_stdout_starts_with(b"1.0\n2.2\n3.4\n")
.success();
}