more work on re-implementing the readline module

This commit is contained in:
2025-06-05 01:48:44 -04:00
parent 2c6577ad06
commit f57cf625ef
10 changed files with 3947 additions and 72 deletions

131
src/tests/readline.rs Normal file
View File

@@ -0,0 +1,131 @@
use crate::prompt::readline::linebuf::LineBuf;
use super::super::*;
#[test]
fn linebuf_empty_linebuf() {
let mut buf = LineBuf::new();
assert_eq!(buf.as_str(), "");
buf.update_graphemes_lazy();
assert_eq!(buf.grapheme_indices(), &[]);
assert!(buf.slice(0..0).is_none());
}
#[test]
fn linebuf_ascii_content() {
let mut buf = LineBuf::new().with_initial("hello", 0);
buf.update_graphemes_lazy();
assert_eq!(buf.grapheme_indices(), &[0, 1, 2, 3, 4]);
assert_eq!(buf.grapheme_at(0), Some("h"));
assert_eq!(buf.grapheme_at(4), Some("o"));
assert_eq!(buf.slice(1..4), Some("ell"));
assert_eq!(buf.slice_to(2), Some("he"));
assert_eq!(buf.slice_from(2), Some("llo"));
}
#[test]
fn linebuf_unicode_graphemes() {
let mut buf = LineBuf::new().with_initial("a🇺🇸b́c", 0);
buf.update_graphemes_lazy();
let indices = buf.grapheme_indices();
assert_eq!(indices.len(), 4); // 4 graphemes + 1 end marker
assert_eq!(buf.grapheme_at(0), Some("a"));
assert_eq!(buf.grapheme_at(1), Some("🇺🇸"));
assert_eq!(buf.grapheme_at(2), Some("")); // b + combining accent
assert_eq!(buf.grapheme_at(3), Some("c"));
assert_eq!(buf.grapheme_at(4), None); // out of bounds
assert_eq!(buf.slice(0..2), Some("a🇺🇸"));
assert_eq!(buf.slice(1..3), Some("🇺🇸b́"));
assert_eq!(buf.slice(2..4), Some("b́c"));
}
#[test]
fn linebuf_slice_to_from_cursor() {
let mut buf = LineBuf::new().with_initial("abçd", 2);
buf.update_graphemes_lazy();
assert_eq!(buf.slice_to_cursor(), Some("ab"));
assert_eq!(buf.slice_from_cursor(), Some("çd"));
}
#[test]
fn linebuf_out_of_bounds_slices() {
let mut buf = LineBuf::new().with_initial("test", 0);
buf.update_graphemes_lazy();
assert_eq!(buf.grapheme_at(5), None); // out of bounds
assert_eq!(buf.slice(2..5), None); // end out of bounds
assert_eq!(buf.slice(4..4), None); // valid but empty
}
#[test]
fn linebuf_this_line() {
let initial = "This is the first line\nThis is the second line\nThis is the third line\nThis is the fourth line";
let mut buf = LineBuf::new().with_initial(initial, 57);
let (start,end) = buf.this_line();
assert_eq!(buf.slice(start..end), Some("This is the third line"))
}
#[test]
fn linebuf_prev_line() {
let initial = "This is the first line\nThis is the second line\nThis is the third line\nThis is the fourth line";
let mut buf = LineBuf::new().with_initial(initial, 57);
let (start,end) = buf.prev_line().unwrap();
assert_eq!(buf.slice(start..end), Some("This is the second line"))
}
#[test]
fn linebuf_next_line() {
let initial = "This is the first line\nThis is the second line\nThis is the third line\nThis is the fourth line";
let mut buf = LineBuf::new().with_initial(initial, 57);
let (start,end) = buf.next_line().unwrap();
assert_eq!(buf.slice(start..end), Some("This is the fourth line"))
}
#[test]
fn linebuf_cursor_motion() {
let mut buf = LineBuf::new().with_initial("Thé quíck 🦊 bröwn fóx jumpś óver the 💤 lázy dóg 🐶", 0);
buf.update_graphemes_lazy();
let total = buf.grapheme_indices.as_ref().unwrap().len();
for i in 0..total {
buf.cursor.set(i);
let expected_to = buf.buffer.get(..buf.grapheme_indices_owned()[i]).unwrap_or("").to_string();
let expected_from = if i + 1 < total {
buf.buffer.get(buf.grapheme_indices_owned()[i]..).unwrap_or("").to_string()
} else {
// last grapheme, ends at buffer end
buf.buffer.get(buf.grapheme_indices_owned()[i]..).unwrap_or("").to_string()
};
let expected_at = {
let start = buf.grapheme_indices_owned()[i];
let end = buf.grapheme_indices_owned().get(i + 1).copied().unwrap_or(buf.buffer.len());
buf.buffer.get(start..end).map(|slice| slice.to_string())
};
assert_eq!(
buf.slice_to_cursor(),
Some(expected_to.as_str()),
"Failed at cursor position {i}: slice_to_cursor"
);
assert_eq!(
buf.slice_from_cursor(),
Some(expected_from.as_str()),
"Failed at cursor position {i}: slice_from_cursor"
);
assert_eq!(
buf.grapheme_at(i).map(|slice| slice.to_string()),
expected_at,
"Failed at cursor position {i}: grapheme_at"
);
}
}