Source code for meta_package_manager.tests.test_specifier

# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

from __future__ import annotations

from dataclasses import asdict

import pytest
from boltons.iterutils import flatten

from meta_package_manager.pool import pool
from meta_package_manager.specifier import PURL_MAP, EmptyReduction, Solver, Specifier


[docs]def test_purl_map(): # Check all our supported managers are registered. assert set(pool.all_manager_ids).issubset(PURL_MAP) # Check our hard-coded purl mapping points to implemented managers. assert ( set(pool.all_manager_ids) .union({None}) .issuperset(set(flatten(PURL_MAP.values()))) )
[docs]def props(spec: Specifier): """Utility to help compares specifiers between themselves. I.e. all properties of specifiers are the same but the ``raw_specs`` property. """ return sorted((k, v) for k, v in asdict(spec).items() if k != "raw_spec")
[docs]@pytest.mark.parametrize( ("spec_string", "expected"), ( pytest.param( "leftpad", ({"package_id": "leftpad", "manager_id": None, "version": None},), id="ascii", ), pytest.param( "left_pad", ({"package_id": "left_pad", "manager_id": None, "version": None},), id="underscore", ), pytest.param( "left.pad", ({"package_id": "left.pad", "manager_id": None, "version": None},), id="dot", ), pytest.param( "left-pad", ({"package_id": "left-pad", "manager_id": None, "version": None},), id="dash", ), pytest.param( "left-pad@8.a7", ({"package_id": "left-pad", "manager_id": None, "version": "8.a7"},), id="version_spec", ), pytest.param( "pkg:npm/leftpad", ( { "package_id": "leftpad", "manager_id": "npm", "version": None, }, ), id="purl_with_manager", ), pytest.param( "pkg:npm/leftpad@1.2.3", ({"package_id": "leftpad", "manager_id": "npm", "version": "1.2.3"},), id="purl_with_version", ), pytest.param( "pkg:rubygems/dummy@21.0-b", ({"package_id": "dummy", "manager_id": "gem", "version": "21.0-b"},), id="purl_single_alias", ), pytest.param( "pkg:rpm/ping@2011-04.gamma", ( { "package_id": "ping", "manager_id": "dnf", "version": "2011-04.gamma", }, { "package_id": "ping", "manager_id": "yum", "version": "2011-04.gamma", }, { "package_id": "ping", "manager_id": "zypper", "version": "2011-04.gamma", }, ), id="purl_multiple_aliases", ), ), ) def test_parse_specs(spec_string, expected): specs = tuple(Specifier.from_string(spec_string)) spec_props = [] for spec in specs: assert spec.raw_spec == spec_string # Serialize each specifier into an hashable set without the 'raw_spec' # field (which we checked above). spec_props.append(props(spec)) assert sorted(spec_props) == sorted(sorted(s.items()) for s in expected)
[docs]@pytest.mark.parametrize( ("spec_strings", "target_managers", "expected"), ( pytest.param( ("leftpad",), None, Specifier.from_string("leftpad"), id="tuple_specs", ), pytest.param( ["leftpad"], None, Specifier.from_string("leftpad"), id="list_specs", ), pytest.param( {"leftpad"}, None, Specifier.from_string("leftpad"), id="set_specs", ), pytest.param( ("leftpad", "leftpad"), None, Specifier.from_string("leftpad"), id="duplicates", ), pytest.param( {"left-pad@8.a7"}, None, Specifier.from_string("left-pad@8.a7"), id="version_spec", ), pytest.param( {"left-pad", "left-pad@8.23.a7"}, None, Specifier.from_string("left-pad@8.23.a7"), id="version_and_unversioned_mix", ), pytest.param( {"pkg:npm/leftpad"}, None, Specifier.from_string("pkg:npm/leftpad"), id="purl_with_manager", ), pytest.param( {"pkg:npm/leftpad@1.2.3"}, None, Specifier.from_string("pkg:npm/leftpad@1.2.3"), id="purl_with_version", ), pytest.param( {"pkg:rubygems/dummy@21.0-b"}, None, Specifier.from_string("pkg:gem/dummy@21.0-b"), id="purl_single_alias", ), pytest.param( {"pkg:rpm/ping@2011-04.gamma"}, ["dnf", "yum", "zypper"], Specifier.from_string("pkg:dnf/ping@2011-04.gamma"), id="purl_multiple_aliases_priority1", ), pytest.param( {"pkg:rpm/ping@2011-04.gamma"}, ["zypper", "yum"], Specifier.from_string("pkg:zypper/ping@2011-04.gamma"), id="purl_multiple_aliases_priority2", ), pytest.param( {"pkg:rpm/ping@2011-04.gamma"}, ["pypi"], EmptyReduction, id="purl_multiple_aliases_unmatching_manager_skip_package", ), pytest.param( {"pkg:rpm/ping@2011-04.gamma"}, None, ValueError, id="unresolveable_multiple_aliases", ), pytest.param( {"pkg:npm/leftpad", "leftpad@77.10.0"}, None, Specifier.from_string("pkg:npm/leftpad"), id="purl_takes_precedence", ), pytest.param( {"leftpad", "leftpad@1.7.3", "pkg:npm/leftpad@1.7.3"}, None, Specifier.from_string("pkg:npm/leftpad@1.7.3"), id="mixed_package_specs", ), pytest.param( {"left-pad@33.1.a", "left-pad@0100"}, None, Specifier.from_string("left-pad@0100"), id="multiple_versions", ), pytest.param( {"left-pad@99.00", "left-pad@99.00"}, None, Specifier.from_string("left-pad@99.00"), id="duplicate_version_spec", ), pytest.param( {"left-pad@99.00", "left-pad@99"}, None, Specifier.from_string("left-pad@99.00"), id="similar_version_spec", ), pytest.param( {"left-pad@99.00", "left-pad@0099.00"}, None, ValueError, id="equivalent_version_spec", ), ), ) def test_reduce_specs(spec_strings, target_managers, expected): solver = Solver(spec_strings, manager_priority=target_managers) if isinstance(expected, type) and issubclass(expected, Exception): with pytest.raises(expected): solver.reduce_specs(solver.spec_pool) else: reduced_spec = solver.reduce_specs(solver.spec_pool) expected = tuple(expected) assert len(expected) == 1 assert props(reduced_spec) == props(expected[0])