diff --git a/tests/integration/lsp/client.rs b/tests/integration/lsp/client.rs index dc6b6679..00442281 100644 --- a/tests/integration/lsp/client.rs +++ b/tests/integration/lsp/client.rs @@ -142,6 +142,13 @@ impl Client { Ok(()) } + pub fn store_on_disk(&mut self, name: &str, text: &str) -> Result<()> { + let path = self.directory.path().join(name); + std::fs::create_dir_all(path.parent().unwrap())?; + std::fs::write(path, text)?; + Ok(()) + } + pub fn shutdown(mut self) -> Result { self.request::(())?; self.notify::(())?; diff --git a/tests/integration/lsp/fixture.rs b/tests/integration/lsp/fixture.rs index 17eb6599..83d63cce 100644 --- a/tests/integration/lsp/fixture.rs +++ b/tests/integration/lsp/fixture.rs @@ -20,6 +20,8 @@ fn parse_line(line: &str) -> Line { Line::File(name, "latex") } else if let Some(name) = line.strip_prefix("%BIB ") { Line::File(name, "bibtex") + } else if let Some(name) = line.strip_prefix("%LOG ") { + Line::File(name, "log") } else if let Some(text) = line.strip_prefix("%SRC ") { Line::Plain(text) } else if let Some(text) = line.strip_prefix("%CUR ") { diff --git a/tests/integration/lsp/text_document.rs b/tests/integration/lsp/text_document.rs index 56ad1ee0..878e9ee9 100644 --- a/tests/integration/lsp/text_document.rs +++ b/tests/integration/lsp/text_document.rs @@ -7,5 +7,6 @@ mod document_symbol; mod folding_range; mod formatting; mod hover; +mod publish_diagnostics; mod references; mod rename; diff --git a/tests/integration/lsp/text_document/publish_diagnostics.rs b/tests/integration/lsp/text_document/publish_diagnostics.rs new file mode 100644 index 00000000..7e406b53 --- /dev/null +++ b/tests/integration/lsp/text_document/publish_diagnostics.rs @@ -0,0 +1,264 @@ +use anyhow::Result; +use insta::{assert_json_snapshot, internals::Redaction}; +use lsp_types::{ + notification::{ + DidChangeConfiguration, DidChangeWatchedFiles, Notification, PublishDiagnostics, + }, + ClientCapabilities, Diagnostic, DidChangeConfigurationParams, DidChangeWatchedFilesParams, + FileChangeType, FileEvent, PublishDiagnosticsParams, Url, +}; +use rustc_hash::FxHashMap; + +use crate::lsp::{client::Client, fixture}; + +struct DiagnosticResult { + all_diagnostics: FxHashMap>, + uri_redaction: Redaction, +} + +fn find_diagnostics(fixture: &str, settings: serde_json::Value) -> Result { + let mut client = Client::spawn()?; + client.initialize(ClientCapabilities::default(), None)?; + + let mut disk_files = Vec::new(); + let fixture = fixture::parse(fixture); + for file in fixture.files { + if file.lang == "log" { + client.store_on_disk(file.name, &file.text)?; + disk_files.push(client.uri(file.name)?); + } else { + client.open(file.name, file.lang, file.text)?; + } + } + + client.notify::(DidChangeWatchedFilesParams { + changes: disk_files + .into_iter() + .map(|uri| FileEvent::new(uri, FileChangeType::CHANGED)) + .collect(), + })?; + + client.notify::(DidChangeConfigurationParams { settings })?; + + let result = client.shutdown()?; + + let uri = Url::from_directory_path(result.directory.path()).unwrap(); + let uri_redaction = insta::dynamic_redaction(move |content, _path| { + content.as_str().unwrap().replace(uri.as_str(), "[tmp]/") + }); + + let all_diagnostics = result + .incoming + .notifications + .into_iter() + .filter_map(|notification| { + notification + .extract::(PublishDiagnostics::METHOD) + .ok() + }) + .map(|params| (params.uri, params.diagnostics)) + .collect(); + + Ok(DiagnosticResult { + all_diagnostics, + uri_redaction, + }) +} + +macro_rules! assert_symbols { + ($result:expr) => { + let result = $result; + assert_json_snapshot!(result.all_diagnostics, { + ".$key" => result.uri_redaction + }); + }; +} + +static BUILD_LOG_FIXTURE: &str = r#" +%TEX main.tex +%SRC \documentclass{article} +%SRC +%SRC \usepackage{amsmath} +%SRC +%SRC \begin{document} +%SRC +%SRC \foo{} +%SRC aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +%SRC +%SRC \end{document} + +%LOG main.log +%SRC This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021/W32TeX) (preloaded format=pdflatex 2022.1.23) 16 JUN 2022 11:04 +%SRC entering extended mode +%SRC restricted \write18 enabled. +%SRC %&-line parsing enabled. +%SRC **main.tex +%SRC (./main.tex +%SRC LaTeX2e <2020-10-01> patch level 4 +%SRC L3 programming layer <2021-02-18> +%SRC (c:/texlive/2021/texmf-dist/tex/latex/base/article.cls +%SRC Document Class: article 2020/04/10 v1.4m Standard LaTeX document class +%SRC (c:/texlive/2021/texmf-dist/tex/latex/base/size10.clo +%SRC File: size10.clo 2020/04/10 v1.4m Standard LaTeX file (size option) +%SRC ) +%SRC \c@part=\count179 +%SRC \c@section=\count180 +%SRC \c@subsection=\count181 +%SRC \c@subsubsection=\count182 +%SRC \c@paragraph=\count183 +%SRC \c@subparagraph=\count184 +%SRC \c@figure=\count185 +%SRC \c@table=\count186 +%SRC \abovecaptionskip=\skip47 +%SRC \belowcaptionskip=\skip48 +%SRC \bibindent=\dimen138 +%SRC ) +%SRC (c:/texlive/2021/texmf-dist/tex/latex/amsmath/amsmath.sty +%SRC Package: amsmath 2020/09/23 v2.17i AMS math features +%SRC \@mathmargin=\skip49 +%SRC +%SRC For additional information on amsmath, use the `?' option. +%SRC (c:/texlive/2021/texmf-dist/tex/latex/amsmath/amstext.sty +%SRC Package: amstext 2000/06/29 v2.01 AMS text +%SRC +%SRC (c:/texlive/2021/texmf-dist/tex/latex/amsmath/amsgen.sty +%SRC File: amsgen.sty 1999/11/30 v2.0 generic functions +%SRC \@emptytoks=\toks15 +%SRC \ex@=\dimen139 +%SRC )) +%SRC (c:/texlive/2021/texmf-dist/tex/latex/amsmath/amsbsy.sty +%SRC Package: amsbsy 1999/11/29 v1.2d Bold Symbols +%SRC \pmbraise@=\dimen140 +%SRC ) +%SRC (c:/texlive/2021/texmf-dist/tex/latex/amsmath/amsopn.sty +%SRC Package: amsopn 2016/03/08 v2.02 operator names +%SRC ) +%SRC \inf@bad=\count187 +%SRC LaTeX Info: Redefining \frac on input line 234. +%SRC \uproot@=\count188 +%SRC \leftroot@=\count189 +%SRC LaTeX Info: Redefining \overline on input line 399. +%SRC \classnum@=\count190 +%SRC \DOTSCASE@=\count191 +%SRC LaTeX Info: Redefining \ldots on input line 496. +%SRC LaTeX Info: Redefining \dots on input line 499. +%SRC LaTeX Info: Redefining \cdots on input line 620. +%SRC \Mathstrutbox@=\box47 +%SRC \strutbox@=\box48 +%SRC \big@size=\dimen141 +%SRC LaTeX Font Info: Redeclaring font encoding OML on input line 743. +%SRC LaTeX Font Info: Redeclaring font encoding OMS on input line 744. +%SRC \macc@depth=\count192 +%SRC \c@MaxMatrixCols=\count193 +%SRC \dotsspace@=\muskip16 +%SRC \c@parentequation=\count194 +%SRC \dspbrk@lvl=\count195 +%SRC \tag@help=\toks16 +%SRC \row@=\count196 +%SRC \column@=\count197 +%SRC \maxfields@=\count198 +%SRC \andhelp@=\toks17 +%SRC \eqnshift@=\dimen142 +%SRC \alignsep@=\dimen143 +%SRC \tagshift@=\dimen144 +%SRC \tagwidth@=\dimen145 +%SRC \totwidth@=\dimen146 +%SRC \lineht@=\dimen147 +%SRC \@envbody=\toks18 +%SRC \multlinegap=\skip50 +%SRC \multlinetaggap=\skip51 +%SRC \mathdisplay@stack=\toks19 +%SRC LaTeX Info: Redefining \[ on input line 2923. +%SRC LaTeX Info: Redefining \] on input line 2924. +%SRC ) +%SRC (c:/texlive/2021/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def +%SRC File: l3backend-pdftex.def 2021-03-18 L3 backend support: PDF output (pdfTeX) +%SRC \l__color_backend_stack_int=\count199 +%SRC \l__pdf_internal_box=\box49 +%SRC ) +%SRC (./main.aux) +%SRC \openout1 = `main.aux'. +%SRC +%SRC LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 5. +%SRC LaTeX Font Info: ... okay on input line 5. +%SRC +%SRC ! Undefined control sequence. +%SRC l.7 \foo +%SRC {} +%SRC The control sequence at the end of the top line +%SRC of your error message was never \def'ed. If you have +%SRC misspelled it (e.g., `\hobx'), type `I' and the correct +%SRC spelling (e.g., `I\hbox'). Otherwise just continue, +%SRC and I'll forget about whatever was undefined. +%SRC +%SRC +%SRC Overfull \hbox (80.00125pt too wide) in paragraph at lines 8--9 +%SRC []\OT1/cmr/m/n/10 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +%SRC aaaaaaaaaaaaaaaaaaaaa +%SRC [] +%SRC +%SRC [1 +%SRC +%SRC {c:/texlive/2021/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./main.aux) ) +%SRC Here is how much of TeX's memory you used: +%SRC 1014 strings out of 478994 +%SRC 13996 string characters out of 5862207 +%SRC 300924 words of memory out of 5000000 +%SRC 18565 multiletter control sequences out of 15000+600000 +%SRC 403430 words of font info for 27 fonts, out of 8000000 for 9000 +%SRC 1141 hyphenation exceptions out of 8191 +%SRC 67i,4n,74p,200b,104s stack positions out of 5000i,500n,10000p,200000b,80000s +%SRC < +%SRC c:/texlive/2021/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb> +%SRC Output written on main.pdf (1 page, 9741 bytes). +%SRC PDF statistics: +%SRC 12 PDF objects out of 1000 (max. 8388607) +%SRC 7 compressed objects within 1 object stream +%SRC 0 named destinations out of 1000 (max. 500000) +%SRC 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#; + +#[test] +fn build_log_filter_none() -> Result<()> { + assert_symbols!(find_diagnostics(BUILD_LOG_FIXTURE, serde_json::json!({}))?); + Ok(()) +} + +#[test] +fn build_log_filter_allowed() -> Result<()> { + assert_symbols!(find_diagnostics( + BUILD_LOG_FIXTURE, + serde_json::json!({ + "diagnostics": { + "allowedPatterns": ["Overfull \\\\[hv]box"] + } + }) + )?); + + Ok(()) +} + +#[test] +fn build_log_filter_ignored() -> Result<()> { + assert_symbols!(find_diagnostics( + BUILD_LOG_FIXTURE, + serde_json::json!({ + "diagnostics": { + "ignoredPatterns": ["Overfull \\\\[hv]box"] + } + }) + )?); + + Ok(()) +} diff --git a/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_allowed.snap b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_allowed.snap new file mode 100644 index 00000000..9fc11d29 --- /dev/null +++ b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_allowed.snap @@ -0,0 +1,24 @@ +--- +source: tests/integration/lsp/text_document/publish_diagnostics.rs +assertion_line: 240 +expression: result.all_diagnostics +--- +{ + "[tmp]/main.tex": [ + { + "range": { + "start": { + "line": 7, + "character": 0 + }, + "end": { + "line": 7, + "character": 0 + } + }, + "severity": 2, + "source": "latex-build", + "message": "Overfull \\hbox (80.00125pt too wide) in paragraph at lines 8--9" + } + ] +} diff --git a/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_ignored.snap b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_ignored.snap new file mode 100644 index 00000000..28e0308a --- /dev/null +++ b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_ignored.snap @@ -0,0 +1,24 @@ +--- +source: tests/integration/lsp/text_document/publish_diagnostics.rs +assertion_line: 254 +expression: result.all_diagnostics +--- +{ + "[tmp]/main.tex": [ + { + "range": { + "start": { + "line": 6, + "character": 0 + }, + "end": { + "line": 6, + "character": 0 + } + }, + "severity": 1, + "source": "latex-build", + "message": "Undefined control sequence." + } + ] +} diff --git a/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_none.snap b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_none.snap new file mode 100644 index 00000000..b1623838 --- /dev/null +++ b/tests/integration/lsp/text_document/snapshots/integration__lsp__text_document__publish_diagnostics__build_log_filter_none.snap @@ -0,0 +1,39 @@ +--- +source: tests/integration/lsp/text_document/publish_diagnostics.rs +assertion_line: 234 +expression: result.all_diagnostics +--- +{ + "[tmp]/main.tex": [ + { + "range": { + "start": { + "line": 6, + "character": 0 + }, + "end": { + "line": 6, + "character": 0 + } + }, + "severity": 1, + "source": "latex-build", + "message": "Undefined control sequence." + }, + { + "range": { + "start": { + "line": 7, + "character": 0 + }, + "end": { + "line": 7, + "character": 0 + } + }, + "severity": 2, + "source": "latex-build", + "message": "Overfull \\hbox (80.00125pt too wide) in paragraph at lines 8--9" + } + ] +}