diff options
Diffstat (limited to 'support/texlab/tests/integration/lsp/text_document/completion.rs')
-rw-r--r-- | support/texlab/tests/integration/lsp/text_document/completion.rs | 870 |
1 files changed, 870 insertions, 0 deletions
diff --git a/support/texlab/tests/integration/lsp/text_document/completion.rs b/support/texlab/tests/integration/lsp/text_document/completion.rs new file mode 100644 index 0000000000..5e160904fe --- /dev/null +++ b/support/texlab/tests/integration/lsp/text_document/completion.rs @@ -0,0 +1,870 @@ +use anyhow::Result; +use insta::assert_json_snapshot; +use lsp_types::{ + request::{Completion, ResolveCompletionItem}, + ClientCapabilities, CompletionItem, CompletionList, CompletionParams, CompletionResponse, + CompletionTextEdit, Range, +}; + +use crate::lsp::{client::Client, fixture}; + +fn complete(fixture: &str) -> Result<Vec<CompletionItem>, anyhow::Error> { + let mut client = Client::spawn()?; + client.initialize(ClientCapabilities::default(), None)?; + let fixture = fixture::parse(fixture); + for file in fixture.files { + client.open(file.name, file.lang, file.text)?; + } + + let range = fixture + .ranges + .values() + .next() + .and_then(|map| map.values().next()) + .map_or_else( + || { + let position = fixture.cursor.unwrap().position; + Range::new(position, position) + }, + |file_range| file_range.range, + ); + + let actual_list = client + .request::<Completion>(CompletionParams { + text_document_position: fixture.cursor.unwrap().into_params(&client)?, + partial_result_params: Default::default(), + work_done_progress_params: Default::default(), + context: None, + })? + .map_or(CompletionList::default(), |actual| match actual { + CompletionResponse::List(list) => list, + CompletionResponse::Array(_) => unreachable!(), + }); + + for item in &actual_list.items { + if let Some(CompletionTextEdit::Edit(edit)) = item.text_edit.as_ref() { + assert_eq!(edit.range, range); + } + } + + let actual_items = actual_list + .items + .into_iter() + .take(5) + .map(|item| client.request::<ResolveCompletionItem>(item)) + .collect::<Result<Vec<_>>>()?; + + client.shutdown()?; + Ok(actual_items) +} + +macro_rules! assert_items { + ($items:expr) => { + assert_json_snapshot!($items, { + "[].data" => "[data]", + "[].sortText" => "[sortText]", + "[].documentation" => "[documentation]", + "[].textEdit.range" => "[range]", + "[]" => insta::sorted_redaction() + }); + }; +} + +#[test] +fn acronym_ref_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \acrshort{f} +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn acronym_ref_empty() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \acrshort{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn acronym_ref_after_group() -> Result<()> { + let actual_items = complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \acrshort{} +%CUR ^ +%1.1 ^"#, + )?; + + assert_eq!(actual_items, Vec::new()); + Ok(()) +} + +#[test] +fn acronym_ref_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \acrshort{f +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn glossary_ref_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \gls{f} +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn glossary_ref_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +%SRC \gls{f +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn argument_empty() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{amsfonts} +%SRC \mathbb{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn argument_word() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{amsfonts} +%SRC \mathbb{A} +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn argument_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{amsfonts} +%SRC \mathbb{ +%CUR ^ +%SRC Test"# + )?); + + Ok(()) +} + +#[test] +fn argument_open_brace_unrelated() -> Result<()> { + let actual_items = complete( + r#" +%TEX main.tex +%SRC \usepackage{amsfonts} +%SRC \mathbb{}{ +%CUR ^ +%SRC Test"#, + )?; + + assert_eq!(actual_items, Vec::new()); + Ok(()) +} + +#[test] +fn begin_environment_without_snippet_support() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \beg +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn citation() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \documentclass{article} +%SRC \bibliography{main} +%SRC \begin{document} +%SRC \cite{ +%CUR ^ +%SRC \end{document} + +%BIB main.bib +%SRC @article{foo:2019, +%SRC author = {Foo Bar}, +%SRC title = {Baz Qux}, +%SRC year = {2019}, +%SRC } +%SRC +%SRC @article{bar:2005,}"# + )?); + + Ok(()) +} + +#[test] +fn citation_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \addbibresource{main.bib} +%SRC \cite{ +%CUR ^ + +%BIB main.bib +%SRC @article{foo,}"# + )?); + + Ok(()) +} + +#[test] +fn citation_open_brace_multiple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \addbibresource{main.bib} +%SRC \cite{foo,a +%CUR ^ +%1.1 ^ + +%BIB main.bib +%SRC @article{foo,}"# + )?); + + Ok(()) +} + +#[test] +fn citation_acronym() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \addbibresource{main.bib} +%SRC \DeclareAcronym{foo}{cite={}} +%CUR ^ + +%BIB main.bib +%SRC @article{foo,}"# + )?); + + Ok(()) +} + +#[test] +fn citation_after_brace() -> Result<()> { + let actual_items = complete( + r#" +%TEX main.tex +%SRC \documentclass{article} +%SRC \bibliography{main} +%SRC \begin{document} +%SRC \cite{} +%CUR ^ +%SRC \end{document} + +%BIB main.bib +%SRC @article{foo,}"#, + )?; + + assert_eq!(actual_items, Vec::new()); + Ok(()) +} + +#[test] +fn color_model_definition_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \definecolor{foo}{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn color_model_definition_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \definecolor{foo}{ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn color_model_definition_set_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \definecolorset{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn color_model_definition_set_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \definecolorset{ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn color_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \color{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn color_word() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \color{re} +%CUR ^ +%1.1 ^^"# + )?); + + Ok(()) +} + +#[test] +fn color_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \color{ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn component_command_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn component_command_simple_before() -> Result<()> { + let actual_items = complete( + r#" +%TEX main.tex +%SRC \ +%CUR ^"#, + )?; + + assert_eq!(actual_items, Vec::new()); + Ok(()) +} + +#[test] +fn component_command_simple_package() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{lipsum} +%SRC \lips +%CUR ^ +%1.1 ^^^^"# + )?); + + Ok(()) +} + +#[test] +fn component_command_bibtex() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{b, +%SRC c = {\LaT } +%CUR ^ +%1.1 ^^^ +%SRC }"# + )?); + + Ok(()) +} + +#[test] +fn component_environment_simple() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \begin{doc +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn component_environment_simple_end() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \begin{document} +%SRC \end{ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn component_environment_class() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \documentclass{article} +%SRC \begin{thein} +%CUR ^ +%1.1 ^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn component_environment_command_definition() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newcommand{\foo}{\begin{doc} +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_at_empty() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_before_preamble() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @preamble +%CUR ^ +%1.1 ^^^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_before_string() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @string +%CUR ^ +%1.1 ^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_before_article() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article +%CUR ^ +%1.1 ^^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_after_preamble() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @preamble{ +%CUR ^ +%1.1 ^^^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_after_string() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @string{ +%CUR ^ +%1.1 ^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn entry_type_complete_entry() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo, author = {foo}} +%CUR ^ +%1.1 ^^^^^^^"# + )?); + + Ok(()) +} + +#[test] +fn field_empty_entry_open() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo, +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn field_empty_entry_closed() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo,} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn field_entry_field_name() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo, a +%CUR ^ +%1.1 ^"# + )?); + + Ok(()) +} + +#[test] +fn field_entry_two_fields_name_open() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo, author = bar, edit +%CUR ^ +%1.1 ^^^^"# + )?); + + Ok(()) +} + +#[test] +fn field_entry_two_fields_name_closed() -> Result<()> { + assert_items!(complete( + r#" +%BIB main.bib +%SRC @article{foo, author = bar, edit} +%CUR ^ +%1.1 ^^^^"# + )?); + + Ok(()) +} + +#[test] +fn import_package_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{lips +%CUR ^ +%1.1 ^^^^"# + )?); + + Ok(()) +} + +#[test] +fn import_package_closed_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepackage{lips} +%CUR ^ +%1.1 ^^^^"# + )?); + + Ok(()) +} + +#[test] +fn import_class_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \documentclass{art \foo +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn import_class_closed_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \documentclass{art} +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn label() -> Result<()> { + assert_items!(complete( + r#" +%TEX foo.tex +%SRC \documentclass{article} +%SRC +%SRC \usepackage{amsmath} +%SRC \usepackage{caption} +%SRC \usepackage{amsthm} +%SRC \newtheorem{lemma}{Lemma} +%SRC +%SRC \begin{document} +%SRC +%SRC \section{Foo}% +%SRC \label{sec:foo} +%SRC +%SRC \begin{equation}% +%SRC \label{eq:foo} +%SRC 1 + 1 = 2 +%SRC \end{equation} +%SRC +%SRC \begin{equation}% +%SRC \label{eq:bar} +%SRC 1 + 1 = 2 +%SRC \end{equation} +%SRC +%SRC \begin{figure}% +%SRC \LaTeX{} +%SRC \caption{Baz}% +%SRC \label{fig:baz} +%SRC \end{figure} +%SRC +%SRC \begin{lemma}% +%SRC \label{thm:foo} +%SRC 1 + 1 = 2 +%SRC \end{lemma} +%SRC +%SRC \include{bar} +%SRC +%SRC \end{document} + +%TEX bar.tex +%SRC \section{Bar}% +%SRC \label{sec:bar} +%SRC +%SRC Lorem ipsum dolor sit amet. +%SRC \ref{} +%CUR ^ + +%TEX foo.aux +%SRC \relax +%SRC \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Baz\relax }}{1}\protected@file@percent } +%SRC \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} +%SRC \newlabel{fig:baz}{{1}{1}} +%SRC \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent } +%SRC \newlabel{sec:foo}{{1}{1}} +%SRC \newlabel{eq:foo}{{1}{1}} +%SRC \newlabel{eq:bar}{{2}{1}} +%SRC \newlabel{thm:foo}{{1}{1}} +%SRC \@input{bar.aux}"# + )?); + + Ok(()) +} + +#[test] +fn theorem_begin() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newtheorem{lemma}{Lemma} +%SRC \begin{lem +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn theorem_end() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \newtheorem{lemma}{Lemma} +%SRC \begin{} +%SRC \end{lem +%CUR ^ +%1.1 ^^^"# + )?); + + Ok(()) +} + +#[test] +fn tikz_library_open_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepgflibrary{ +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn tikz_library_closed_brace() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \usepgflibrary{} +%CUR ^"# + )?); + + Ok(()) +} + +#[test] +fn test_user_command() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \foobar +%SRC \fooba +%CUR ^ +%1.1 ^^^^^ +%SRC \begin{foo} +%SRC \end{foo} +%SRC \begin{fo} +"# + )?); + + Ok(()) +} + +#[test] +fn test_user_environment() -> Result<()> { + assert_items!(complete( + r#" +%TEX main.tex +%SRC \foobar +%SRC \fooba +%SRC \begin{foo} +%SRC \end{foo} +%SRC \begin{fo} +%CUR ^ +%1.1 ^^ +"# + )?); + + Ok(()) +} |