jenkins-bot has submitted this change and it was merged.

Change subject: [FEAT] Support assertAPIError
......................................................................


[FEAT] Support assertAPIError

To assert a specific APIError the base class supports `assertAPIError` which
wraps around `assertRaises` and additionally checks if the error is of a
specific code and optionally a specific info. Like `assertRaises` it can be
used as a context manager when additional checks should be done afterwards.

Change-Id: Ib211974ec3acd17fb45c2280e084723257a88650
---
M tests/aspects.py
M tests/upload_tests.py
M tests/utils.py
3 files changed, 72 insertions(+), 6 deletions(-)

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



diff --git a/tests/aspects.py b/tests/aspects.py
index 0503077..2dfcc09 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -56,7 +56,7 @@
 from tests import unittest, patch_request, unpatch_request
 from tests.utils import (
     add_metaclass, execute_pwb, DrySite, DryRequest,
-    WarningSourceSkipContextManager,
+    WarningSourceSkipContextManager, AssertAPIErrorContextManager,
 )
 
 OSWIN32 = (sys.platform == 'win32')
@@ -263,6 +263,33 @@
 
     assertPagelistTitles = assertPageTitlesEqual
 
+    def assertAPIError(self, code, info=None, callable_obj=None, *args,
+                       **kwargs):
+        """
+        Assert that a specific APIError wrapped around L{assertRaises}.
+
+        If no callable object is defined and it returns a context manager, that
+        context manager will return the underlying context manager used by
+        L{assertRaises}. So it's possible to access the APIError by using it's
+        C{exception} attribute.
+
+        @param code: The code of the error which must have happened.
+        @type code: str
+        @param info: The info string of the error or None if no it shouldn't be
+            checked.
+        @type info: str or None
+        @param callable_obj: The object that will be tested. If None it returns
+            a context manager like L{assertRaises}.
+        @type callable_obj: callable
+        @param args: The positional arguments forwarded to the callable object.
+        @param kwargs: The keyword arguments forwared to the callable object.
+        @return: The context manager if callable_obj is None and None 
otherwise.
+        @rtype: None or context manager
+        """
+        msg = kwargs.pop('msg', None)
+        return AssertAPIErrorContextManager(
+            code, info, msg, self).handle(callable_obj, args, kwargs)
+
 
 class TestTimerMixin(TestCaseBase):
 
diff --git a/tests/upload_tests.py b/tests/upload_tests.py
index a7987d8..7968f01 100644
--- a/tests/upload_tests.py
+++ b/tests/upload_tests.py
@@ -15,8 +15,6 @@
 
 import pywikibot
 
-from pywikibot.data.api import APIError
-
 from tests import join_images_path
 from tests.aspects import unittest, TestCase
 
@@ -103,9 +101,8 @@
         self._finish_upload(chunk_size, self.sounds_png)
 
         # Check if it's still cached
-        with self.assertRaises(APIError) as cm:
+        with self.assertAPIError('siiinvalidsessiondata') as cm:
             self.site.stash_info(self._file_key)
-        self.assertEqual(cm.exception.code, 'siiinvalidsessiondata')
         self.assertTrue(cm.exception.info.startswith('File not found'),
                         'info ({0}) did not start with '
                         '"File not found"'.format(cm.exception.info))
diff --git a/tests/utils.py b/tests/utils.py
index 7cb96d6..6884cb1 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -32,7 +32,7 @@
 from pywikibot import config
 from pywikibot.comms import threadedhttp
 from pywikibot.site import Namespace
-from pywikibot.data.api import CachedRequest
+from pywikibot.data.api import CachedRequest, APIError
 from pywikibot.data.api import Request as _original_Request
 from pywikibot.tools import (
     PYTHON_VERSION,
@@ -244,6 +244,48 @@
         return log
 
 
+class AssertAPIErrorContextManager(object):
+
+    """
+    Context manager to assert certain APIError exceptions.
+
+    This is build similar to the L{unittest.TestCase.assertError} 
implementation
+    which creates an context manager. It then calls L{handle} which either
+    returns this manager if no executing object given or calls the callable
+    object.
+    """
+
+    def __init__(self, code, info, msg, test_case):
+        """Create instance expecting the code and info."""
+        self.code = code
+        self.info = info
+        self.msg = msg
+        self.test_case = test_case
+
+    def __enter__(self):
+        """Enter this context manager and the unittest's context manager."""
+        self.cm = self.test_case.assertRaises(APIError, msg=self.msg)
+        self.cm.__enter__()
+        return self.cm
+
+    def __exit__(self, exc_type, exc_value, tb):
+        """Exit the context manager and assert code and optionally info."""
+        result = self.cm.__exit__(exc_type, exc_value, tb)
+        assert result is isinstance(exc_value, APIError)
+        if result:
+            self.test_case.assertEqual(exc_value.code, self.code)
+            if self.info:
+                self.test_case.assertEqual(exc_value.info, self.info)
+        return result
+
+    def handle(self, callable_obj, args, kwargs):
+        """Handle the callable object by returning itself or using itself."""
+        if callable_obj is None:
+            return self
+        with self:
+            callable_obj(*args, **kwargs)
+
+
 class DryParamInfo(dict):
 
     """Dummy class to use instead of L{pywikibot.data.api.ParamInfo}."""

-- 
To view, visit https://gerrit.wikimedia.org/r/239683
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib211974ec3acd17fb45c2280e084723257a88650
Gerrit-PatchSet: 3
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <commodorefabia...@gmx.de>
Gerrit-Reviewer: John Vandenberg <jay...@gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgr...@gmail.com>
Gerrit-Reviewer: XZise <commodorefabia...@gmx.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to