generalize folding tests

By using xml-like tags, we will be able to test nested foldings.
This commit is contained in:
Aleksey Kladov 2018-12-20 22:30:30 +03:00
parent 61dcaa6add
commit 8d7e8a175e
2 changed files with 52 additions and 28 deletions

View file

@ -170,7 +170,7 @@ mod tests {
use test_utils::extract_ranges; use test_utils::extract_ranges;
fn do_check(text: &str, fold_kinds: &[FoldKind]) { fn do_check(text: &str, fold_kinds: &[FoldKind]) {
let (ranges, text) = extract_ranges(text); let (ranges, text) = extract_ranges(text, "fold");
let file = SourceFileNode::parse(&text); let file = SourceFileNode::parse(&text);
let folds = folding_ranges(&file); let folds = folding_ranges(&file);
@ -198,22 +198,22 @@ mod tests {
#[test] #[test]
fn test_fold_comments() { fn test_fold_comments() {
let text = r#" let text = r#"
<|>// Hello <fold>// Hello
// this is a multiline // this is a multiline
// comment // comment
//<|> //</fold>
// But this is not // But this is not
fn main() { fn main() {
<|>// We should <fold>// We should
// also // also
// fold // fold
// this one.<|> // this one.</fold>
<|>//! But this one is different <fold>//! But this one is different
//! because it has another flavor<|> //! because it has another flavor</fold>
<|>/* As does this <fold>/* As does this
multiline comment */<|> multiline comment */</fold>
}"#; }"#;
let fold_kinds = &[ let fold_kinds = &[
@ -228,11 +228,11 @@ fn main() {
#[test] #[test]
fn test_fold_imports() { fn test_fold_imports() {
let text = r#" let text = r#"
<|>use std::{ <fold>use std::{
str, str,
vec, vec,
io as iop io as iop
};<|> };</fold>
fn main() { fn main() {
}"#; }"#;
@ -244,12 +244,12 @@ fn main() {
#[test] #[test]
fn test_fold_import_groups() { fn test_fold_import_groups() {
let text = r#" let text = r#"
<|>use std::str; <fold>use std::str;
use std::vec; use std::vec;
use std::io as iop;<|> use std::io as iop;</fold>
<|>use std::mem; <fold>use std::mem;
use std::f64;<|> use std::f64;</fold>
use std::collections::HashMap; use std::collections::HashMap;
// Some random comment // Some random comment
@ -265,17 +265,17 @@ fn main() {
#[test] #[test]
fn test_fold_import_and_groups() { fn test_fold_import_and_groups() {
let text = r#" let text = r#"
<|>use std::str; <fold>use std::str;
use std::vec; use std::vec;
use std::io as iop;<|> use std::io as iop;</fold>
<|>use std::mem; <fold>use std::mem;
use std::f64;<|> use std::f64;</fold>
<|>use std::collections::{ <fold>use std::collections::{
HashMap, HashMap,
VecDeque, VecDeque,
};<|> };</fold>
// Some random comment // Some random comment
fn main() { fn main() {

View file

@ -66,15 +66,39 @@ pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
Some((TextRange::from_to(start, end), text)) Some((TextRange::from_to(start, end), text))
} }
pub fn extract_ranges(text: &str) -> (Vec<TextRange>, String) { /// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
let open = format!("<{}>", tag);
let close = format!("</{}>", tag);
let mut ranges = Vec::new(); let mut ranges = Vec::new();
let mut text = String::from(text); let mut res = String::new();
while let Some((range, new_text)) = try_extract_range(&text) { let mut stack = Vec::new();
text = new_text; loop {
ranges.push(range); match text.find('<') {
None => {
res.push_str(text);
break;
}
Some(i) => {
res.push_str(&text[..i]);
text = &text[i..];
if text.starts_with(&open) {
text = &text[open.len()..];
let from = TextUnit::of_str(&res);
stack.push(from);
} else if text.starts_with(&close) {
text = &text[close.len()..];
let from = stack
.pop()
.unwrap_or_else(|| panic!("unmatched </{}>", tag));
let to = TextUnit::of_str(&res);
ranges.push(TextRange::from_to(from, to));
}
}
}
} }
assert!(stack.is_empty(), "unmatched <{}>", tag);
(ranges, text) (ranges, res)
} }
pub fn add_cursor(text: &str, offset: TextUnit) -> String { pub fn add_cursor(text: &str, offset: TextUnit) -> String {