Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-core/src/test.rs')
-rw-r--r--helix-core/src/test.rs386
1 files changed, 0 insertions, 386 deletions
diff --git a/helix-core/src/test.rs b/helix-core/src/test.rs
deleted file mode 100644
index 71c71cce..00000000
--- a/helix-core/src/test.rs
+++ /dev/null
@@ -1,386 +0,0 @@
-//! Test helpers.
-use crate::{Range, Selection};
-use ropey::Rope;
-use smallvec::SmallVec;
-use std::cmp::Reverse;
-use unicode_segmentation::UnicodeSegmentation;
-
-/// Convert annotated test string to test string and selection.
-///
-/// `#[|` for primary selection with head before anchor followed by `]#`.
-/// `#(|` for secondary selection with head before anchor followed by `)#`.
-/// `#[` for primary selection with head after anchor followed by `|]#`.
-/// `#(` for secondary selection with head after anchor followed by `|)#`.
-///
-/// If the selection contains any LF or CRLF sequences, which are immediately
-/// followed by the same grapheme, then the subsequent one is removed. This is
-/// to allow representing having the cursor over the end of the line.
-///
-/// # Examples
-///
-/// ```
-/// use helix_core::{Range, Selection, test::print};
-/// use smallvec::smallvec;
-///
-/// assert_eq!(
-/// print("#[a|]#b#(|c)#"),
-/// ("abc".to_owned(), Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0))
-/// );
-/// ```
-///
-/// # Panics
-///
-/// Panics when missing primary or appeared more than once.
-/// Panics when missing head or anchor.
-/// Panics when head come after head or anchor come after anchor.
-pub fn print(s: &str) -> (String, Selection) {
- let mut primary_idx = None;
- let mut ranges = SmallVec::new();
- let mut iter = UnicodeSegmentation::graphemes(s, true).peekable();
- let mut left = String::with_capacity(s.len());
-
- 'outer: while let Some(c) = iter.next() {
- let start = left.chars().count();
-
- if c != "#" {
- left.push_str(c);
- continue;
- }
-
- let (is_primary, close_pair) = match iter.next() {
- Some("[") => (true, "]"),
- Some("(") => (false, ")"),
- Some(ch) => {
- left.push('#');
- left.push_str(ch);
- continue;
- }
- None => break,
- };
-
- if is_primary && primary_idx.is_some() {
- panic!("primary `#[` already appeared {:?} {:?}", left, s);
- }
-
- let head_at_beg = iter.next_if_eq(&"|").is_some();
- let last_grapheme = |s: &str| {
- UnicodeSegmentation::graphemes(s, true)
- .next_back()
- .map(String::from)
- };
-
- while let Some(c) = iter.next() {
- let next = iter.peek();
- let mut prev = last_grapheme(left.as_str());
-
- if !(c == close_pair && next == Some(&"#")) {
- left.push_str(c);
- continue;
- }
-
- if !head_at_beg {
- match &prev {
- Some(p) if p != "|" => {
- left.push_str(c);
- continue;
- }
- Some(p) if p == "|" => {
- left.pop().unwrap(); // pop the |
- prev = last_grapheme(left.as_str());
- }
- _ => (),
- }
- }
-
- iter.next(); // skip "#"
- let next = iter.peek();
-
- // skip explicit line end inside selection
- if (prev == Some(String::from("\r\n")) || prev == Some(String::from("\n")))
- && next.map(|n| String::from(*n)) == prev
- {
- iter.next();
- }
-
- if is_primary {
- primary_idx = Some(ranges.len());
- }
-
- let (anchor, head) = match head_at_beg {
- true => (left.chars().count(), start),
- false => (start, left.chars().count()),
- };
-
- ranges.push(Range::new(anchor, head));
- continue 'outer;
- }
-
- if head_at_beg {
- panic!("missing end `{}#` {:?} {:?}", close_pair, left, s);
- } else {
- panic!("missing end `|{}#` {:?} {:?}", close_pair, left, s);
- }
- }
-
- let primary = match primary_idx {
- Some(i) => i,
- None => panic!("missing primary `#[|]#` {:?}", s),
- };
-
- let selection = Selection::new(ranges, primary);
- (left, selection)
-}
-
-/// Convert test string and selection to annotated test string.
-///
-/// `#[|` for primary selection with head before anchor followed by `]#`.
-/// `#(|` for secondary selection with head before anchor followed by `)#`.
-/// `#[` for primary selection with head after anchor followed by `|]#`.
-/// `#(` for secondary selection with head after anchor followed by `|)#`.
-///
-/// # Examples
-///
-/// ```
-/// use helix_core::{Range, Selection, test::plain};
-/// use smallvec::smallvec;
-///
-/// assert_eq!(
-/// plain("abc", &Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0)),
-/// "#[a|]#b#(|c)#".to_owned()
-/// );
-/// ```
-pub fn plain<R: Into<Rope>>(s: R, selection: &Selection) -> String {
- let s = s.into();
- let primary = selection.primary_index();
- let mut out = String::with_capacity(s.len_bytes() + 5 * selection.len());
- out.push_str(&s.to_string());
-
- let mut insertion: Vec<_> = selection
- .iter()
- .enumerate()
- .flat_map(|(i, range)| {
- // sort like this before reversed so anchor < head later
- match (range.anchor < range.head, i == primary) {
- (true, true) => [(range.anchor, "#["), (range.head, "|]#")],
- (true, false) => [(range.anchor, "#("), (range.head, "|)#")],
- (false, true) => [(range.anchor, "]#"), (range.head, "#[|")],
- (false, false) => [(range.anchor, ")#"), (range.head, "#(|")],
- }
- })
- .map(|(char_idx, marker)| (s.char_to_byte(char_idx), marker))
- .collect();
-
- // insert in reverse order
- insertion.sort_unstable_by_key(|k| Reverse(k.0));
- for (i, s) in insertion {
- out.insert_str(i, s);
- }
- out
-}
-
-#[cfg(test)]
-#[allow(clippy::module_inception)]
-mod test {
- use super::*;
-
- #[test]
- fn print_single() {
- assert_eq!(
- (String::from("hello"), Selection::single(1, 0)),
- print("#[|h]#ello")
- );
- assert_eq!(
- (String::from("hello"), Selection::single(0, 1)),
- print("#[h|]#ello")
- );
- assert_eq!(
- (String::from("hello"), Selection::single(4, 0)),
- print("#[|hell]#o")
- );
- assert_eq!(
- (String::from("hello"), Selection::single(0, 4)),
- print("#[hell|]#o")
- );
- assert_eq!(
- (String::from("hello"), Selection::single(5, 0)),
- print("#[|hello]#")
- );
- assert_eq!(
- (String::from("hello"), Selection::single(0, 5)),
- print("#[hello|]#")
- );
- }
-
- #[test]
- fn print_multi() {
- assert_eq!(
- (
- String::from("hello"),
- Selection::new(
- SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),
- 0
- )
- ),
- print("#[|h]#ell#(|o)#")
- );
- assert_eq!(
- (
- String::from("hello"),
- Selection::new(
- SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),
- 0
- )
- ),
- print("#[h|]#ell#(o|)#")
- );
- assert_eq!(
- (
- String::from("hello"),
- Selection::new(
- SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),
- 0
- )
- ),
- print("#[|he]#l#(|lo)#")
- );
- assert_eq!(
- (
- String::from("hello\r\nhello\r\nhello\r\n"),
- Selection::new(
- SmallVec::from_slice(&[
- Range::new(7, 5),
- Range::new(21, 19),
- Range::new(14, 12)
- ]),
- 0
- )
- ),
- print("hello#[|\r\n]#hello#(|\r\n)#hello#(|\r\n)#")
- );
- }
-
- #[test]
- fn print_multi_byte_code_point() {
- assert_eq!(
- (String::from("„“"), Selection::single(1, 0)),
- print("#[|„]#“")
- );
- assert_eq!(
- (String::from("„“"), Selection::single(2, 1)),
- print("„#[|“]#")
- );
- assert_eq!(
- (String::from("„“"), Selection::single(0, 1)),
- print("#[„|]#“")
- );
- assert_eq!(
- (String::from("„“"), Selection::single(1, 2)),
- print("„#[“|]#")
- );
- assert_eq!(
- (String::from("they said „hello“"), Selection::single(11, 10)),
- print("they said #[|„]#hello“")
- );
- }
-
- #[test]
- fn print_multi_code_point_grapheme() {
- assert_eq!(
- (
- String::from("hello 👨‍👩‍👧‍👦 goodbye"),
- Selection::single(13, 6)
- ),
- print("hello #[|👨‍👩‍👧‍👦]# goodbye")
- );
- }
-
- #[test]
- fn plain_single() {
- assert_eq!("#[|h]#ello", plain("hello", &Selection::single(1, 0)));
- assert_eq!("#[h|]#ello", plain("hello", &Selection::single(0, 1)));
- assert_eq!("#[|hell]#o", plain("hello", &Selection::single(4, 0)));
- assert_eq!("#[hell|]#o", plain("hello", &Selection::single(0, 4)));
- assert_eq!("#[|hello]#", plain("hello", &Selection::single(5, 0)));
- assert_eq!("#[hello|]#", plain("hello", &Selection::single(0, 5)));
- }
-
- #[test]
- fn plain_multi() {
- assert_eq!(
- plain(
- "hello",
- &Selection::new(
- SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),
- 0
- )
- ),
- String::from("#[|h]#ell#(|o)#")
- );
- assert_eq!(
- plain(
- "hello",
- &Selection::new(
- SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),
- 0
- )
- ),
- String::from("#[h|]#ell#(o|)#")
- );
- assert_eq!(
- plain(
- "hello",
- &Selection::new(
- SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),
- 0
- )
- ),
- String::from("#[|he]#l#(|lo)#")
- );
- assert_eq!(
- plain(
- "hello\r\nhello\r\nhello\r\n",
- &Selection::new(
- SmallVec::from_slice(&[
- Range::new(7, 5),
- Range::new(21, 19),
- Range::new(14, 12)
- ]),
- 0
- )
- ),
- String::from("hello#[|\r\n]#hello#(|\r\n)#hello#(|\r\n)#")
- );
- }
-
- #[test]
- fn plain_multi_byte_code_point() {
- assert_eq!(
- plain("„“", &Selection::single(1, 0)),
- String::from("#[|„]#“")
- );
- assert_eq!(
- plain("„“", &Selection::single(2, 1)),
- String::from("„#[|“]#")
- );
- assert_eq!(
- plain("„“", &Selection::single(0, 1)),
- String::from("#[„|]#“")
- );
- assert_eq!(
- plain("„“", &Selection::single(1, 2)),
- String::from("„#[“|]#")
- );
- assert_eq!(
- plain("they said „hello“", &Selection::single(11, 10)),
- String::from("they said #[|„]#hello“")
- );
- }
-
- #[test]
- fn plain_multi_code_point_grapheme() {
- assert_eq!(
- plain("hello 👨‍👩‍👧‍👦 goodbye", &Selection::single(13, 6)),
- String::from("hello #[|👨‍👩‍👧‍👦]# goodbye")
- );
- }
-}