mod common;
use multiline_input::
{
builder::Builder,
error::Error,
};
use common::mock_terminal::MockTerminal;
use crossterm::event::{ KeyCode, KeyModifiers };
#[ test ]
fn test_error_no_tty()
{
let terminal = MockTerminal::new( false, ( 80, 24 ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
assert!( matches!( result, Err( Error::NoTty ) ), "Expected NoTty error, got {:?}", result );
}
#[ test ]
fn test_error_no_tty_message()
{
let error = Error::NoTty;
let message = format!( "{}", error );
assert!( message.contains( "TTY" ) || message.contains( "terminal" ), "Error message should mention TTY: {}", message );
}
#[ test ]
fn test_error_terminal_too_narrow()
{
let mut terminal = MockTerminal::new( true, ( 19, 24 ) );
terminal.push_key( common::mock_terminal::key( KeyCode::Char( 'a' ), KeyModifiers::NONE ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
match result
{
Err( Error::TerminalTooSmall { width, height, min_width, min_height } ) =>
{
assert_eq!( width, 19, "Should report actual width" );
assert_eq!( height, 24, "Should report actual height" );
assert_eq!( min_width, 20, "Should report required minimum width" );
assert_eq!( min_height, 3, "Should report required minimum height" );
}
other => panic!( "Expected TerminalTooSmall error, got {:?}", other ),
}
}
#[ test ]
fn test_error_terminal_too_short()
{
let mut terminal = MockTerminal::new( true, ( 80, 2 ) );
terminal.push_key( common::mock_terminal::key( KeyCode::Char( 'a' ), KeyModifiers::NONE ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
match result
{
Err( Error::TerminalTooSmall { width, height, min_width, min_height } ) =>
{
assert_eq!( width, 80, "Should report actual width" );
assert_eq!( height, 2, "Should report actual height" );
assert_eq!( min_width, 20, "Should report required minimum width" );
assert_eq!( min_height, 3, "Should report required minimum height" );
}
other => panic!( "Expected TerminalTooSmall error, got {:?}", other ),
}
}
#[ test ]
fn test_error_terminal_too_small_both()
{
let mut terminal = MockTerminal::new( true, ( 10, 1 ) );
terminal.push_key( common::mock_terminal::key( KeyCode::Char( 'a' ), KeyModifiers::NONE ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
match result
{
Err( Error::TerminalTooSmall { width, height, .. } ) =>
{
assert_eq!( width, 10, "Should report actual width" );
assert_eq!( height, 1, "Should report actual height" );
}
other => panic!( "Expected TerminalTooSmall error, got {:?}", other ),
}
}
#[ test ]
fn test_terminal_exactly_minimum_size()
{
let mut terminal = MockTerminal::new( true, ( 20, 3 ) );
terminal.push_key( common::mock_terminal::key( KeyCode::Char( 'a' ), KeyModifiers::NONE ) );
terminal.push_key( common::mock_terminal::key( KeyCode::Enter, KeyModifiers::NONE ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
assert!( result.is_ok(), "Minimum size (20x3) should be sufficient, got {:?}", result );
assert_eq!( result.unwrap(), Some( "a".to_string() ) );
}
#[ test ]
fn test_error_terminal_too_small_message()
{
let error = Error::TerminalTooSmall
{
width: 10,
height: 2,
min_width: 20,
min_height: 3,
};
let message = format!( "{}", error );
assert!( message.contains( "10" ), "Should mention actual width: {}", message );
assert!( message.contains( "2" ), "Should mention actual height: {}", message );
assert!( message.contains( "20" ), "Should mention required width: {}", message );
assert!( message.contains( "3" ), "Should mention required height: {}", message );
}
#[ test ]
fn test_error_raw_mode_enable_non_tty()
{
let terminal = MockTerminal::new( false, ( 80, 24 ) );
let editor = Builder::new().build_with( terminal );
let result = editor.collect();
assert!( matches!( result, Err( Error::NoTty ) ), "Expected NoTty error, got {:?}", result );
}
#[ test ]
fn test_error_display_all_variants()
{
let no_tty = Error::NoTty;
let msg = format!( "{}", no_tty );
assert!( !msg.is_empty(), "NoTty error should have non-empty message" );
let too_small = Error::TerminalTooSmall { width: 10, height: 2, min_width: 20, min_height: 3 };
let msg = format!( "{}", too_small );
assert!( !msg.is_empty(), "TerminalTooSmall error should have non-empty message" );
let io_error = Error::Io( std::io::Error::new( std::io::ErrorKind::BrokenPipe, "test" ) );
let msg = format!( "{}", io_error );
assert!( !msg.is_empty(), "Io error should have non-empty message" );
let validation_error = Error::ValidationFailed( "test validation".to_string() );
let msg = format!( "{}", validation_error );
assert!( msg.contains( "test validation" ), "ValidationFailed should include custom message" );
}
#[ test ]
fn test_error_source()
{
use std::error::Error as StdError;
let inner = std::io::Error::new( std::io::ErrorKind::BrokenPipe, "pipe broken" );
let error = Error::Io( inner );
let source = error.source();
assert!( source.is_some(), "Error::Io should have source" );
}