mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 09:12:11 +08:00
Move termsize test into separate file
This commit is contained in:
parent
99ffa4567a
commit
5c5ab4f179
@ -3,8 +3,6 @@ use crate::common::assert_sync;
|
||||
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 @@ impl Termsize {
|
||||
}
|
||||
}
|
||||
|
||||
struct TermsizeData {
|
||||
/// Exposed for testing.
|
||||
pub(crate) struct TermsizeData {
|
||||
// The last termsize returned by TIOCGWINSZ, or none if none.
|
||||
last_from_tty: Option<Termsize>,
|
||||
// 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 @@ impl TermsizeData {
|
||||
/// SIGWINCH.
|
||||
pub struct TermsizeContainer {
|
||||
// Our lock-protected data.
|
||||
data: Mutex<TermsizeData>,
|
||||
/// Exposed for testing.
|
||||
pub(crate) data: Mutex<TermsizeData>,
|
||||
|
||||
// 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<Termsize>,
|
||||
/// Exposed for testing.
|
||||
pub(crate) tty_size_reader: fn() -> Option<Termsize>,
|
||||
}
|
||||
|
||||
impl TermsizeContainer {
|
||||
@ -203,7 +205,8 @@ impl TermsizeContainer {
|
||||
}
|
||||
|
||||
/// 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<Option<Termsize>> = Mutex::new(None);
|
||||
fn stubby_termsize() -> Option<Termsize> {
|
||||
*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());
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ mod redirection;
|
||||
mod screen;
|
||||
mod std;
|
||||
mod string_escape;
|
||||
mod termsize;
|
||||
mod threads;
|
||||
mod tokenizer;
|
||||
mod topic_monitor;
|
||||
|
85
src/tests/termsize.rs
Normal file
85
src/tests/termsize.rs
Normal file
@ -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<Option<Termsize>> = Mutex::new(None);
|
||||
fn stubby_termsize() -> Option<Termsize> {
|
||||
*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());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user