예제 #1
0
def test_required_installed_analyzer():
    pkgs_reqs = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
        PackageRequirement(name='parsimonious', operator='<=', version='0.5'),
    ], )

    pkgs_installed = InstalledPackages(
        packages=[
            InstalledPackage(name='coverage', version='3.5'),  # ok
            InstalledPackage(name='parsimonious', version='0.5'),  # ok
        ], )

    analyzer = RequiredInstalledAnalyzer(
        requirements_txt=pkgs_reqs,
        installed_packages=pkgs_installed,
    )
    advice_list = analyzer.analyze()

    expected_advice_list = AdviceList(advice_list=[
        Advice(
            analyzer=analyzer,
            severity='debug',
            message=("Required dependency 'coverage<3.6' "
                     "is satisfied by installed 'coverage-3.5'"),
        ),
        Advice(
            analyzer=analyzer,
            severity='debug',
            message=("Required dependency 'parsimonious<=0.5' "
                     "is satisfied by installed 'parsimonious-0.5'"),
        ),
    ], )

    assert expected_advice_list == advice_list
예제 #2
0
def test_requirements_txt_equality():
    reqs1 = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
        PackageRequirement(name='parsimonious', operator='<=', version='0.5'),
    ], )

    # missing one package
    reqs2 = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
    ], )

    # operator differs
    reqs3 = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
        PackageRequirement(name='parsimonious', operator='==', version='0.5'),
    ], )

    assert not reqs1 == None  # noqa
    assert reqs1 == reqs1
    assert not reqs1 != reqs1

    assert reqs1 != reqs2
    assert not reqs1 == reqs2

    assert reqs1 != reqs3
    assert not reqs1 == reqs3

    # Test repr
    assert repr(reqs1) == '<RequirementsTxt num_packages=2>'
예제 #3
0
    def parse(self):
        pkgs = []

        for line in self.fileobj:
            line = self.strip_comment(line)
            line = self.strip_flag(line)
            line = line.strip()

            # If the line was all comment or whitespace then skip it
            if not line:
                continue

            match = self.rx_name_op_version.match(line)
            if not match:
                match = self.rx_name.match(line)

            # Was unable to parse the line
            if not match or not len(match.groups()) in [1, 3]:
                _logger.warn('Unable to parse requirements line: %s', line)
                continue

            pkg = PackageRequirement(
                name=match.groupdict()['name'],
                operator=match.groupdict().get('operator'),
                version=match.groupdict().get('version'),
            )
            pkgs.append(pkg)

        reqs = RequirementsTxt(packages=pkgs)
        return reqs
예제 #4
0
def test_is_unused_analyzer():
    pkgs_reqs = RequirementsTxt(packages=[
        PackageRequirement(name='click', operator='==', version='1.8'),
        PackageRequirement(name='six', operator='==', version='3.5'),
    ], )

    pkgs_installed = InstalledPackages(packages=[
        InstalledPackage(name='click', version='1.8'),
        InstalledPackage(name='six', version='3.5'),
    ], )

    # mock: the top level of the package is the name of the package
    site_packages = SitePackages(
        python_path=None,
        installed_package_names=[],
    )
    site_packages.get_package_top_levels = lambda pkg_name: [pkg_name]

    # mock: grep says six is used, nothing else is
    git_grep = GitGrep(basedir=None)
    git_grep.package_is_imported = lambda pkg_name: (True if pkg_name == 'six'
                                                     else False)

    analyzer = IsUnusedAnalyzer(
        requirements_txt=pkgs_reqs,
        installed_packages=pkgs_installed,
        site_packages=site_packages,
        grep=git_grep,
    )
    advice_list = analyzer.analyze()

    expected_advice_list = AdviceList(advice_list=[
        Advice(
            analyzer=analyzer,
            severity='info',
            message=("Required dependency 'click==1.8' "
                     "is never imported (click)"),
        ),
    ], )

    assert expected_advice_list == advice_list
예제 #5
0
def test_requirements_txt_parser():
    reqs_expected = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
        PackageRequirement(name='parsimonious', operator='<=', version='0.5'),
        PackageRequirement(name='pytest', operator='==', version='2.3.5'),
        PackageRequirement(name='six', operator='>=', version='1.6.0'),
        PackageRequirement(name='tox', operator='>', version='1.6.1'),
        PackageRequirement(name='mock', operator='!=', version='5.1.1'),
        PackageRequirement(name='ply', operator='~=', version='3.10'),
        PackageRequirement(name='jsonpath', operator='===', version='2.0.x'),
        PackageRequirement(name='simplejson', operator=None, version=None),
    ], )

    parser = RequirementsTxtParser(fileobj=StringIO(REQS_EXAMPLE))
    reqs = parser.parse()

    assert reqs_expected == reqs
def test_required_not_installed_analyzer():
    pkgs_reqs = RequirementsTxt(packages=[
        PackageRequirement(name='coverage', operator='<', version='3.6'),
        PackageRequirement(name='parsimonious', operator='<=', version='0.5'),
        PackageRequirement(name='six', operator='>=', version='0.5'),
    ], )

    pkgs_installed = InstalledPackages(
        packages=[
            InstalledPackage(name='coverage', version='3.5'),  # ok
            # parsimonious missing
            InstalledPackage(name='six', version='0.4.9'),  # version too low
        ], )

    analyzer = RequiredNotInstalledAnalyzer(
        requirements_txt=pkgs_reqs,
        installed_packages=pkgs_installed,
    )
    advice_list = analyzer.analyze()

    expected_advice_list = AdviceList(advice_list=[
        Advice(
            analyzer=analyzer,
            severity='error',
            message=(
                "Required dependency 'parsimonious<=0.5' is not installed"),
        ),
        Advice(
            analyzer=analyzer,
            severity='error',
            message=("Required dependency 'six>=0.5' "
                     "is not satisfied by installed 'six-0.4.9'"),
        ),
    ], )

    assert expected_advice_list == advice_list
예제 #7
0
def test_requirements_txt_get_by_name():
    coverage = PackageRequirement(name='coverage', operator='<', version='3.6')

    reqs = RequirementsTxt(packages=[
        coverage,
    ], )

    # exact name matches
    assert reqs.get_by_name('coverage') is coverage
    assert reqs.get_by_name('Coverage') is None

    # ignore case
    assert reqs.get_by_name('coverage', ignore_case=True) is coverage
    assert reqs.get_by_name('Coverage', ignore_case=True) is coverage

    # nothing else matches
    assert reqs.get_by_name('coverage==1.0') is None
    assert reqs.get_by_name('cov') is None
예제 #8
0
def test_can_be_upgraded_analyzer():
    pkgs_available = AvailablePackages(
        packages=[
            PackageReleases(name='abc', versions=('8.5', '8.6')),
            PackageReleases(name='click', versions=('1.8', '1.9')),
            PackageReleases(name='coverage', versions=('3.5', '3.6', '4.0', '4.1')),
            PackageReleases(name='ply', versions=('0.5', '0.5.1')),
            PackageReleases(name='six', versions=('0.8', '0.9')),
        ],
    )

    pkgs_reqs = RequirementsTxt(
        packages=[
            PackageRequirement(name='abc', operator='<=', version='9.0'),
            PackageRequirement(name='click', operator=None, version=None),
            PackageRequirement(name='coverage', operator='<', version='4.0'),  # -> 4.1
            PackageRequirement(name='ply', operator='==', version='0.5'),  # -> 0.5.1
            PackageRequirement(name='six', operator='==', version='0.9'),
        ],
    )

    pkgs_installed = InstalledPackages(
        packages=[
            InstalledPackage(name='abc', version='8.5'),  # -> 8.6
            InstalledPackage(name='click', version='1.8'),  # -> 1.9
            InstalledPackage(name='coverage', version='3.5'),  # -> 3.6
        ],
    )

    analyzer = CanBeUpgradedAnalyzer(
        requirements_txt=pkgs_reqs,
        installed_packages=pkgs_installed,
        available_packages=pkgs_available,
    )
    advice_list = analyzer.analyze()

    expected_advice_list = AdviceList(
        advice_list=[
            Advice(
                analyzer=analyzer,
                severity='info',
                message=(
                    "Installed dependency 'abc-8.5' "
                    "can be updated to 'abc-8.6'"
                ),
            ),
            Advice(
                analyzer=analyzer,
                severity='info',
                message=(
                    "Installed dependency 'click-1.8' "
                    "can be updated to 'click-1.9'"
                ),
            ),
            Advice(
                analyzer=analyzer,
                severity='info',
                message=(
                    "Required dependency 'coverage<4.0' "
                    "can be upgraded to 'coverage-4.1'"
                ),
            ),
            Advice(
                analyzer=analyzer,
                severity='info',
                message=(
                    "Installed dependency 'coverage-3.5' "
                    "can be updated to 'coverage-3.6'"
                ),
            ),
            Advice(
                analyzer=analyzer,
                severity='info',
                message=(
                    "Required dependency 'ply==0.5' "
                    "can be upgraded to 'ply-0.5.1'"
                ),
            ),
        ],
    )

    assert expected_advice_list == advice_list
예제 #9
0
def test_can_be_upgraded_analyzer():
    pkgs_reqs = RequirementsTxt(
        packages=[
            PackageRequirement(name='locustio', operator='==',
                               version='0.8a2'),  # top level
            PackageRequirement(name='Flask', operator='==',
                               version='0.12.2'),  # one level down
            PackageRequirement(name='Jinja2', operator='==',
                               version='2.9.6'),  # two levels down
        ], )

    pkgs_installed = InstalledPackages(
        packages=[
            # locustio dependency closure
            InstalledPackage(name='Flask', version='0.12.2'),
            InstalledPackage(name='Jinja2', version='2.9.6'),
            InstalledPackage(name='MarkupSafe', version='1.0'),
            InstalledPackage(name='Werkzeug', version='0.12.2'),
            InstalledPackage(name='certifi', version='2017.7.27.1'),
            InstalledPackage(name='chardet', version='3.0.4'),
            InstalledPackage(name='click', version='6.7'),
            InstalledPackage(name='gevent', version='1.2.2'),
            InstalledPackage(name='greenlet', version='0.4.12'),
            InstalledPackage(name='idna', version='2.6'),
            InstalledPackage(name='itsdangerous', version='0.24'),
            InstalledPackage(name='locustio', version='0.8a2'),
            InstalledPackage(name='msgpack-python', version='0.4.8'),
            InstalledPackage(name='pyzmq', version='15.2.0'),
            InstalledPackage(name='requests', version='2.18.4'),
            InstalledPackage(name='six', version='1.11.0'),
            InstalledPackage(name='urllib3', version='1.22'),

            # top level dependencies, but not reported as they are known
            # "virtual" dependencies
            InstalledPackage(name='pkg-resources', version='0.0.0'),
            InstalledPackage(name='setuptools', version='36.5.0'),

            # top level dependency that is not required - should be reported
            InstalledPackage(name='ipdb', version='0.10.3'),
        ], )

    installed_names = [pkg.name for pkg in pkgs_installed.packages]
    site_packages = SitePackages(
        python_path=None,
        installed_package_names=installed_names,
    )
    site_packages._query_cache = EXAMPLE_RESULTS_DICT

    analyzer = IsTransitiveDepAnalyzer(
        requirements_txt=pkgs_reqs,
        installed_packages=pkgs_installed,
        site_packages=site_packages,
    )
    advice_list = analyzer.analyze()

    expected_advice_list = AdviceList(advice_list=[
        Advice(
            analyzer=analyzer,
            severity='info',
            message=("Required dependency 'Flask==0.12.2' "
                     "is a transitive dependency of 'locustio==0.8a2'"),
        ),
        Advice(
            analyzer=analyzer,
            severity='info',
            message=("Required dependency 'Jinja2==2.9.6' "
                     "is a transitive dependency of 'locustio==0.8a2'"),
        ),
        Advice(
            analyzer=analyzer,
            severity='warn',
            message=("Installed non-transitive dependency 'ipdb-0.10.3' "
                     "is not required"),
        ),
    ], )

    assert expected_advice_list == advice_list