Skip to content

Commit bf1f813

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

File tree

2 files changed

+72
-16
lines changed

2 files changed

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

0 commit comments

Comments
 (0)