1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
import textwrap
from typing import List, Optional, Callable
import pytest
from debputy.lsp.lsp_debian_control import _lint_debian_control
from lint_tests.lint_tutil import (
run_linter,
group_diagnostics_by_severity,
requires_levenshtein,
exactly_one_diagnostic,
)
try:
from lsprotocol.types import Diagnostic, DiagnosticSeverity
except ImportError:
pass
TestLinter = Callable[[List[str]], Optional[List["Diagnostic"]]]
@pytest.fixture
def line_linter() -> TestLinter:
path = "/nowhere/debian/control"
def _linter(lines: List[str]) -> Optional[List["Diagnostic"]]:
return run_linter(path, lines, _lint_debian_control)
return _linter
def test_dctrl_lint(line_linter: TestLinter) -> None:
lines = textwrap.dedent(
"""\
Source: foo
Some-Other-Field: bar
Build-Depends: debhelper-compat (= 13)
Package: foo
Architecture: all
# Unknown section
Section: base
"""
).splitlines(keepends=True)
diagnostics = line_linter(lines)
by_severity = group_diagnostics_by_severity(diagnostics)
# This example triggers errors and warnings, but no hint of info
assert DiagnosticSeverity.Error in by_severity
assert DiagnosticSeverity.Warning in by_severity
assert DiagnosticSeverity.Hint not in by_severity
assert DiagnosticSeverity.Information not in by_severity
errors = by_severity[DiagnosticSeverity.Error]
print(errors)
assert len(errors) == 3
first_error, second_error, third_error = errors
msg = "Stanza is missing field Standards-Version"
assert first_error.message == msg
assert f"{first_error.range}" == "0:0-1:0"
msg = "Stanza is missing field Maintainer"
assert second_error.message == msg
assert f"{second_error.range}" == "0:0-1:0"
msg = "Stanza is missing field Priority"
assert third_error.message == msg
assert f"{third_error.range}" == "4:0-5:0"
warnings = by_severity[DiagnosticSeverity.Warning]
assert len(warnings) == 2
first_warn, second_warn = warnings
msg = "Stanza is missing field Description"
assert first_warn.message == msg
assert f"{first_warn.range}" == "4:0-5:0"
msg = 'The value "base" is not supported in Section.'
assert second_warn.message == msg
assert f"{second_warn.range}" == "8:9-8:13"
@requires_levenshtein
def test_dctrl_lint_typos(line_linter: TestLinter) -> None:
lines = textwrap.dedent(
"""\
Source: foo
Standards-Version: 4.5.2
Priority: optional
Section: devel
Maintainer: Jane Developer <jane@example.com>
# Typo
Build-Dpends: debhelper-compat (= 13)
Package: foo
Architecture: all
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)
diag = exactly_one_diagnostic(diagnostics)
msg = 'The "Build-Dpends" looks like a typo of "Build-Depends".'
assert diag.message == msg
assert diag.severity == DiagnosticSeverity.Warning
assert f"{diag.range}" == "6:0-6:12"
|