mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-12-23 09:19:21 +00:00
Start replacing old integration tests and benches
This commit is contained in:
parent
58633bf5a4
commit
52b62ffa0b
11 changed files with 0 additions and 862 deletions
|
|
@ -50,9 +50,5 @@ walkdir = "2"
|
|||
criterion = "0.3"
|
||||
indoc = "0.3.4"
|
||||
|
||||
[[bench]]
|
||||
name = "completion"
|
||||
harness = false
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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(¶ms.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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
103
src/scenario.rs
103
src/scenario.rs
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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)
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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())]
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue