1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

tests: untrimmed stdout assertion (fix #1235)

This commit is contained in:
Julio Rincon 2019-02-08 07:54:48 +11:00
parent a673c12694
commit 29c6ad5f6a
16 changed files with 73 additions and 59 deletions

4
src/cat/cat.rs Normal file → Executable file
View file

@ -419,6 +419,7 @@ fn write_to_end<W: Write>(in_buf: &[u8], writer: &mut W) -> usize {
} }
fn write_tab_to_end<W: Write>(mut in_buf: &[u8], writer: &mut W) -> usize { fn write_tab_to_end<W: Write>(mut in_buf: &[u8], writer: &mut W) -> usize {
let mut count = 0;
loop { loop {
match in_buf match in_buf
.iter() .iter()
@ -427,10 +428,11 @@ fn write_tab_to_end<W: Write>(mut in_buf: &[u8], writer: &mut W) -> usize {
Some(p) => { Some(p) => {
writer.write_all(&in_buf[..p]).unwrap(); writer.write_all(&in_buf[..p]).unwrap();
if in_buf[p] == b'\n' { if in_buf[p] == b'\n' {
return p + 1; return count + p + 1;
} else { } else {
writer.write_all(b"^I").unwrap(); writer.write_all(b"^I").unwrap();
in_buf = &in_buf[p + 1..]; in_buf = &in_buf[p + 1..];
count += p + 1;
} }
} }
None => { None => {

15
src/join/join.rs Normal file → Executable file
View file

@ -106,12 +106,17 @@ impl<'a> Repr<'a> {
} }
/// Print each field except the one at the index. /// Print each field except the one at the index.
fn print_fields(&self, line: &Line, index: usize, max_fields: usize) { fn print_fields(&self, line: &Line, index: usize, max_fields: Option<usize>) {
for i in 0..min(max_fields, line.fields.len()) { for i in 0..min(max_fields.unwrap_or(usize::max_value()), line.fields.len()) {
if i != index { if i != index {
print!("{}{}", self.separator, line.fields[i]); print!("{}{}", self.separator, line.fields[i]);
} }
} }
if let Some(n) = max_fields {
for _ in line.fields.len()..n {
print!("{}", self.separator)
}
}
} }
/// Print each field or the empty filler if the field is not set. /// Print each field or the empty filler if the field is not set.
@ -232,7 +237,7 @@ struct State<'a> {
print_unpaired: bool, print_unpaired: bool,
lines: Lines<Box<BufRead + 'a>>, lines: Lines<Box<BufRead + 'a>>,
seq: Vec<Line>, seq: Vec<Line>,
max_fields: usize, max_fields: Option<usize>,
line_num: usize, line_num: usize,
has_failed: bool, has_failed: bool,
} }
@ -261,7 +266,7 @@ impl<'a> State<'a> {
print_unpaired: print_unpaired == file_num, print_unpaired: print_unpaired == file_num,
lines: f.lines(), lines: f.lines(),
seq: Vec::new(), seq: Vec::new(),
max_fields: usize::max_value(), max_fields: None,
line_num: 0, line_num: 0,
has_failed: false, has_failed: false,
} }
@ -363,7 +368,7 @@ impl<'a> State<'a> {
fn initialize(&mut self, read_sep: Sep, autoformat: bool) { fn initialize(&mut self, read_sep: Sep, autoformat: bool) {
if let Some(line) = self.read_line(read_sep) { if let Some(line) = self.read_line(read_sep) {
if autoformat { if autoformat {
self.max_fields = line.fields.len(); self.max_fields = Some(line.fields.len());
} }
self.seq.push(line); self.seq.push(line);

6
tests/common/util.rs Normal file → Executable file
View file

@ -89,12 +89,12 @@ impl CmdResult {
} }
/// asserts that the command resulted in stdout stream output that equals the /// asserts that the command resulted in stdout stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace /// passed in value, trailing whitespace are kept to force strict comparison (#1235)
/// stdout_only is a better choice unless stderr may or will be non-empty /// stdout_only is a better choice unless stderr may or will be non-empty
pub fn stdout_is<T: AsRef<str>>(&self, msg: T) -> Box<&CmdResult> { pub fn stdout_is<T: AsRef<str>>(&self, msg: T) -> Box<&CmdResult> {
assert_eq!( assert_eq!(
String::from(msg.as_ref()).trim_right(), String::from(msg.as_ref()),
self.stdout.trim_right() self.stdout
); );
Box::new(self) Box::new(self)
} }

View file

@ -1,4 +1,3 @@
2 ;b;x 2 ;b;x
3; c; y 3; c; y
4 ;d;z 4 ;d;z

View file

@ -1,3 +1,3 @@
NaN NaN
.02 .02
.03 .03

View file

@ -1,3 +1,3 @@
.03 .03
.02 .02
NaN NaN

View file

@ -4,23 +4,23 @@ use common::util::*;
#[test] #[test]
fn test_directory() { fn test_directory() {
new_ucmd!().args(&["/root/alpha/beta/gamma/delta/epsilon/omega/"]) new_ucmd!().args(&["/root/alpha/beta/gamma/delta/epsilon/omega/"])
.succeeds().stdout_only("omega"); .succeeds().stdout_only("omega\n");
} }
#[test] #[test]
fn test_file() { fn test_file() {
new_ucmd!().args(&["/etc/passwd"]).succeeds().stdout_only("passwd"); new_ucmd!().args(&["/etc/passwd"]).succeeds().stdout_only("passwd\n");
} }
#[test] #[test]
fn test_remove_suffix() { fn test_remove_suffix() {
new_ucmd!().args(&["/usr/local/bin/reallylongexecutable.exe", ".exe"]) new_ucmd!().args(&["/usr/local/bin/reallylongexecutable.exe", ".exe"])
.succeeds().stdout_only("reallylongexecutable"); .succeeds().stdout_only("reallylongexecutable\n");
} }
#[test] #[test]
fn test_dont_remove_suffix() { fn test_dont_remove_suffix() {
new_ucmd!().args(&["/foo/bar/baz", "baz"]).succeeds().stdout_only( "baz"); new_ucmd!().args(&["/foo/bar/baz", "baz"]).succeeds().stdout_only( "baz\n");
} }
#[test] #[test]
@ -28,7 +28,7 @@ fn test_multiple_param() {
for multiple_param in vec!["-a", "--multiple"] { for multiple_param in vec!["-a", "--multiple"] {
let path = "/foo/bar/baz"; let path = "/foo/bar/baz";
new_ucmd!().args(&[multiple_param, path, path]) new_ucmd!().args(&[multiple_param, path, path])
.succeeds().stdout_only("baz\nbaz"); .succeeds().stdout_only("baz\nbaz\n");
} }
} }
@ -38,7 +38,7 @@ fn test_suffix_param() {
let path = "/foo/bar/baz.exe"; let path = "/foo/bar/baz.exe";
new_ucmd!() new_ucmd!()
.args(&[suffix_param, ".exe", path, path]) .args(&[suffix_param, ".exe", path, path])
.succeeds().stdout_only("baz\nbaz"); .succeeds().stdout_only("baz\nbaz\n");
} }
} }

View file

@ -38,7 +38,7 @@ fn test_stdin_show_nonprinting() {
.args(&[same_param]) .args(&[same_param])
.pipe_in("\t\0\n") .pipe_in("\t\0\n")
.succeeds() .succeeds()
.stdout_only("\t^@"); .stdout_only("\t^@\n");
} }
} }
@ -49,7 +49,7 @@ fn test_stdin_show_tabs() {
.args(&[same_param]) .args(&[same_param])
.pipe_in("\t\0\n") .pipe_in("\t\0\n")
.succeeds() .succeeds()
.stdout_only("^I\0"); .stdout_only("^I\0\n");
} }
} }
@ -59,9 +59,9 @@ fn test_stdin_show_ends() {
for same_param in vec!["-E", "--show-ends"] { for same_param in vec!["-E", "--show-ends"] {
new_ucmd!() new_ucmd!()
.args(&[same_param,"-"]) .args(&[same_param,"-"])
.pipe_in("\t\0\n") .pipe_in("\t\0\n\t")
.succeeds() .succeeds()
.stdout_only("\t\0$"); .stdout_only("\t\0$\n\t");
} }
} }
@ -72,7 +72,7 @@ fn test_stdin_show_all() {
.args(&[same_param]) .args(&[same_param])
.pipe_in("\t\0\n") .pipe_in("\t\0\n")
.succeeds() .succeeds()
.stdout_only("^I^@$"); .stdout_only("^I^@$\n");
} }
} }

View file

@ -4,26 +4,26 @@ use common::util::*;
#[test] #[test]
fn test_path_with_trailing_slashes() { fn test_path_with_trailing_slashes() {
new_ucmd!().arg("/root/alpha/beta/gamma/delta/epsilon/omega//") new_ucmd!().arg("/root/alpha/beta/gamma/delta/epsilon/omega//")
.run().stdout_is("/root/alpha/beta/gamma/delta/epsilon"); .run().stdout_is("/root/alpha/beta/gamma/delta/epsilon\n");
} }
#[test] #[test]
fn test_path_without_trailing_slashes() { fn test_path_without_trailing_slashes() {
new_ucmd!().arg("/root/alpha/beta/gamma/delta/epsilon/omega") new_ucmd!().arg("/root/alpha/beta/gamma/delta/epsilon/omega")
.run().stdout_is("/root/alpha/beta/gamma/delta/epsilon"); .run().stdout_is("/root/alpha/beta/gamma/delta/epsilon\n");
} }
#[test] #[test]
fn test_root() { fn test_root() {
new_ucmd!().arg("/").run().stdout_is("/"); new_ucmd!().arg("/").run().stdout_is("/\n");
} }
#[test] #[test]
fn test_pwd() { fn test_pwd() {
new_ucmd!().arg(".").run().stdout_is("."); new_ucmd!().arg(".").run().stdout_is(".\n");
} }
#[test] #[test]
fn test_empty() { fn test_empty() {
new_ucmd!().arg("").run().stdout_is("."); new_ucmd!().arg("").run().stdout_is(".\n");
} }

View file

@ -45,12 +45,12 @@ fn test_escape_form_feed() {
#[test] #[test]
fn test_escape_hex() { fn test_escape_hex() {
new_ucmd!().args(&["-e", "\\x41"]).succeeds().stdout_only("A"); new_ucmd!().args(&["-e", "\\x41"]).succeeds().stdout_only("A\n");
} }
#[test] #[test]
fn test_escape_newline() { fn test_escape_newline() {
new_ucmd!().args(&["-e", "\\na"]).succeeds().stdout_only("\na"); new_ucmd!().args(&["-e", "\\na"]).succeeds().stdout_only("\na\n");
} }
#[test] #[test]
@ -60,7 +60,7 @@ fn test_escape_no_further_output() {
#[test] #[test]
fn test_escape_octal() { fn test_escape_octal() {
new_ucmd!().args(&["-e", "\\0100"]).succeeds().stdout_only("@"); new_ucmd!().args(&["-e", "\\0100"]).succeeds().stdout_only("@\n");
} }
#[test] #[test]

View file

@ -124,7 +124,7 @@ fn new_line_separated() {
.arg("-t") .arg("-t")
.arg("") .arg("")
.pipe_in("1 a\n1 b\n8 h\n") .pipe_in("1 a\n1 b\n8 h\n")
.succeeds().stdout_only("1 a\n8 h"); .succeeds().stdout_only("1 a\n8 h\n");
} }
#[test] #[test]
@ -174,6 +174,14 @@ fn autoformat() {
.arg("-o") .arg("-o")
.arg("auto") .arg("auto")
.succeeds().stdout_only_fixture("autoformat.expected"); .succeeds().stdout_only_fixture("autoformat.expected");
new_ucmd!()
.arg("-")
.arg("fields_2.txt")
.arg("-o")
.arg("auto")
.pipe_in("1 x y z\n2 p")
.succeeds().stdout_only("1 x y z a\n2 p b\n");
} }
#[test] #[test]
@ -246,11 +254,11 @@ fn single_file_with_header() {
.arg("capitalized.txt") .arg("capitalized.txt")
.arg("empty.txt") .arg("empty.txt")
.arg("--header") .arg("--header")
.succeeds().stdout_is("A 1"); .succeeds().stdout_is("A 1\n");
new_ucmd!() new_ucmd!()
.arg("empty.txt") .arg("empty.txt")
.arg("capitalized.txt") .arg("capitalized.txt")
.arg("--header") .arg("--header")
.succeeds().stdout_is("A 1"); .succeeds().stdout_is("A 1\n");
} }

View file

@ -6,7 +6,7 @@ fn test_from_si() {
.args(&["--from=si"]) .args(&["--from=si"])
.pipe_in("1000\n1.1M\n0.1G") .pipe_in("1000\n1.1M\n0.1G")
.run() .run()
.stdout_is("1000\n1100000\n100000000"); .stdout_is("1000\n1100000\n100000000\n");
} }
#[test] #[test]
@ -15,7 +15,7 @@ fn test_from_iec() {
.args(&["--from=iec"]) .args(&["--from=iec"])
.pipe_in("1024\n1.1M\n0.1G") .pipe_in("1024\n1.1M\n0.1G")
.run() .run()
.stdout_is("1024\n1153434\n107374182"); .stdout_is("1024\n1153434\n107374182\n");
} }
#[test] #[test]
@ -24,7 +24,7 @@ fn test_from_iec_i() {
.args(&["--from=iec-i"]) .args(&["--from=iec-i"])
.pipe_in("1024\n1.1Mi\n0.1Gi") .pipe_in("1024\n1.1Mi\n0.1Gi")
.run() .run()
.stdout_is("1024\n1153434\n107374182"); .stdout_is("1024\n1153434\n107374182\n");
} }
#[test] #[test]
@ -33,7 +33,7 @@ fn test_from_auto() {
.args(&["--from=auto"]) .args(&["--from=auto"])
.pipe_in("1K\n1Ki") .pipe_in("1K\n1Ki")
.run() .run()
.stdout_is("1000\n1024"); .stdout_is("1000\n1024\n");
} }
#[test] #[test]
@ -42,7 +42,7 @@ fn test_to_si() {
.args(&["--to=si"]) .args(&["--to=si"])
.pipe_in("1000\n1100000\n100000000") .pipe_in("1000\n1100000\n100000000")
.run() .run()
.stdout_is("1.0K\n1.1M\n100.0M"); .stdout_is("1.0K\n1.1M\n100.0M\n");
} }
#[test] #[test]
@ -51,7 +51,7 @@ fn test_to_iec() {
.args(&["--to=iec"]) .args(&["--to=iec"])
.pipe_in("1024\n1153434\n107374182") .pipe_in("1024\n1153434\n107374182")
.run() .run()
.stdout_is("1.0K\n1.1M\n102.4M"); .stdout_is("1.0K\n1.1M\n102.4M\n");
} }
#[test] #[test]
@ -60,7 +60,7 @@ fn test_to_iec_i() {
.args(&["--to=iec-i"]) .args(&["--to=iec-i"])
.pipe_in("1024\n1153434\n107374182") .pipe_in("1024\n1153434\n107374182")
.run() .run()
.stdout_is("1.0Ki\n1.1Mi\n102.4Mi"); .stdout_is("1.0Ki\n1.1Mi\n102.4Mi\n");
} }
#[test] #[test]
@ -68,7 +68,7 @@ fn test_input_from_free_arguments() {
new_ucmd!() new_ucmd!()
.args(&["--from=si", "1K", "1.1M", "0.1G"]) .args(&["--from=si", "1K", "1.1M", "0.1G"])
.run() .run()
.stdout_is("1000\n1100000\n100000000"); .stdout_is("1000\n1100000\n100000000\n");
} }
#[test] #[test]
@ -77,7 +77,7 @@ fn test_padding() {
.args(&["--from=si", "--padding=8"]) .args(&["--from=si", "--padding=8"])
.pipe_in("1K\n1.1M\n0.1G") .pipe_in("1K\n1.1M\n0.1G")
.run() .run()
.stdout_is(" 1000\n 1100000\n100000000"); .stdout_is(" 1000\n 1100000\n100000000\n");
} }
#[test] #[test]
@ -86,7 +86,7 @@ fn test_negative_padding() {
.args(&["--from=si", "--padding=-8"]) .args(&["--from=si", "--padding=-8"])
.pipe_in("1K\n1.1M\n0.1G") .pipe_in("1K\n1.1M\n0.1G")
.run() .run()
.stdout_is("1000 \n1100000 \n100000000"); .stdout_is("1000 \n1100000 \n100000000\n");
} }
#[test] #[test]
@ -95,7 +95,7 @@ fn test_header() {
.args(&["--from=si", "--header=2"]) .args(&["--from=si", "--header=2"])
.pipe_in("header\nheader2\n1K\n1.1M\n0.1G") .pipe_in("header\nheader2\n1K\n1.1M\n0.1G")
.run() .run()
.stdout_is("header\nheader2\n1000\n1100000\n100000000"); .stdout_is("header\nheader2\n1000\n1100000\n100000000\n");
} }
#[test] #[test]
@ -104,7 +104,7 @@ fn test_header_default() {
.args(&["--from=si", "--header"]) .args(&["--from=si", "--header"])
.pipe_in("header\n1K\n1.1M\n0.1G") .pipe_in("header\n1K\n1.1M\n0.1G")
.run() .run()
.stdout_is("header\n1000\n1100000\n100000000"); .stdout_is("header\n1000\n1100000\n100000000\n");
} }
#[test] #[test]
@ -113,12 +113,12 @@ fn test_negative() {
.args(&["--from=si"]) .args(&["--from=si"])
.pipe_in("-1000\n-1.1M\n-0.1G") .pipe_in("-1000\n-1.1M\n-0.1G")
.run() .run()
.stdout_is("-1000\n-1100000\n-100000000"); .stdout_is("-1000\n-1100000\n-100000000\n");
new_ucmd!() new_ucmd!()
.args(&["--to=iec-i"]) .args(&["--to=iec-i"])
.pipe_in("-1024\n-1153434\n-107374182") .pipe_in("-1024\n-1153434\n-107374182")
.run() .run()
.stdout_is("-1.0Ki\n-1.1Mi\n-102.4Mi"); .stdout_is("-1.0Ki\n-1.1Mi\n-102.4Mi\n");
} }
#[test] #[test]
@ -126,7 +126,7 @@ fn test_no_op() {
new_ucmd!() new_ucmd!()
.pipe_in("1024\n1234567") .pipe_in("1024\n1234567")
.run() .run()
.stdout_is("1024\n1234567"); .stdout_is("1024\n1234567\n");
} }
#[test] #[test]
@ -135,7 +135,7 @@ fn test_normalize() {
.args(&["--from=si", "--to=si"]) .args(&["--from=si", "--to=si"])
.pipe_in("10000000K\n0.001K") .pipe_in("10000000K\n0.001K")
.run() .run()
.stdout_is("10.0G\n1"); .stdout_is("10.0G\n1\n");
} }
#[test] #[test]
@ -143,5 +143,5 @@ fn test_si_to_iec() {
new_ucmd!() new_ucmd!()
.args(&["--from=si", "--to=iec", "15334263563K"]) .args(&["--from=si", "--to=iec", "15334263563K"])
.run() .run()
.stdout_is("13.9T"); .stdout_is("13.9T\n");
} }

View file

@ -23,7 +23,7 @@ fn test_long_format() {
new_ucmd!() new_ucmd!()
.arg("-l").arg(ulogin) .arg("-l").arg(ulogin)
.run() .run()
.stdout_is(format!("Login name: {:<28}In real life: {}\nDirectory: {:<29}Shell: {}\n", .stdout_is(format!("Login name: {:<28}In real life: {}\nDirectory: {:<29}Shell: {}\n\n",
ulogin, real_name, pw.user_dir(), pw.user_shell())); ulogin, real_name, pw.user_dir(), pw.user_shell()));
new_ucmd!() new_ucmd!()

View file

@ -4,5 +4,5 @@ use common::util::*;
#[test] #[test]
fn test_default() { fn test_default() {
let (at, mut ucmd) = at_and_ucmd!(); let (at, mut ucmd) = at_and_ucmd!();
ucmd.run().stdout_is(at.root_dir_resolved()); ucmd.run().stdout_is(at.root_dir_resolved() + "\n");
} }

View file

@ -9,7 +9,7 @@ fn test_canonicalize() {
ucmd.arg("-f") ucmd.arg("-f")
.arg(".") .arg(".")
.run() .run()
.stdout_is(at.root_dir_resolved()); .stdout_is(at.root_dir_resolved() + "\n");
} }
#[test] #[test]
@ -18,7 +18,7 @@ fn test_canonicalize_existing() {
ucmd.arg("-e") ucmd.arg("-e")
.arg(".") .arg(".")
.run() .run()
.stdout_is(at.root_dir_resolved()); .stdout_is(at.root_dir_resolved() + "\n");
} }
#[test] #[test]
@ -28,7 +28,7 @@ fn test_canonicalize_missing() {
ucmd.arg("-m") ucmd.arg("-m")
.arg(GIBBERISH) .arg(GIBBERISH)
.run() .run()
.stdout_is(expected); .stdout_is(expected + "\n");
} }
#[test] #[test]

View file

@ -4,7 +4,7 @@ use common::util::*;
#[test] #[test]
fn test_current_directory() { fn test_current_directory() {
let (at, mut ucmd) = at_and_ucmd!(); let (at, mut ucmd) = at_and_ucmd!();
ucmd.arg(".").run().stdout_is(at.root_dir_resolved()); ucmd.arg(".").run().stdout_is(at.root_dir_resolved() + "\n");
} }
#[test] #[test]
@ -12,12 +12,12 @@ fn test_long_redirection_to_current_dir() {
let (at, mut ucmd) = at_and_ucmd!(); let (at, mut ucmd) = at_and_ucmd!();
// Create a 256-character path to current directory // Create a 256-character path to current directory
let dir = path_concat!(".", ..128); let dir = path_concat!(".", ..128);
ucmd.arg(dir).run().stdout_is(at.root_dir_resolved()); ucmd.arg(dir).run().stdout_is(at.root_dir_resolved() + "\n");
} }
#[test] #[test]
fn test_long_redirection_to_root() { fn test_long_redirection_to_root() {
// Create a 255-character path to root // Create a 255-character path to root
let dir = path_concat!("..", ..85); let dir = path_concat!("..", ..85);
new_ucmd!().arg(dir).run().stdout_is(get_root_path()); new_ucmd!().arg(dir).run().stdout_is(get_root_path().to_owned() + "\n");
} }