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

Change subject: [FEAT] tests: Generic reading bot class test case
......................................................................


[FEAT] tests: Generic reading bot class test case

For tests which use a Bot class and also userPut (or similar) this test case
can be used as it monkey patches '_save_page' to prevent actually saving the
page.

Change-Id: Iaec972f813f2470d1f2e51fde8d59b29d929925c
---
M tests/bot_tests.py
M tests/disambredir_tests.py
2 files changed, 90 insertions(+), 24 deletions(-)

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



diff --git a/tests/bot_tests.py b/tests/bot_tests.py
index b2a9a7c..4764e79 100644
--- a/tests/bot_tests.py
+++ b/tests/bot_tests.py
@@ -14,7 +14,81 @@
 import pywikibot
 import pywikibot.bot
 
-from tests.aspects import unittest, DefaultSiteTestCase, SiteAttributeTestCase
+from tests.aspects import (
+    unittest, DefaultSiteTestCase, SiteAttributeTestCase, TestCase,
+)
+
+
+class FakeSaveBotTestCase(TestCase):
+
+    """
+    An abstract test case which patches the bot class to not actually write.
+
+    It redirects the bot's _save_page to it's own C{bot_save} method. Currently
+    userPut, put_current and user_edit_entity call it. By default it'll call
+    the original method but replace the function called to actually save the
+    page by C{page_save}. It patches the bot class as soon as this class'
+    attribute bot is defined. It also sets the bot's 'always' option to True to
+    avoid user interaction.
+
+    The C{bot_save} method compares the save counter before the call and 
asserts
+    that it has increased by one after the call. It also stores locally in
+    C{save_called} if C{page_save} has been called. If C{bot_save} or
+    C{page_save} are implemented they should call super's method at some point
+    to make sure these assertions work. At C{tearDown} it checks that the pages
+    are saved often enough. The attribute C{default_assert_saves} defines the
+    number of saves which must happen and compares it to the difference using
+    the save counter. It is possible to define C{assert_saves} after C{setUp} 
to
+    overwrite the default value for certain tests. By default the number of
+    saves it asserts are 1. Additionally C{save_called} increases by 1 on each
+    call of C{page_save} and should be equal to C{assert_saves}.
+
+    This means if the bot class actually does other writes, like using
+    L{pywikibot.page.Page.save} manually, it'll still write.
+    """
+
+    @property
+    def bot(self):
+        """Get the current bot."""
+        return self._bot
+
+    @bot.setter
+    def bot(self, value):
+        """Set and patch the current bot."""
+        assert value._save_page != self.bot_save, 'bot may not be patched.'
+        self._bot = value
+        self._bot.options['always'] = True
+        self._original = self._bot._save_page
+        self._bot._save_page = self.bot_save
+        self._old_counter = self._bot._save_counter
+
+    def setUp(self):
+        """Set up test by reseting the counters."""
+        super(FakeSaveBotTestCase, self).setUp()
+        self.assert_saves = getattr(self, 'default_assert_saves', 1)
+        self.save_called = 0
+
+    def tearDown(self):
+        """Tear down by asserting the counters."""
+        self.assertEqual(self._bot._save_counter,
+                         self._old_counter + self.assert_saves)
+        self.assertEqual(self.save_called, self.assert_saves)
+        super(FakeSaveBotTestCase, self).tearDown()
+
+    def bot_save(self, page, func, *args, **kwargs):
+        """Handle when bot's userPut was called."""
+        self.assertGreaterEqual(self._bot._save_counter, 0)
+        old_counter = self._bot._save_counter
+        old_local_cnt = self.save_called
+        result = self._original(page, self.page_save, *args, **kwargs)
+        self.assertEqual(self._bot._save_counter, old_counter + 1)
+        self.assertEqual(self.save_called, old_local_cnt + 1)
+        self.assertGreater(self._bot._save_counter, self._old_counter)
+        return result
+
+    def page_save(self, *args, **kwargs):
+        """Handle when bot calls the page's save method."""
+        self.save_called += 1
 
 
 class TestBotTreatExit(object):
diff --git a/tests/disambredir_tests.py b/tests/disambredir_tests.py
index 5b34e47..5e260c7 100644
--- a/tests/disambredir_tests.py
+++ b/tests/disambredir_tests.py
@@ -18,11 +18,12 @@
 
 from scripts import disambredir
 
-from tests.aspects import unittest, TestCase
+from tests.aspects import unittest
+from tests.bot_tests import FakeSaveBotTestCase
 from tests.utils import fixed_generator
 
 
-class TestDisambigurationRedirectBot(TestCase):
+class TestDisambigurationRedirectBot(FakeSaveBotTestCase):
 
     """
     Test cases for DisambigurationRedirectBot.
@@ -62,70 +63,61 @@
     def setUpClass(cls):
         """Initialize page variable."""
         super(TestDisambigurationRedirectBot, cls).setUpClass()
+        # Patch the page to be independent of the actual site
         cls.page = pywikibot.Page(cls.site, 'User:BobBot/Test disambig')
+        cls.page.linkedPages = fixed_generator(
+            [pywikibot.Page(cls.site, 'User:BobBot/Redir'),
+             pywikibot.Page(cls.site, 'Main Page')])
+
+    def bot_save(self, page, *args, **kwargs):
+        """Check if the page matches."""
+        self.assertIs(page, self.page)
+        return super(TestDisambigurationRedirectBot, self).bot_save(
+            page, *args, **kwargs)
 
     def setUp(self):
         """Set up the test page."""
-        def _save_page(*args, **kwargs):
-            self.assertIs(args[0], self.page)
-            self.save_called = True
-            return  # avert actually saving
-
         super(TestDisambigurationRedirectBot, self).setUp()
         self.page.text = ('[[User:BobBot/Redir#Foo|Bar]]\n'
                           '[[User:BobBot/Redir|Baz]]\n'
                           '[[Main Page|Label]]\n')
         self.bot = disambredir.DisambiguationRedirectBot(generator=[self.page])
-        self.bot.options['always'] = True
-        # Patch the page and bot to not actually save anything
-        self.page.linkedPages = fixed_generator(
-            [pywikibot.Page(self.site, 'User:BobBot/Redir'),
-             pywikibot.Page(self.site, 'Main Page')])
-        self.save_called = False
-        self.bot._save_page = _save_page
 
     def test_unchanged(self):
         """Test no change."""
+        # No changes needed, won't call the save method
+        self.assert_saves = 0
         self._patch_create_callback('n')
-        self.assertFalse(self.save_called)
         self.bot.run()
         self.assertEqual(self.page.text,
                          '[[User:BobBot/Redir#Foo|Bar]]\n'
                          '[[User:BobBot/Redir|Baz]]\n'
                          '[[Main Page|Label]]\n')
-        # No changes needed, won't call the save method
-        self.assertFalse(self.save_called)
 
     def test_unlink(self):
         """Test unlinking."""
         self._patch_create_callback('u')
-        self.assertFalse(self.save_called)
         self.bot.run()
         self.assertEqual(self.page.text,
                          'Bar\nBaz\n[[Main Page|Label]]\n')
-        self.assertTrue(self.save_called)
 
     def test_replace_target(self):
         """Test replacing just target page."""
         self._patch_create_callback('t')
-        self.assertFalse(self.save_called)
         self.bot.run()
         self.assertEqual(self.page.text,
                          '[[Main Page#Foo|Bar]]\n'
                          '[[Main Page|Baz]]\n'
                          '[[Main Page|Label]]\n')
-        self.assertTrue(self.save_called)
 
     def test_replace_all(self):
         """Test replacing target and label."""
         self._patch_create_callback('l')
-        self.assertFalse(self.save_called)
         self.bot.run()
         self.assertEqual(self.page.text,
                          '[[Main Page#Foo|Main Page]]\n'
                          '[[Main Page]]\n'
                          '[[Main Page|Label]]\n')
-        self.assertTrue(self.save_called)
 
 
 if __name__ == '__main__':

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Iaec972f813f2470d1f2e51fde8d59b29d929925c
Gerrit-PatchSet: 3
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: XZise <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to