diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/lint_tests/lint_tutil.py | 7 | ||||
-rw-r--r-- | tests/lint_tests/test_lint_dctrl.py | 69 | ||||
-rw-r--r-- | tests/lsp_tests/test_lsp_debputy_manifest_completer.py | 4 | ||||
-rw-r--r-- | tests/test_debputy_plugin.py | 136 | ||||
-rw-r--r-- | tests/test_declarative_parser.py | 9 | ||||
-rw-r--r-- | tests/test_migrations.py | 4 | ||||
-rw-r--r-- | tests/test_parser.py | 83 | ||||
-rw-r--r-- | tests/test_style.py | 84 |
8 files changed, 347 insertions, 49 deletions
diff --git a/tests/lint_tests/lint_tutil.py b/tests/lint_tests/lint_tutil.py index c32ad3c..c16fde3 100644 --- a/tests/lint_tests/lint_tutil.py +++ b/tests/lint_tests/lint_tutil.py @@ -9,7 +9,10 @@ from debputy.linting.lint_util import ( LintStateImpl, LintState, ) -from debputy.lsp.maint_prefs import MaintainerPreferenceTable, EffectivePreference +from debputy.lsp.maint_prefs import ( + MaintainerPreferenceTable, + EffectiveFormattingPreference, +) from debputy.packages import DctrlParser from debputy.plugin.api.feature_set import PluginProvidedFeatureSet @@ -43,7 +46,7 @@ class LintWrapper: self._dctrl_parser = dctrl_parser self.source_root: Optional[VirtualPathBase] = None self.lint_maint_preference_table = MaintainerPreferenceTable({}, {}) - self.effective_preference: Optional[EffectivePreference] = None + self.effective_preference: Optional[EffectiveFormattingPreference] = None def __call__(self, lines: List[str]) -> Optional[List["Diagnostic"]]: source_package = None diff --git a/tests/lint_tests/test_lint_dctrl.py b/tests/lint_tests/test_lint_dctrl.py index 80d7525..229acc1 100644 --- a/tests/lint_tests/test_lint_dctrl.py +++ b/tests/lint_tests/test_lint_dctrl.py @@ -1209,3 +1209,72 @@ def test_dctrl_lint_dep_field_restricted_or_relations( assert problem_text == "|" assert f"{issue.range}" == "13:1-13:2" assert issue.severity == DiagnosticSeverity.Error + + +def test_dctrl_duplicate_key(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: jquery-tablesorter + Section: javascript + Priority: optional + Maintainer: Debian Javascript Maintainers <pkg-javascript-devel@lists.alioth.de\ + bian.org> + Uploaders: Paul Gevers <elbrus@debian.org> + Build-Depends: + debhelper-compat (=13), + grunt, + libjs-qunit, + node-grunt-contrib-clean, + node-grunt-contrib-copy, + node-grunt-contrib-uglify, + node-grunt-contrib-concat, + Standards-Version: {CURRENT_STANDARDS_VERSION} + Homepage: https://github.com/Mottie/tablesorter + Vcs-Git: https://salsa.debian.org/js-team/jquery-tablesorter.git + Vcs-Browser: https://salsa.debian.org/js-team/jquery-tablesorter + Rules-Requires-Root: no + + Package: libjs-jquery-tablesorter + Architecture: all + Multi-Arch: foreign + Depends: + ${{misc:Depends}}, + libjs-jquery, + libjs-jquery-metadata, + Recommends: javascript-common + Multi-Arch: foreign + Description: jQuery flexible client-side table sorting plugin + Tablesorter is a jQuery plugin for turning a standard HTML table with THEAD + and TBODY tags into a sortable table without page refreshes. Tablesorter can + successfully parse and sort many types of data including linked data in a + cell. It has many useful features including: + . + * Multi-column alphanumeric sorting and filtering. + * Multi-tbody sorting + * Supports Bootstrap v2-4. + * Parsers for sorting text, alphanumeric text, URIs, integers, currency, + floats, IP addresses, dates (ISO, long and short formats) and time. + Add your own easily. + * Inline editing + * Support for ROWSPAN and COLSPAN on TH elements. + * Support secondary "hidden" sorting (e.g., maintain alphabetical sort when + sorting on other criteria). + * Extensibility via widget system. + * Cross-browser: IE 6.0+, FF 2+, Safari 2.0+, Opera 9.0+, Chrome 5.0+. + + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + assert len(diagnostics) == 1 + + issue = diagnostics[0] + + msg = ( + "The Multi-Arch field name was used multiple times in this stanza." + " Please ensure the field is only used once per stanza. Note that Multi-Arch and" + " X[BCS]-Multi-Arch are considered the same field." + ) + assert issue.message == msg + assert f"{issue.range}" == "27:0-27:10" + assert issue.severity == DiagnosticSeverity.Error diff --git a/tests/lsp_tests/test_lsp_debputy_manifest_completer.py b/tests/lsp_tests/test_lsp_debputy_manifest_completer.py index f052164..92056ed 100644 --- a/tests/lsp_tests/test_lsp_debputy_manifest_completer.py +++ b/tests/lsp_tests/test_lsp_debputy_manifest_completer.py @@ -200,7 +200,7 @@ def test_basic_debputy_completer_manifest_variable_value( ) assert isinstance(completions, list) keywords = {m.label for m in completions} - assert "0.1" in keywords + assert "'0.1'" in keywords cursor_pos = put_doc_with_cursor( ls, @@ -219,7 +219,7 @@ def test_basic_debputy_completer_manifest_variable_value( ) assert isinstance(completions, list) keywords = {m.label for m in completions} - assert "0.1" in keywords + assert "'0.1'" in keywords def test_basic_debputy_completer_install_rule_dispatch_key( diff --git a/tests/test_debputy_plugin.py b/tests/test_debputy_plugin.py index dc60597..8a4cc59 100644 --- a/tests/test_debputy_plugin.py +++ b/tests/test_debputy_plugin.py @@ -19,6 +19,16 @@ from debputy.plugin.api.test_api import ( from debputy.plugin.api.test_api import manifest_variable_resolution_context from debputy.plugin.api.test_api.test_impl import initialize_plugin_under_test_preloaded from debputy.plugin.api.test_api.test_spec import DetectedService +from debputy.plugin.debputy.build_system_rules import ( + AutoconfBuildSystemRule, + MakefileBuildSystemRule, + PerlBuildBuildSystemRule, + PerlMakeMakerBuildSystemRule, + QmakeBuildSystemRule, + Qmake6BuildSystemRule, + CMakeBuildSystemRule, + MesonBuildSystemRule, +) from debputy.plugin.debputy.debputy_plugin import initialize_debputy_features from debputy.plugin.debputy.private_api import load_libcap from debputy.plugin.debputy.service_management import SystemdServiceContext @@ -1252,3 +1262,129 @@ def test_auto_depends_solink() -> None: context=context_too_many_matches, ) assert "misc:Depends" not in sodep_metadata.substvars + + +@pytest.mark.parametrize( + "filename,expected,mode,content", + [ + ("configure.ac", True, 0o0644, None), + ("configure.in", True, 0o0644, "AC_INIT"), + ("configure.in", True, 0o0644, "AC_PREREQ"), + ("configure.in", False, 0o0644, "None of the above"), + ("configure", True, 0o0755, "GNU Autoconf"), + ("configure", False, 0o0644, "GNU Autoconf"), + ("configure", False, 0o0755, "No magic keyword"), + ("random-file", False, 0o0644, "No configure at all"), + ], +) +def test_auto_detect_autoconf_build_system( + filename: str, + expected: bool, + mode: int, + content: Optional[str], +) -> None: + fs_root = build_virtual_file_system( + [virtual_path_def(filename, mode=mode, content=content)] + ) + detected = AutoconfBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("GNUmakefile", True), + ("Makefile", True), + ("makefile", True), + ("random-file", False), + ], +) +def test_auto_detect_make_build_system( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected = MakefileBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("Build.PL", True), + ("random-file", False), + ], +) +def test_auto_detect_perl_build_build_system( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected = PerlBuildBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("Makefile.PL", True), + ("random-file", False), + ], +) +def test_auto_detect_perl_makemaker_build_system( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected = PerlMakeMakerBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("foo.pro", True), + ("random-file", False), + ], +) +def test_auto_detect_qmake_build_systems( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected_qmake = QmakeBuildSystemRule.auto_detect_build_system(fs_root) + detected_qmake6 = Qmake6BuildSystemRule.auto_detect_build_system(fs_root) + assert detected_qmake == expected + assert detected_qmake6 == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("CMakeLists.txt", True), + ("random-file", False), + ], +) +def test_auto_detect_cmake_build_systems( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected = CMakeBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected + + +@pytest.mark.parametrize( + "filename,expected", + [ + ("meson.build", True), + ("random-file", False), + ], +) +def test_auto_detect_meson_build_systems( + filename: str, + expected: bool, +) -> None: + fs_root = build_virtual_file_system([filename]) + detected = MesonBuildSystemRule.auto_detect_build_system(fs_root) + assert detected == expected diff --git a/tests/test_declarative_parser.py b/tests/test_declarative_parser.py index 26291dd..d52f1c3 100644 --- a/tests/test_declarative_parser.py +++ b/tests/test_declarative_parser.py @@ -10,11 +10,12 @@ from typing import ( import pytest from debputy.highlevel_manifest import PackageTransformationDefinition -from debputy.manifest_parser.base_types import DebputyParsedContent, TypeMapping -from debputy.manifest_parser.declarative_parser import ( - DebputyParseHint, - ParserGenerator, +from debputy.manifest_parser.tagging_types import ( + DebputyParsedContent, + TypeMapping, ) +from debputy.manifest_parser.parse_hints import DebputyParseHint +from debputy.manifest_parser.declarative_parser import ParserGenerator from debputy.manifest_parser.mapper_code import type_mapper_str2package from debputy.manifest_parser.parser_data import ParserContextData from debputy.manifest_parser.util import AttributePath diff --git a/tests/test_migrations.py b/tests/test_migrations.py index f53c716..b179cab 100644 --- a/tests/test_migrations.py +++ b/tests/test_migrations.py @@ -15,7 +15,7 @@ from debputy.dh_migration.migrators_impl import ( migrate_install_file, migrate_maintscript, migrate_links_files, - detect_dh_addons, + detect_dh_addons_with_zz_integration, migrate_not_installed_file, migrate_installman_file, migrate_bash_completion, @@ -1465,7 +1465,7 @@ def test_detect_dh_addons( accept_no_migration_issues: AcceptableMigrationIssues, accept_any_migration_issues: AcceptableMigrationIssues, ) -> None: - migrator = detect_dh_addons + migrator = detect_dh_addons_with_zz_integration empty_fs = build_virtual_file_system([DEBIAN_DIR_ENTRY]) dctrl_no_addons_content = textwrap.dedent( diff --git a/tests/test_parser.py b/tests/test_parser.py index 1c84445..0b1ed56 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -489,3 +489,86 @@ def test_yaml_clean_after_removal_unsafe_path( else: with pytest.raises(ManifestParseException) as e_info: manifest_parser_pkg_foo.parse_manifest(fd=content) + + +def test_yaml_build_environment_default( + manifest_parser_pkg_foo: YAMLManifestParser, +) -> None: + content = textwrap.dedent( + ( + """\ + + manifest-version: '0.1' + default-build-environment: + set: + FOO: "bar" + builds: + # FIXME: we should not require an empty dict here + - autoconf: {} + """ + ) + ) + manifest = manifest_parser_pkg_foo.parse_manifest(fd=content) + envs = manifest.build_environments + assert not envs.environments + base_env = {} + envs.default_environment.update_env(base_env) + assert "FOO" in base_env + build_rule = manifest.build_rules[0] + assert build_rule.environment is envs.default_environment + + +def test_yaml_build_environments_no_default( + manifest_parser_pkg_foo: YAMLManifestParser, +) -> None: + content = textwrap.dedent( + ( + f"""\ + + manifest-version: '0.1' + build-environments: + - name: custom-env + set: + FOO: "bar" + builds: + - autoconf: + environment: custom-env + """ + ) + ) + manifest = manifest_parser_pkg_foo.parse_manifest(fd=content) + envs = manifest.build_environments + assert "custom-env" in envs.environments + custom_env = envs.environments["custom-env"] + assert envs.default_environment is None + base_env = {} + custom_env.update_env(base_env) + assert "FOO" in base_env + build_rule = manifest.build_rules[0] + assert build_rule.environment is custom_env + + +def test_yaml_build_environments_no_default_error( + manifest_parser_pkg_foo: YAMLManifestParser, +) -> None: + content = textwrap.dedent( + ( + """\ + + manifest-version: '0.1' + build-environments: + - name: custom-env + set: + FOO: "bar" + builds: + # FIXME: we should not require an empty dict here + - autoconf: {} + """ + ) + ) + with pytest.raises(ManifestParseException) as e_info: + manifest_parser_pkg_foo.parse_manifest(fd=content) + + expected_msg = "The following named environments were never referenced: custom-env" + msg = e_info.value.args[0] + assert msg == expected_msg diff --git a/tests/test_style.py b/tests/test_style.py index d3cfb14..8f5b6ca 100644 --- a/tests/test_style.py +++ b/tests/test_style.py @@ -7,7 +7,7 @@ from debputy.yaml.compat import CommentedMap from debputy.lsp.maint_prefs import ( MaintainerPreferenceTable, determine_effective_preference, - EffectivePreference, + EffectiveFormattingPreference, _WAS_DEFAULTS, ) from debputy.packages import SourcePackage @@ -16,19 +16,25 @@ from debputy.packages import SourcePackage def test_load_styles() -> None: styles = MaintainerPreferenceTable.load_preferences() assert "niels@thykier.net" in styles.maintainer_preferences - nt_style = styles.maintainer_preferences["niels@thykier.net"] + nt_maint_pref = styles.maintainer_preferences["niels@thykier.net"] # Note this is data dependent; if it fails because the style changes, update the test - assert nt_style.canonical_name == "Niels Thykier" - assert not nt_style.is_packaging_team - assert nt_style.formatting_deb822_normalize_field_content - assert nt_style.formatting_deb822_short_indent - assert nt_style.formatting_deb822_always_wrap - assert nt_style.formatting_deb822_trailing_separator - assert nt_style.formatting_deb822_max_line_length == 79 - assert not nt_style.formatting_deb822_normalize_stanza_order + assert nt_maint_pref.canonical_name == "Niels Thykier" + assert not nt_maint_pref.is_packaging_team + black_style = styles.named_styles["black"] + nt_style = nt_maint_pref.formatting + assert nt_style is not None + assert black_style == black_style - # TODO: Not implemented yet - assert not nt_style.formatting_deb822_normalize_field_order + +def test_load_no_styles() -> None: + styles = MaintainerPreferenceTable.load_preferences() + assert "packages@qa.debian.org" in styles.maintainer_preferences + qa_maint_pref = styles.maintainer_preferences["packages@qa.debian.org"] + assert qa_maint_pref.canonical_name == "Debian QA Group" + assert qa_maint_pref.is_packaging_team + # Orphaned packages do not have a predefined style, since Debian (nor Debian QA) have + # one well-defined style. + assert qa_maint_pref.formatting is None def test_load_named_styles() -> None: @@ -36,15 +42,15 @@ def test_load_named_styles() -> None: assert "black" in styles.named_styles black_style = styles.named_styles["black"] # Note this is data dependent; if it fails because the style changes, update the test - assert black_style.formatting_deb822_normalize_field_content - assert black_style.formatting_deb822_short_indent - assert black_style.formatting_deb822_always_wrap - assert black_style.formatting_deb822_trailing_separator - assert black_style.formatting_deb822_max_line_length == 79 - assert not black_style.formatting_deb822_normalize_stanza_order + assert black_style.deb822_normalize_field_content + assert black_style.deb822_short_indent + assert black_style.deb822_always_wrap + assert black_style.deb822_trailing_separator + assert black_style.deb822_max_line_length == 79 + assert not black_style.deb822_normalize_stanza_order # TODO: Not implemented yet - assert not black_style.formatting_deb822_normalize_field_order + assert not black_style.deb822_normalize_field_order def test_compat_styles() -> None: @@ -56,11 +62,11 @@ def test_compat_styles() -> None: assert "random-package@packages.debian.org" not in styles.maintainer_preferences assert "random@example.org" not in styles.maintainer_preferences - nt_pref = styles.maintainer_preferences["niels@thykier.net"].as_effective_pref() - zeha_pref = styles.maintainer_preferences["zeha@debian.org"].as_effective_pref() + nt_style = styles.maintainer_preferences["niels@thykier.net"].formatting + zeha_style = styles.maintainer_preferences["zeha@debian.org"].formatting # Data dependency - assert nt_pref == zeha_pref + assert nt_style == zeha_style fields = Deb822( { @@ -72,7 +78,7 @@ def test_compat_styles() -> None: src = SourcePackage(fields) effective_style, tool, _ = determine_effective_preference(styles, src, None) - assert effective_style == nt_pref + assert effective_style == nt_style assert tool == "debputy reformat" fields["Uploaders"] = ( @@ -81,8 +87,8 @@ def test_compat_styles() -> None: src = SourcePackage(fields) effective_style, tool, _ = determine_effective_preference(styles, src, None) - assert effective_style == nt_pref - assert effective_style == zeha_pref + assert effective_style == nt_style + assert effective_style == zeha_style assert tool == "debputy reformat" fields["Uploaders"] = ( @@ -112,7 +118,7 @@ def test_compat_styles_team_maint() -> None: team_style = styles.maintainer_preferences["team@lists.debian.org"] assert team_style.is_packaging_team effective_style, tool, _ = determine_effective_preference(styles, src, None) - assert effective_style == team_style.as_effective_pref() + assert effective_style == team_style.formatting assert tool is None @@ -158,7 +164,7 @@ def test_was_from_salsa_ci_style() -> None: {"variables": CommentedMap({"SALSA_CI_DISABLE_WRAP_AND_SORT": "no"})} ) effective_style, tool, _ = determine_effective_preference(styles, src, salsa_ci) - was_style = EffectivePreference(**_WAS_DEFAULTS) + was_style = EffectiveFormattingPreference(**_WAS_DEFAULTS) assert effective_style == was_style assert tool == "wrap-and-sort" @@ -169,37 +175,37 @@ def test_was_from_salsa_ci_style() -> None: ( "-a", { - "formatting_deb822_always_wrap": True, + "deb822_always_wrap": True, }, ), ( "-sa", { - "formatting_deb822_always_wrap": True, - "formatting_deb822_short_indent": True, + "deb822_always_wrap": True, + "deb822_short_indent": True, }, ), ( "-sa --keep-first", { - "formatting_deb822_always_wrap": True, - "formatting_deb822_short_indent": True, + "deb822_always_wrap": True, + "deb822_short_indent": True, }, ), ( "-sab --keep-first", { - "formatting_deb822_always_wrap": True, - "formatting_deb822_short_indent": True, - "formatting_deb822_normalize_stanza_order": True, + "deb822_always_wrap": True, + "deb822_short_indent": True, + "deb822_normalize_stanza_order": True, }, ), ( "-sab --no-keep-first", { - "formatting_deb822_always_wrap": True, - "formatting_deb822_short_indent": True, - "formatting_deb822_normalize_stanza_order": False, + "deb822_always_wrap": True, + "deb822_short_indent": True, + "deb822_normalize_stanza_order": False, }, ), ], @@ -232,7 +238,7 @@ def test_was_from_salsa_ci_style_args( assert effective_style is None assert tool is None else: - was_style = EffectivePreference(**_WAS_DEFAULTS).replace( + was_style = EffectiveFormattingPreference(**_WAS_DEFAULTS).replace( **style_delta, ) |