jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/582299 )

Change subject: [tests] decorate MW version
......................................................................

[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(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



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

[email protected]_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 https://gerrit.wikimedia.org/r/c/pywikibot/core/+/582299
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ic3790694f540614828b0c4303de4091bdd613c48
Gerrit-Change-Number: 582299
Gerrit-PatchSet: 20
Gerrit-Owner: Dvorapa <[email protected]>
Gerrit-Reviewer: Dvorapa <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to