diff options
author | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 12:03:43 +0530 |
---|---|---|
committer | Sebastian Thiel <sthiel@thoughtworks.com> | 2019-06-03 12:03:43 +0530 |
commit | 05c8ec1a6e2ce9af3f55d75cb761cf3b66244bb8 (patch) | |
tree | 12bd04d0864f9232debad5ccefb76ab2c7d82741 | |
parent | 11147d8e344435b95adaca68e5125836c0bf2ed9 (diff) |
The first test for user input, yeah!
-rw-r--r-- | src/interactive/app.rs | 11 | ||||
-rw-r--r-- | src/interactive/mod.rs | 2 | ||||
-rw-r--r-- | src/interactive/widgets.rs | 34 | ||||
-rw-r--r-- | tests/interactive.rs | 27 |
4 files changed, 66 insertions, 8 deletions
diff --git a/src/interactive/app.rs b/src/interactive/app.rs index 95606c1..622fa71 100644 --- a/src/interactive/app.rs +++ b/src/interactive/app.rs @@ -26,7 +26,7 @@ pub struct TerminalApp { } impl TerminalApp { - fn draw_to_terminal<B>(&self, terminal: &mut Terminal<B>) -> Result<(), Error> + fn draw<B>(&self, terminal: &mut Terminal<B>) -> Result<(), Error> where B: Backend, { @@ -35,6 +35,7 @@ impl TerminalApp { display, state, } = self; + terminal.draw(|mut f| { let full_screen = f.size(); MainWindow { @@ -44,6 +45,7 @@ impl TerminalApp { } .render(&mut f, full_screen) })?; + Ok(()) } pub fn process_events<B, R>( @@ -57,13 +59,14 @@ impl TerminalApp { { use termion::event::Key::{Char, Ctrl}; - self.draw_to_terminal(terminal)?; + self.draw(terminal)?; for key in keys.filter_map(Result::ok) { match key { + Char('s') => self.state.sorting.toggle_size(), Ctrl('c') | Char('\n') | Char('q') => break, _ => {} }; - self.draw_to_terminal(terminal)?; + self.draw(terminal)?; } Ok(WalkResult { num_errors: self.traversal.io_errors, @@ -85,6 +88,7 @@ impl TerminalApp { let state = DisplayState { root: traversal.root_index, selected: None, + sorting: Default::default(), }; MainWindow { traversal, @@ -99,6 +103,7 @@ impl TerminalApp { state: DisplayState { root: traversal.root_index, selected: None, + sorting: Default::default(), }, display: display_options, traversal: traversal, diff --git a/src/interactive/mod.rs b/src/interactive/mod.rs index 84130f8..040fd10 100644 --- a/src/interactive/mod.rs +++ b/src/interactive/mod.rs @@ -1,6 +1,6 @@ mod app; mod traverse; -mod widgets; +pub mod widgets; pub use self::app::*; pub use self::traverse::*; diff --git a/src/interactive/widgets.rs b/src/interactive/widgets.rs index 6b7cd80..86caef5 100644 --- a/src/interactive/widgets.rs +++ b/src/interactive/widgets.rs @@ -13,11 +13,35 @@ pub struct Entries<'a> { pub tree: &'a Tree, pub root: TreeIndex, pub display: DisplayOptions, + pub sorting: SortMode, +} + +#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq)] +pub enum SortMode { + SizeDescending, + SizeAscending, +} + +impl SortMode { + pub fn toggle_size(&mut self) { + use SortMode::*; + *self = match self { + SizeAscending => SizeDescending, + SizeDescending => SizeAscending, + } + } +} + +impl Default for SortMode { + fn default() -> Self { + SortMode::SizeDescending + } } pub struct DisplayState { pub root: TreeIndex, pub selected: Option<TreeIndex>, + pub sorting: SortMode, } pub struct MainWindow<'a, 'b> { @@ -81,6 +105,7 @@ impl<'a, 'b> Widget for MainWindow<'a, 'b> { tree: &tree, root: state.root, display: *display, + sorting: state.sorting, } .draw(entries, buf); @@ -95,16 +120,21 @@ impl<'a, 'b> Widget for MainWindow<'a, 'b> { impl<'a> Widget for Entries<'a> { fn draw(&mut self, area: Rect, buf: &mut Buffer) { - use petgraph::Direction; let Self { tree, root, display, + sorting, } = self; + use petgraph::Direction; + use SortMode::*; List::new( tree.neighbors_directed(*root, Direction::Outgoing) .filter_map(|w| tree.node_weight(w)) - .sorted_by(|l, r| l.size.cmp(&r.size)) + .sorted_by(|l, r| match sorting { + SizeDescending => l.size.cmp(&r.size), + SizeAscending => r.size.cmp(&l.size), + }) .rev() .map(|w| { Text::Raw( diff --git a/tests/interactive.rs b/tests/interactive.rs index 159f05e..1fb32da 100644 --- a/tests/interactive.rs +++ b/tests/interactive.rs @@ -1,10 +1,13 @@ mod app { - use dua::interactive::{EntryData, TerminalApp, Tree, TreeIndexType}; - use dua::{ByteFormat, Color, TraversalSorting, WalkOptions}; + use dua::{ + interactive::{widgets::SortMode, EntryData, TerminalApp, Tree, TreeIndexType}, + ByteFormat, Color, TraversalSorting, WalkOptions, + }; use failure::Error; use petgraph::prelude::NodeIndex; use pretty_assertions::assert_eq; use std::{ffi::OsString, fmt, path::Path}; + use termion::input::TermRead; use tui::backend::TestBackend; use tui::Terminal; @@ -38,6 +41,26 @@ mod app { Ok(()) } + #[test] + fn simple_user_journey() -> Result<(), Error> { + let (mut terminal, mut app) = initialized_app_and_terminal("sample-02")?; + assert_eq!( + app.state.sorting, + SortMode::SizeDescending, + "it starts in descending order by size" + ); + + // when hitting the S key + app.process_events(&mut terminal, b"s".keys())?; + assert_eq!( + app.state.sorting, + SortMode::SizeAscending, + "it sets the sort to size ascending" + ); + + Ok(()) + } + fn initialized_app_and_terminal( fixture_path: &str, ) -> Result<(Terminal<TestBackend>, TerminalApp), Error> { |