summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/lint_tests/lint_tutil.py10
-rw-r--r--tests/lint_tests/test_lint_dcpy.py64
-rw-r--r--tests/lint_tests/test_lint_dctrl.py265
-rw-r--r--tests/lint_tests/test_lint_dpatches_series.py152
-rw-r--r--tests/lsp_tests/test_lsp_dpatches_series.py59
-rw-r--r--tests/plugin_tests/grantlee_test.py34
6 files changed, 571 insertions, 13 deletions
diff --git a/tests/lint_tests/lint_tutil.py b/tests/lint_tests/lint_tutil.py
index 26df505..65fe0ad 100644
--- a/tests/lint_tests/lint_tutil.py
+++ b/tests/lint_tests/lint_tutil.py
@@ -3,8 +3,8 @@ from typing import List, Optional, Mapping, Any, Callable
import pytest
+from debputy.filesystem_scan import VirtualPathBase
from debputy.linting.lint_util import (
- LinterImpl,
LinterPositionCodec,
LintStateImpl,
LintState,
@@ -44,6 +44,7 @@ class LintWrapper:
self.dctrl_lines: Optional[List[str]] = None
self.path = path
self._dctrl_parser = dctrl_parser
+ self.source_root: Optional[VirtualPathBase] = None
self.lint_style_preference_table = StylePreferenceTable({}, {})
self.effective_preference: Optional[EffectivePreference] = None
@@ -57,11 +58,13 @@ class LintWrapper:
dctrl_lines, ignore_errors=True
)
)
+ source_root = self.source_root
+ debian_dir = source_root.get("debian") if source_root is not None else None
state = LintStateImpl(
self._debputy_plugin_feature_set,
self.lint_style_preference_table,
- None,
- None,
+ source_root,
+ debian_dir,
self.path,
"".join(dctrl_lines) if dctrl_lines is not None else "",
lines,
@@ -84,6 +87,7 @@ def check_diagnostics(
if diagnostics:
for diagnostic in diagnostics:
assert diagnostic.severity is not None
+ assert diagnostic.source is not None
return diagnostics
diff --git a/tests/lint_tests/test_lint_dcpy.py b/tests/lint_tests/test_lint_dcpy.py
new file mode 100644
index 0000000..f827d3e
--- /dev/null
+++ b/tests/lint_tests/test_lint_dcpy.py
@@ -0,0 +1,64 @@
+import textwrap
+
+import pytest
+
+from debputy.lsp.lsp_debian_copyright import _lint_debian_copyright
+from debputy.packages import DctrlParser
+from debputy.plugin.api.feature_set import PluginProvidedFeatureSet
+from lint_tests.lint_tutil import (
+ group_diagnostics_by_severity,
+ LintWrapper,
+)
+
+try:
+ from lsprotocol.types import Diagnostic, DiagnosticSeverity
+except ImportError:
+ pass
+
+
+@pytest.fixture
+def line_linter(
+ debputy_plugin_feature_set: PluginProvidedFeatureSet,
+ lint_dctrl_parser: DctrlParser,
+) -> LintWrapper:
+ return LintWrapper(
+ "/nowhere/debian/copyright",
+ _lint_debian_copyright,
+ debputy_plugin_feature_set,
+ lint_dctrl_parser,
+ )
+
+
+def test_dcpy_files_lint(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ """\
+ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+ Files: foo .//unnecessary///many/slashes
+ Copyright: Noone <noone@example.com>
+ License: something
+ yada yada yada
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ by_severity = group_diagnostics_by_severity(diagnostics)
+ assert DiagnosticSeverity.Warning in by_severity
+
+ assert DiagnosticSeverity.Error not in by_severity
+ assert DiagnosticSeverity.Hint not in by_severity
+ assert DiagnosticSeverity.Information not in by_severity
+
+ warnings = by_severity[DiagnosticSeverity.Warning]
+ print(warnings)
+ assert len(warnings) == 2
+
+ first_warn, second_warn = warnings
+
+ msg = 'Unnecessary prefix ".//"'
+ assert first_warn.message == msg
+ assert f"{first_warn.range}" == "2:11-2:14"
+
+ msg = 'Simplify to a single "/"'
+ assert second_warn.message == msg
+ assert f"{second_warn.range}" == "2:25-2:28"
diff --git a/tests/lint_tests/test_lint_dctrl.py b/tests/lint_tests/test_lint_dctrl.py
index bcb1613..7e9477e 100644
--- a/tests/lint_tests/test_lint_dctrl.py
+++ b/tests/lint_tests/test_lint_dctrl.py
@@ -4,6 +4,7 @@ from typing import List, Optional
import pytest
from debputy.lsp.lsp_debian_control import _lint_debian_control
+from debputy.lsp.lsp_debian_control_reference_data import CURRENT_STANDARDS_VERSION
from debputy.packages import DctrlParser
from debputy.plugin.api.feature_set import PluginProvidedFeatureSet
from lint_tests.lint_tutil import (
@@ -18,9 +19,6 @@ except ImportError:
pass
-STANDARDS_VERSION = "4.7.0"
-
-
class DctrlLintWrapper(LintWrapper):
def __call__(self, lines: List[str]) -> Optional[List["Diagnostic"]]:
@@ -104,7 +102,7 @@ def test_dctrl_lint_typos(line_linter: LintWrapper) -> None:
lines = textwrap.dedent(
f"""\
Source: foo
- Standards-Version: {STANDARDS_VERSION}
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
Priority: optional
Section: devel
Maintainer: Jane Developer <jane@example.com>
@@ -137,7 +135,7 @@ def test_dctrl_lint_mx_value_with_typo(line_linter: LintWrapper) -> None:
lines = textwrap.dedent(
f"""\
Source: foo
- Standards-Version: {STANDARDS_VERSION}
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
Priority: optional
Section: devel
Maintainer: Jane Developer <jane@example.com>
@@ -176,7 +174,7 @@ def test_dctrl_lint_mx_value(line_linter: LintWrapper) -> None:
lines = textwrap.dedent(
f"""\
Source: foo
- Standards-Version: {STANDARDS_VERSION}
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
Priority: optional
Section: devel
Maintainer: Jane Developer <jane@example.com>
@@ -205,7 +203,7 @@ def test_dctrl_lint_mx_value(line_linter: LintWrapper) -> None:
lines = textwrap.dedent(
f"""\
Source: foo
- Standards-Version: {STANDARDS_VERSION}
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
Priority: optional
Section: devel
Maintainer: Jane Developer <jane@example.com>
@@ -238,14 +236,14 @@ def test_dctrl_lint_dup_sep(line_linter: LintWrapper) -> None:
Source: foo
Section: devel
Priority: optional
- Standards-Version: {STANDARDS_VERSION}
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
Maintainer: Jane Developer <jane@example.com>
Build-Depends: debhelper-compat (= 13)
Package: foo
Architecture: all
- Depends: foo,
- , bar
+ Depends: bar,
+ , baz
Description: Some very interesting synopsis
A very interesting description
that spans multiple lines
@@ -263,3 +261,250 @@ def test_dctrl_lint_dup_sep(line_linter: LintWrapper) -> None:
assert error.message == msg
assert f"{error.range}" == "10:1-10:2"
assert error.severity == DiagnosticSeverity.Error
+
+
+def test_dctrl_lint_ma(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ Multi-Arch: same
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 1
+ error = diagnostics[0]
+
+ msg = "Multi-Arch: same is not valid for Architecture: all packages. Maybe you want foreign?"
+ assert error.message == msg
+ assert f"{error.range}" == "9:12-9:16"
+ assert error.severity == DiagnosticSeverity.Error
+
+
+def test_dctrl_lint_udeb(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ XB-Installer-Menu-Item: 1234
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+
+ Package: bar-udeb
+ Architecture: all
+ Section: debian-installer
+ Package-Type: udeb
+ XB-Installer-Menu-Item: golf
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 2
+ first, second = diagnostics
+
+ msg = "The XB-Installer-Menu-Item field is only applicable to udeb packages (`Package-Type: udeb`)"
+ assert first.message == msg
+ assert f"{first.range}" == "9:0-9:22"
+ assert first.severity == DiagnosticSeverity.Warning
+
+ msg = r'The value "golf" does not match the regex ^[1-9]\d{3,4}$.'
+ assert second.message == msg
+ assert f"{second.range}" == "21:24-21:28"
+ assert second.severity == DiagnosticSeverity.Error
+
+
+def test_dctrl_lint_arch_only_fields(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ X-DH-Build-For-Type: target
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 1
+ issue = diagnostics[0]
+
+ msg = "The X-DH-Build-For-Type field is not applicable to arch:all packages (`Architecture: all`)"
+ assert issue.message == msg
+ assert f"{issue.range}" == "9:0-9:19"
+ assert issue.severity == DiagnosticSeverity.Warning
+
+
+def test_dctrl_lint_sv(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: 4.6.2
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 1
+ issue = diagnostics[0]
+
+ msg = f"Latest Standards-Version is {CURRENT_STANDARDS_VERSION}"
+ assert issue.message == msg
+ assert f"{issue.range}" == "3:19-3:24"
+ assert issue.severity == DiagnosticSeverity.Information
+
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: Golf
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 1
+ issue = diagnostics[0]
+
+ msg = f'Not a valid version. Current version is "{CURRENT_STANDARDS_VERSION}"'
+ assert issue.message == msg
+ assert f"{issue.range}" == "3:19-3:23"
+ assert issue.severity == DiagnosticSeverity.Warning
+
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: {CURRENT_STANDARDS_VERSION}.0
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+
+ Package: foo
+ Architecture: all
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 1
+ issue = diagnostics[0]
+
+ msg = "Unnecessary version segment. This part of the version is only used for editorial changes"
+ assert issue.message == msg
+ assert f"{issue.range}" == "3:24-3:26"
+ assert issue.severity == DiagnosticSeverity.Information
+
+
+def test_dctrl_lint_multiple_vcs(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ f"""\
+ Source: foo
+ Section: devel
+ Priority: optional
+ Standards-Version: {CURRENT_STANDARDS_VERSION}
+ Maintainer: Jane Developer <jane@example.com>
+ Build-Depends: debhelper-compat (= 13)
+ Vcs-Git: https://salsa.debian.org/debian/foo
+ Vcs-Svn: https://svn.debian.org/debian/foo
+ Vcs-Browser: https://salsa.debian.org/debian/foo
+
+ Package: foo
+ Architecture: all
+ Depends: bar, baz
+ Description: Some very interesting synopsis
+ A very interesting description
+ that spans multiple lines
+ .
+ Just so be clear, this is for a test.
+ """
+ ).splitlines(keepends=True)
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert diagnostics and len(diagnostics) == 2
+ first_issue, second_issue = diagnostics
+
+ msg = f'Multiple Version Control fields defined ("Vcs-Git")'
+ assert first_issue.message == msg
+ assert f"{first_issue.range}" == "6:0-7:0"
+ assert first_issue.severity == DiagnosticSeverity.Warning
+
+ msg = f'Multiple Version Control fields defined ("Vcs-Svn")'
+ assert second_issue.message == msg
+ assert f"{second_issue.range}" == "7:0-8:0"
+ assert second_issue.severity == DiagnosticSeverity.Warning
diff --git a/tests/lint_tests/test_lint_dpatches_series.py b/tests/lint_tests/test_lint_dpatches_series.py
new file mode 100644
index 0000000..ed2a802
--- /dev/null
+++ b/tests/lint_tests/test_lint_dpatches_series.py
@@ -0,0 +1,152 @@
+import textwrap
+
+import pytest
+
+from debputy.lsp.lsp_debian_patches_series import _lint_debian_patches_series
+from debputy.packages import DctrlParser
+from debputy.plugin.api.feature_set import PluginProvidedFeatureSet
+from debputy.plugin.api.test_api import build_virtual_file_system
+from lint_tests.lint_tutil import (
+ LintWrapper,
+)
+
+try:
+ from lsprotocol.types import Diagnostic, DiagnosticSeverity
+except ImportError:
+ pass
+
+
+@pytest.fixture
+def line_linter(
+ debputy_plugin_feature_set: PluginProvidedFeatureSet,
+ lint_dctrl_parser: DctrlParser,
+) -> LintWrapper:
+ return LintWrapper(
+ "/nowhere/debian/patches/series",
+ _lint_debian_patches_series,
+ debputy_plugin_feature_set,
+ lint_dctrl_parser,
+ )
+
+
+def test_dpatches_series_files_lint(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ """\
+ # Some leading comment
+
+ ../some.patch
+
+ .//.//./subdir/another-delta.diff # foo
+
+ subdir/no-issues.patch # bar
+ """
+ ).splitlines(keepends=True)
+
+ fs = build_virtual_file_system(
+ [
+ "./debian/patches/series",
+ "./debian/some.patch",
+ "./debian/patches/subdir/another-delta.diff",
+ "./debian/patches/subdir/no-issues.patch",
+ ]
+ )
+
+ line_linter.source_root = fs
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert len(diagnostics) == 2
+
+ first_issue, second_issue = diagnostics
+
+ msg = 'Disallowed prefix "../"'
+ assert first_issue.message == msg
+ assert f"{first_issue.range}" == "2:0-2:3"
+ assert first_issue.severity == DiagnosticSeverity.Error
+
+ msg = 'Unnecessary prefix ".//.//./"'
+ assert second_issue.message == msg
+ assert f"{second_issue.range}" == "4:0-4:8"
+ assert second_issue.severity == DiagnosticSeverity.Warning
+
+
+def test_dpatches_series_files_file_mismatch_lint(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ """\
+ # Some leading comment
+
+ some/used-twice.patch
+
+ some/missing-file.patch
+
+ some/used-twice.patch
+ """
+ ).splitlines(keepends=True)
+
+ fs = build_virtual_file_system(
+ [
+ "./debian/patches/series",
+ "./debian/ignored.patch",
+ "./debian/patches/some/unused-file.diff",
+ "./debian/patches/some/used-twice.patch",
+ ]
+ )
+
+ line_linter.source_root = fs
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert len(diagnostics) == 3
+
+ first_issue, second_issue, third_issue = diagnostics
+
+ msg = 'Non-existing patch "some/missing-file.patch"'
+ assert first_issue.message == msg
+ assert f"{first_issue.range}" == "4:0-4:23"
+ assert first_issue.severity == DiagnosticSeverity.Error
+
+ msg = 'Duplicate patch: "some/used-twice.patch"'
+ assert second_issue.message == msg
+ assert f"{second_issue.range}" == "6:0-6:21"
+ assert second_issue.severity == DiagnosticSeverity.Error
+
+ msg = 'Unused patch: "some/unused-file.diff"'
+ assert third_issue.message == msg
+ assert f"{third_issue.range}" == "0:0-7:22"
+ assert third_issue.severity == DiagnosticSeverity.Warning
+
+
+def test_dpatches_series_files_ext_lint(line_linter: LintWrapper) -> None:
+ lines = textwrap.dedent(
+ """\
+ # Some leading comment
+
+ some/ok.diff
+
+ some/ok.patch
+
+ some/no-extension
+ """
+ ).splitlines(keepends=True)
+
+ fs = build_virtual_file_system(
+ [
+ "./debian/patches/series",
+ "./debian/patches/some/ok.diff",
+ "./debian/patches/some/ok.patch",
+ "./debian/patches/some/no-extension",
+ ]
+ )
+
+ line_linter.source_root = fs
+
+ diagnostics = line_linter(lines)
+ print(diagnostics)
+ assert len(diagnostics) == 1
+
+ issue = diagnostics[0]
+
+ msg = 'Patch not using ".patch" or ".diff" as extension: "some/no-extension"'
+ assert issue.message == msg
+ assert f"{issue.range}" == "6:0-6:17"
+ assert issue.severity == DiagnosticSeverity.Hint
diff --git a/tests/lsp_tests/test_lsp_dpatches_series.py b/tests/lsp_tests/test_lsp_dpatches_series.py
new file mode 100644
index 0000000..e7a1275
--- /dev/null
+++ b/tests/lsp_tests/test_lsp_dpatches_series.py
@@ -0,0 +1,59 @@
+import textwrap
+
+from debputy.lsp.debputy_ls import DebputyLanguageServer
+
+try:
+ from lsprotocol.types import (
+ CompletionParams,
+ TextDocumentIdentifier,
+ HoverParams,
+ MarkupContent,
+ SemanticTokensParams,
+ )
+
+ from debputy.lsp.lsp_debian_patches_series import (
+ _debian_patches_semantic_tokens_full,
+ _debian_patches_series_completions,
+ )
+
+ from pygls.server import LanguageServer
+except ImportError:
+ pass
+from lsp_tests.lsp_tutil import (
+ put_doc_no_cursor,
+ resolve_semantic_tokens,
+ resolved_semantic_token,
+)
+
+
+def test_dpatches_series_semantic_tokens(ls: "DebputyLanguageServer") -> None:
+ doc_uri = "file:///nowhere/debian/patches/series"
+ put_doc_no_cursor(
+ ls,
+ doc_uri,
+ "debian/patches/series",
+ textwrap.dedent(
+ """\
+ # Some leading comment
+
+ some.patch
+
+ another-delta.diff # foo
+"""
+ ),
+ )
+
+ semantic_tokens = _debian_patches_semantic_tokens_full(
+ ls,
+ SemanticTokensParams(TextDocumentIdentifier(doc_uri)),
+ )
+ resolved_semantic_tokens = resolve_semantic_tokens(semantic_tokens)
+ assert resolved_semantic_tokens is not None
+ assert resolved_semantic_tokens == [
+ resolved_semantic_token(0, 0, len("# Some leading comment"), "comment"),
+ resolved_semantic_token(2, 0, len("some.patch"), "string"),
+ resolved_semantic_token(4, 0, len("another-delta.diff"), "string"),
+ resolved_semantic_token(
+ 4, len("another-delta.diff") + 1, len("# foo"), "comment"
+ ),
+ ]
diff --git a/tests/plugin_tests/grantlee_test.py b/tests/plugin_tests/grantlee_test.py
new file mode 100644
index 0000000..2cbcd2c
--- /dev/null
+++ b/tests/plugin_tests/grantlee_test.py
@@ -0,0 +1,34 @@
+from debputy.plugin.api.test_api import (
+ initialize_plugin_under_test,
+ build_virtual_file_system,
+ package_metadata_context,
+)
+
+
+def test_grantlee_dependencies(amd64_dpkg_architecture_variables) -> None:
+ plugin = initialize_plugin_under_test()
+ fs = build_virtual_file_system([])
+ context = package_metadata_context(package_fields={"Architecture": "all"})
+ metadata = plugin.run_metadata_detector("detect-grantlee-dependencies", fs, context)
+ assert "grantlee:Depends" not in metadata.substvars
+
+ context = package_metadata_context(
+ package_fields={"Architecture": "any"},
+ host_arch=amd64_dpkg_architecture_variables.current_host_arch,
+ )
+ madir = amd64_dpkg_architecture_variables.current_host_multiarch
+ fs = build_virtual_file_system(
+ [
+ f"usr/lib/{madir}/grantlee/random-dir",
+ ]
+ )
+ metadata = plugin.run_metadata_detector("detect-grantlee-dependencies", fs, context)
+ assert "grantlee:Depends" not in metadata.substvars
+
+ fs = build_virtual_file_system(
+ [
+ f"usr/lib/{madir}/grantlee/5.0/foo.so",
+ ]
+ )
+ metadata = plugin.run_metadata_detector("detect-grantlee-dependencies", fs, context)
+ assert metadata.substvars["grantlee:Depends"] == "grantlee5-templates-5-0"