Add tests for `pep_sphinx_extensions` (#2545)
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM>
This commit is contained in:
parent
73d438cadb
commit
0b0dd6ddd5
|
@ -22,7 +22,6 @@ jobs:
|
|||
- name: 👷 Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install --upgrade -r requirements.txt
|
||||
|
||||
- name: 🔧 Render PEPs
|
||||
run: make pages -j$(nproc)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
name: Test Sphinx Extensions
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/test.yml"
|
||||
- "pep_sphinx_extensions/**"
|
||||
- "tox.ini"
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/test.yml"
|
||||
- "pep_sphinx_extensions/**"
|
||||
- "tox.ini"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10"]
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: pip
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install -U pip
|
||||
python -m pip install -U wheel
|
||||
python -m pip install -U tox
|
||||
|
||||
- name: Run tests with tox
|
||||
run: |
|
||||
tox -e py -- -v --cov-report term
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
flags: ${{ matrix.os }}
|
||||
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
|
@ -7,6 +7,8 @@ __pycache__
|
|||
*.pyo
|
||||
*~
|
||||
*env
|
||||
.coverage
|
||||
.tox
|
||||
.vscode
|
||||
*.swp
|
||||
/build
|
||||
|
|
|
@ -42,6 +42,30 @@ repos:
|
|||
- id: check-yaml
|
||||
name: "Check YAML"
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
name: "Format with Black"
|
||||
args:
|
||||
- '--target-version=py39'
|
||||
- '--target-version=py310'
|
||||
files: 'pep_sphinx_extensions/tests/.*'
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
name: "Sort imports with isort"
|
||||
args: ['--profile=black', '--atomic']
|
||||
files: 'pep_sphinx_extensions/tests/.*'
|
||||
|
||||
- repo: https://github.com/tox-dev/tox-ini-fmt
|
||||
rev: 0.5.2
|
||||
hooks:
|
||||
- id: tox-ini-fmt
|
||||
name: "Format tox.ini"
|
||||
|
||||
# RST checks
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.9.0
|
||||
|
|
3
Makefile
3
Makefile
|
@ -41,6 +41,9 @@ lint: venv
|
|||
$(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit
|
||||
$(VENVDIR)/bin/python3 -m pre_commit run --all-files
|
||||
|
||||
test: venv
|
||||
$(VENVDIR)/bin/python3 -bb -X dev -W error -m pytest
|
||||
|
||||
spellcheck: venv
|
||||
$(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit
|
||||
$(VENVDIR)/bin/python3 -m pre_commit run --all-files --hook-stage manual codespell
|
||||
|
|
|
@ -204,8 +204,8 @@ def _process_pretty_url(url: str) -> tuple[str, str]:
|
|||
item_name, item_type = LINK_PRETTIFIERS[parts[2]](parts)
|
||||
except KeyError as error:
|
||||
raise ValueError(
|
||||
"{url} not a link to a recognized domain to prettify") from error
|
||||
item_name = item_name.title().replace("Sig", "SIG")
|
||||
f"{url} not a link to a recognized domain to prettify") from error
|
||||
item_name = item_name.title().replace("Sig", "SIG").replace("Pep", "PEP")
|
||||
return item_name, item_type
|
||||
|
||||
|
||||
|
|
|
@ -33,10 +33,6 @@ def parse_author_email(author_email_tuple: tuple[str, str], authors_overrides: d
|
|||
if name_parts.mononym is not None:
|
||||
return Author(name_parts.mononym, name_parts.mononym, email)
|
||||
|
||||
if name_parts.surname[1] == ".":
|
||||
# Add an escape to avoid docutils turning `v.` into `22.`.
|
||||
name_parts.surname = f"\\{name_parts.surname}"
|
||||
|
||||
if name_parts.suffix:
|
||||
last_first = f"{name_parts.surname}, {name_parts.forename}, {name_parts.suffix}"
|
||||
return Author(last_first, name_parts.surname, email)
|
||||
|
@ -63,7 +59,7 @@ def _parse_name(full_name: str) -> _Name:
|
|||
num_parts = len(name_parts)
|
||||
suffix = raw_suffix.strip()
|
||||
|
||||
if num_parts == 0:
|
||||
if name_parts == [""]:
|
||||
raise ValueError("Name is empty!")
|
||||
elif num_parts == 1:
|
||||
return _Name(mononym=name_parts[0], suffix=suffix)
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
from pathlib import Path
|
||||
|
||||
from pep_sphinx_extensions.pep_processor.transforms import pep_footer
|
||||
|
||||
|
||||
def test_add_source_link():
|
||||
out = pep_footer._add_source_link(Path("pep-0008.txt"))
|
||||
|
||||
assert "https://github.com/python/peps/blob/main/pep-0008.txt" in str(out)
|
||||
|
||||
|
||||
def test_add_commit_history_info():
|
||||
out = pep_footer._add_commit_history_info(Path("pep-0008.txt"))
|
||||
|
||||
assert str(out).startswith(
|
||||
"<paragraph>Last modified: "
|
||||
'<reference refuri="https://github.com/python/peps/commits/main/pep-0008.txt">'
|
||||
)
|
||||
# A variable timestamp comes next, don't test that
|
||||
assert str(out).endswith("</reference></paragraph>")
|
||||
|
||||
|
||||
def test_add_commit_history_info_invalid():
|
||||
out = pep_footer._add_commit_history_info(Path("pep-not-found.txt"))
|
||||
|
||||
assert str(out) == "<paragraph/>"
|
||||
|
||||
|
||||
def test_get_last_modified_timestamps():
|
||||
out = pep_footer._get_last_modified_timestamps()
|
||||
|
||||
assert len(out) >= 585
|
||||
# Should be a Unix timestamp and at least this
|
||||
assert out["pep-0008.txt"] >= 1643124055
|
|
@ -0,0 +1,114 @@
|
|||
import pytest
|
||||
|
||||
from pep_sphinx_extensions.pep_processor.transforms import pep_headers
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
("my-mailing-list@example.com", "my-mailing-list@example.com"),
|
||||
("python-tulip@googlegroups.com", "https://groups.google.com/g/python-tulip"),
|
||||
("db-sig@python.org", "https://mail.python.org/mailman/listinfo/db-sig"),
|
||||
("import-sig@python.org", "https://mail.python.org/pipermail/import-sig/"),
|
||||
(
|
||||
"python-announce@python.org",
|
||||
"https://mail.python.org/archives/list/python-announce@python.org/",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_generate_list_url(test_input, expected):
|
||||
out = pep_headers._generate_list_url(test_input)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
"https://mail.python.org/pipermail/python-3000/2006-November/004190.html",
|
||||
("Python-3000", "message"),
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/archives/list/python-dev@python.org/thread/HW2NFOEMCVCTAFLBLC3V7MLM6ZNMKP42/",
|
||||
("Python-Dev", "thread"),
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/mailman3/lists/capi-sig.python.org/",
|
||||
("Capi-SIG", "list"),
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/mailman/listinfo/web-sig",
|
||||
("Web-SIG", "list"),
|
||||
),
|
||||
(
|
||||
"https://discuss.python.org/t/pep-643-metadata-for-package-source-distributions/5577",
|
||||
("Discourse", "thread"),
|
||||
),
|
||||
(
|
||||
"https://discuss.python.org/c/peps/",
|
||||
("PEPs Discourse", "category"),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_process_pretty_url(test_input, expected):
|
||||
out = pep_headers._process_pretty_url(test_input)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
"https://example.com/",
|
||||
"https://example.com/ not a link to a recognized domain to prettify",
|
||||
),
|
||||
(
|
||||
"https://mail.python.org",
|
||||
"https://mail.python.org not a link to a list, message or thread",
|
||||
),
|
||||
(
|
||||
"https://discuss.python.org/",
|
||||
"https://discuss.python.org not a link to a Discourse thread or category",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_process_pretty_url_invalid(test_input, expected):
|
||||
with pytest.raises(ValueError, match=expected):
|
||||
pep_headers._process_pretty_url(test_input)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
"https://mail.python.org/pipermail/python-3000/2006-November/004190.html",
|
||||
"Python-3000 message",
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/archives/list/python-dev@python.org/thread/HW2NFOEMCVCTAFLBLC3V7MLM6ZNMKP42/",
|
||||
"Python-Dev thread",
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/mailman3/lists/capi-sig.python.org/",
|
||||
"Capi-SIG list",
|
||||
),
|
||||
(
|
||||
"https://mail.python.org/mailman/listinfo/web-sig",
|
||||
"Web-SIG list",
|
||||
),
|
||||
(
|
||||
"https://discuss.python.org/t/pep-643-metadata-for-package-source-distributions/5577",
|
||||
"Discourse thread",
|
||||
),
|
||||
(
|
||||
"https://discuss.python.org/c/peps/",
|
||||
"PEPs Discourse category",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_make_link_pretty(test_input, expected):
|
||||
out = pep_headers._make_link_pretty(test_input)
|
||||
|
||||
assert out == expected
|
|
@ -0,0 +1,25 @@
|
|||
import pytest
|
||||
from docutils import nodes
|
||||
|
||||
from pep_sphinx_extensions.pep_processor.transforms import pep_zero
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
nodes.reference(
|
||||
"", text="user@example.com", refuri="mailto:user@example.com"
|
||||
),
|
||||
'<raw format="html" xml:space="preserve">user at example.com</raw>',
|
||||
),
|
||||
(
|
||||
nodes.reference("", text="Introduction", refid="introduction"),
|
||||
'<reference refid="introduction">Introduction</reference>',
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_generate_list_url(test_input, expected):
|
||||
out = pep_zero._mask_email(test_input)
|
||||
|
||||
assert str(out) == expected
|
|
@ -0,0 +1,69 @@
|
|||
import pytest
|
||||
|
||||
from pep_sphinx_extensions.pep_zero_generator import author
|
||||
from pep_sphinx_extensions.tests.utils import AUTHORS_OVERRIDES
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
("First Last", "first@example.com"),
|
||||
author.Author(
|
||||
last_first="Last, First", nick="Last", email="first@example.com"
|
||||
),
|
||||
),
|
||||
(
|
||||
("Guido van Rossum", "guido@example.com"),
|
||||
author.Author(
|
||||
last_first="van Rossum, Guido (GvR)",
|
||||
nick="GvR",
|
||||
email="guido@example.com",
|
||||
),
|
||||
),
|
||||
(
|
||||
("Hugo van Kemenade", "hugo@example.com"),
|
||||
author.Author(
|
||||
last_first="van Kemenade, Hugo",
|
||||
nick="van Kemenade",
|
||||
email="hugo@example.com",
|
||||
),
|
||||
),
|
||||
(
|
||||
("Eric N. Vander Weele", "eric@example.com"),
|
||||
author.Author(
|
||||
last_first="Vander Weele, Eric N.",
|
||||
nick="Vander Weele",
|
||||
email="eric@example.com",
|
||||
),
|
||||
),
|
||||
(
|
||||
("Mariatta", "mariatta@example.com"),
|
||||
author.Author(
|
||||
last_first="Mariatta", nick="Mariatta", email="mariatta@example.com"
|
||||
),
|
||||
),
|
||||
(
|
||||
("First Last Jr.", "first@example.com"),
|
||||
author.Author(
|
||||
last_first="Last, First, Jr.", nick="Last", email="first@example.com"
|
||||
),
|
||||
),
|
||||
pytest.param(
|
||||
("First Last", "first at example.com"),
|
||||
author.Author(
|
||||
last_first="Last, First", nick="Last", email="first@example.com"
|
||||
),
|
||||
marks=pytest.mark.xfail,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_author_email(test_input, expected):
|
||||
out = author.parse_author_email(test_input, AUTHORS_OVERRIDES)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_parse_author_email_empty_name():
|
||||
with pytest.raises(ValueError, match="Name is empty!"):
|
||||
author.parse_author_email(("", "user@example.com"), AUTHORS_OVERRIDES)
|
|
@ -0,0 +1,88 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from pep_sphinx_extensions.pep_zero_generator import parser
|
||||
from pep_sphinx_extensions.pep_zero_generator.author import Author
|
||||
from pep_sphinx_extensions.pep_zero_generator.errors import PEPError
|
||||
from pep_sphinx_extensions.tests.utils import AUTHORS_OVERRIDES
|
||||
|
||||
|
||||
def test_pep_repr():
|
||||
pep8 = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
assert repr(pep8) == "<PEP 0008 - Style Guide for Python Code>"
|
||||
|
||||
|
||||
def test_pep_less_than():
|
||||
pep8 = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
pep3333 = parser.PEP(Path("pep-3333.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
assert pep8 < pep3333
|
||||
|
||||
|
||||
def test_pep_equal():
|
||||
pep_a = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
pep_b = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
assert pep_a == pep_b
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(80, "Style Guide for Python Code"),
|
||||
(10, "Style ..."),
|
||||
],
|
||||
)
|
||||
def test_pep_details(test_input, expected):
|
||||
pep8 = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
assert pep8.details(title_length=test_input) == {
|
||||
"authors": "GvR, Warsaw, Coghlan",
|
||||
"number": 8,
|
||||
"status": " ",
|
||||
"title": expected,
|
||||
"type": "P",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
"First Last <user@example.com>",
|
||||
[Author(last_first="Last, First", nick="Last", email="user@example.com")],
|
||||
),
|
||||
(
|
||||
"First Last",
|
||||
[Author(last_first="Last, First", nick="Last", email="")],
|
||||
),
|
||||
(
|
||||
"user@example.com (First Last)",
|
||||
[Author(last_first="Last, First", nick="Last", email="user@example.com")],
|
||||
),
|
||||
pytest.param(
|
||||
"First Last <user at example.com>",
|
||||
[Author(last_first="Last, First", nick="Last", email="user@example.com")],
|
||||
marks=pytest.mark.xfail,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_authors(test_input, expected):
|
||||
# Arrange
|
||||
pep = parser.PEP(Path("pep-0160.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
# Act
|
||||
out = parser._parse_authors(pep, test_input, AUTHORS_OVERRIDES)
|
||||
|
||||
# Assert
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_parse_authors_invalid():
|
||||
|
||||
pep = parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)
|
||||
|
||||
with pytest.raises(PEPError, match="no authors found"):
|
||||
parser._parse_authors(pep, "", AUTHORS_OVERRIDES)
|
|
@ -0,0 +1,12 @@
|
|||
from pathlib import Path
|
||||
|
||||
from pep_sphinx_extensions.pep_zero_generator import parser, pep_index_generator
|
||||
from pep_sphinx_extensions.tests.utils import AUTHORS_OVERRIDES
|
||||
|
||||
|
||||
def test_create_pep_json():
|
||||
peps = [parser.PEP(Path("pep-0008.txt"), AUTHORS_OVERRIDES)]
|
||||
|
||||
out = pep_index_generator.create_pep_json(peps)
|
||||
|
||||
assert '"url": "https://peps.python.org/pep-0008/"' in out
|
|
@ -0,0 +1,76 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from pep_sphinx_extensions.pep_zero_generator import parser, writer
|
||||
from pep_sphinx_extensions.tests.utils import AUTHORS_OVERRIDES
|
||||
|
||||
|
||||
def test_pep_zero_writer_emit_text_newline():
|
||||
pep0_writer = writer.PEPZeroWriter()
|
||||
pep0_writer.emit_text("my text 1")
|
||||
pep0_writer.emit_newline()
|
||||
pep0_writer.emit_text("my text 2")
|
||||
|
||||
assert pep0_writer.output == ["my text 1", "", "my text 2"]
|
||||
|
||||
|
||||
def test_pep_zero_writer_emit_title():
|
||||
pep0_writer = writer.PEPZeroWriter()
|
||||
pep0_writer.emit_title("My Title")
|
||||
pep0_writer.emit_subtitle("My Subtitle")
|
||||
|
||||
assert pep0_writer.output == [
|
||||
"My Title",
|
||||
"========",
|
||||
"",
|
||||
"My Subtitle",
|
||||
"-----------",
|
||||
"",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
"pep-9000.rst",
|
||||
{
|
||||
"Fussyreverend, Francis": "one@example.com",
|
||||
"Soulfulcommodore, Javier": "two@example.com",
|
||||
},
|
||||
),
|
||||
(
|
||||
"pep-9001.rst",
|
||||
{"Fussyreverend, Francis": "", "Soulfulcommodore, Javier": ""},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_verify_email_addresses(test_input, expected):
|
||||
# Arrange
|
||||
peps = [
|
||||
parser.PEP(
|
||||
Path(f"pep_sphinx_extensions/tests/peps/{test_input}"), AUTHORS_OVERRIDES
|
||||
)
|
||||
]
|
||||
|
||||
# Act
|
||||
out = writer._verify_email_addresses(peps)
|
||||
|
||||
# Assert
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_sort_authors():
|
||||
# Arrange
|
||||
authors_dict = {
|
||||
"Zebra, Zoë": "zoe@example.com",
|
||||
"lowercase, laurence": "laurence@example.com",
|
||||
"Aardvark, Alfred": "alfred@example.com",
|
||||
}
|
||||
|
||||
# Act
|
||||
out = writer._sort_authors(authors_dict)
|
||||
|
||||
# Assert
|
||||
assert out == ["Aardvark, Alfred", "lowercase, laurence", "Zebra, Zoë"]
|
|
@ -0,0 +1,7 @@
|
|||
PEP: 9000
|
||||
Title: Test with authors with email addresses
|
||||
Author: Francis Fussyreverend <one@example.com>,
|
||||
Javier Soulfulcommodore <two@example.com>
|
||||
Created: 20-Apr-2022
|
||||
Status: Draft
|
||||
Type: Process
|
|
@ -0,0 +1,7 @@
|
|||
PEP: 9001
|
||||
Title: Test with authors with no email addresses
|
||||
Author: Francis Fussyreverend,
|
||||
Javier Soulfulcommodore
|
||||
Created: 20-Apr-2022
|
||||
Status: Draft
|
||||
Type: Process
|
|
@ -0,0 +1,6 @@
|
|||
AUTHORS_OVERRIDES = {
|
||||
"Guido van Rossum": {
|
||||
"Surname First": "van Rossum, Guido (GvR)",
|
||||
"Name Reference": "GvR",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[pytest]
|
||||
addopts = -r a --strict-config --strict-markers --import-mode=importlib --cov pep_sphinx_extensions --cov-report html --cov-report xml
|
||||
empty_parameter_set_mark = fail_at_collect
|
||||
filterwarnings =
|
||||
error
|
||||
minversion = 6.0
|
||||
testpaths = pep_sphinx_extensions
|
||||
xfail_strict = True
|
|
@ -5,3 +5,7 @@ docutils >= 0.17.1
|
|||
|
||||
# For RSS
|
||||
feedgen >= 0.9.0 # For RSS feed
|
||||
|
||||
# For tests
|
||||
pytest
|
||||
pytest-cov
|
||||
|
|
Loading…
Reference in New Issue