Fix bug on multiple simultaneous input + tests
This commit is contained in:
parent
494f89daef
commit
0c8c6d4f0c
@ -418,82 +418,3 @@ impl_display!(for Show);
|
||||
impl_display!(for EnableBlinking);
|
||||
impl_display!(for DisableBlinking);
|
||||
impl_display!(for SetCursorStyle);
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "events")]
|
||||
mod tests {
|
||||
use std::io::{self, stdout};
|
||||
|
||||
use crate::execute;
|
||||
|
||||
use super::{
|
||||
sys::position, MoveDown, MoveLeft, MoveRight, MoveTo, MoveUp, RestorePosition, SavePosition,
|
||||
};
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_move_to() {
|
||||
let (saved_x, saved_y) = position().unwrap();
|
||||
|
||||
execute!(stdout(), MoveTo(saved_x + 1, saved_y + 1)).unwrap();
|
||||
assert_eq!(position().unwrap(), (saved_x + 1, saved_y + 1));
|
||||
|
||||
execute!(stdout(), MoveTo(saved_x, saved_y)).unwrap();
|
||||
assert_eq!(position().unwrap(), (saved_x, saved_y));
|
||||
}
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_move_right() {
|
||||
let (saved_x, saved_y) = position().unwrap();
|
||||
execute!(io::stdout(), MoveRight(1)).unwrap();
|
||||
assert_eq!(position().unwrap(), (saved_x + 1, saved_y));
|
||||
}
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_move_left() {
|
||||
execute!(stdout(), MoveTo(2, 0), MoveLeft(2)).unwrap();
|
||||
assert_eq!(position().unwrap(), (0, 0));
|
||||
}
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_move_up() {
|
||||
execute!(stdout(), MoveTo(0, 2), MoveUp(2)).unwrap();
|
||||
assert_eq!(position().unwrap(), (0, 0));
|
||||
}
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_move_down() {
|
||||
execute!(stdout(), MoveTo(0, 0), MoveDown(2)).unwrap();
|
||||
|
||||
assert_eq!(position().unwrap(), (0, 2));
|
||||
}
|
||||
|
||||
// Test is disabled, because it's failing on Travis
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_save_restore_position() {
|
||||
let (saved_x, saved_y) = position().unwrap();
|
||||
|
||||
execute!(
|
||||
stdout(),
|
||||
SavePosition,
|
||||
MoveTo(saved_x + 1, saved_y + 1),
|
||||
RestorePosition
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let (x, y) = position().unwrap();
|
||||
|
||||
assert_eq!(x, saved_x);
|
||||
assert_eq!(y, saved_y);
|
||||
}
|
||||
}
|
||||
|
110
src/event.rs
110
src/event.rs
@ -928,6 +928,41 @@ impl Display for KeyCode {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TerminalState {
|
||||
char_buffer: VecDeque<u8>,
|
||||
}
|
||||
|
||||
impl TerminalState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
char_buffer: VecDeque::<u8>::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn events_for_input(&mut self, input: &[u8]) -> std::io::Result<Vec<Event>> {
|
||||
let mut result: Vec<Event> = Vec::new();
|
||||
|
||||
self.char_buffer.extend(input);
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
|
||||
loop {
|
||||
match self.char_buffer.pop_front() {
|
||||
None => return Ok(result),
|
||||
Some(c) => {
|
||||
buf.push(c);
|
||||
match parse_event(&buf, true)? {
|
||||
None => continue,
|
||||
Some(e) => {
|
||||
result.push(e);
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
@ -1035,36 +1070,51 @@ mod tests {
|
||||
assert_eq!(format!("{}", Modifier(RightAlt)), "Right Alt");
|
||||
assert_eq!(format!("{}", Modifier(RightSuper)), "Right Super");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TerminalState {
|
||||
char_buffer: VecDeque<u8>,
|
||||
}
|
||||
|
||||
impl TerminalState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
char_buffer: VecDeque::<u8>::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn events_for_input(&mut self, input: &[u8]) -> std::io::Result<Vec<Event>> {
|
||||
let mut result: Vec<Event> = Vec::new();
|
||||
|
||||
self.char_buffer.extend(input);
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
|
||||
loop {
|
||||
match self.char_buffer.pop_front() {
|
||||
None => return Ok(result),
|
||||
Some(c) => {
|
||||
buf.push(c);
|
||||
match parse_event(&buf, true)? {
|
||||
None => continue,
|
||||
Some(e) => result.push(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
pub fn terminalstate_event_parser_works() {
|
||||
let mut ts = TerminalState::new();
|
||||
use KeyEventKind::*;
|
||||
assert_eq!(
|
||||
ts.events_for_input(b"Hello\n").unwrap(),
|
||||
vec![
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('H'),
|
||||
modifiers: KeyModifiers::SHIFT,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
}),
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('e'),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
}),
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('l'),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
}),
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('l'),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
}),
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('o'),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
}),
|
||||
Event::Key(KeyEvent {
|
||||
code: Char('j'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
kind: Press,
|
||||
state: KeyEventState::NONE
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -52,19 +52,19 @@ impl Filter for EventFilter {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
super::Event, CursorPositionFilter, Event, EventFilter, Filter, InternalEventFilter,
|
||||
KeyboardEnhancementFlagsFilter, PrimaryDeviceAttributesFilter,
|
||||
super::Event, CursorPositionFilter, EventFilter, Filter, KeyboardEnhancementFlagsFilter,
|
||||
PrimaryDeviceAttributesFilter,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_cursor_position_filter_filters_cursor_position() {
|
||||
assert!(!CursorPositionFilter.eval(&Event::Event(Event::Resize(10, 10))));
|
||||
assert!(!CursorPositionFilter.eval(&Event::Resize(10, 10)));
|
||||
assert!(CursorPositionFilter.eval(&Event::CursorPosition(0, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keyboard_enhancement_status_filter_filters_keyboard_enhancement_status() {
|
||||
assert!(!KeyboardEnhancementFlagsFilter.eval(&Event::Event(Event::Resize(10, 10))));
|
||||
assert!(!KeyboardEnhancementFlagsFilter.eval(&Event::Resize(10, 10)));
|
||||
assert!(
|
||||
KeyboardEnhancementFlagsFilter.eval(&Event::KeyboardEnhancementFlags(
|
||||
crate::event::KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
|
||||
@ -75,19 +75,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_primary_device_attributes_filter_filters_primary_device_attributes() {
|
||||
assert!(!PrimaryDeviceAttributesFilter.eval(&Event::Event(Event::Resize(10, 10))));
|
||||
assert!(!PrimaryDeviceAttributesFilter.eval(&Event::Resize(10, 10)));
|
||||
assert!(PrimaryDeviceAttributesFilter.eval(&Event::PrimaryDeviceAttributes));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_event_filter_filters_events() {
|
||||
assert!(EventFilter.eval(&Event::Event(Event::Resize(10, 10))));
|
||||
assert!(!EventFilter.eval(&Event::CursorPosition(0, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_event_filter_filters_internal_events() {
|
||||
assert!(InternalEventFilter.eval(&Event::Event(Event::Resize(10, 10))));
|
||||
assert!(InternalEventFilter.eval(&Event::CursorPosition(0, 0)));
|
||||
assert!(EventFilter.eval(&Event::Resize(10, 10)));
|
||||
assert!(EventFilter.eval(&Event::CursorPosition(0, 0)));
|
||||
}
|
||||
}
|
||||
|
@ -125,49 +125,6 @@ impl fmt::Display for Colored {
|
||||
mod tests {
|
||||
use crate::style::{Color, Colored};
|
||||
|
||||
fn check_format_color(colored: Colored, expected: &str) {
|
||||
Colored::set_ansi_color_disabled(true);
|
||||
assert_eq!(colored.to_string(), "");
|
||||
Colored::set_ansi_color_disabled(false);
|
||||
assert_eq!(colored.to_string(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_color() {
|
||||
let colored = Colored::ForegroundColor(Color::Red);
|
||||
check_format_color(colored, "38;5;9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_bg_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Red);
|
||||
check_format_color(colored, "48;5;9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_reset_fg_color() {
|
||||
let colored = Colored::ForegroundColor(Color::Reset);
|
||||
check_format_color(colored, "39");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_reset_bg_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Reset);
|
||||
check_format_color(colored, "49");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_rgb_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Rgb { r: 1, g: 2, b: 3 });
|
||||
check_format_color(colored, "48;2;1;2;3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_ansi_color() {
|
||||
let colored = Colored::ForegroundColor(Color::AnsiValue(255));
|
||||
check_format_color(colored, "38;5;255");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_ansi_fg() {
|
||||
test_parse_ansi(Colored::ForegroundColor)
|
||||
@ -274,16 +231,4 @@ mod tests {
|
||||
test("48;2;0;2;25;");
|
||||
test("48;2;0;2;25;3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_color() {
|
||||
std::env::set_var("NO_COLOR", "1");
|
||||
assert!(Colored::ansi_color_disabled());
|
||||
std::env::set_var("NO_COLOR", "XXX");
|
||||
assert!(Colored::ansi_color_disabled());
|
||||
std::env::set_var("NO_COLOR", "");
|
||||
assert!(!Colored::ansi_color_disabled());
|
||||
std::env::remove_var("NO_COLOR");
|
||||
assert!(!Colored::ansi_color_disabled());
|
||||
}
|
||||
}
|
||||
|
@ -405,63 +405,3 @@ impl_display!(for ScrollUp);
|
||||
impl_display!(for ScrollDown);
|
||||
impl_display!(for SetSize);
|
||||
impl_display!(for Clear);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{io::stdout, thread, time};
|
||||
|
||||
use crate::execute;
|
||||
|
||||
use super::*;
|
||||
|
||||
// Test is disabled, because it's failing on Travis CI
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_resize_ansi() {
|
||||
let (width, height) = size().unwrap();
|
||||
|
||||
execute!(stdout(), SetSize(35, 35)).unwrap();
|
||||
|
||||
// see issue: https://github.com/eminence/terminal-size/issues/11
|
||||
thread::sleep(time::Duration::from_millis(30));
|
||||
|
||||
assert_eq!((35, 35), size().unwrap());
|
||||
|
||||
// reset to previous size
|
||||
execute!(stdout(), SetSize(width, height)).unwrap();
|
||||
|
||||
// see issue: https://github.com/eminence/terminal-size/issues/11
|
||||
thread::sleep(time::Duration::from_millis(30));
|
||||
|
||||
assert_eq!((width, height), size().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_raw_mode() {
|
||||
// check we start from normal mode (may fail on some test harnesses)
|
||||
assert!(!is_raw_mode_enabled().unwrap());
|
||||
|
||||
// enable the raw mode
|
||||
if enable_raw_mode().is_err() {
|
||||
// Enabling raw mode doesn't work on the ci
|
||||
// So we just ignore it
|
||||
return;
|
||||
}
|
||||
|
||||
// check it worked (on unix it doesn't really check the underlying
|
||||
// tty but rather check that the code is consistent)
|
||||
assert!(is_raw_mode_enabled().unwrap());
|
||||
|
||||
// enable it again, this should not change anything
|
||||
enable_raw_mode().unwrap();
|
||||
|
||||
// check we're still in raw mode
|
||||
assert!(is_raw_mode_enabled().unwrap());
|
||||
|
||||
// now let's disable it
|
||||
disable_raw_mode().unwrap();
|
||||
|
||||
// check we're back to normal mode
|
||||
assert!(!is_raw_mode_enabled().unwrap());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user