Improve testing for copyright year substitution (#12950)

This commit is contained in:
Adam Turner
2024-10-03 21:56:50 +01:00
committed by GitHub
parent 7546545876
commit 5f3846f8c6
7 changed files with 228 additions and 113 deletions

View File

@@ -648,6 +648,7 @@ def _substitute_copyright_year(copyright_line: str, replace_year: str) -> str:
* ``YYYY`` * ``YYYY``
* ``YYYY,`` * ``YYYY,``
* ``YYYY `` * ``YYYY ``
* ``YYYY-YYYY``
* ``YYYY-YYYY,`` * ``YYYY-YYYY,``
* ``YYYY-YYYY `` * ``YYYY-YYYY ``

View File

@@ -1,3 +0,0 @@
========================
test-copyright-multiline
========================

View File

@@ -1 +0,0 @@
copyright = '2006-2009, Author'

View File

@@ -1,4 +0,0 @@
=================
test-correct-year
=================

View File

@@ -0,0 +1,76 @@
import time
import pytest
@pytest.fixture(
params=[
1293840000, # 2011-01-01 00:00:00
1293839999, # 2010-12-31 23:59:59
]
)
def source_date_year(request, monkeypatch):
source_date_epoch = request.param
with monkeypatch.context() as m:
m.setenv('SOURCE_DATE_EPOCH', str(source_date_epoch))
yield time.gmtime(source_date_epoch).tm_year
@pytest.mark.sphinx('html', testroot='copyright-multiline')
def test_html_multi_line_copyright(app):
app.build(force_all=True)
content = (app.outdir / 'index.html').read_text(encoding='utf-8')
# check the copyright footer line by line (empty lines ignored)
assert ' &#169; Copyright 2006.<br/>\n' in content
assert ' &#169; Copyright 2006-2009, Alice.<br/>\n' in content
assert ' &#169; Copyright 2010-2013, Bob.<br/>\n' in content
assert ' &#169; Copyright 2014-2017, Charlie.<br/>\n' in content
assert ' &#169; Copyright 2018-2021, David.<br/>\n' in content
assert ' &#169; Copyright 2022-2025, Eve.' in content
# check the raw copyright footer block (empty lines included)
assert (
' &#169; Copyright 2006.<br/>\n'
' \n'
' &#169; Copyright 2006-2009, Alice.<br/>\n'
' \n'
' &#169; Copyright 2010-2013, Bob.<br/>\n'
' \n'
' &#169; Copyright 2014-2017, Charlie.<br/>\n'
' \n'
' &#169; Copyright 2018-2021, David.<br/>\n'
' \n'
' &#169; Copyright 2022-2025, Eve.'
) in content
@pytest.mark.sphinx('html', testroot='copyright-multiline')
def test_html_multi_line_copyright_sde(source_date_year, app):
app.build(force_all=True)
content = (app.outdir / 'index.html').read_text(encoding='utf-8')
# check the copyright footer line by line (empty lines ignored)
assert f' &#169; Copyright {source_date_year}.<br/>\n' in content
assert f' &#169; Copyright 2006-{source_date_year}, Alice.<br/>\n' in content
assert f' &#169; Copyright 2010-{source_date_year}, Bob.<br/>\n' in content
assert f' &#169; Copyright 2014-{source_date_year}, Charlie.<br/>\n' in content
assert f' &#169; Copyright 2018-{source_date_year}, David.<br/>\n' in content
assert f' &#169; Copyright 2022-{source_date_year}, Eve.' in content
# check the raw copyright footer block (empty lines included)
assert (
f' &#169; Copyright {source_date_year}.<br/>\n'
f' \n'
f' &#169; Copyright 2006-{source_date_year}, Alice.<br/>\n'
f' \n'
f' &#169; Copyright 2010-{source_date_year}, Bob.<br/>\n'
f' \n'
f' &#169; Copyright 2014-{source_date_year}, Charlie.<br/>\n'
f' \n'
f' &#169; Copyright 2018-{source_date_year}, David.<br/>\n'
f' \n'
f' &#169; Copyright 2022-{source_date_year}, Eve.'
) in content

View File

@@ -3,7 +3,6 @@
from __future__ import annotations from __future__ import annotations
import pickle import pickle
import time
from collections import Counter from collections import Counter
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
@@ -18,7 +17,6 @@ from sphinx.config import (
Config, Config,
_Opt, _Opt,
check_confval_types, check_confval_types,
correct_copyright_year,
is_serializable, is_serializable,
) )
from sphinx.deprecation import RemovedInSphinx90Warning from sphinx.deprecation import RemovedInSphinx90Warning
@@ -741,101 +739,6 @@ def test_conf_py_nitpick_ignore_list(tmp_path):
assert cfg.nitpick_ignore_regex == [] assert cfg.nitpick_ignore_regex == []
@pytest.fixture(
params=[
# test with SOURCE_DATE_EPOCH unset: no modification
None,
# test with SOURCE_DATE_EPOCH set: copyright year should be updated
1293840000,
1293839999,
]
)
def source_date_year(request, monkeypatch):
sde = request.param
with monkeypatch.context() as m:
if sde:
m.setenv('SOURCE_DATE_EPOCH', str(sde))
yield time.gmtime(sde).tm_year
else:
m.delenv('SOURCE_DATE_EPOCH', raising=False)
yield None
@pytest.mark.sphinx('html', testroot='copyright-multiline')
def test_multi_line_copyright(source_date_year, app):
app.build(force_all=True)
content = (app.outdir / 'index.html').read_text(encoding='utf-8')
if source_date_year is None:
# check the copyright footer line by line (empty lines ignored)
assert ' &#169; Copyright 2006.<br/>\n' in content
assert ' &#169; Copyright 2006-2009, Alice.<br/>\n' in content
assert ' &#169; Copyright 2010-2013, Bob.<br/>\n' in content
assert ' &#169; Copyright 2014-2017, Charlie.<br/>\n' in content
assert ' &#169; Copyright 2018-2021, David.<br/>\n' in content
assert ' &#169; Copyright 2022-2025, Eve.' in content
# check the raw copyright footer block (empty lines included)
assert (
' &#169; Copyright 2006.<br/>\n'
' \n'
' &#169; Copyright 2006-2009, Alice.<br/>\n'
' \n'
' &#169; Copyright 2010-2013, Bob.<br/>\n'
' \n'
' &#169; Copyright 2014-2017, Charlie.<br/>\n'
' \n'
' &#169; Copyright 2018-2021, David.<br/>\n'
' \n'
' &#169; Copyright 2022-2025, Eve.'
) in content
else:
# check the copyright footer line by line (empty lines ignored)
assert f' &#169; Copyright {source_date_year}.<br/>\n' in content
assert f' &#169; Copyright 2006-{source_date_year}, Alice.<br/>\n' in content
assert f' &#169; Copyright 2010-{source_date_year}, Bob.<br/>\n' in content
assert f' &#169; Copyright 2014-{source_date_year}, Charlie.<br/>\n' in content
assert f' &#169; Copyright 2018-{source_date_year}, David.<br/>\n' in content
assert f' &#169; Copyright 2022-{source_date_year}, Eve.' in content
# check the raw copyright footer block (empty lines included)
assert (
f' &#169; Copyright {source_date_year}.<br/>\n'
f' \n'
f' &#169; Copyright 2006-{source_date_year}, Alice.<br/>\n'
f' \n'
f' &#169; Copyright 2010-{source_date_year}, Bob.<br/>\n'
f' \n'
f' &#169; Copyright 2014-{source_date_year}, Charlie.<br/>\n'
f' \n'
f' &#169; Copyright 2018-{source_date_year}, David.<br/>\n'
f' \n'
f' &#169; Copyright 2022-{source_date_year}, Eve.'
) in content
@pytest.mark.parametrize(
('conf_copyright', 'expected_copyright'),
[
('1970', '{current_year}'),
# https://github.com/sphinx-doc/sphinx/issues/11913
('1970-1990', '1970-{current_year}'),
('1970-1990 Alice', '1970-{current_year} Alice'),
],
)
def test_correct_copyright_year(conf_copyright, expected_copyright, source_date_year):
config = Config({}, {'copyright': conf_copyright})
correct_copyright_year(_app=None, config=config)
actual_copyright = config['copyright']
if source_date_year is None:
expected_copyright = conf_copyright
else:
expected_copyright = expected_copyright.format(current_year=source_date_year)
assert actual_copyright == expected_copyright
def test_gettext_compact_command_line_true(): def test_gettext_compact_command_line_true():
config = Config({}, {'gettext_compact': '1'}) config = Config({}, {'gettext_compact': '1'})
config.add('gettext_compact', True, '', {bool, str}) config.add('gettext_compact', True, '', {bool, str})

View File

@@ -1,20 +1,31 @@
"""Test copyright year adjustment""" """Test copyright year adjustment"""
import time
import pytest import pytest
from sphinx.config import Config, correct_copyright_year
LT = time.localtime()
LT_NEW = (2009, *LT[1:], LT.tm_zone, LT.tm_gmtoff)
LOCALTIME_2009 = type(LT)(LT_NEW)
@pytest.fixture( @pytest.fixture(
params=[ params=[
# test with SOURCE_DATE_EPOCH unset: no modification # test with SOURCE_DATE_EPOCH unset: no modification
(None, '2006-2009'), (None, ''),
# test with SOURCE_DATE_EPOCH set: copyright year should be updated # test with SOURCE_DATE_EPOCH set: copyright year should be updated
('1293840000', '2006-2011'), ('1293840000', '2011'),
('1293839999', '2006-2010'), ('1293839999', '2010'),
('1199145600', '2008'),
('1199145599', '2007'),
], ],
) )
def expect_date(request, monkeypatch): def expect_date(request, monkeypatch):
sde, expect = request.param sde, expect = request.param
with monkeypatch.context() as m: with monkeypatch.context() as m:
m.setattr(time, 'localtime', lambda *a: LOCALTIME_2009)
if sde: if sde:
m.setenv('SOURCE_DATE_EPOCH', sde) m.setenv('SOURCE_DATE_EPOCH', sde)
else: else:
@@ -22,8 +33,140 @@ def expect_date(request, monkeypatch):
yield expect yield expect
@pytest.mark.sphinx('html', testroot='correct-year') def test_correct_year(expect_date):
def test_correct_year(expect_date, app): # test that copyright is substituted
app.build() copyright_date = '2006-2009, Alice'
content = (app.outdir / 'index.html').read_text(encoding='utf8') cfg = Config({'copyright': copyright_date}, {})
assert expect_date in content assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'2006-{expect_date}, Alice'
else:
assert cfg.copyright == copyright_date
def test_correct_year_space(expect_date):
# test that copyright is substituted
copyright_date = '2006-2009 Alice'
cfg = Config({'copyright': copyright_date}, {})
assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'2006-{expect_date} Alice'
else:
assert cfg.copyright == copyright_date
def test_correct_year_no_author(expect_date):
# test that copyright is substituted
copyright_date = '2006-2009'
cfg = Config({'copyright': copyright_date}, {})
assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'2006-{expect_date}'
else:
assert cfg.copyright == copyright_date
def test_correct_year_single(expect_date):
# test that copyright is substituted
copyright_date = '2009, Alice'
cfg = Config({'copyright': copyright_date}, {})
assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'{expect_date}, Alice'
else:
assert cfg.copyright == copyright_date
def test_correct_year_single_space(expect_date):
# test that copyright is substituted
copyright_date = '2009 Alice'
cfg = Config({'copyright': copyright_date}, {})
assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'{expect_date} Alice'
else:
assert cfg.copyright == copyright_date
def test_correct_year_single_no_author(expect_date):
# test that copyright is substituted
copyright_date = '2009'
cfg = Config({'copyright': copyright_date}, {})
assert cfg.copyright == copyright_date
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == f'{expect_date}'
else:
assert cfg.copyright == copyright_date
def test_correct_year_multi_line(expect_date):
# test that copyright is substituted
copyright_dates = (
'2006',
'2006-2009, Alice',
'2010-2013, Bob',
'2014-2017, Charlie',
'2018-2021, David',
'2022-2025, Eve',
)
cfg = Config({'copyright': copyright_dates}, {})
assert cfg.copyright == copyright_dates
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == (
f'{expect_date}',
f'2006-{expect_date}, Alice',
f'2010-{expect_date}, Bob',
f'2014-{expect_date}, Charlie',
f'2018-{expect_date}, David',
f'2022-{expect_date}, Eve',
)
else:
assert cfg.copyright == copyright_dates
def test_correct_year_multi_line_all_formats(expect_date):
# test that copyright is substituted
copyright_dates = (
'2009',
'2009 Alice',
'2009, Bob',
'2006-2009',
'2006-2009 Charlie',
'2006-2009, David',
)
cfg = Config({'copyright': copyright_dates}, {})
assert cfg.copyright == copyright_dates
correct_copyright_year(None, cfg) # type: ignore[arg-type]
if expect_date:
assert cfg.copyright == (
f'{expect_date}',
f'{expect_date} Alice',
f'{expect_date}, Bob',
f'2006-{expect_date}',
f'2006-{expect_date} Charlie',
f'2006-{expect_date}, David',
)
else:
assert cfg.copyright == copyright_dates
def test_correct_year_app(expect_date, tmp_path, make_app):
# integration test
copyright_date = '2006-2009, Alice'
(tmp_path / 'conf.py').touch()
app = make_app(
'dummy',
srcdir=tmp_path,
confoverrides={'copyright': copyright_date},
)
if expect_date:
assert app.config.copyright == f'2006-{expect_date}, Alice'
else:
assert app.config.copyright == copyright_date