summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/main.rs3
-rw-r--r--src/core/modules/mod.rs2
-rw-r--r--src/core/modules/window_size_error/mod.rs139
-rw-r--r--src/core/process/tests.rs3
4 files changed, 143 insertions, 4 deletions
diff --git a/src/core/main.rs b/src/core/main.rs
index cb80d74..ffe1359 100644
--- a/src/core/main.rs
+++ b/src/core/main.rs
@@ -13,11 +13,10 @@ use crate::{
arguments::Args,
exit::Exit,
help::build_help,
- modules::{ConfirmAbort, ConfirmRebase, Error, ExternalEditor, Insert, List, ShowCommit},
+ modules::{ConfirmAbort, ConfirmRebase, Error, ExternalEditor, Insert, List, ShowCommit, WindowSizeError},
process::Process,
},
module::{ExitStatus, Modules, State},
- window_size_error::WindowSizeError,
};
pub(super) fn load_config() -> Result<Config, Exit> {
diff --git a/src/core/modules/mod.rs b/src/core/modules/mod.rs
index 0981152..20ac7c1 100644
--- a/src/core/modules/mod.rs
+++ b/src/core/modules/mod.rs
@@ -5,6 +5,7 @@ mod external_editor;
mod insert;
mod list;
mod show_commit;
+mod window_size_error;
pub use self::{
confirm_abort::ConfirmAbort,
@@ -14,4 +15,5 @@ pub use self::{
insert::Insert,
list::List,
show_commit::ShowCommit,
+ window_size_error::WindowSizeError,
};
diff --git a/src/core/modules/window_size_error/mod.rs b/src/core/modules/window_size_error/mod.rs
new file mode 100644
index 0000000..f0730f5
--- /dev/null
+++ b/src/core/modules/window_size_error/mod.rs
@@ -0,0 +1,139 @@
+use input::{Event, EventHandler, InputOptions};
+use lazy_static::lazy_static;
+use todo_file::TodoFile;
+use view::{RenderContext, ViewData, ViewLine, ViewSender};
+
+use crate::module::{Module, ProcessResult, State};
+
+const HEIGHT_ERROR_MESSAGE: &str = "Window too small, increase height to continue";
+const SHORT_ERROR_MESSAGE: &str = "Window too small";
+const SIZE_ERROR_MESSAGE: &str = "Size!";
+
+lazy_static! {
+ static ref INPUT_OPTIONS: InputOptions = InputOptions::new().movement(true).resize(false);
+}
+
+pub struct WindowSizeError {
+ return_state: State,
+ view_data: ViewData,
+}
+
+impl Module for WindowSizeError {
+ fn activate(&mut self, _: &TodoFile, previous_state: State) -> ProcessResult {
+ self.return_state = previous_state;
+ ProcessResult::new()
+ }
+
+ fn build_view_data(&mut self, context: &RenderContext, _: &TodoFile) -> &ViewData {
+ let view_width = context.width();
+ let message = if !context.is_minimum_view_width() {
+ if view_width >= SHORT_ERROR_MESSAGE.len() {
+ SHORT_ERROR_MESSAGE
+ }
+ else {
+ // not much to do if the window gets too narrow
+ SIZE_ERROR_MESSAGE
+ }
+ }
+ else if view_width >= HEIGHT_ERROR_MESSAGE.len() {
+ HEIGHT_ERROR_MESSAGE
+ }
+ else {
+ // this message will always be safe here
+ SHORT_ERROR_MESSAGE
+ };
+
+ self.view_data.update_view_data(|updater| {
+ updater.clear();
+ updater.push_line(ViewLine::from(message));
+ });
+ &mut self.view_data
+ }
+
+ fn handle_events(&mut self, event_handler: &EventHandler, _: &ViewSender, _: &mut TodoFile) -> ProcessResult {
+ let event = event_handler.read_event(&INPUT_OPTIONS, |event, _| event);
+ let mut result = ProcessResult::from(event);
+
+ if let Event::Resize(width, height) = event {
+ let render_context = RenderContext::new(width, height);
+ if !render_context.is_window_too_small() {
+ result = result.state(self.return_state);
+ }
+ }
+
+ result
+ }
+}
+
+impl WindowSizeError {
+ pub fn new() -> Self {
+ Self {
+ return_state: State::List,
+ view_data: ViewData::new(|_| {}),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use rstest::rstest;
+ use view::assert_rendered_output;
+
+ use super::*;
+ use crate::{assert_process_result, module::testutil::module_test};
+
+ const MINIMUM_WINDOW_HEIGHT: usize = 5;
+ const MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH: usize = 45;
+
+ #[rstest(
+ width, height, expected,
+ case::width_too_small_long_message(SHORT_ERROR_MESSAGE.len(), MINIMUM_WINDOW_HEIGHT + 1, "Window too small"),
+ case::width_too_small_short_message(SHORT_ERROR_MESSAGE.len() - 1, MINIMUM_WINDOW_HEIGHT + 1, "Size!"),
+ case::height_too_small_long_message(
+ MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH, MINIMUM_WINDOW_HEIGHT, "Window too small, increase height to continue"
+ ),
+ case::height_too_small_short_message(
+ MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH - 1, MINIMUM_WINDOW_HEIGHT, "Window too small"
+ )
+ )]
+ #[allow(clippy::cast_possible_wrap)]
+ fn build_view_data(width: usize, height: usize, expected: &str) {
+ module_test(&[], &[], |mut test_context| {
+ test_context.render_context.update(width as u16, height as u16);
+ let mut module = WindowSizeError::new();
+ let view_data = test_context.build_view_data(&mut module);
+ assert_rendered_output!(view_data, "{BODY}", format!("{{Normal}}{}", expected));
+ });
+ }
+
+ #[test]
+ fn event_resize_window_still_small() {
+ module_test(&[], &[Event::Resize(1, 1)], |mut test_context| {
+ let mut module = WindowSizeError::new();
+ test_context.activate(&mut module, State::ConfirmRebase);
+ assert_process_result!(test_context.handle_event(&mut module), event = Event::Resize(1, 1));
+ });
+ }
+
+ #[test]
+ fn event_resize_window_no_longer_too_small() {
+ module_test(&[], &[Event::Resize(100, 100)], |mut test_context| {
+ let mut module = WindowSizeError::new();
+ test_context.activate(&mut module, State::ConfirmRebase);
+ assert_process_result!(
+ test_context.handle_event(&mut module),
+ event = Event::Resize(100, 100),
+ state = State::ConfirmRebase
+ );
+ });
+ }
+
+ #[test]
+ fn event_other_character() {
+ module_test(&[], &[Event::from('a')], |mut test_context| {
+ let mut module = WindowSizeError::new();
+ test_context.activate(&mut module, State::ConfirmRebase);
+ assert_process_result!(test_context.handle_event(&mut module), event = Event::from('a'));
+ });
+ }
+}
diff --git a/src/core/process/tests.rs b/src/core/process/tests.rs
index da05998..659f801 100644
--- a/src/core/process/tests.rs
+++ b/src/core/process/tests.rs
@@ -8,9 +8,8 @@ use view::{assert_rendered_output, ViewData};
use super::*;
use crate::{
- core::modules::Error,
+ core::modules::{Error, WindowSizeError},
module::{testutil::module_test, Module},
- window_size_error::WindowSizeError,
};
struct TestModule {