From 7a7c8ddc4a4432907f433fdef3f0a233c790780f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 22:16:54 +0200 Subject: Merging upstream version 0.1.25. Signed-off-by: Daniel Baumann --- tests/lsp_tests/__init__.py | 0 tests/lsp_tests/conftest.py | 43 +++ tests/lsp_tests/lsp_tutil.py | 45 +++ tests/lsp_tests/test_lsp_dctrl.py | 72 +++++ tests/lsp_tests/test_lsp_debputy_manifest_hover.py | 308 +++++++++++++++++++++ tests/test_declarative_parser.py | 2 +- tests/test_parser.py | 14 + 7 files changed, 483 insertions(+), 1 deletion(-) create mode 100644 tests/lsp_tests/__init__.py create mode 100644 tests/lsp_tests/conftest.py create mode 100644 tests/lsp_tests/lsp_tutil.py create mode 100644 tests/lsp_tests/test_lsp_dctrl.py create mode 100644 tests/lsp_tests/test_lsp_debputy_manifest_hover.py (limited to 'tests') diff --git a/tests/lsp_tests/__init__.py b/tests/lsp_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/lsp_tests/conftest.py b/tests/lsp_tests/conftest.py new file mode 100644 index 0000000..8b42582 --- /dev/null +++ b/tests/lsp_tests/conftest.py @@ -0,0 +1,43 @@ +import pytest +from debputy.plugin.api.feature_set import PluginProvidedFeatureSet + +try: + from pygls.server import LanguageServer + from lsprotocol.types import ( + InitializeParams, + ClientCapabilities, + GeneralClientCapabilities, + PositionEncodingKind, + TextDocumentItem, + Position, + CompletionParams, + TextDocumentIdentifier, + HoverParams, + MarkupContent, + ) + from debputy.lsp.lsp_features import lsp_set_plugin_features + + HAS_PYGLS = True +except ImportError: + HAS_PYGLS = False + + +@pytest.fixture() +def ls(debputy_plugin_feature_set: PluginProvidedFeatureSet) -> "LanguageServer": + if not HAS_PYGLS: + pytest.skip("Missing pygls") + ls = LanguageServer("debputy", "v") + ls.lsp.lsp_initialize( + InitializeParams( + ClientCapabilities( + general=GeneralClientCapabilities( + position_encodings=[PositionEncodingKind.Utf32], + ) + ) + ) + ) + lsp_set_plugin_features(debputy_plugin_feature_set) + try: + yield ls + finally: + lsp_set_plugin_features(None) diff --git a/tests/lsp_tests/lsp_tutil.py b/tests/lsp_tests/lsp_tutil.py new file mode 100644 index 0000000..1e509af --- /dev/null +++ b/tests/lsp_tests/lsp_tutil.py @@ -0,0 +1,45 @@ +from typing import Tuple + +try: + from pygls.server import LanguageServer + from lsprotocol.types import ( + TextDocumentItem, + Position, + ) +except ImportError: + pass + + +def _locate_cursor(text: str) -> Tuple[str, "Position"]: + lines = text.splitlines(keepends=True) + for line_no in range(len(lines)): + line = lines[line_no] + try: + c = line.index("") + except ValueError: + continue + line = line.replace("", "") + lines[line_no] = line + pos = Position(line_no, c) + return "".join(lines), pos + raise ValueError('Missing "" marker') + + +def put_doc_with_cursor( + ls: "LanguageServer", + uri: str, + language_id: str, + content: str, + *, + doc_version: int = 1, +) -> "Position": + cleaned_content, cursor_pos = _locate_cursor(content) + ls.workspace.put_text_document( + TextDocumentItem( + uri, + language_id, + doc_version, + cleaned_content, + ) + ) + return cursor_pos diff --git a/tests/lsp_tests/test_lsp_dctrl.py b/tests/lsp_tests/test_lsp_dctrl.py new file mode 100644 index 0000000..2a2466f --- /dev/null +++ b/tests/lsp_tests/test_lsp_dctrl.py @@ -0,0 +1,72 @@ +import textwrap + +try: + from lsprotocol.types import ( + CompletionParams, + TextDocumentIdentifier, + HoverParams, + MarkupContent, + ) + + from debputy.lsp.lsp_debian_control import ( + _debian_control_completions, + _debian_control_hover, + ) + + from pygls.server import LanguageServer +except ImportError: + pass +from lsp_tests.lsp_tutil import put_doc_with_cursor + + +def test_dctrl_complete_field(ls: "LanguageServer") -> None: + dctrl_uri = "file:///nowhere/debian/control" + + cursor_pos = put_doc_with_cursor( + ls, + dctrl_uri, + "debian/control", + textwrap.dedent( + """\ + Source: foo + + Package: foo + +""" + ), + ) + matches = _debian_control_completions( + ls, + CompletionParams(TextDocumentIdentifier(dctrl_uri), cursor_pos), + ) + assert matches + keywords = {m.label for m in matches} + assert "Multi-Arch" in keywords + assert "Architecture" in keywords + # Already present or wrong section + assert "Package" not in keywords + assert "Source" not in keywords + + +def test_dctrl_hover_doc_field(ls: "LanguageServer") -> None: + dctrl_uri = "file:///nowhere/debian/control" + cursor_pos = put_doc_with_cursor( + ls, + dctrl_uri, + "debian/control", + textwrap.dedent( + """\ + Source: foo + + Package: foo + Architecture: any +""" + ), + ) + + hover_doc = _debian_control_hover( + ls, + HoverParams(TextDocumentIdentifier(dctrl_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert "Determines which architecture" in hover_doc.contents.value diff --git a/tests/lsp_tests/test_lsp_debputy_manifest_hover.py b/tests/lsp_tests/test_lsp_debputy_manifest_hover.py new file mode 100644 index 0000000..c66db80 --- /dev/null +++ b/tests/lsp_tests/test_lsp_debputy_manifest_hover.py @@ -0,0 +1,308 @@ +import textwrap + +import pytest + +from lsp_tests.lsp_tutil import put_doc_with_cursor + +try: + from pygls.server import LanguageServer + from lsprotocol.types import ( + InitializeParams, + ClientCapabilities, + GeneralClientCapabilities, + PositionEncodingKind, + TextDocumentItem, + Position, + CompletionParams, + TextDocumentIdentifier, + HoverParams, + MarkupContent, + ) + from debputy.lsp.lsp_debian_debputy_manifest import debputy_manifest_hover + + HAS_PYGLS = True +except ImportError: + HAS_PYGLS = False + + +def test_basic_debputy_hover_tlk(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("Installations") + + +def test_basic_debputy_hover_install_docs_key(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("Install documentation (`install-docs`)") + + +def test_basic_debputy_hover_install_docs_sources(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("# Attribute `sources`") + + +def test_basic_debputy_hover_install_docs_when(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md + when: +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("# Attribute `when`") + + +def test_basic_debputy_hover_install_docs_str_cond(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md + when: cross-compiling +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith( + "Cross-Compiling condition `cross-compiling`" + ) + + +def test_basic_debputy_hover_install_docs_mapping_cond_key( + ls: "LanguageServer", +) -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md + when: + not: cross-compiling +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("Negated condition `not` (mapping)") + + +@pytest.mark.xfail +def test_basic_debputy_hover_install_docs_mapping_cond_str_value( + ls: "LanguageServer", +) -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + installations: + - install-docs: + sources: + - GETTING-STARTED-WITH-dh-debputy.md + - MANIFEST-FORMAT.md + - MIGRATING-A-DH-PLUGIN.md + when: + not: cross-compiling +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + # This should be showing `cross-compiling` docs, but we are showing `not` docs + assert hover_doc.contents.value.startswith( + "Cross-Compiling condition `cross-compiling`" + ) + + +def test_basic_debputy_hover_binary_version(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + packages: + foo: + binary-version: +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith( + "Custom binary version (`binary-version`)" + ) + + +def test_basic_debputy_hover_services(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + packages: + foo: + services: + - service: foo +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith( + "Define how services in the package will be handled (`services`)" + ) + + +def test_basic_debputy_hover_services_service(ls: "LanguageServer") -> None: + debputy_manifest_uri = "file:///nowhere/debian/debputy.manifest" + cursor_pos = put_doc_with_cursor( + ls, + debputy_manifest_uri, + "debian/debputy.manifest", + textwrap.dedent( + """\ + manifest-version: '0.1' + packages: + foo: + services: + - service: foo +""" + ), + ) + + hover_doc = debputy_manifest_hover( + ls, + HoverParams(TextDocumentIdentifier(debputy_manifest_uri), cursor_pos), + ) + assert hover_doc is not None and isinstance(hover_doc.contents, MarkupContent) + assert hover_doc.contents.value.startswith("# Attribute `service`") diff --git a/tests/test_declarative_parser.py b/tests/test_declarative_parser.py index a5061cb..94341ea 100644 --- a/tests/test_declarative_parser.py +++ b/tests/test_declarative_parser.py @@ -198,7 +198,7 @@ def test_declarative_parser_ok( ): pg = ParserGenerator() pg.register_mapped_type(TypeMapping(BinaryPackage, str, type_mapper_str2package)) - parser = pg.parser_from_typed_dict( + parser = pg.generate_parser( parse_content, source_content=source_content, ) diff --git a/tests/test_parser.py b/tests/test_parser.py index bc041fc..4792842 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -58,6 +58,20 @@ def test_parsing_version_only(manifest_parser_pkg_foo): assert [p.name for p in manifest.active_packages] == ["foo"] +def test_parsing_empty_installations(manifest_parser_pkg_foo): + content = textwrap.dedent( + """\ + manifest-version: '0.1' + installations: [] + """ + ) + + manifest = manifest_parser_pkg_foo.parse_manifest(fd=content) + + assert [p.name for p in manifest.all_packages] == ["foo"] + assert [p.name for p in manifest.active_packages] == ["foo"] + + def test_parsing_variables(manifest_parser_pkg_foo): # https://salsa.debian.org/debian/debputy/-/issues/58 content = textwrap.dedent( -- cgit v1.2.3