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")
|