File: test_0packaging.py

package info (click to toggle)
python-aiosmtpd 1.4.6-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,016 kB
  • sloc: python: 8,064; makefile: 159
file content (100 lines) | stat: -rw-r--r-- 3,506 bytes parent folder | download
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
# Copyright 2014-2021 The aiosmtpd Developers
# SPDX-License-Identifier: Apache-2.0

"""Test meta / packaging"""

import re
import subprocess
from datetime import datetime
from itertools import tee
from pathlib import Path

import pytest

# noinspection PyPackageRequirements
from packaging import version

from aiosmtpd import __version__

RE_DUNDERVER = re.compile(r"__version__\s*?=\s*?(['\"])(?P<ver>[^'\"]+)\1\s*$")
RE_VERHEADING = re.compile(r"(?P<ver>([0-9.]+)\S*)\s*\((?P<date>[^)]+)\)")


@pytest.fixture
def aiosmtpd_version() -> version.Version:
    return version.parse(__version__)


class TestVersion:
    def test_pep440(self, aiosmtpd_version: version.Version):
        """Ensure version number compliance to PEP-440"""
        assert isinstance(
            aiosmtpd_version, version.Version
        ), "Version number must comply with PEP-440"

    # noinspection PyUnboundLocalVariable
    @pytest.mark.skip
    def test_ge_master(
        self, aiosmtpd_version: version.Version, capsys: pytest.CaptureFixture
    ):
        """Ensure version is monotonically increasing"""
        reference = "master:aiosmtpd/__init__.py"
        cmd = f"git show {reference}".split()
        try:
            with capsys.disabled():
                master_smtp = subprocess.check_output(cmd).decode()  # nosec
        except subprocess.CalledProcessError:
            pytest.skip("Skipping due to git error")

        try:
            m = next(m for ln in master_smtp.splitlines() if (m := RE_DUNDERVER.match(ln)))
        except StopIteration:
            pytest.fail(f"Cannot find __version__ in {reference}!")
        master_ver = version.parse(m.group("ver"))
        assert aiosmtpd_version >= master_ver, "Version number cannot be < master's"


class TestNews:
    news_rst = list(Path(__file__).parent.parent.rglob("*/NEWS.rst"))[0]

    def test_NEWS_version(self, aiosmtpd_version: version.Version):
        with self.news_rst.open("rt") as fin:
            # pairwise() from https://docs.python.org/3/library/itertools.html
            a, b = tee(fin)
            next(b, None)
            for ln1, ln2 in zip(a, b):
                if not ln1[0].isdigit():
                    continue
                ln1 = ln1.strip()
                ln2 = ln2.strip()
                equals = "=" * len(ln1)
                if not ln2.startswith(equals):
                    continue
                break
        newsvers = ln1.split()[0]
        newsver = version.parse(newsvers)
        if newsver.base_version < aiosmtpd_version.base_version:
            pytest.fail(
                f"NEWS.rst is not updated: "
                f"{newsver.base_version} < {aiosmtpd_version.base_version}"
            )

    def test_release_date(self, aiosmtpd_version: version.Version):
        if aiosmtpd_version.pre is not None:
            pytest.skip("Not a release version")
        with self.news_rst.open("rt") as fin:
            for ln in fin:
                ln = ln.strip()
                m = RE_VERHEADING.match(ln)
                if not m:
                    continue
                ver = version.Version(m.group("ver"))
                if ver != aiosmtpd_version:
                    continue
                try:
                    datetime.strptime(m.group("date"), "%Y-%m-%d")
                except ValueError:
                    pytest.fail("Release version not dated correctly")
                break
            else:
                pytest.fail("Release version has no NEWS fragment")