Skip to content

Commit 53628a6

Browse files
committed
Adding integration tests for the COLUMNS env variable support in stty
1 parent 3a7385c commit 53628a6

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

src/uu/stty/src/stty.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ struct WrappedPrinter {
500500
}
501501

502502
impl WrappedPrinter {
503-
fn new(term_size: &Option<TermSize>) -> Self {
503+
fn new(term_size: Option<&TermSize>) -> Self {
504504
let columns = match term_size {
505505
Some(term_size) => term_size.columns,
506506
None => {
@@ -549,8 +549,8 @@ impl WrappedPrinter {
549549
fn print_terminal_size(
550550
termios: &Termios,
551551
opts: &Options,
552-
window_size: &Option<TermSize>,
553-
term_size: &Option<TermSize>,
552+
window_size: Option<&TermSize>,
553+
term_size: Option<&TermSize>,
554554
) -> nix::Result<()> {
555555
let speed = cfgetospeed(termios);
556556
let mut printer = WrappedPrinter::new(window_size);
@@ -769,7 +769,7 @@ fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result<String> {
769769
fn print_control_chars(
770770
termios: &Termios,
771771
opts: &Options,
772-
term_size: &Option<TermSize>,
772+
term_size: Option<&TermSize>,
773773
) -> nix::Result<()> {
774774
if !opts.all {
775775
// Print only control chars that differ from sane defaults
@@ -825,8 +825,7 @@ fn print_settings(termios: &Termios, opts: &Options) -> nix::Result<()> {
825825
let device_fd = opts.file.as_raw_fd();
826826
let term_size = {
827827
let mut term_size = TermSize::default();
828-
let term_size =
829-
unsafe { tiocgwinsz(device_fd, &raw mut term_size) }.map(|_| term_size);
828+
let term_size = unsafe { tiocgwinsz(device_fd, &raw mut term_size) }.map(|_| term_size);
830829
if opts.all {
831830
Some(term_size?)
832831
} else {
@@ -835,21 +834,21 @@ fn print_settings(termios: &Termios, opts: &Options) -> nix::Result<()> {
835834
};
836835

837836
let stdout_fd = stdout().as_raw_fd();
838-
let window_size = if device_fd != stdout_fd {
837+
let window_size = if device_fd == stdout_fd {
838+
&term_size
839+
} else {
839840
let mut term_size = TermSize::default();
840841
&unsafe { tiocgwinsz(stdout_fd, &raw mut term_size) }
841842
.map(|_| term_size)
842843
.ok()
843-
} else {
844-
&term_size
845844
};
846845

847-
print_terminal_size(termios, opts, &window_size, &term_size)?;
848-
print_control_chars(termios, opts, &window_size)?;
849-
print_flags(termios, opts, CONTROL_FLAGS, &window_size);
850-
print_flags(termios, opts, INPUT_FLAGS, &window_size);
851-
print_flags(termios, opts, OUTPUT_FLAGS, &window_size);
852-
print_flags(termios, opts, LOCAL_FLAGS, &window_size);
846+
print_terminal_size(termios, opts, window_size.as_ref(), term_size.as_ref())?;
847+
print_control_chars(termios, opts, window_size.as_ref())?;
848+
print_flags(termios, opts, CONTROL_FLAGS, window_size.as_ref());
849+
print_flags(termios, opts, INPUT_FLAGS, window_size.as_ref());
850+
print_flags(termios, opts, OUTPUT_FLAGS, window_size.as_ref());
851+
print_flags(termios, opts, LOCAL_FLAGS, window_size.as_ref());
853852
}
854853
Ok(())
855854
}
@@ -858,7 +857,7 @@ fn print_flags<T: TermiosFlag>(
858857
termios: &Termios,
859858
opts: &Options,
860859
flags: &[Flag<T>],
861-
term_size: &Option<TermSize>,
860+
term_size: Option<&TermSize>,
862861
) {
863862
let mut printer = WrappedPrinter::new(term_size);
864863
for &Flag {

tests/by-util/test_stty.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,59 @@ fn non_negatable_combo() {
349349
.fails()
350350
.stderr_contains("invalid argument '-ek'");
351351
}
352+
353+
#[test]
354+
#[cfg(unix)]
355+
fn test_columns_env_wrapping() {
356+
let (path, _controller, _replica) = pty_path();
357+
358+
// Must pipe output so stty uses COLUMNS env instead of actual terminal size
359+
for (columns, max_len) in [(20, 20), (40, 40), (50, 50)] {
360+
let result = new_ucmd!()
361+
.args(&["--all", "--file", &path])
362+
.env("COLUMNS", columns.to_string())
363+
.set_stdout(Stdio::piped())
364+
.succeeds();
365+
366+
for line in result.stdout_str().lines() {
367+
assert!(
368+
line.len() <= max_len,
369+
"Line exceeds COLUMNS={columns}: '{line}'"
370+
);
371+
}
372+
}
373+
374+
// Wide columns should allow longer lines
375+
let result = new_ucmd!()
376+
.args(&["--all", "--file", &path])
377+
.env("COLUMNS", "200")
378+
.set_stdout(Stdio::piped())
379+
.succeeds();
380+
let has_long_line = result.stdout_str().lines().any(|line| line.len() > 80);
381+
assert!(
382+
has_long_line,
383+
"Expected at least one line longer than 80 chars with COLUMNS=200"
384+
);
385+
386+
// Invalid values should fall back to default
387+
for invalid in ["invalid", "0", "-10"] {
388+
new_ucmd!()
389+
.args(&["--all", "--file", &path])
390+
.env("COLUMNS", invalid)
391+
.set_stdout(Stdio::piped())
392+
.succeeds();
393+
}
394+
395+
// Without --all flag
396+
let result = new_ucmd!()
397+
.args(&["--file", &path])
398+
.env("COLUMNS", "30")
399+
.set_stdout(Stdio::piped())
400+
.succeeds();
401+
for line in result.stdout_str().lines() {
402+
assert!(
403+
line.len() <= 30,
404+
"Line exceeds COLUMNS=30 without --all: '{line}'"
405+
);
406+
}
407+
}

0 commit comments

Comments
 (0)