diff options
Diffstat (limited to 'support/texlab/tests/lsp/text_document/completion.rs')
-rw-r--r-- | support/texlab/tests/lsp/text_document/completion.rs | 821 |
1 files changed, 821 insertions, 0 deletions
diff --git a/support/texlab/tests/lsp/text_document/completion.rs b/support/texlab/tests/lsp/text_document/completion.rs new file mode 100644 index 0000000000..7e0c3c31d4 --- /dev/null +++ b/support/texlab/tests/lsp/text_document/completion.rs @@ -0,0 +1,821 @@ +use insta::assert_json_snapshot; +use itertools::Itertools; +use lsp_types::{ + request::{Completion, ResolveCompletionItem}, + CompletionItem, CompletionParams, CompletionResponse, CompletionTextEdit, Range, +}; + +use crate::fixture::TestBed; + +fn complete(fixture: &str) -> Vec<CompletionItem> { + let test_bed = TestBed::new(fixture).unwrap(); + test_bed + .initialize( + serde_json::from_value(serde_json::json!({ + "textDocument": { + "completion": { + "completionItem": { + "documentationFormat": ["plaintext", "markdown"] + } + } + } + })) + .unwrap(), + ) + .unwrap(); + + let text_document_position = test_bed.cursor().unwrap(); + let position = text_document_position.position; + let range = test_bed + .locations() + .first() + .map_or_else(|| Range::new(position, position), |location| location.range); + + let items = match test_bed + .client() + .send_request::<Completion>(CompletionParams { + text_document_position, + partial_result_params: Default::default(), + work_done_progress_params: Default::default(), + context: None, + }) + .unwrap() + { + Some(CompletionResponse::Array(items)) => items, + Some(CompletionResponse::List(list)) => list.items, + None => Vec::new(), + }; + + for item in &items { + if let Some(CompletionTextEdit::Edit(edit)) = item.text_edit.as_ref() { + assert_eq!(edit.range, range); + } + } + + items + .into_iter() + .take(5) + .map(|item| { + let mut item = test_bed + .client() + .send_request::<ResolveCompletionItem>(item) + .unwrap(); + + item.data = None; + item.kind = None; + item.sort_text = None; + item.documentation = None; + item.text_edit = None; + item + }) + .sorted_by(|item1, item2| item1.label.cmp(&item2.label)) + .collect() +} + +#[test] +fn acronym_ref_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\acrshort{f} + | + ^"# + )); +} + +#[test] +fn acronym_ref_empty() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\acrshort{} + |"# + )); +} + +#[test] +fn acronym_ref_after_group() { + assert_eq!( + complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\acrshort{} + |"#, + ), + Vec::new() + ); +} + +#[test] +fn acronym_ref_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\acrshort{f + | + ^"# + )); +} + +#[test] +fn acronym_package_ref() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\acrodef{fpsLabel}[FPS]{Frames per Second} +\ac{f + | + ^"# + )); +} + +#[test] +fn glossary_ref_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\gls{f} + | + ^"# + )); +} + +#[test] +fn glossary_ref_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second} +\gls{f + | + ^"# + )); +} + +#[test] +fn argument_empty() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{amsfonts} +\mathbb{} + |"# + )); +} + +#[test] +fn argument_word() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{amsfonts} +\mathbb{A} + | + ^"# + )); +} + +#[test] +fn argument_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{amsfonts} +\mathbb{ + | +Test"# + )); +} + +#[test] +fn argument_open_brace_unrelated() { + assert_eq!( + complete( + r#" +%! main.tex +\usepackage{amsfonts} +\mathbb{}{ + | +Test"#, + ), + Vec::new() + ); +} + +#[test] +fn begin_environment_without_snippet_support() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\beg + | + ^^^"# + )); +} + +#[test] +fn citation() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\documentclass{article} +\bibliography{main} +\begin{document} +\cite{ + | +\end{document} + +%! main.bib +@article{foo:2019, + author = {Foo Bar}, + title = {Baz Qux}, + year = {2019}, +} + +@article{bar:2005,}"# + )); +} + +#[test] +fn citation_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\addbibresource{main.bib} +\cite{ + | + +%! main.bib +@article{foo,}"# + )); +} + +#[test] +fn citation_open_brace_multiple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\addbibresource{main.bib} +\cite{foo,a + | + ^ + +%! main.bib +@article{foo,}"# + )); +} + +#[test] +fn citation_acronym() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\addbibresource{main.bib} +\DeclareAcronym{foo}{cite={}} + | + +%! main.bib +@article{foo,}"# + )); +} + +#[test] +fn citation_after_brace() { + assert_eq!( + complete( + r#" +%! main.tex +\documentclass{article} +\bibliography{main} +\begin{document} +\cite{} + | +\end{document} + +%! main.bib +@article{foo,}"#, + ), + Vec::new() + ); +} + +#[test] +fn color_model_definition_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\definecolor{foo}{} + |"# + )); +} + +#[test] +fn color_model_definition_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\definecolor{foo}{ + |"# + )); +} + +#[test] +fn color_model_definition_set_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\definecolorset{} + |"# + )); +} + +#[test] +fn color_model_definition_set_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\definecolorset{ + |"# + )); +} + +#[test] +fn color_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\color{} + |"# + )); +} + +#[test] +fn color_word() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\color{re} + | + ^^"# + )); +} + +#[test] +fn color_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\color{ + |"# + )); +} + +#[test] +fn component_command_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\ + |"# + )); +} + +#[test] +fn component_command_simple_before() { + assert_eq!( + complete( + r#" +%! main.tex +\ +|"#, + ), + Vec::new() + ); +} + +#[test] +fn component_command_simple_package() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{lipsum} +\lips + | + ^^^^"# + )); +} + +#[test] +fn component_command_bibtex() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{b, + c = {\LaT } + | + ^^^ +}"# + )); +} + +#[test] +fn component_environment_simple() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\begin{doc + | + ^^^"# + )); +} + +#[test] +fn component_environment_simple_end() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\begin{document} +\end{ + |"# + )); +} + +#[test] +fn component_environment_class() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\documentclass{article} +\begin{thein} + | + ^^^^^"# + )); +} + +#[test] +fn component_environment_command_definition() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newcommand{\foo}{\begin{doc} + | + ^^^"# + )); +} + +#[test] +fn entry_type_at_empty() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@ + |"# + )); +} + +#[test] +fn entry_type_before_preamble() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@preamble + | + ^^^^^^^^"# + )); +} + +#[test] +fn entry_type_before_string() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@string + | + ^^^^^^"# + )); +} + +#[test] +fn entry_type_before_article() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article + | + ^^^^^^^"# + )); +} + +#[test] +fn entry_type_after_preamble() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@preamble{ + | + ^^^^^^^^"# + )); +} + +#[test] +fn entry_type_after_string() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@string{ + | + ^^^^^^"# + )); +} + +#[test] +fn entry_type_complete_entry() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo, author = {foo}} + | + ^^^^^^^"# + )); +} + +#[test] +fn field_empty_entry_open() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo, + |"# + )); +} + +#[test] +fn field_empty_entry_closed() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo,} + |"# + )); +} + +#[test] +fn field_entry_field_name() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo, a + | + ^"# + )); +} + +#[test] +fn field_entry_two_fields_name_open() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo, author = bar, edit + | + ^^^^"# + )); +} + +#[test] +fn field_entry_two_fields_name_closed() { + assert_json_snapshot!(complete( + r#" +%! main.bib +@article{foo, author = bar, edit} + | + ^^^^"# + )); +} + +#[test] +fn import_package_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{lips + | + ^^^^"# + )); +} + +#[test] +fn import_package_closed_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepackage{lips} + | + ^^^^"# + )); +} + +#[test] +fn import_class_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\documentclass{art \foo + | + ^^^"# + )); +} + +#[test] +fn import_class_closed_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\documentclass{art} + | + ^^^"# + )); +} + +#[test] +fn label() { + assert_json_snapshot!(complete( + r#" +%! foo.tex +\documentclass{article} + +\usepackage{amsmath} +\usepackage{caption} +\usepackage{amsthm} +\newtheorem{lemma}{Lemma} + +\begin{document} + +\section{Foo}% +\label{sec:foo} + +\begin{equation}% +\label{eq:foo} + 1 + 1 = 2 +\end{equation} + +\begin{equation}% +\label{eq:bar} + 1 + 1 = 2 +\end{equation} + +\begin{figure}% +\LaTeX{} +\caption{Baz}% +\label{fig:baz} +\end{figure} + +\begin{lemma}% +\label{thm:foo} + 1 + 1 = 2 +\end{lemma} + +\include{bar} + +\end{document} + +%! bar.tex +\section{Bar}% +\label{sec:bar} + +Lorem ipsum dolor sit amet. +\ref{} + | + +%! foo.aux +\relax +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Baz\relax }}{1}\protected@file@percent } +\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} +\newlabel{fig:baz}{{1}{1}} +\@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent } +\newlabel{sec:foo}{{1}{1}} +\newlabel{eq:foo}{{1}{1}} +\newlabel{eq:bar}{{2}{1}} +\newlabel{thm:foo}{{1}{1}} +\@input{bar.aux}"# + )); +} + +#[test] +fn theorem_begin() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newtheorem{lemma}{Lemma} +\begin{lem + | + ^^^"# + )); +} + +#[test] +fn theorem_end() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\newtheorem{lemma}{Lemma} +\begin{} +\end{lem + | + ^^^"# + )); +} + +#[test] +fn tikz_library_open_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepgflibrary{ + |"# + )); +} + +#[test] +fn tikz_library_closed_brace() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\usepgflibrary{} + |"# + )); +} + +#[test] +fn test_user_command() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\foobar +\fooba + | + ^^^^^ +\begin{foo} +\end{foo} +\begin{fo}"# + )); +} + +#[test] +fn test_user_environment() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\foobar +\fooba +\begin{foo} +\end{foo} +\begin{fo} + | + ^^"# + )); +} + +#[test] +fn test_project_resolution_import() { + assert_json_snapshot!(complete( + r#" +%! main.tex +\documentclass{article} +\import{sub}{sub/sub.tex} +\lipsu + | + ^^^^^ + +%! sub/sub.tex +\input{child.tex} + +%! sub/child.tex +\usepackage{lipsum}"# + )); +} + +#[test] +fn test_project_resolution_texlabroot() { + assert_json_snapshot!(complete( + r#" +%! src/main.tex +\documentclass{article} +\include{src/foo} +\lipsu + | + ^^^^^ + +%! src/foo.tex +\include{src/bar} + +%! src/bar.tex +\usepackage{lipsum} + +%! .texlabroot"# + )); +} |