pub struct TestTerminal { /* private fields */ }Expand description
A test terminal backed by a pseudo-terminal (PTY).
This provides low-level access to PTY operations for spawning processes, reading output, and sending input.
Implementations§
Source§impl TestTerminal
impl TestTerminal
Sourcepub fn new(width: u16, height: u16) -> Result<Self>
pub fn new(width: u16, height: u16) -> Result<Self>
Creates a new test terminal with the specified dimensions.
§Arguments
width- Terminal width in columnsheight- Terminal height in rows
§Errors
Returns an error if:
- Terminal dimensions are invalid (zero or too large)
- PTY creation fails
§Example
use ratatui_testlib::TestTerminal;
let terminal = TestTerminal::new(80, 24)?;Sourcepub fn with_buffer_size(self, size: usize) -> Self
pub fn with_buffer_size(self, size: usize) -> Self
Sourcepub fn spawn(&mut self, cmd: CommandBuilder) -> Result<()>
pub fn spawn(&mut self, cmd: CommandBuilder) -> Result<()>
Spawns a process in the PTY with default timeout.
§Arguments
cmd- Command to spawn
§Errors
Returns an error if:
- A process is already running
- Process spawn fails
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
let mut terminal = TestTerminal::new(80, 24)?;
let mut cmd = CommandBuilder::new("ls");
cmd.arg("-la");
terminal.spawn(cmd)?;Sourcepub fn spawn_with_timeout(
&mut self,
cmd: CommandBuilder,
timeout: Duration,
) -> Result<()>
pub fn spawn_with_timeout( &mut self, cmd: CommandBuilder, timeout: Duration, ) -> Result<()>
Spawns a process in the PTY with a specified timeout.
This method supports the full CommandBuilder API including arguments, environment variables, and working directory.
§Arguments
cmd- Command to spawn (with args, env, cwd configured)timeout- Maximum time to wait for spawn to complete
§Errors
Returns an error if:
- A process is already running
- Process spawn fails
- Spawn operation times out
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
use std::time::Duration;
let mut terminal = TestTerminal::new(80, 24)?;
let mut cmd = CommandBuilder::new("bash");
cmd.arg("-c").arg("echo $TEST_VAR");
cmd.env("TEST_VAR", "hello");
terminal.spawn_with_timeout(cmd, Duration::from_secs(3))?;Sourcepub fn read(&mut self, buf: &mut [u8]) -> Result<usize>
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize>
Reads available output from the PTY.
This is a non-blocking read that returns immediately with whatever data is available. Handles EAGAIN/EWOULDBLOCK and EINTR gracefully.
§Arguments
buf- Buffer to read into
§Errors
Returns an error if the read operation fails (excluding EAGAIN/EWOULDBLOCK).
§Example
use ratatui_testlib::TestTerminal;
let mut terminal = TestTerminal::new(80, 24)?;
let mut buf = [0u8; 1024];
match terminal.read(&mut buf) {
Ok(0) => println!("No data available"),
Ok(n) => println!("Read {} bytes", n),
Err(e) => eprintln!("Read error: {}", e),
}Sourcepub fn read_timeout(
&mut self,
buf: &mut [u8],
timeout: Duration,
) -> Result<usize>
pub fn read_timeout( &mut self, buf: &mut [u8], timeout: Duration, ) -> Result<usize>
Reads output from the PTY with a timeout.
This method polls for data until either:
- Data is available and read
- The timeout expires
§Arguments
buf- Buffer to read intotimeout- Maximum time to wait for data
§Errors
Returns an error if:
- The timeout expires without reading data
- A read error occurs
§Example
use ratatui_testlib::TestTerminal;
use std::time::Duration;
let mut terminal = TestTerminal::new(80, 24)?;
let mut buf = [0u8; 1024];
let n = terminal.read_timeout(&mut buf, Duration::from_secs(1))?;
println!("Read {} bytes", n);Sourcepub fn read_all(&mut self) -> Result<Vec<u8>>
pub fn read_all(&mut self) -> Result<Vec<u8>>
Reads all available output from the PTY into a buffer.
This method performs buffered reading with a configurable buffer size. It reads until no more data is immediately available.
§Errors
Returns an error if a read operation fails.
§Example
use ratatui_testlib::TestTerminal;
let mut terminal = TestTerminal::new(80, 24)?;
let output = terminal.read_all()?;
println!("Output: {}", String::from_utf8_lossy(&output));Sourcepub fn write(&mut self, data: &[u8]) -> Result<usize>
pub fn write(&mut self, data: &[u8]) -> Result<usize>
Writes data to the PTY (sends input to the process).
Handles EINTR (interrupted system calls) gracefully by retrying.
§Arguments
data- Data to write
§Errors
Returns an error if the write operation fails.
§Example
use ratatui_testlib::TestTerminal;
let mut terminal = TestTerminal::new(80, 24)?;
terminal.write(b"hello\n")?;Sourcepub fn is_running(&mut self) -> bool
pub fn is_running(&mut self) -> bool
Checks if the child process is still running.
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
let mut terminal = TestTerminal::new(80, 24)?;
let cmd = CommandBuilder::new("sleep");
terminal.spawn(cmd)?;
assert!(terminal.is_running());Sourcepub fn kill(&mut self) -> Result<()>
pub fn kill(&mut self) -> Result<()>
Kills the child process.
This method first attempts to terminate the process gracefully (SIGTERM), then forcefully kills it (SIGKILL) if needed.
§Errors
Returns an error if no process is running or if the kill operation fails.
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
let mut terminal = TestTerminal::new(80, 24)?;
let cmd = CommandBuilder::new("sleep");
terminal.spawn(cmd)?;
terminal.kill()?;Sourcepub fn wait(&mut self) -> Result<ExitStatus>
pub fn wait(&mut self) -> Result<ExitStatus>
Waits for the child process to exit and returns its exit status.
§Errors
Returns an error if no process is running.
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
let mut terminal = TestTerminal::new(80, 24)?;
let mut cmd = CommandBuilder::new("echo");
cmd.arg("hello");
terminal.spawn(cmd)?;
let status = terminal.wait()?;Sourcepub fn wait_timeout(&mut self, timeout: Duration) -> Result<ExitStatus>
pub fn wait_timeout(&mut self, timeout: Duration) -> Result<ExitStatus>
Waits for the child process to exit with a timeout.
§Arguments
timeout- Maximum time to wait for process exit
§Errors
Returns an error if:
- No process is running
- The timeout expires before the process exits
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
use std::time::Duration;
let mut terminal = TestTerminal::new(80, 24)?;
let mut cmd = CommandBuilder::new("echo");
cmd.arg("hello");
terminal.spawn(cmd)?;
let status = terminal.wait_timeout(Duration::from_secs(5))?;Sourcepub fn get_exit_status(&self) -> Option<ExitStatus>
pub fn get_exit_status(&self) -> Option<ExitStatus>
Returns the cached exit status of the child process, if available.
This returns the exit status if the process has already exited.
Call is_running() or wait() to update the status.
§Example
use ratatui_testlib::TestTerminal;
use portable_pty::CommandBuilder;
let mut terminal = TestTerminal::new(80, 24)?;
let cmd = CommandBuilder::new("echo");
terminal.spawn(cmd)?;
terminal.wait()?;
if let Some(status) = terminal.get_exit_status() {
println!("Process exited with status: {:?}", status);
}Trait Implementations§
Auto Trait Implementations§
impl Freeze for TestTerminal
impl !RefUnwindSafe for TestTerminal
impl Send for TestTerminal
impl !Sync for TestTerminal
impl Unpin for TestTerminal
impl !UnwindSafe for TestTerminal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.