diff options
Diffstat (limited to 'support/texlab/crates/test-utils')
-rw-r--r-- | support/texlab/crates/test-utils/Cargo.toml | 17 | ||||
-rw-r--r-- | support/texlab/crates/test-utils/src/fixture.rs | 103 | ||||
-rw-r--r-- | support/texlab/crates/test-utils/src/lib.rs | 1 |
3 files changed, 121 insertions, 0 deletions
diff --git a/support/texlab/crates/test-utils/Cargo.toml b/support/texlab/crates/test-utils/Cargo.toml new file mode 100644 index 0000000000..4ce7b1a5ca --- /dev/null +++ b/support/texlab/crates/test-utils/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "test-utils" +version = "0.0.0" +license.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true + +[dependencies] +base-db = { path = "../base-db" } +distro = { path = "../distro" } +rowan = "0.15.11" +syntax = { path = "../syntax" } +url = "2.3.1" + +[lib] +doctest = false diff --git a/support/texlab/crates/test-utils/src/fixture.rs b/support/texlab/crates/test-utils/src/fixture.rs new file mode 100644 index 0000000000..2935b4f519 --- /dev/null +++ b/support/texlab/crates/test-utils/src/fixture.rs @@ -0,0 +1,103 @@ +use std::path::PathBuf; + +use base_db::{Owner, Workspace}; +use rowan::{TextRange, TextSize}; +use url::Url; + +#[derive(Debug)] +pub struct Fixture { + pub workspace: Workspace, + pub documents: Vec<DocumentSpec>, +} + +impl Fixture { + pub fn parse(input: &str) -> Fixture { + let mut documents = Vec::new(); + + let mut start = 0; + for end in input + .match_indices("%!") + .skip(1) + .map(|(i, _)| i) + .chain(std::iter::once(input.len())) + { + documents.push(DocumentSpec::parse(&input[start..end])); + start = end; + } + + let mut workspace = Workspace::default(); + for document in &documents { + let path = PathBuf::from(document.uri.path()); + let language = distro::Language::from_path(&path).unwrap_or(distro::Language::Tex); + + workspace.open( + document.uri.clone(), + document.text.clone(), + language, + Owner::Client, + TextSize::from(0), + ); + } + + Self { + workspace, + documents, + } + } +} + +#[derive(Debug)] +pub struct DocumentSpec { + pub uri: Url, + pub text: String, + pub cursor: Option<TextSize>, + pub ranges: Vec<TextRange>, +} + +impl DocumentSpec { + pub fn parse(input: &str) -> Self { + let (uri_str, input) = input + .trim() + .strip_prefix("%! ") + .map(|input| input.split_once('\n').unwrap_or((input, ""))) + .unwrap(); + + let uri = Url::parse(&format!("file:///texlab/{uri_str}")).unwrap(); + + let mut ranges = Vec::new(); + let mut cursor = None; + + let mut text = String::new(); + for line in input.lines().map(|line| line.trim_end()) { + if line.chars().all(|c| matches!(c, ' ' | '^' | '|' | '!')) && !line.is_empty() { + cursor = cursor.or_else(|| { + let offset = line.find('|')?; + Some(TextSize::from((text.len() + offset) as u32)) + }); + + if let Some(start) = line.find('!') { + let position = TextSize::from((text.len() + start) as u32); + ranges.push(TextRange::new(position, position)); + } + + if let Some(start) = line.find('^') { + let end = line.rfind('^').unwrap() + 1; + ranges.push(TextRange::new( + TextSize::from((text.len() + start) as u32), + TextSize::from((text.len() + end) as u32), + )); + } + } else { + text.push_str(line); + text.push('\n'); + } + } + + Self { + uri, + text, + cursor, + ranges, + } + } +} diff --git a/support/texlab/crates/test-utils/src/lib.rs b/support/texlab/crates/test-utils/src/lib.rs new file mode 100644 index 0000000000..8e0974bc65 --- /dev/null +++ b/support/texlab/crates/test-utils/src/lib.rs @@ -0,0 +1 @@ +pub mod fixture; |