diff --git a/helix-core/src/surround.rs b/helix-core/src/surround.rs index 2d4242b39..fada7c5c6 100644 --- a/helix-core/src/surround.rs +++ b/helix-core/src/surround.rs @@ -439,7 +439,7 @@ pub fn find_prev_tag( loop { let prev_char = match chars.prev() { Some(ch) => ch, - None => return Err(Error::RangeExceedsText), + None => return Err(Error::PairNotFound), }; cursor_pos -= 1; @@ -448,7 +448,7 @@ pub fn find_prev_tag( loop { let current_char = match chars.prev() { Some(ch) => ch, - None => return Err(Error::RangeExceedsText), + None => return Err(Error::PairNotFound), }; cursor_pos -= 1; if current_char == '<' { @@ -485,13 +485,13 @@ pub fn find_next_tag( loop { let next_char = match chars.next() { Some(ch) => ch, - None => return Err(Error::RangeExceedsText), + None => return Err(Error::PairNotFound), }; cursor_pos += 1; if next_char == '<' { let char_after_that = match chars.next() { Some(ch) => ch, - None => return Err(Error::RangeExceedsText), + None => return Err(Error::PairNotFound), }; cursor_pos += 1; if char_after_that == '/' { @@ -499,7 +499,7 @@ pub fn find_next_tag( loop { let current_char = match chars.next() { Some(ch) => ch, - None => return Err(Error::RangeExceedsText), + None => return Err(Error::PairNotFound), }; cursor_pos += 1; if is_valid_tagname_char(current_char) { @@ -665,7 +665,7 @@ mod test { } #[test] - fn test_find_surrounding_tag_with_imposter() { + fn test_find_surrounding_tag_with_extra_closing_tag() { let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( "
test
", " ___ ^ ___ ", @@ -679,11 +679,11 @@ mod test { } #[test] - fn test_find_surrounding_tag_with_many_tags() { + fn test_find_surrounding_tag_with_broken_tags() { let (doc, selection, _) = rope_with_selections_and_expectations_tags( "
simple example
", " ^ ", - vec!["span"], + vec![], ); assert_eq!( @@ -693,7 +693,7 @@ mod test { } #[test] - fn test_find_surrounding_tag_with_many_many_tags() { + fn test_find_surrounding_tag_with_many_tags() { let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( "
simple example
", " ____ ^ ____ ", @@ -707,10 +707,10 @@ mod test { } #[test] - fn test_find_surrounding_tag_with_nth_tag() { + fn test_find_surrounding_tag_with_nth_tag_newline() { let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( - "
test
", - " ____ ^ ____ ", + "
test\n\n
", + " ____ ^ \n\n ____ ", vec!["span"], ); @@ -734,6 +734,90 @@ mod test { ); } + #[test] + fn test_find_surrounding_tag_empty_document() { + let (doc, selection, _) = rope_with_selections_and_expectations_tags( + " hello world, wonderful world! ", + " ^ ", + vec![], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 1), + Err(Error::PairNotFound) + ); + } + + #[test] + fn test_find_surrounding_tag_unclosed_tag() { + let (doc, selection, _) = rope_with_selections_and_expectations_tags( + "this is an
Unclosed tag", + " ^ ", + vec![], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 1), + Err(Error::PairNotFound) + ); + } + + #[test] + fn test_find_surrounding_tag_nested_with_partial_overlap() { + let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( + "

Text

", + " ____ ^ ____ ", + vec!["span"], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 1), + expectations + ); + } + + #[test] + fn test_find_surrounding_tag_nested_same_tag_multiple_levels() { + let (doc, selection, _) = rope_with_selections_and_expectations_tags( + "
Nested
", + " ___ ^ ___ ", + vec!["div"], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 2), + Err(Error::PairNotFound) + ); + } + + #[test] + fn test_find_surrounding_tag_self_closing_tags_ignored() { + let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( + "
Text
", + " ___ ^ ___ ", + vec!["div"], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 1), + expectations + ); + } + + #[test] + fn test_find_surrounding_tag_adjacent_tags() { + let (doc, selection, expectations) = rope_with_selections_and_expectations_tags( + "
", + " ___ ^ ___ ", + vec!["div"], + ); + + assert_eq!( + get_surround_pos_tag(doc.slice(..), &selection, 1), + expectations + ); + } + /// Create a Rope and a matching Selection using a specification language. /// ^ is a cursor position. /// Continuous _ denote start and end of ranges. These are returned as (Range, Range)