Start replacing old integration tests and benches

This commit is contained in:
Patrick Förster 2019-09-27 15:11:10 +02:00
parent 58633bf5a4
commit 52b62ffa0b
11 changed files with 0 additions and 862 deletions

View file

@ -50,9 +50,5 @@ walkdir = "2"
criterion = "0.3"
indoc = "0.3.4"
[[bench]]
name = "completion"
harness = false
[profile.release]
lto = true

View file

@ -1,95 +0,0 @@
use criterion::{criterion_group, Criterion};
use futures::executor::block_on;
use lsp_types::*;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
fn initialize(name: &'static str) -> Scenario {
let scenario = block_on(Scenario::new("completion/bench", &FULL_CAPABILITIES));
block_on(scenario.open(name));
scenario
}
fn run(scenario: &Scenario, name: &str, position: Position, has_items: bool) {
let uri = scenario.uri(name);
let params = CompletionParams {
text_document_position: TextDocumentPositionParams {
text_document: TextDocumentIdentifier::new(uri.into()),
position,
},
context: None,
};
let items = block_on(scenario.server.completion(params)).unwrap();
assert_eq!(items.items.len() > 0, has_items);
}
fn criterion_benchmark(criterion: &mut Criterion) {
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX word", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(5, 0), false);
});
});
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX command", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(6, 1), true);
})
});
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX argument symbol", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(7, 8), true);
});
});
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX environment", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(8, 7), true);
});
});
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX class import", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(9, 15), true);
});
});
let scenario = initialize("foo.tex");
criterion.bench_function("LaTeX package import", move |b| {
b.iter(|| {
run(&scenario, "foo.tex", Position::new(10, 12), true);
});
});
let scenario = initialize("foo.bib");
criterion.bench_function("BibTeX type", move |b| {
b.iter(|| {
run(&scenario, "foo.bib", Position::new(0, 1), true);
});
});
let scenario = initialize("foo.bib");
criterion.bench_function("BibTeX field", move |b| {
b.iter(|| {
run(&scenario, "foo.bib", Position::new(3, 5), true);
});
});
let scenario = initialize("foo.bib");
criterion.bench_function("BibTeX command", move |b| {
b.iter(|| {
run(&scenario, "foo.bib", Position::new(7, 14), true);
});
});
}
criterion_group!(benches, criterion_benchmark);
#[tokio::main]
async fn main() {
benches();
}

View file

@ -1,14 +1,7 @@
use crate::build::BuildOptions;
use crate::diagnostics::LatexLintOptions;
use crate::formatting::bibtex::BibtexFormattingOptions;
use crate::workspace::Uri;
use futures::lock::Mutex;
use futures_boxed::boxed;
use jsonrpc::client::Result;
use jsonrpc_derive::{jsonrpc_client, jsonrpc_method};
use lsp_types::*;
use serde::Serialize;
use std::collections::HashMap;
#[jsonrpc_client(LatexLspClient)]
pub trait LspClient {
@ -40,84 +33,3 @@ pub trait LspClient {
#[boxed]
async fn log_message(&self, params: LogMessageParams);
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct LspClientMockOptions {
pub bibtex_formatting: Option<BibtexFormattingOptions>,
pub latex_lint: Option<LatexLintOptions>,
pub latex_build: Option<BuildOptions>,
}
#[derive(Debug, Default)]
pub struct LspClientMock {
pub messages: Mutex<Vec<ShowMessageParams>>,
pub options: Mutex<LspClientMockOptions>,
pub diagnostics_by_uri: Mutex<HashMap<Uri, Vec<Diagnostic>>>,
pub log_messages: Mutex<Vec<LogMessageParams>>,
}
impl LspClientMock {
pub async fn log(&self) -> String {
let messages = self.log_messages.lock().await;
let mut combined_message = String::new();
for params in messages.iter() {
combined_message.push_str(&params.message);
combined_message.push('\n');
}
combined_message
}
}
impl LspClient for LspClientMock {
#[boxed]
async fn configuration(&self, params: ConfigurationParams) -> Result<serde_json::Value> {
fn serialize<T>(options: &Option<T>) -> Result<serde_json::Value>
where
T: Serialize,
{
options
.as_ref()
.map(|options| serde_json::to_value(vec![options]).unwrap())
.ok_or_else(|| jsonrpc::Error::internal_error("Internal error".to_owned()))
}
let options = self.options.lock().await;
match params.items[0].section.as_ref().unwrap().as_ref() {
"bibtex.formatting" => serialize(&options.bibtex_formatting),
"latex.lint" => serialize(&options.latex_lint),
"latex.build" => serialize(&options.latex_build),
_ => panic!("Invalid language configuration!"),
}
}
#[boxed]
async fn show_message(&self, params: ShowMessageParams) {
let mut messages = self.messages.lock().await;
messages.push(params);
}
#[boxed]
async fn register_capability(&self, _params: RegistrationParams) -> Result<()> {
Ok(())
}
#[boxed]
async fn publish_diagnostics(&self, params: PublishDiagnosticsParams) {
let mut diagnostics_by_uri = self.diagnostics_by_uri.lock().await;
diagnostics_by_uri.insert(params.uri.into(), params.diagnostics);
}
#[boxed]
async fn work_done_progress_create(&self, _params: WorkDoneProgressCreateParams) -> Result<()> {
Ok(())
}
#[boxed]
async fn progress(&self, _params: ProgressParams) {}
#[boxed]
async fn log_message(&self, params: LogMessageParams) {
let mut messages = self.log_messages.lock().await;
messages.push(params);
}
}

View file

@ -18,7 +18,6 @@ pub mod link;
pub mod range;
pub mod reference;
pub mod rename;
pub mod scenario;
pub mod server;
pub mod symbol;
pub mod syntax;

View file

@ -1,103 +0,0 @@
use crate::client::LspClientMock;
use crate::server::LatexLspServer;
use crate::workspace::Uri;
use copy_dir::copy_dir;
use jsonrpc::server::ActionHandler;
use lsp_types::*;
use std::fs::remove_dir;
use std::path::PathBuf;
use std::sync::Arc;
use tempfile::TempDir;
pub static FULL_CAPABILITIES: ClientCapabilities = ClientCapabilities {
workspace: Some(WorkspaceClientCapabilities {
configuration: Some(true),
did_change_watched_files: Some(GenericCapability {
dynamic_registration: Some(true),
}),
workspace_folders: None,
apply_edit: None,
execute_command: None,
symbol: None,
workspace_edit: None,
did_change_configuration: None,
}),
text_document: None,
experimental: None,
window: Some(WindowClientCapabilities {
work_done_progress: Some(true),
}),
};
pub struct Scenario {
pub server: LatexLspServer<LspClientMock>,
pub client: Arc<LspClientMock>,
pub directory: TempDir,
}
impl Scenario {
pub async fn new<'a>(name: &'a str, client_capabilities: &'a ClientCapabilities) -> Self {
let directory = tempfile::tempdir().unwrap();
remove_dir(directory.path()).unwrap();
let source = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("scenarios")
.join(name);
copy_dir(source, directory.path()).unwrap();
let client = Arc::new(LspClientMock::default());
let server = LatexLspServer::new(Arc::clone(&client));
let root_uri = Uri::from_file_path(directory.path()).unwrap();
let init_params = InitializeParams {
process_id: None,
root_path: Some(directory.path().to_string_lossy().into_owned()),
root_uri: Some(root_uri.into()),
initialization_options: None,
capabilities: client_capabilities.to_owned(),
trace: None,
workspace_folders: None,
};
server.initialize(init_params).await.unwrap();
server.execute_actions().await;
server.initialized(InitializedParams {});
server.execute_actions().await;
Self {
server,
client,
directory,
}
}
pub fn uri(&self, name: &str) -> Uri {
let mut path = self.directory.path().to_owned();
path.push(name);
Uri::from_file_path(path).unwrap()
}
pub async fn read(&self, name: &'static str) -> String {
let mut path = self.directory.path().to_owned();
path.push(name);
std::fs::read_to_string(path).unwrap().replace('\r', "")
}
pub async fn open(&self, name: &'static str) {
let text = self.read(name).await;
let language_id = if name.ends_with(".tex") {
"latex"
} else {
"bibtex"
};
self.server.did_open(DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: self.uri(name).into(),
version: 0,
language_id: language_id.to_owned(),
text,
},
});
self.server.execute_actions().await;
}
}

View file

@ -1,218 +0,0 @@
use lsp_types::*;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
pub async fn run(scenario: &'static str, file: &'static str, position: Position) -> Vec<String> {
let scenario = format!("completion/{}", scenario);
let scenario = Scenario::new(&scenario, &FULL_CAPABILITIES).await;
scenario.open(file).await;
let params = CompletionParams {
text_document_position: TextDocumentPositionParams {
text_document: TextDocumentIdentifier::new(scenario.uri(file).into()),
position,
},
context: None,
};
let items = scenario
.server
.completion(params)
.await
.unwrap()
.items
.into_iter()
.map(|item| (*item.label).to_owned())
.collect();
scenario.directory.close().unwrap();
items
}
#[tokio::test]
async fn test_kernel_command() {
let items = run("kernel", "foo.tex", Position::new(2, 5)).await;
assert!(items.iter().any(|item| item == "usepackage"));
}
#[tokio::test]
async fn test_kernel_command_bibtex() {
let items = run("kernel", "foo.bib", Position::new(1, 17)).await;
assert!(items.iter().any(|item| item == "LaTeX"));
}
#[tokio::test]
async fn test_kernel_environment() {
let items = run("kernel", "foo.tex", Position::new(4, 10)).await;
assert!(items.iter().any(|item| item == "document"));
}
#[tokio::test]
async fn test_user_command() {
let items = run("user", "foo.tex", Position::new(2, 3)).await;
assert!(items.iter().all(|item| item != "fo"));
assert!(items.iter().any(|item| item == "foo"));
}
#[tokio::test]
async fn test_label() {
let mut items = run("label", "foo.tex", Position::new(5, 5)).await;
items.sort();
assert_eq!(items, vec!["bar", "baz", "foo"]);
}
#[tokio::test]
async fn test_citation() {
let mut items = run("citation", "foo.tex", Position::new(3, 6)).await;
items.sort();
assert_eq!(items, vec!["bar", "baz", "foo"]);
}
#[tokio::test]
async fn test_symbol_command_kernel() {
let items = run("symbol", "foo.tex", Position::new(0, 1)).await;
assert!(items.iter().any(|item| item == "varepsilon"));
}
#[tokio::test]
async fn test_symbol_argument() {
let items = run("symbol", "foo.tex", Position::new(1, 8)).await;
assert_eq!(items.len(), 26);
assert_eq!(items[0], "A");
}
#[tokio::test]
async fn test_color() {
let items = run("color", "foo.tex", Position::new(0, 10)).await;
assert!(items.iter().any(|item| item == "black"));
}
#[tokio::test]
async fn test_color_model() {
let items = run("color", "foo.tex", Position::new(1, 18)).await;
assert!(items.iter().any(|item| item == "rgb"));
}
#[tokio::test]
async fn test_include_top_level() {
let mut items = run("include", "foo.tex", Position::new(0, 9)).await;
items.sort();
assert_eq!(items, vec!["bar", "foo", "qux"]);
}
#[tokio::test]
async fn test_include_directory() {
let mut items = run("include", "foo.tex", Position::new(1, 11)).await;
items.sort();
assert_eq!(items, vec!["bar.tex", "baz.tex"]);
}
#[tokio::test]
async fn test_include_bibliography() {
let items = run("include", "bar/baz.tex", Position::new(0, 16)).await;
assert_eq!(items, vec!["foo.bib"]);
}
#[tokio::test]
async fn test_include_graphics() {
let mut items = run("include", "bar/baz.tex", Position::new(1, 17)).await;
items.sort();
assert_eq!(items, vec!["image1.png", "image2.jpg"]);
}
#[tokio::test]
async fn test_include_graphics_svg() {
let items = run("include", "bar/baz.tex", Position::new(2, 12)).await;
assert_eq!(items, vec!["image3"]);
}
#[tokio::test]
async fn test_import_class() {
let items = run("import", "foo.tex", Position::new(0, 18)).await;
assert!(items.iter().any(|item| item == "article"));
}
#[tokio::test]
async fn test_import_package() {
let items = run("import", "foo.tex", Position::new(1, 15)).await;
assert!(items.iter().any(|item| item == "amsmath"));
}
#[tokio::test]
async fn test_package_command() {
let items = run("component", "foo.tex", Position::new(2, 3)).await;
assert!(items.iter().any(|item| item == "AmS"));
}
#[tokio::test]
async fn test_package_environment() {
let items = run("component", "foo.tex", Position::new(3, 11)).await;
assert!(items.iter().any(|item| item == "align"));
}
#[tokio::test]
async fn test_class_command() {
let items = run("component", "foo.tex", Position::new(4, 8)).await;
assert!(items.iter().any(|item| item == "thetable"));
}
#[tokio::test]
async fn test_class_environment() {
let items = run("component", "foo.tex", Position::new(5, 14)).await;
assert!(items.iter().any(|item| item == "theindex"));
}
#[tokio::test]
async fn test_multiple_packages() {
let items = run("component", "bar.tex", Position::new(2, 8)).await;
assert!(items.iter().any(|item| item == "varDelta"));
let items = run("component", "bar.tex", Position::new(3, 8)).await;
assert!(items.iter().any(|item| item == "geometry"));
}
#[tokio::test]
async fn test_pgf_library() {
let items = run("pgf_library", "foo.tex", Position::new(0, 18)).await;
assert!(items.iter().any(|item| item == "arrows"));
}
#[tokio::test]
async fn test_tikz_library() {
let items = run("tikz_library", "foo.tex", Position::new(0, 19)).await;
assert!(items.iter().any(|item| item == "arrows"));
}
#[tokio::test]
async fn test_entry_type() {
let items = run("entry_type", "foo.bib", Position::new(0, 1)).await;
assert!(items.iter().any(|item| item == "article"));
}
#[tokio::test]
async fn test_entry_type_preamble() {
let items = run("entry_type", "foo.bib", Position::new(1, 3)).await;
assert!(items.iter().any(|item| item == "preamble"));
}
#[tokio::test]
async fn test_entry_type_string() {
let items = run("entry_type", "foo.bib", Position::new(2, 3)).await;
assert!(items.iter().any(|item| item == "string"));
}
#[tokio::test]
async fn test_entry_type_comment() {
let items = run("entry_type", "foo.bib", Position::new(3, 3)).await;
assert!(items.iter().any(|item| item == "comment"));
}
#[tokio::test]
async fn test_field_name() {
let items = run("field_name", "foo.bib", Position::new(1, 7)).await;
assert!(items.iter().any(|item| item == "author"));
}
#[tokio::test]
async fn test_preselect() {
let items = run("preselect", "foo.tex", Position::new(4, 5)).await;
assert_eq!(items[0], "center");
}

View file

@ -1,46 +0,0 @@
use lsp_types::*;
use texlab::definition::DefinitionResponse;
use texlab::range::RangeExt;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
pub async fn run(
scenario: &'static str,
file: &'static str,
position: Position,
) -> (Scenario, Vec<Location>) {
let scenario = format!("definition/{}", scenario);
let scenario = Scenario::new(&scenario, &FULL_CAPABILITIES).await;
let identifier = TextDocumentIdentifier::new(scenario.uri(file).into());
let params = TextDocumentPositionParams::new(identifier, position);
scenario.open(file).await;
let definitions = scenario.server.definition(params).await.unwrap();
let locations = match definitions {
DefinitionResponse::Locations(locations) => locations,
DefinitionResponse::LocationLinks(_) => unreachable!(),
};
(scenario, locations)
}
#[tokio::test]
async fn test_citation() {
let (scenario, definitions) = run("citation", "foo.tex", Position::new(5, 8)).await;
assert_eq!(
definitions,
vec![Location::new(
scenario.uri("foo.bib").into(),
Range::new_simple(2, 9, 2, 12)
)]
);
}
#[tokio::test]
async fn test_label() {
let (scenario, definitions) = run("label", "foo.tex", Position::new(8, 8)).await;
assert_eq!(
definitions,
vec![Location::new(
scenario.uri("bar.tex").into(),
Range::new_simple(0, 0, 0, 11)
)]
);
}

View file

@ -1,53 +0,0 @@
use jsonrpc::server::ActionHandler;
use lsp_types::*;
use texlab::diagnostics::BibtexErrorCode;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
#[tokio::test]
async fn test_lint_latex_disabled() {
let scenario = Scenario::new("diagnostics/lint", &FULL_CAPABILITIES).await;
scenario.open("foo.tex").await;
let identifier = TextDocumentIdentifier::new(scenario.uri("foo.tex").into());
scenario.server.did_save(DidSaveTextDocumentParams {
text_document: identifier,
});
scenario.server.execute_actions().await;
let diagnostics_by_uri = scenario.client.diagnostics_by_uri.lock().await;
let diagnostics = diagnostics_by_uri.get(&scenario.uri("foo.tex")).unwrap();
assert!(diagnostics.is_empty());
}
#[tokio::test]
async fn test_lint_bibtex() {
let scenario = Scenario::new("diagnostics/lint", &FULL_CAPABILITIES).await;
scenario.open("foo.bib").await;
let diagnostics_by_uri = scenario.client.diagnostics_by_uri.lock().await;
let diagnostics = diagnostics_by_uri.get(&scenario.uri("foo.bib")).unwrap();
assert_eq!(diagnostics.len(), 1);
assert_eq!(
diagnostics[0].message,
BibtexErrorCode::MissingBeginBrace.message()
);
assert_eq!(diagnostics[0].range.start.line, 0);
}
#[tokio::test]
async fn test_build() {
let scenario = Scenario::new("diagnostics/build", &FULL_CAPABILITIES).await;
scenario.open("foo.tex").await;
scenario
.server
.did_change_watched_files(DidChangeWatchedFilesParams {
changes: vec![FileEvent {
uri: scenario.uri("foo.log").into(),
typ: FileChangeType::Changed,
}],
});
scenario.server.execute_actions().await;
let diagnostics_by_uri = scenario.client.diagnostics_by_uri.lock().await;
let diagnostics = diagnostics_by_uri.get(&scenario.uri("foo.tex")).unwrap();
assert_eq!(diagnostics.len(), 1);
assert_eq!(diagnostics[0].message, "Undefined control sequence.");
assert_eq!(diagnostics[0].range.start.line, 3);
}

View file

@ -1,56 +0,0 @@
use lsp_types::*;
use std::collections::HashMap;
use texlab::formatting::bibtex::BibtexFormattingOptions;
use texlab::range::RangeExt;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
pub async fn run(
scenario: &'static str,
file: &'static str,
options: Option<BibtexFormattingOptions>,
) -> (Scenario, Vec<TextEdit>) {
let scenario = format!("formatting/{}", scenario);
let scenario = Scenario::new(&scenario, &FULL_CAPABILITIES).await;
scenario.open(file).await;
scenario.client.options.lock().await.bibtex_formatting = options;
let params = DocumentFormattingParams {
text_document: TextDocumentIdentifier::new(scenario.uri(file).into()),
options: FormattingOptions {
tab_size: 4,
insert_spaces: true,
properties: HashMap::new(),
},
};
let edits = scenario.server.formatting(params).await.unwrap();
(scenario, edits)
}
#[tokio::test]
async fn test_bibtex_entry_default() {
let (scenario, edits) = run("bibtex/default", "foo.bib", None).await;
assert_eq!(edits.len(), 1);
assert_eq!(edits[0].new_text, scenario.read("bar.bib").await);
assert_eq!(edits[0].range, Range::new_simple(0, 0, 0, 52));
}
#[tokio::test]
async fn test_bibtex_entry_infinite_line_length() {
let (scenario, edits) = run(
"bibtex/infinite_line_length",
"foo.bib",
Some(BibtexFormattingOptions {
line_length: Some(0),
}),
)
.await;
assert_eq!(edits.len(), 1);
assert_eq!(edits[0].new_text, scenario.read("bar.bib").await);
assert_eq!(edits[0].range, Range::new_simple(0, 0, 0, 149));
}
#[tokio::test]
async fn test_latex() {
let (_, edits) = run("latex", "foo.tex", None).await;
assert!(edits.is_empty());
}

View file

@ -1,98 +0,0 @@
use lsp_types::*;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
use texlab::syntax::LANGUAGE_DATA;
pub async fn run(
scenario: &'static str,
file: &'static str,
position: Position,
) -> Option<HoverContents> {
let scenario = format!("hover/{}", scenario);
let scenario = Scenario::new(&scenario, &FULL_CAPABILITIES).await;
scenario.open(file).await;
let identifier = TextDocumentIdentifier::new(scenario.uri(file).into());
let params = TextDocumentPositionParams::new(identifier, position);
let contents = scenario
.server
.hover(params)
.await
.unwrap()
.map(|hover| hover.contents);
contents
}
#[tokio::test]
async fn test_entry_type_known() {
let contents = run("bibtex/entry_type", "foo.bib", Position::new(0, 5))
.await
.unwrap();
assert_eq!(
contents,
HoverContents::Markup(MarkupContent {
kind: MarkupKind::Markdown,
value: LANGUAGE_DATA
.entry_type_documentation("article")
.unwrap()
.to_owned()
})
);
}
#[tokio::test]
async fn test_entry_type_unknown() {
let contents = run("bibtex/entry_type", "foo.bib", Position::new(2, 2)).await;
assert_eq!(contents, None);
}
#[tokio::test]
async fn test_field_known() {
let contents = run("bibtex/field", "foo.bib", Position::new(1, 4))
.await
.unwrap();
assert_eq!(
contents,
HoverContents::Markup(MarkupContent {
kind: MarkupKind::Markdown,
value: LANGUAGE_DATA
.field_documentation("author")
.unwrap()
.to_owned()
})
)
}
#[tokio::test]
async fn test_field_unknown() {
let contents = run("bibtex/field", "foo.bib", Position::new(2, 5)).await;
assert_eq!(contents, None);
}
#[tokio::test]
async fn test_citation_latex() {
let contents = run("latex/citation", "foo.tex", Position::new(2, 7)).await;
assert_ne!(contents, None);
}
#[tokio::test]
async fn test_citation_bibtex() {
let contents = run("latex/citation", "foo.bib", Position::new(0, 11)).await;
assert_ne!(contents, None);
}
#[tokio::test]
async fn test_component_class() {
let contents = run("latex/component", "foo.tex", Position::new(0, 19)).await;
assert!(contents.is_some());
}
#[tokio::test]
async fn test_component_package() {
let contents = run("latex/component", "foo.tex", Position::new(2, 16)).await;
assert!(contents.is_some());
}
#[tokio::test]
async fn test_component_package_unknown() {
let contents = run("latex/component", "foo.tex", Position::new(3, 14)).await;
assert_eq!(contents, None);
}

View file

@ -1,100 +0,0 @@
use jsonrpc::server::ActionHandler;
use lsp_types::*;
use texlab::range::RangeExt;
use texlab::scenario::{Scenario, FULL_CAPABILITIES};
async fn run_completion(
scenario: &Scenario,
file: &'static str,
position: Position,
) -> Vec<CompletionItem> {
let params = CompletionParams {
text_document_position: TextDocumentPositionParams {
text_document: TextDocumentIdentifier::new(scenario.uri(file).into()),
position,
},
context: None,
};
scenario.server.completion(params).await.unwrap().items
}
#[tokio::test]
async fn test_did_change() {
let scenario = Scenario::new("synchronization/did_change", &FULL_CAPABILITIES).await;
scenario.open("foo.tex").await;
assert_eq!(
run_completion(&scenario, "foo.tex", Position::new(0, 1))
.await
.len()
> 0,
false
);
let params = DidChangeTextDocumentParams {
text_document: VersionedTextDocumentIdentifier::new(scenario.uri("foo.tex").into(), 0),
content_changes: vec![TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: "\\".to_owned(),
}],
};
scenario.server.did_change(params);
scenario.server.execute_actions().await;
assert!(!run_completion(&scenario, "foo.tex", Position::new(0, 1))
.await
.is_empty());
}
#[tokio::test]
async fn test_indexing() {
let scenario = Scenario::new("synchronization/did_change", &FULL_CAPABILITIES).await;
scenario.open("foo.tex").await;
let mut path = scenario.directory.path().to_owned();
path.push("bar.tex");
std::fs::write(&path, "\\foo").unwrap();
let params = DidChangeTextDocumentParams {
text_document: VersionedTextDocumentIdentifier::new(scenario.uri("foo.tex").into(), 0),
content_changes: vec![TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: "\\fo\n\\include{bar}".to_owned(),
}],
};
scenario.server.did_change(params);
scenario.server.execute_actions().await;
let items = run_completion(&scenario, "foo.tex", Position::new(0, 1)).await;
assert!(items.iter().any(|item| item.label == "foo"));
}
#[tokio::test]
async fn test_find_root() {
let scenario = Scenario::new("synchronization/find_root", &FULL_CAPABILITIES).await;
scenario.open("test1.tex").await;
let params = RenameParams {
text_document_position: TextDocumentPositionParams {
text_document: TextDocumentIdentifier::new(scenario.uri("test1.tex").into()),
position: Position::new(0, 28),
},
new_name: "foo".into(),
};
let changes = scenario
.server
.rename(params)
.await
.unwrap()
.unwrap()
.changes
.unwrap();
assert_eq!(
changes.get(&scenario.uri("test1.tex")).unwrap(),
&vec![TextEdit::new(Range::new_simple(0, 26, 0, 31), "foo".into())]
);
assert_eq!(
changes.get(&scenario.uri("test2.tex")).unwrap(),
&vec![TextEdit::new(Range::new_simple(2, 41, 2, 46), "foo".into())]
);
}