jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[tests] decorate MW version

Bug: T130516
Change-Id: Ic3790694f540614828b0c4303de4091bdd613c48
---
M tests/README.rst
M tests/api_tests.py
M tests/aspects.py
M tests/edit_tests.py
M tests/site_generators_tests.py
5 files changed, 71 insertions(+), 23 deletions(-)

diff --git a/tests/README.rst b/tests/README.rst
index 7c62773..acc4b21 100644
--- a/tests/README.rst
+++ b/tests/README.rst
@@ -207,6 +207,17 @@
@require_modules(['important1', 'musthave2'])
def test_require_modules(self):

+@tests.aspects.require_version
+------------------------------
+Require a given MediaWiki version
+
+::
+
+ from tests.aspects import require_version
+ [......]
+ @require_version('>=1.27.0')
+ def test_require_version(self):
+
@unittest.mock.patch
-----------------------
Replaces `target` with object specified in `new`. Refer to mock's documentation.
diff --git a/tests/api_tests.py b/tests/api_tests.py
index e945abd..560356e 100755
--- a/tests/api_tests.py
+++ b/tests/api_tests.py
@@ -18,7 +18,9 @@
from pywikibot.exceptions import APIError, NoUsernameError
from pywikibot.throttle import Throttle
from pywikibot.tools import suppress_warnings
+
from tests.aspects import (
+ require_version,
DefaultDrySiteTestCase,
DefaultSiteTestCase,
TestCase,
@@ -292,13 +294,10 @@

self.assertIn('query+revisions', pi.prefix_map)

+ @require_version('>=1.25wmf4', 'support the new paraminfo api')
def test_new_mode(self):
"""Test the new modules-only mode explicitly."""
site = self.get_site()
- if site.mw_version < '1.25wmf4':
- self.skipTest(
- "version {} doesn't support the new paraminfo api"
- .format(site.mw_version))
pi = api.ParamInfo(site, modules_only_mode=True)
pi.fetch(['info'])
self.assertIn('query+info', pi._paraminfo)
diff --git a/tests/aspects.py b/tests/aspects.py
index 36709de..60c442d 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -19,6 +19,7 @@
import warnings
from collections.abc import Sized
from contextlib import contextmanager, suppress
+from functools import wraps
from http import HTTPStatus
from unittest.util import safe_repr

@@ -35,6 +36,7 @@
from pywikibot.family import WikimediaFamily
from pywikibot.site import BaseSite
from pywikibot.tools import suppress_warnings
+from pywikibot.tools import MediaWikiVersion # noqa: F401 (used by f-string)
from tests import (
WARN_SITE_CODE,
patch_request,
@@ -311,6 +313,59 @@
return test_requirement


+def require_version(version_needed: str, reason: str = ''):
+ """Require minimum MediaWiki version to be queried.
+
+ The version needed for the test; must be given with a preleading rich
+ comparisons operator like ``<1.27wmf4`` or ``>=1.39``. If the
+ comparison does not match the test will be skipped.
+
+ This decorator can only be used for TestCase having a single site.
+ It cannot be used for DrySite tests. In addition version comparison
+ for other than the current site e.g. for the related data or image
+ repositoy of the current site is ot possible.
+
+ .. versionadded:: 8.0.0
+
+ :param version_needed: The version needed
+ :param reason: A reason for skipping the test.
+ :raises Exception: Usage validation fails
+ """
+ def test_requirement(method):
+ """Test the requirement and return an optionally decorated object."""
+ @wraps(method)
+ def wrapper(self, *args, **kwargs):
+ """Validate environment."""
+ if not isinstance(self.site, BaseSite) \
+ or isinstance(self.site, DrySite):
+ raise Exception(
+ f'{type(self).__name__}.site must be a BaseSite not '
+ f'{type(self.site).__name__}.')
+
+ if args or kwargs:
+ raise Exception(
+ f'Test method {method.__name__!r} has parameters which is '
+ f'not supported with require_version decorator.')
+
+ _, op, version = re.split('([<>]=?)', version_needed)
+ if not op:
+ raise Exception(f'There is no valid operator given with '
+ f'version {version_needed!r}')
+
+ skip = not eval(
+ f'self.site.mw_version {op} MediaWikiVersion(version)')
+ if not skip:
+ return method(self, *args, **kwargs)
+
+ myreason = ' to ' + reason if reason else ''
+ raise unittest.SkipTest(
+ f'MediaWiki {op} v{version} required{myreason}.')
+
+ return wrapper
+
+ return test_requirement
+
+
class DisableSiteMixin(TestCaseBase):

"""Test cases not connected to a Site object.
diff --git a/tests/edit_tests.py b/tests/edit_tests.py
index 6fb8834..e967087 100755
--- a/tests/edit_tests.py
+++ b/tests/edit_tests.py
@@ -12,7 +12,7 @@
import pywikibot
from pywikibot import config, page_put_queue
from pywikibot.exceptions import Error
-from tests.aspects import TestCase
+from tests.aspects import TestCase, require_version
from tests.oauth_tests import OAuthSiteTestCase


@@ -79,17 +79,13 @@
write = True
rights = 'mergehistory'

+ @require_version('>=1.27.0wmf.13', 'support the history merge API')
def setup_test_pages(self):
"""Helper function to set up pages that we will use in these tests."""
site = self.get_site()
source = pywikibot.Page(site, 'User:Sn1per/MergeTest1')
dest = pywikibot.Page(site, 'User:Sn1per/MergeTest2')

- # Make sure the wiki supports action=mergehistory
- if site.mw_version < '1.27.0-wmf.13':
- self.skipTest('Wiki version must be 1.27.0-wmf.13 or newer to '
- 'support the history merge API.')
-
if source.exists():
source.delete('Pywikibot merge history unit test')
if dest.exists():
diff --git a/tests/site_generators_tests.py b/tests/site_generators_tests.py
index ba0b11c..7f02d86 100644
--- a/tests/site_generators_tests.py
+++ b/tests/site_generators_tests.py
@@ -110,9 +110,6 @@

def test_page_redirects(self):
"""Test Site.page_redirects."""
- if self.get_site().mw_version < '1.24':
- self.skipTest('site.page_redirects() needs mw 1.24')
-
redirects_ns_0 = set(self.site.page_redirects(
self.mainpage,
namespaces=0,
@@ -1262,13 +1259,6 @@

login = True

- @classmethod
- def setUpClass(cls):
- """Skip test if necessary."""
- super().setUpClass()
- if cls.site.mw_version < '1.25':
- cls.skipTest(cls, 'site.alldeletedrevisions() needs mw 1.25')
-
def test_basic(self):
"""Test the site.alldeletedrevisions() method."""
mysite = self.get_site()
@@ -1430,9 +1420,6 @@
def test_prefix(self):
"""Test the site.alldeletedrevisions() method with prefix."""
mysite = self.get_site()
- if mysite.mw_version < '1.25':
- self.skipTest('site.alldeletedrevisions() needs mw 1.25')
-
for data in mysite.alldeletedrevisions(prefix='John', total=5):
self.assertIsInstance(data, dict)
for key in ('title', 'ns', 'revisions'):

To view, visit change 582299. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ic3790694f540614828b0c4303de4091bdd613c48
Gerrit-Change-Number: 582299
Gerrit-PatchSet: 20
Gerrit-Owner: Dvorapa <dvorapa@seznam.cz>
Gerrit-Reviewer: Dvorapa <dvorapa@seznam.cz>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged