finished tests, some restructuring, bugfixes

This commit is contained in:
Anton-4 2021-01-30 12:09:14 +01:00
parent a5ac077ec9
commit f3f57a13ef
9 changed files with 189 additions and 198 deletions

View file

@ -15,12 +15,12 @@ pub enum EdError {
#[snafu(display("ClipboardWriteFailed: could not set clipboard contents: {}", err_msg))] #[snafu(display("ClipboardWriteFailed: could not set clipboard contents: {}", err_msg))]
ClipboardWriteFailed { err_msg: String }, ClipboardWriteFailed { err_msg: String },
#[snafu(display("ClipboardInitFailed: could not initialize ClipboardContext: {}.", err_msg))] #[snafu(display(
"ClipboardInitFailed: could not initialize ClipboardContext: {}.",
err_msg
))]
ClipboardInitFailed { err_msg: String }, ClipboardInitFailed { err_msg: String },
#[snafu(display("EdModelIsNone: editor model EdModel was never succesfully initiliazed."))]
EdModelIsNone { },
#[snafu(display( #[snafu(display(
"FileOpenFailed: failed to open file with path {} with the following error: {}.", "FileOpenFailed: failed to open file with path {} with the following error: {}.",
path_str, path_str,

View file

@ -1,8 +1,8 @@
use crate::error::EdResult; use crate::error::EdResult;
use crate::mvc::app_model::AppModel; use crate::mvc::app_model::AppModel;
use crate::mvc::app_update::{pass_keydown_to_focused, handle_copy, handle_paste}; use crate::mvc::app_update::{handle_copy, handle_paste, pass_keydown_to_focused};
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
use winit::event::VirtualKeyCode::*; use winit::event::VirtualKeyCode::*;
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
pub fn handle_keydown( pub fn handle_keydown(
elem_state: ElementState, elem_state: ElementState,
@ -10,9 +10,8 @@ pub fn handle_keydown(
modifiers: ModifiersState, modifiers: ModifiersState,
app_model: &mut AppModel, app_model: &mut AppModel,
) -> EdResult<()> { ) -> EdResult<()> {
if let ElementState::Released = elem_state { if let ElementState::Released = elem_state {
return Ok(()) return Ok(());
} }
match virtual_keycode { match virtual_keycode {
@ -28,17 +27,23 @@ pub fn handle_keydown(
todo!("cut"); todo!("cut");
} }
C => if modifiers.ctrl() { C => {
handle_copy(app_model)? if modifiers.ctrl() {
}, handle_copy(app_model)?
V => if modifiers.ctrl() { }
handle_paste(app_model)? }
}, V => {
X => if modifiers.ctrl() { if modifiers.ctrl() {
//handle_cut(app_model)? handle_paste(app_model)?
todo!("cut"); }
}, }
_ => () X => {
if modifiers.ctrl() {
//handle_cut(app_model)?
todo!("cut");
}
}
_ => (),
} }
Ok(()) Ok(())

View file

@ -25,7 +25,7 @@ use crate::graphics::style::CODE_FONT_SIZE;
use crate::graphics::style::CODE_TXT_XY; use crate::graphics::style::CODE_TXT_XY;
use crate::mvc::app_model::AppModel; use crate::mvc::app_model::AppModel;
use crate::mvc::ed_model::EdModel; use crate::mvc::ed_model::EdModel;
use crate::mvc::{ed_model, ed_view, app_update}; use crate::mvc::{app_update, ed_model, ed_view};
use crate::resources::strings::NOTHING_OPENED; use crate::resources::strings::NOTHING_OPENED;
use crate::vec_result::get_res; use crate::vec_result::get_res;
use bumpalo::Bump; use bumpalo::Bump;

View file

@ -1,10 +1,9 @@
use super::ed_model::EdModel; use super::ed_model::EdModel;
use crate::error::{EdResult, print_err}; use crate::error::EdError::{ClipboardInitFailed, ClipboardReadFailed, ClipboardWriteFailed};
use crate::error::EdError::{ClipboardReadFailed, ClipboardWriteFailed, ClipboardInitFailed, EdModelIsNone}; use crate::error::{print_err, EdResult};
use clipboard::{ClipboardContext, ClipboardProvider}; use clipboard::{ClipboardContext, ClipboardProvider};
use std::fmt; use std::fmt;
#[derive(Debug)] #[derive(Debug)]
pub struct AppModel { pub struct AppModel {
pub ed_model_opt: Option<EdModel>, pub ed_model_opt: Option<EdModel>,
@ -13,59 +12,38 @@ pub struct AppModel {
impl AppModel { impl AppModel {
pub fn init(ed_model_opt: Option<EdModel>) -> AppModel { pub fn init(ed_model_opt: Option<EdModel>) -> AppModel {
let clipboard_res = Clipboard::init();
let clipboard_opt =
match clipboard_res {
Ok(clipboard) => Some(clipboard),
Err(e) => {
print_err(&e);
None
}
};
AppModel { AppModel {
ed_model_opt, ed_model_opt,
clipboard_opt clipboard_opt: AppModel::init_clipboard_opt(),
} }
} }
pub fn get_ed_model(&self) -> EdResult<&EdModel> { pub fn init_clipboard_opt() -> Option<Clipboard> {
if let Some(ref ed_model) = self.ed_model_opt { let clipboard_res = Clipboard::init();
Ok(ed_model)
} else {
Err(EdModelIsNone {})
}
}
pub fn get_ed_model_mut(&mut self) -> EdResult<& mut EdModel> { match clipboard_res {
if let Some(ref mut ed_model) = self.ed_model_opt { Ok(clipboard) => Some(clipboard),
Ok(ed_model) Err(e) => {
} else { print_err(&e);
Err(EdModelIsNone {}) None
}
} }
} }
} }
pub struct Clipboard { pub struct Clipboard {
context: ClipboardContext context: ClipboardContext,
} }
impl Clipboard { impl Clipboard {
pub fn init() -> EdResult<Clipboard> { pub fn init() -> EdResult<Clipboard> {
let context_res = ClipboardProvider::new(); let context_res = ClipboardProvider::new();
match context_res { match context_res {
Ok(context) => Ok( Ok(context) => Ok(Clipboard { context }),
Clipboard {
context
}
),
Err(e) => Err(ClipboardInitFailed { Err(e) => Err(ClipboardInitFailed {
err_msg: e.to_string() err_msg: e.to_string(),
}) }),
} }
} }
@ -76,8 +54,8 @@ impl Clipboard {
match content_res { match content_res {
Ok(content_str) => Ok(content_str), Ok(content_str) => Ok(content_str),
Err(e) => Err(ClipboardReadFailed { Err(e) => Err(ClipboardReadFailed {
err_msg: e.to_string() err_msg: e.to_string(),
}) }),
} }
} }
@ -87,16 +65,37 @@ impl Clipboard {
match content_set_res { match content_set_res {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(e) => Err(ClipboardWriteFailed { Err(e) => Err(ClipboardWriteFailed {
err_msg: e.to_string() err_msg: e.to_string(),
}) }),
} }
} }
} }
pub fn set_clipboard_txt(clipboard_opt: &mut Option<Clipboard>, txt: &str) -> EdResult<()> {
if let Some(ref mut clipboard) = clipboard_opt {
clipboard.set_content(txt.to_owned())?;
} else {
return Err(ClipboardWriteFailed {
err_msg: "Clipboard was never initialized succesfully.".to_owned(),
});
}
Ok(())
}
pub fn get_clipboard_txt(clipboard_opt: &mut Option<Clipboard>) -> EdResult<String> {
if let Some(ref mut clipboard) = clipboard_opt {
clipboard.get_content()
} else {
Err(ClipboardReadFailed {
err_msg: "Clipboard was never initialized succesfully.".to_owned(),
})
}
}
impl fmt::Debug for Clipboard { impl fmt::Debug for Clipboard {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// showing the clipboard would require a mut ref which is not possible // showing the clipboard would require a mut ref which is not possible
f.debug_struct("Clipboard (can't show)") f.debug_struct("Clipboard (can't show)").finish()
.finish()
} }
} }

View file

@ -1,24 +1,17 @@
use super::app_model;
use super::app_model::AppModel; use super::app_model::AppModel;
use super::ed_model::Position;
use super::ed_update; use super::ed_update;
use super::ed_model::{Position};
use crate::error::EdResult; use crate::error::EdResult;
use crate::error::EdError::{ClipboardWriteFailed, ClipboardReadFailed};
use winit::event::{ModifiersState, VirtualKeyCode}; use winit::event::{ModifiersState, VirtualKeyCode};
pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> { pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
if let Some(ref mut ed_model) = app_model.ed_model_opt { if let Some(ref mut ed_model) = app_model.ed_model_opt {
if ed_model.has_focus { if ed_model.has_focus {
let selected_str_opt = super::ed_model::get_selected_str(ed_model)?; let selected_str_opt = super::ed_model::get_selected_str(ed_model)?;
if let Some(selected_str) = selected_str_opt { if let Some(selected_str) = selected_str_opt {
if let Some(ref mut clipboard) = app_model.clipboard_opt { app_model::set_clipboard_txt(&mut app_model.clipboard_opt, selected_str)?;
clipboard.set_content(selected_str.to_owned())?;
} else {
return Err(ClipboardWriteFailed {
err_msg: "Clipboard was never initialized succesfully.".to_owned()
})
}
} }
} }
} }
@ -27,52 +20,55 @@ pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
} }
pub fn handle_paste(app_model: &mut AppModel) -> EdResult<()> { pub fn handle_paste(app_model: &mut AppModel) -> EdResult<()> {
if let Some(ref mut ed_model) = app_model.ed_model_opt { if let Some(ref mut ed_model) = app_model.ed_model_opt {
if ed_model.has_focus { if ed_model.has_focus {
if let Some(ref mut clipboard) = app_model.clipboard_opt { let clipboard_content = app_model::get_clipboard_txt(&mut app_model.clipboard_opt)?;
let clipboard_content = clipboard.get_content()?;
if !clipboard_content.is_empty() { if !clipboard_content.is_empty() {
let mut rsplit_iter = clipboard_content.rsplit('\n');
// safe unwrap because we checked if empty
let last_line_nr_chars = rsplit_iter.next().unwrap().len();
let clipboard_nr_lines = rsplit_iter.count();
let mut rsplit_iter = clipboard_content.rsplit('\n'); let old_caret_pos = ed_model.caret_pos;
// safe unwrap because we checked if empty
let last_line_nr_chars = rsplit_iter.next().unwrap().len();
let clipboard_nr_lines = rsplit_iter.count();
let old_caret_pos = ed_model.caret_pos; if let Some(selection) = ed_model.selection_opt {
let start_caret_pos = selection.start_pos;
ed_model.text_buf.del_selection(selection)?;
ed_model.selection_opt = None;
if let Some(selection) = ed_model.selection_opt { ed_model
let start_caret_pos = selection.start_pos; .text_buf
ed_model.text_buf.del_selection(selection)?; .insert_str(start_caret_pos, &clipboard_content)?;
ed_model.selection_opt = None;
ed_model.text_buf.insert_str(
start_caret_pos,
&clipboard_content
)?;
if clipboard_nr_lines > 0 {
ed_model.caret_pos = Position { ed_model.caret_pos = Position {
line: start_caret_pos.line + clipboard_nr_lines, line: start_caret_pos.line + clipboard_nr_lines,
column: start_caret_pos.column + last_line_nr_chars column: last_line_nr_chars,
} }
} else { } else {
ed_model.text_buf.insert_str( ed_model.caret_pos = Position {
old_caret_pos, line: start_caret_pos.line,
&clipboard_content column: start_caret_pos.column + last_line_nr_chars,
)?; }
}
} else {
ed_model
.text_buf
.insert_str(old_caret_pos, &clipboard_content)?;
if clipboard_nr_lines > 0 {
ed_model.caret_pos = Position { ed_model.caret_pos = Position {
line: old_caret_pos.line + clipboard_nr_lines, line: old_caret_pos.line + clipboard_nr_lines,
column: old_caret_pos.column + last_line_nr_chars column: last_line_nr_chars,
}
} else {
ed_model.caret_pos = Position {
line: old_caret_pos.line,
column: old_caret_pos.column + last_line_nr_chars,
} }
} }
} }
} else {
return Err(ClipboardReadFailed {
err_msg: "Clipboard was never initialized succesfully.".to_owned()
})
} }
} }
} }
@ -92,7 +88,7 @@ pub fn pass_keydown_to_focused(
} }
} }
pub fn handle_new_char(received_char: &char, app_model: &mut AppModel) -> EdResult<()> { pub fn handle_new_char(received_char: &char, app_model: &mut AppModel) -> EdResult<()> {
if let Some(ref mut ed_model) = app_model.ed_model_opt { if let Some(ref mut ed_model) = app_model.ed_model_opt {
if ed_model.has_focus { if ed_model.has_focus {
ed_update::handle_new_char(received_char, ed_model)?; ed_update::handle_new_char(received_char, ed_model)?;
@ -104,108 +100,107 @@ pub fn handle_new_char(received_char: &char, app_model: &mut AppModel) -> EdResu
#[cfg(test)] #[cfg(test)]
pub mod test_app_update { pub mod test_app_update {
use crate::mvc::app_model;
use crate::mvc::app_model::{AppModel, Clipboard}; use crate::mvc::app_model::{AppModel, Clipboard};
use crate::mvc::app_update::{handle_copy, handle_paste}; use crate::mvc::app_update::{handle_copy, handle_paste};
use crate::mvc::ed_update::test_ed_update::{gen_caret_text_buf};
use crate::mvc::ed_model::{EdModel, Position, RawSelection}; use crate::mvc::ed_model::{EdModel, Position, RawSelection};
use crate::selection::test_selection::{convert_selection_to_dsl, all_lines_vec}; use crate::mvc::ed_update::test_ed_update::gen_caret_text_buf;
use crate::selection::test_selection::{all_lines_vec, convert_selection_to_dsl};
use crate::text_buffer::TextBuffer; use crate::text_buffer::TextBuffer;
use crate::error::EdResult;
use crate::error::EdError::ClipboardInitFailed;
pub fn mock_app_model( pub fn mock_app_model(
text_buf: TextBuffer, text_buf: TextBuffer,
caret_pos: Position, caret_pos: Position,
selection_opt: Option<RawSelection>, selection_opt: Option<RawSelection>,
clipboard_opt: Option<Clipboard>,
) -> AppModel { ) -> AppModel {
AppModel::init( AppModel {
Some( ed_model_opt: Some(EdModel {
EdModel { text_buf,
text_buf, caret_pos,
caret_pos, selection_opt,
selection_opt, glyph_dim_rect_opt: None,
glyph_dim_rect_opt: None, has_focus: true,
has_focus: true, }),
} clipboard_opt,
)
)
}
fn get_clipboard(app_model: &mut AppModel) -> EdResult<&mut Clipboard> {
if let Some(ref mut clipboard) = app_model.clipboard_opt {
Ok(clipboard)
} else {
Err(ClipboardInitFailed {
err_msg: "Clipboard was never initialized succesfully.".to_owned()
})
} }
} }
fn assert_copy( fn assert_copy(
pre_lines_str: &[&str], pre_lines_str: &[&str],
expected_clipboard_content: &str, expected_clipboard_content: &str,
) -> Result<(), String> { clipboard_opt: Option<Clipboard>,
) -> Result<Option<Clipboard>, String> {
let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?; let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?;
let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt); let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt, clipboard_opt);
handle_copy(&mut app_model)?; handle_copy(&mut app_model)?;
let clipboard = get_clipboard(&mut app_model)?; let clipboard_content = app_model::get_clipboard_txt(&mut app_model.clipboard_opt)?;
assert_eq!( assert_eq!(clipboard_content, expected_clipboard_content);
clipboard.get_content()?,
expected_clipboard_content
);
Ok(()) Ok(app_model.clipboard_opt)
} }
fn assert_paste( fn assert_paste(
pre_lines_str: &[&str], pre_lines_str: &[&str],
clipboard_content: &str, clipboard_content: &str,
expected_post_lines_str: &[&str], expected_post_lines_str: &[&str],
) -> Result<(), String> { clipboard_opt: Option<Clipboard>,
) -> Result<Option<Clipboard>, String> {
let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?; let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?;
let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt); let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt, clipboard_opt);
let clipboard = get_clipboard(&mut app_model)?;
clipboard.set_content(clipboard_content.to_owned())?; app_model::set_clipboard_txt(&mut app_model.clipboard_opt, clipboard_content)?;
handle_paste(&mut app_model)?; handle_paste(&mut app_model)?;
let ed_model = app_model.get_ed_model()?; let ed_model = app_model.ed_model_opt.unwrap();
let mut text_buf_lines = all_lines_vec(&ed_model.text_buf); let mut text_buf_lines = all_lines_vec(&ed_model.text_buf);
let post_lines_str = convert_selection_to_dsl( let post_lines_str = convert_selection_to_dsl(
ed_model.selection_opt, ed_model.selection_opt,
ed_model.caret_pos, ed_model.caret_pos,
&mut text_buf_lines &mut text_buf_lines,
)?; )?;
assert_eq!( assert_eq!(post_lines_str, expected_post_lines_str);
post_lines_str,
expected_post_lines_str
);
Ok(()) Ok(app_model.clipboard_opt)
} }
#[test] #[test]
fn copy() -> Result<(), String> { fn copy_paste() -> Result<(), String> {
assert_copy(&["[a]|"], "a")?; // can only init clipboard once
assert_copy(&["|[b]"], "b")?; let mut clipboard_opt = AppModel::init_clipboard_opt();
assert_copy(&["a[ ]|"], " ")?;
assert_copy(&["[ ]|b"], " ")?;
assert_copy(&["a\n", "[b\n", "]|"], "b\n")?;
assert_copy(&["[a\n", " b\n", "]|"], "a\n b\n")?;
assert_copy(&["abc\n", "d[ef\n", "ghi]|\n", "jkl"], "ef\nghi")?;
Ok(()) clipboard_opt = assert_copy(&["[a]|"], "a", clipboard_opt)?;
} clipboard_opt = assert_copy(&["|[b]"], "b", clipboard_opt)?;
clipboard_opt = assert_copy(&["a[ ]|"], " ", clipboard_opt)?;
#[test] clipboard_opt = assert_copy(&["[ ]|b"], " ", clipboard_opt)?;
fn paste() -> Result<(), String> { clipboard_opt = assert_copy(&["a\n", "[b\n", "]|"], "b\n", clipboard_opt)?;
assert_paste(&["|"], "", &["|"])?; clipboard_opt = assert_copy(&["[a\n", " b\n", "]|"], "a\n b\n", clipboard_opt)?;
clipboard_opt = assert_copy(
&["abc\n", "d[ef\n", "ghi]|\n", "jkl"],
"ef\nghi",
clipboard_opt,
)?;
clipboard_opt = assert_paste(&["|"], "", &["|"], clipboard_opt)?;
clipboard_opt = assert_paste(&["|"], "a", &["a|"], clipboard_opt)?;
clipboard_opt = assert_paste(&["a|"], "b", &["ab|"], clipboard_opt)?;
clipboard_opt = assert_paste(&["|a"], "b", &["b|a"], clipboard_opt)?;
clipboard_opt = assert_paste(&["[a]|"], "c", &["c|"], clipboard_opt)?;
clipboard_opt = assert_paste(&["[ab]|"], "d", &["d|"], clipboard_opt)?;
clipboard_opt = assert_paste(&["a[b]|c"], "e", &["ae|c"], clipboard_opt)?;
clipboard_opt = assert_paste(&["a\n", "[b\n", "]|"], "f", &["a\n", "f|"], clipboard_opt)?;
assert_paste(
&["abc\n", "d[ef\n", "ghi]|\n", "jkl"],
"ef\nghi",
&["abc\n", "def\n", "ghi|\n", "jkl"],
clipboard_opt,
)?;
Ok(()) Ok(())
} }

View file

@ -6,7 +6,6 @@ use std::cmp::Ordering;
use std::fmt; use std::fmt;
use std::path::Path; use std::path::Path;
#[derive(Debug)] #[derive(Debug)]
pub struct EdModel { pub struct EdModel {
pub text_buf: TextBuffer, pub text_buf: TextBuffer,
@ -30,13 +29,9 @@ pub fn get_selected_str(ed_model: &EdModel) -> EdResult<Option<&str>> {
if let Some(curr_selection) = ed_model.selection_opt { if let Some(curr_selection) = ed_model.selection_opt {
let selected_str = ed_model.text_buf.get_selection(curr_selection)?; let selected_str = ed_model.text_buf.get_selection(curr_selection)?;
Ok( Ok(Some(selected_str))
Some(selected_str)
)
} else { } else {
Ok( Ok(None)
None
)
} }
} }

View file

@ -1,12 +1,11 @@
use super::app_model::AppModel;
use super::ed_model::EdModel; use super::ed_model::EdModel;
use super::ed_model::{Position, RawSelection}; use super::ed_model::{Position, RawSelection};
use crate::error::EdResult; use crate::error::EdResult;
use crate::text_buffer::TextBuffer; use crate::text_buffer::TextBuffer;
use crate::util::is_newline; use crate::util::is_newline;
use std::cmp::{max, min}; use std::cmp::{max, min};
use winit::event::{ModifiersState, VirtualKeyCode};
use winit::event::VirtualKeyCode::*; use winit::event::VirtualKeyCode::*;
use winit::event::{ModifiersState, VirtualKeyCode};
pub type MoveCaretFun = pub type MoveCaretFun =
fn(Position, Option<RawSelection>, bool, &TextBuffer) -> (Position, Option<RawSelection>); fn(Position, Option<RawSelection>, bool, &TextBuffer) -> (Position, Option<RawSelection>);
@ -352,7 +351,12 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
ed_model.selection_opt = None; ed_model.selection_opt = None;
} }
'\u{3}' | '\u{16}' | '\u{30}' | '\u{e000}'..='\u{f8ff}' | '\u{f0000}'..='\u{ffffd}' | '\u{100000}'..='\u{10fffd}' => { '\u{3}'
| '\u{16}'
| '\u{30}'
| '\u{e000}'..='\u{f8ff}'
| '\u{f0000}'..='\u{ffffd}'
| '\u{100000}'..='\u{10fffd}' => {
// chars that can be ignored // chars that can be ignored
} }
_ => { _ => {
@ -385,7 +389,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
pub fn handle_key_down( pub fn handle_key_down(
modifiers: &ModifiersState, modifiers: &ModifiersState,
virtual_keycode: VirtualKeyCode, virtual_keycode: VirtualKeyCode,
ed_model: &mut EdModel ed_model: &mut EdModel,
) { ) {
match virtual_keycode { match virtual_keycode {
Left => handle_arrow(move_caret_left, modifiers, ed_model), Left => handle_arrow(move_caret_left, modifiers, ed_model),
@ -398,7 +402,7 @@ pub fn handle_key_down(
#[cfg(test)] #[cfg(test)]
pub mod test_ed_update { pub mod test_ed_update {
use crate::mvc::app_update::test_app_update::{mock_app_model}; use crate::mvc::app_update::test_app_update::mock_app_model;
use crate::mvc::ed_model::{Position, RawSelection}; use crate::mvc::ed_model::{Position, RawSelection};
use crate::mvc::ed_update::handle_new_char; use crate::mvc::ed_update::handle_new_char;
use crate::selection::test_selection::{ use crate::selection::test_selection::{
@ -423,25 +427,21 @@ pub mod test_ed_update {
) -> Result<(), String> { ) -> Result<(), String> {
let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?; let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?;
let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt); let app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt, None);
let mut ed_model = app_model.get_ed_model_mut()?; let mut ed_model = app_model.ed_model_opt.unwrap();
if let Err(e) = handle_new_char(&new_char, ed_model) { if let Err(e) = handle_new_char(&new_char, &mut ed_model) {
return Err(e.to_string()); return Err(e.to_string());
} }
if let Some(ed_model) = app_model.ed_model_opt { let mut actual_lines = all_lines_vec(&ed_model.text_buf);
let mut actual_lines = all_lines_vec(&ed_model.text_buf); let dsl_slice = convert_selection_to_dsl(
let dsl_slice = convert_selection_to_dsl( ed_model.selection_opt,
ed_model.selection_opt, ed_model.caret_pos,
ed_model.caret_pos, &mut actual_lines,
&mut actual_lines, )
) .unwrap();
.unwrap(); assert_eq!(dsl_slice, expected_post_lines_str);
assert_eq!(dsl_slice, expected_post_lines_str);
} else {
panic!("Mock AppModel did not have an EdModel.");
}
Ok(()) Ok(())
} }

View file

@ -1,5 +1,5 @@
pub mod app_model; pub mod app_model;
pub mod app_update; pub mod app_update;
pub mod ed_model; pub mod ed_model;
pub mod ed_view;
pub mod ed_update; pub mod ed_update;
pub mod ed_view;

View file

@ -25,7 +25,7 @@ impl TextBuffer {
self.insert_str(caret_pos, &new_char.to_string()) self.insert_str(caret_pos, &new_char.to_string())
} }
pub fn insert_str(&mut self, caret_pos: Position, new_str: &str) -> EdResult<()> { pub fn insert_str(&mut self, caret_pos: Position, new_str: &str) -> EdResult<()> {
let char_indx = self.pos_to_char_indx(caret_pos); let char_indx = self.pos_to_char_indx(caret_pos);
self.check_bounds(char_indx)?; self.check_bounds(char_indx)?;
@ -101,10 +101,7 @@ impl TextBuffer {
} }
pub fn line_len(&self, line_nr: usize) -> Option<usize> { pub fn line_len(&self, line_nr: usize) -> Option<usize> {
self.line(line_nr) self.line(line_nr).map(|line| line.len())
.map(
|line| line.len()
)
} }
pub fn line_len_res(&self, line_nr: usize) -> EdResult<usize> { pub fn line_len_res(&self, line_nr: usize) -> EdResult<usize> {