From 5c5ab4f179a975ec359ad9a01e959413fbf9c707 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 23 Mar 2024 17:22:52 +0100 Subject: [PATCH] Move termsize test into separate file --- src/termsize.rs | 97 +++++-------------------------------------- src/tests/mod.rs | 1 + src/tests/termsize.rs | 85 +++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 86 deletions(-) create mode 100644 src/tests/termsize.rs diff --git a/src/termsize.rs b/src/termsize.rs index f9e8c947f..5bb9a4340 100644 --- a/src/termsize.rs +++ b/src/termsize.rs @@ -3,8 +3,6 @@ use crate::env::{EnvMode, EnvVar, Environment}; use crate::flog::FLOG; use crate::parser::Parser; -#[cfg(test)] -use crate::tests::prelude::*; use crate::wchar::prelude::*; use crate::wutil::fish_wcstoi; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; @@ -83,7 +81,8 @@ pub fn defaults() -> Self { } } -struct TermsizeData { +/// Exposed for testing. +pub(crate) struct TermsizeData { // The last termsize returned by TIOCGWINSZ, or none if none. last_from_tty: Option, // The last termsize seen from the environment (COLUMNS/LINES), or none if none. @@ -94,7 +93,7 @@ struct TermsizeData { } impl TermsizeData { - const fn defaults() -> Self { + pub(crate) const fn defaults() -> Self { Self { last_from_tty: None, last_from_env: None, @@ -126,14 +125,17 @@ fn mark_override_from_env(&mut self, ts: Termsize) { /// SIGWINCH. pub struct TermsizeContainer { // Our lock-protected data. - data: Mutex, + /// Exposed for testing. + pub(crate) data: Mutex, // An indication that we are currently in the process of setting COLUMNS and LINES, and so do // not react to any changes. - setting_env_vars: AtomicBool, + /// Exposed for testing. + pub(crate) setting_env_vars: AtomicBool, /// A function used for accessing the termsize from the tty. This is only exposed for testing. - tty_size_reader: fn() -> Option, + /// Exposed for testing. + pub(crate) tty_size_reader: fn() -> Option, } impl TermsizeContainer { @@ -203,7 +205,8 @@ fn set_columns_lines_vars(&self, val: Termsize, parser: &Parser) { } /// Note that COLUMNS and/or LINES global variables changed. - fn handle_columns_lines_var_change(&self, vars: &dyn Environment) { + /// Exposed for testing. + pub(crate) fn handle_columns_lines_var_change(&self, vars: &dyn Environment) { // Do nothing if we are the ones setting it. if self.setting_env_vars.load(Ordering::Relaxed) { return; @@ -270,81 +273,3 @@ pub fn termsize_update(parser: &Parser) -> Termsize { pub fn termsize_invalidate_tty() { TermsizeContainer::invalidate_tty(); } - -#[test] -#[serial] -fn test_termsize() { - test_init(); - let env_global = EnvMode::GLOBAL; - let parser = Parser::principal_parser(); - let vars = parser.vars(); - - // Use a static variable so we can pretend we're the kernel exposing a terminal size. - static STUBBY_TERMSIZE: Mutex> = Mutex::new(None); - fn stubby_termsize() -> Option { - *STUBBY_TERMSIZE.lock().unwrap() - } - let ts = TermsizeContainer { - data: Mutex::new(TermsizeData::defaults()), - setting_env_vars: AtomicBool::new(false), - tty_size_reader: stubby_termsize, - }; - - // Initially default value. - assert_eq!(ts.last(), Termsize::defaults()); - - // Haha we change the value, it doesn't even know. - *STUBBY_TERMSIZE.lock().unwrap() = Some(Termsize { - width: 42, - height: 84, - }); - assert_eq!(ts.last(), Termsize::defaults()); - - // Ok let's tell it. But it still doesn't update right away. - TermsizeContainer::handle_winch(); - assert_eq!(ts.last(), Termsize::defaults()); - - // Ok now we tell it to update. - ts.updating(parser); - assert_eq!(ts.last(), Termsize::new(42, 84)); - assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "42"); - assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "84"); - - // Wow someone set COLUMNS and LINES to a weird value. - // Now the tty's termsize doesn't matter. - vars.set_one(L!("COLUMNS"), env_global, L!("75").to_owned()); - vars.set_one(L!("LINES"), env_global, L!("150").to_owned()); - ts.handle_columns_lines_var_change(parser.vars()); - assert_eq!(ts.last(), Termsize::new(75, 150)); - assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "75"); - assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "150"); - - vars.set_one(L!("COLUMNS"), env_global, L!("33").to_owned()); - ts.handle_columns_lines_var_change(parser.vars()); - assert_eq!(ts.last(), Termsize::new(33, 150)); - - // Oh it got SIGWINCH, now the tty matters again. - TermsizeContainer::handle_winch(); - assert_eq!(ts.last(), Termsize::new(33, 150)); - assert_eq!(ts.updating(parser), stubby_termsize().unwrap()); - assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "42"); - assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "84"); - - // Test initialize(). - vars.set_one(L!("COLUMNS"), env_global, L!("83").to_owned()); - vars.set_one(L!("LINES"), env_global, L!("38").to_owned()); - ts.initialize(vars); - assert_eq!(ts.last(), Termsize::new(83, 38)); - - // initialize() even beats the tty reader until a sigwinch. - let ts2 = TermsizeContainer { - data: Mutex::new(TermsizeData::defaults()), - setting_env_vars: AtomicBool::new(false), - tty_size_reader: stubby_termsize, - }; - ts.initialize(parser.vars()); - ts2.updating(parser); - assert_eq!(ts.last(), Termsize::new(83, 38)); - TermsizeContainer::handle_winch(); - assert_eq!(ts2.updating(parser), stubby_termsize().unwrap()); -} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 61c68ab55..7c9d5111f 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -20,6 +20,7 @@ mod screen; mod std; mod string_escape; +mod termsize; mod threads; mod tokenizer; mod topic_monitor; diff --git a/src/tests/termsize.rs b/src/tests/termsize.rs new file mode 100644 index 000000000..2c22186bc --- /dev/null +++ b/src/tests/termsize.rs @@ -0,0 +1,85 @@ +use crate::env::{EnvMode, Environment}; +use crate::parser::Parser; +use crate::termsize::*; +use crate::tests::prelude::*; +use crate::wchar::prelude::*; +use std::sync::atomic::AtomicBool; +use std::sync::Mutex; + +#[test] +#[serial] +fn test_termsize() { + test_init(); + let env_global = EnvMode::GLOBAL; + let parser = Parser::principal_parser(); + let vars = parser.vars(); + + // Use a static variable so we can pretend we're the kernel exposing a terminal size. + static STUBBY_TERMSIZE: Mutex> = Mutex::new(None); + fn stubby_termsize() -> Option { + *STUBBY_TERMSIZE.lock().unwrap() + } + let ts = TermsizeContainer { + data: Mutex::new(TermsizeData::defaults()), + setting_env_vars: AtomicBool::new(false), + tty_size_reader: stubby_termsize, + }; + + // Initially default value. + assert_eq!(ts.last(), Termsize::defaults()); + + // Haha we change the value, it doesn't even know. + *STUBBY_TERMSIZE.lock().unwrap() = Some(Termsize { + width: 42, + height: 84, + }); + assert_eq!(ts.last(), Termsize::defaults()); + + // Ok let's tell it. But it still doesn't update right away. + TermsizeContainer::handle_winch(); + assert_eq!(ts.last(), Termsize::defaults()); + + // Ok now we tell it to update. + ts.updating(parser); + assert_eq!(ts.last(), Termsize::new(42, 84)); + assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "42"); + assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "84"); + + // Wow someone set COLUMNS and LINES to a weird value. + // Now the tty's termsize doesn't matter. + vars.set_one(L!("COLUMNS"), env_global, L!("75").to_owned()); + vars.set_one(L!("LINES"), env_global, L!("150").to_owned()); + ts.handle_columns_lines_var_change(parser.vars()); + assert_eq!(ts.last(), Termsize::new(75, 150)); + assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "75"); + assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "150"); + + vars.set_one(L!("COLUMNS"), env_global, L!("33").to_owned()); + ts.handle_columns_lines_var_change(parser.vars()); + assert_eq!(ts.last(), Termsize::new(33, 150)); + + // Oh it got SIGWINCH, now the tty matters again. + TermsizeContainer::handle_winch(); + assert_eq!(ts.last(), Termsize::new(33, 150)); + assert_eq!(ts.updating(parser), stubby_termsize().unwrap()); + assert_eq!(vars.get(L!("COLUMNS")).unwrap().as_string(), "42"); + assert_eq!(vars.get(L!("LINES")).unwrap().as_string(), "84"); + + // Test initialize(). + vars.set_one(L!("COLUMNS"), env_global, L!("83").to_owned()); + vars.set_one(L!("LINES"), env_global, L!("38").to_owned()); + ts.initialize(vars); + assert_eq!(ts.last(), Termsize::new(83, 38)); + + // initialize() even beats the tty reader until a sigwinch. + let ts2 = TermsizeContainer { + data: Mutex::new(TermsizeData::defaults()), + setting_env_vars: AtomicBool::new(false), + tty_size_reader: stubby_termsize, + }; + ts.initialize(parser.vars()); + ts2.updating(parser); + assert_eq!(ts.last(), Termsize::new(83, 38)); + TermsizeContainer::handle_winch(); + assert_eq!(ts2.updating(parser), stubby_termsize().unwrap()); +}