Skip to content

Commit 8c2fa63

Browse files
committed
Adding integration tests for the COLUMNS env variable support in stty
1 parent c13d396 commit 8c2fa63

File tree

2 files changed

+73
-17
lines changed

2 files changed

+73
-17
lines changed

src/uu/stty/src/stty.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ struct WrappedPrinter {
546546
}
547547

548548
impl WrappedPrinter {
549-
fn new(term_size: &Option<TermSize>) -> Self {
549+
fn new(term_size: Option<&TermSize>) -> Self {
550550
let columns = match term_size {
551551
Some(term_size) => term_size.columns,
552552
None => {
@@ -595,8 +595,8 @@ impl WrappedPrinter {
595595
fn print_terminal_size(
596596
termios: &Termios,
597597
opts: &Options,
598-
window_size: &Option<TermSize>,
599-
term_size: &Option<TermSize>,
598+
window_size: Option<&TermSize>,
599+
term_size: Option<&TermSize>,
600600
) -> nix::Result<()> {
601601
let speed = cfgetospeed(termios);
602602
let mut printer = WrappedPrinter::new(window_size);
@@ -610,7 +610,7 @@ fn print_terminal_size(
610610
target_os = "netbsd",
611611
target_os = "openbsd"
612612
))]
613-
print!("{} ", translate!("stty-output-speed", "speed" => speed));
613+
printer.print(&translate!("stty-output-speed", "speed" => speed));
614614

615615
// Other platforms need to use the baud rate enum, so printing the right value
616616
// becomes slightly more complicated.
@@ -815,7 +815,7 @@ fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result<String> {
815815
fn print_control_chars(
816816
termios: &Termios,
817817
opts: &Options,
818-
term_size: &Option<TermSize>,
818+
term_size: Option<&TermSize>,
819819
) -> nix::Result<()> {
820820
if !opts.all {
821821
// Print only control chars that differ from sane defaults
@@ -871,8 +871,7 @@ fn print_settings(termios: &Termios, opts: &Options) -> nix::Result<()> {
871871
let device_fd = opts.file.as_raw_fd();
872872
let term_size = {
873873
let mut term_size = TermSize::default();
874-
let term_size =
875-
unsafe { tiocgwinsz(device_fd, &raw mut term_size) }.map(|_| term_size);
874+
let term_size = unsafe { tiocgwinsz(device_fd, &raw mut term_size) }.map(|_| term_size);
876875
if opts.all {
877876
Some(term_size?)
878877
} else {
@@ -881,21 +880,21 @@ fn print_settings(termios: &Termios, opts: &Options) -> nix::Result<()> {
881880
};
882881

883882
let stdout_fd = stdout().as_raw_fd();
884-
let window_size = if device_fd != stdout_fd {
883+
let window_size = if device_fd == stdout_fd {
884+
&term_size
885+
} else {
885886
let mut term_size = TermSize::default();
886887
&unsafe { tiocgwinsz(stdout_fd, &raw mut term_size) }
887888
.map(|_| term_size)
888889
.ok()
889-
} else {
890-
&term_size
891890
};
892891

893-
print_terminal_size(termios, opts, &window_size, &term_size)?;
894-
print_control_chars(termios, opts, &window_size)?;
895-
print_flags(termios, opts, CONTROL_FLAGS, &window_size);
896-
print_flags(termios, opts, INPUT_FLAGS, &window_size);
897-
print_flags(termios, opts, OUTPUT_FLAGS, &window_size);
898-
print_flags(termios, opts, LOCAL_FLAGS, &window_size);
892+
print_terminal_size(termios, opts, window_size.as_ref(), term_size.as_ref())?;
893+
print_control_chars(termios, opts, window_size.as_ref())?;
894+
print_flags(termios, opts, CONTROL_FLAGS, window_size.as_ref());
895+
print_flags(termios, opts, INPUT_FLAGS, window_size.as_ref());
896+
print_flags(termios, opts, OUTPUT_FLAGS, window_size.as_ref());
897+
print_flags(termios, opts, LOCAL_FLAGS, window_size.as_ref());
899898
}
900899
Ok(())
901900
}
@@ -904,7 +903,7 @@ fn print_flags<T: TermiosFlag>(
904903
termios: &Termios,
905904
opts: &Options,
906905
flags: &[Flag<T>],
907-
term_size: &Option<TermSize>,
906+
term_size: Option<&TermSize>,
908907
) {
909908
let mut printer = WrappedPrinter::new(term_size);
910909
for &Flag {

tests/by-util/test_stty.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,60 @@ fn test_saved_state_with_control_chars() {
526526
.stderr_is(exp_result.stderr_str())
527527
.code_is(exp_result.code());
528528
}
529+
530+
#[test]
531+
#[cfg(unix)]
532+
fn test_columns_env_wrapping() {
533+
use std::process::Stdio;
534+
let (path, _controller, _replica) = pty_path();
535+
536+
// Must pipe output so stty uses COLUMNS env instead of actual terminal size
537+
for (columns, max_len) in [(20, 20), (40, 40), (50, 50)] {
538+
let result = new_ucmd!()
539+
.args(&["--all", "--file", &path])
540+
.env("COLUMNS", columns.to_string())
541+
.set_stdout(Stdio::piped())
542+
.succeeds();
543+
544+
for line in result.stdout_str().lines() {
545+
assert!(
546+
line.len() <= max_len,
547+
"Line exceeds COLUMNS={columns}: '{line}'"
548+
);
549+
}
550+
}
551+
552+
// Wide columns should allow longer lines
553+
let result = new_ucmd!()
554+
.args(&["--all", "--file", &path])
555+
.env("COLUMNS", "200")
556+
.set_stdout(Stdio::piped())
557+
.succeeds();
558+
let has_long_line = result.stdout_str().lines().any(|line| line.len() > 80);
559+
assert!(
560+
has_long_line,
561+
"Expected at least one line longer than 80 chars with COLUMNS=200"
562+
);
563+
564+
// Invalid values should fall back to default
565+
for invalid in ["invalid", "0", "-10"] {
566+
new_ucmd!()
567+
.args(&["--all", "--file", &path])
568+
.env("COLUMNS", invalid)
569+
.set_stdout(Stdio::piped())
570+
.succeeds();
571+
}
572+
573+
// Without --all flag
574+
let result = new_ucmd!()
575+
.args(&["--file", &path])
576+
.env("COLUMNS", "30")
577+
.set_stdout(Stdio::piped())
578+
.succeeds();
579+
for line in result.stdout_str().lines() {
580+
assert!(
581+
line.len() <= 30,
582+
"Line exceeds COLUMNS=30 without --all: '{line}'"
583+
);
584+
}
585+
}

0 commit comments

Comments
 (0)