on master help sign in
fix test::plain

test::plain uses char indices when it should use byte indices

commitd3b051d28ea62c313fc72583d04f2a897e8d6f40 authorSkyler Hawthorne <skyler@dead10ck.com> dateSat 22 Oct 2022, 17:29 (4 years ago) parent58ea193
4 files changed+109−15
helix-core/src/movement.rs+6−6 helix-core/src/test.rs+98−4 helix-core/src/textobject.rs+3−3 helix-term/tests/test/helpers.rs+2−2
helix-core/src/movement.rs+6−6
@@ -1474,7 +1474,7 @@ mod test {
14741474 let text = Rope::from(s.as_str());
14751475 let selection =
14761476 selection.transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Move));
1477− let actual = crate::test::plain(&s, &selection);
1477+ let actual = crate::test::plain(s.as_ref(), &selection);
14781478 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
14791479 }
14801480 }
@@ -1497,7 +1497,7 @@ mod test {
14971497 let text = Rope::from(s.as_str());
14981498 let selection =
14991499 selection.transform(|r| move_prev_paragraph(text.slice(..), r, 2, Movement::Move));
1500− let actual = crate::test::plain(&s, &selection);
1500+ let actual = crate::test::plain(s.as_ref(), &selection);
15011501 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
15021502 }
15031503 }
@@ -1520,7 +1520,7 @@ mod test {
15201520 let text = Rope::from(s.as_str());
15211521 let selection = selection
15221522 .transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Extend));
1523− let actual = crate::test::plain(&s, &selection);
1523+ let actual = crate::test::plain(s.as_ref(), &selection);
15241524 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
15251525 }
15261526 }
@@ -1562,7 +1562,7 @@ mod test {
15621562 let text = Rope::from(s.as_str());
15631563 let selection =
15641564 selection.transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Move));
1565− let actual = crate::test::plain(&s, &selection);
1565+ let actual = crate::test::plain(s.as_ref(), &selection);
15661566 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
15671567 }
15681568 }
@@ -1585,7 +1585,7 @@ mod test {
15851585 let text = Rope::from(s.as_str());
15861586 let selection =
15871587 selection.transform(|r| move_next_paragraph(text.slice(..), r, 2, Movement::Move));
1588− let actual = crate::test::plain(&s, &selection);
1588+ let actual = crate::test::plain(s.as_ref(), &selection);
15891589 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
15901590 }
15911591 }
@@ -1608,7 +1608,7 @@ mod test {
16081608 let text = Rope::from(s.as_str());
16091609 let selection = selection
16101610 .transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Extend));
1611− let actual = crate::test::plain(&s, &selection);
1611+ let actual = crate::test::plain(s.as_ref(), &selection);
16121612 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
16131613 }
16141614 }
helix-core/src/test.rs+98−4
@@ -1,5 +1,6 @@
11//! Test helpers.
22use crate::{Range, Selection};
3+use ropey::Rope;
34use smallvec::SmallVec;
45use std::cmp::Reverse;
56use unicode_segmentation::UnicodeSegmentation;
@@ -148,10 +149,12 @@ pub fn print(s: &str) -> (String, Selection) {
148149/// "#[a|]#b#(|c)#".to_owned()
149150/// );
150151/// ```
151−pub fn plain(s: &str, selection: &Selection) -> String {
152+pub fn plain<R: Into<Rope>>(s: R, selection: &Selection) -> String {
153+ let s = s.into();
152154 let primary = selection.primary_index();
153− let mut out = String::with_capacity(s.len() + 5 * selection.len());
154− out.push_str(s);
155+ let mut out = String::with_capacity(s.len_bytes() + 5 * selection.len());
156+ out.push_str(&s.to_string());
157+
155158 let mut insertion: Vec<_> = selection
156159 .iter()
157160 .enumerate()
@@ -164,7 +167,9 @@ pub fn plain(s: &str, selection: &Selection) -> String {
164167 (false, false) => [(range.anchor, ")#"), (range.head, "#(|")],
165168 }
166169 })
170+ .map(|(char_idx, marker)| (s.char_to_byte(char_idx), marker))
167171 .collect();
172+
168173 // insert in reverse order
169174 insertion.sort_unstable_by_key(|k| Reverse(k.0));
170175 for (i, s) in insertion {
@@ -173,7 +178,6 @@ pub fn plain(s: &str, selection: &Selection) -> String {
173178 out
174179}
175180
176−#[allow(clippy::module_inception)]
177181#[cfg(test)]
178182#[allow(clippy::module_inception)]
179183mod test {
@@ -289,4 +293,94 @@ mod test {
289293 print("hello #[|👨‍👩‍👧‍👦]# goodbye")
290294 );
291295 }
296+
297+ #[test]
298+ fn plain_single() {
299+ assert_eq!("#[|h]#ello", plain("hello", &Selection::single(1, 0)));
300+ assert_eq!("#[h|]#ello", plain("hello", &Selection::single(0, 1)));
301+ assert_eq!("#[|hell]#o", plain("hello", &Selection::single(4, 0)));
302+ assert_eq!("#[hell|]#o", plain("hello", &Selection::single(0, 4)));
303+ assert_eq!("#[|hello]#", plain("hello", &Selection::single(5, 0)));
304+ assert_eq!("#[hello|]#", plain("hello", &Selection::single(0, 5)));
305+ }
306+
307+ #[test]
308+ fn plain_multi() {
309+ assert_eq!(
310+ plain(
311+ "hello",
312+ &Selection::new(
313+ SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),
314+ 0
315+ )
316+ ),
317+ String::from("#[|h]#ell#(|o)#")
318+ );
319+ assert_eq!(
320+ plain(
321+ "hello",
322+ &Selection::new(
323+ SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),
324+ 0
325+ )
326+ ),
327+ String::from("#[h|]#ell#(o|)#")
328+ );
329+ assert_eq!(
330+ plain(
331+ "hello",
332+ &Selection::new(
333+ SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),
334+ 0
335+ )
336+ ),
337+ String::from("#[|he]#l#(|lo)#")
338+ );
339+ assert_eq!(
340+ plain(
341+ "hello\r\nhello\r\nhello\r\n",
342+ &Selection::new(
343+ SmallVec::from_slice(&[
344+ Range::new(7, 5),
345+ Range::new(21, 19),
346+ Range::new(14, 12)
347+ ]),
348+ 0
349+ )
350+ ),
351+ String::from("hello#[|\r\n]#hello#(|\r\n)#hello#(|\r\n)#")
352+ );
353+ }
354+
355+ #[test]
356+ fn plain_multi_byte_code_point() {
357+ assert_eq!(
358+ plain("„“", &Selection::single(1, 0)),
359+ String::from("#[|„]#“")
360+ );
361+ assert_eq!(
362+ plain("„“", &Selection::single(2, 1)),
363+ String::from("„#[|“]#")
364+ );
365+ assert_eq!(
366+ plain("„“", &Selection::single(0, 1)),
367+ String::from("#[„|]#“")
368+ );
369+ assert_eq!(
370+ plain("„“", &Selection::single(1, 2)),
371+ String::from("„#[“|]#")
372+ );
373+ assert_eq!(
374+ plain("they said „hello“", &Selection::single(11, 10)),
375+ String::from("they said #[|„]#hello“")
376+ );
377+ }
378+
379+ #[test]
380+ fn plain_multi_code_point_grapheme() {
381+ assert_eq!(
382+ plain("hello 👨‍👩‍👧‍👦 goodbye", &Selection::single(13, 6)),
383+ String::from("hello #[|👨‍👩‍👧‍👦]# goodbye")
384+ );
385+ }
292386}
helix-core/src/textobject.rs+3−3
@@ -437,7 +437,7 @@ mod test {
437437 let text = Rope::from(s.as_str());
438438 let selection = selection
439439 .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 1));
440− let actual = crate::test::plain(&s, &selection);
440+ let actual = crate::test::plain(s.as_ref(), &selection);
441441 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
442442 }
443443 }
@@ -460,7 +460,7 @@ mod test {
460460 let text = Rope::from(s.as_str());
461461 let selection = selection
462462 .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 2));
463− let actual = crate::test::plain(&s, &selection);
463+ let actual = crate::test::plain(s.as_ref(), &selection);
464464 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
465465 }
466466 }
@@ -491,7 +491,7 @@ mod test {
491491 let text = Rope::from(s.as_str());
492492 let selection = selection
493493 .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Around, 1));
494− let actual = crate::test::plain(&s, &selection);
494+ let actual = crate::test::plain(s.as_ref(), &selection);
495495 assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
496496 }
497497 }
helix-term/tests/test/helpers.rs+2−2
@@ -65,7 +65,7 @@ pub async fn test_key_sequences(
6565
6666 for (i, (in_keys, test_fn)) in inputs.into_iter().enumerate() {
6767 let (view, doc) = current_ref!(app.editor);
68− let state = test::plain(&doc.text().to_string(), doc.selection(view.id));
68+ let state = test::plain(doc.text().slice(..), doc.selection(view.id));
6969
7070 log::debug!("executing test with document state:\n\n-----\n\n{}", state);
7171
@@ -81,7 +81,7 @@ pub async fn test_key_sequences(
8181
8282 if !app_exited {
8383 let (view, doc) = current_ref!(app.editor);
84− let state = test::plain(&doc.text().to_string(), doc.selection(view.id));
84+ let state = test::plain(doc.text().slice(..), doc.selection(view.id));
8585
8686 log::debug!(
8787 "finished running test with document state:\n\n-----\n\n{}",