mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 21:28:51 +00:00
generalize folding tests
By using xml-like tags, we will be able to test nested foldings.
This commit is contained in:
parent
61dcaa6add
commit
8d7e8a175e
2 changed files with 52 additions and 28 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue