jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] replace: Add replacements to their container ......................................................................
[FIX] replace: Add replacements to their container
The replacements from the fixes have only been added to the over all replacements, but not their respective container which have been always empty.
Change-Id: Ie72f3acc02afeab994c95f0fd811c666801c6dbd --- M pywikibot/fixes.py M scripts/replace.py A tests/data/fixes.py A tests/replacebot_tests.py 4 files changed, 229 insertions(+), 6 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/fixes.py b/pywikibot/fixes.py index 70419a5..29bc3fb 100644 --- a/pywikibot/fixes.py +++ b/pywikibot/fixes.py @@ -637,13 +637,20 @@ }, }
+ +def _load_file(filename): + """Load the fixes from the given filename.""" + if os.path.exists(filename): + # load binary, to let compile decode it according to the file header + with open(filename, 'rb') as f: + exec(compile(f.read(), filename, 'exec')) + return True + else: + return False + # # Load the user fixes file. -filename = config.datafilepath('user-fixes.py') -if os.path.exists(filename): - # load binary, to let compile decode it according to the file header - with open(filename, 'rb') as f: - exec(compile(f.read(), filename, 'exec')) +if _load_file(config.datafilepath('user-fixes.py')): user_fixes_loaded = True else: user_fixes_loaded = False diff --git a/scripts/replace.py b/scripts/replace.py index 61faf7b..9dacfb8 100755 --- a/scripts/replace.py +++ b/scripts/replace.py @@ -902,12 +902,14 @@ pywikibot.warning('The new string "{0}" contains formatting ' 'characters like U+200E'.format( chars.replace_invisible(replacement[1]))) - replacements.append(ReplacementListEntry( + replacement_set.append(ReplacementListEntry( old=replacement[0], new=replacement[1], fix_set=replacement_set, edit_summary=summary, )) + if replacement_set: + replacements.extend(replacement_set)
# Set the regular expression flags flags = re.UNICODE diff --git a/tests/data/fixes.py b/tests/data/fixes.py new file mode 100644 index 0000000..ef76906 --- /dev/null +++ b/tests/data/fixes.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +"""Collection of fixes for tests.""" +from __future__ import unicode_literals + +# flake8 cannot detect that fixes is defined via pywikibot.fixes +if 'fixes' not in globals(): + fixes = {} + +fixes['has-msg'] = { + 'regex': False, + 'msg': { + 'en': 'en', + 'de': 'de', + }, + 'replacements': [ + ('1', '2'), + ] +} + +fixes['has-msg-tw'] = { + 'regex': False, + 'msg': 'replace-replacing', + 'replacements': [ + ('1', '2'), + ] +} + +fixes['no-msg'] = { + 'regex': False, + 'replacements': [ + ('1', '2'), + ] +} + +fixes['has-msg-multiple'] = { + 'regex': False, + 'msg': { + 'en': 'en', + 'de': 'de', + }, + 'replacements': [ + ('1', '2'), + ('3', '4'), + ('5', '6'), + ] +} diff --git a/tests/replacebot_tests.py b/tests/replacebot_tests.py new file mode 100644 index 0000000..610b811 --- /dev/null +++ b/tests/replacebot_tests.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +"""Tests for the replace script and ReplaceRobot class.""" +# +# (C) Pywikibot team, 2015 +# +# Distributed under the terms of the MIT license. +# +from __future__ import unicode_literals + +__version__ = '$Id$' +# +import os + +from pywikibot import fixes + +from scripts import replace + +from tests import _data_dir +from tests.aspects import unittest, TestCase + +# Load only the custom fixes +fixes.fixes.clear() +fixes._load_file(os.path.join(_data_dir, 'fixes.py')) + + +class TestReplacementsMain(TestCase): + + """Test various calls of main().""" + + SUMMARY_CONFIRMATION = ( + 'Press Enter to use this automatic message, or enter a ' + 'description of the\nchanges your bot will make:') + + family = 'test' + code = 'test' + + def setUp(self): + """Replace the original bot class with a fake one.""" + class FakeReplaceBot(object): + + """A fake bot class for the minimal support.""" + + changed_pages = -42 # show that weird number to show this was used + + def __init__(inner_self, generator, replacements, exceptions={}, + always=False, allowoverlap=False, recursive=False, + addedCat=None, sleep=None, summary='', site=None, + **kwargs): + inner_self.replacements = replacements + inner_self.site = site + self.bots.append(inner_self) + + def run(inner_self): + """Nothing to do here.""" + pass + + super(TestReplacementsMain, self).setUp() + self._original_bot = replace.ReplaceRobot + self._original_input = replace.pywikibot.input + self.bots = [] + self.inputs = [] + replace.ReplaceRobot = FakeReplaceBot + replace.pywikibot.input = self._fake_input + + def tearDown(self): + """Bring back the old bot class.""" + replace.ReplaceRobot = self._original_bot + replace.pywikibot.input = self._original_input + super(TestReplacementsMain, self).tearDown() + + def _fake_input(self, message): + """Cache the message and return static text "TESTRUN".""" + self.inputs.append(message) + return 'TESTRUN' + + def _run(self, *args): + """Run the L{replace.main} with the given args and summary and page.""" + # -page to not have an empty generator + # -lang and -family as it will use Site() otherwise + return replace.main(*(args + ('-lang:test', '-family:test', + '-page:TEST'))) + + def test_invalid_replacements(self): + """Test invalid command line replacement configurations.""" + # old and new need to be together + self.assertFalse(self._run('foo', '-replacementfile:/dev/null', 'bar')) + # only old provided + self.assertFalse(self._run('foo')) + + # In the end no bots should've been created + self.assertFalse(self.bots) + + def _test_replacement(self, replacement, clazz=replace.Replacement, + offset=0): + """Test a replacement from the command line.""" + self.assertIsInstance(replacement, clazz) + self.assertEqual(replacement.old, str(offset * 2 + 1)) + self.assertEqual(replacement.new, str(offset * 2 + 2)) + + def _test_fix_replacement(self, replacement, length=1, offset=0): + """Test a replacement from a fix.""" + assert length > offset + self._test_replacement(replacement, replace.ReplacementListEntry, + offset) + self.assertIsInstance(replacement.fix_set, replace.ReplacementList) + self.assertIsInstance(replacement.fix_set, list) + self.assertIn(replacement, replacement.fix_set) + self.assertIs(replacement, replacement.fix_set[offset]) + self.assertEqual(len(replacement.fix_set), length) + + def _get_bot(self, only_confirmation, *args): + """Run with arguments, assert and return one bot.""" + self.assertIsNone(self._run(*args)) + self.assertEqual(len(self.bots), 1) + bot = self.bots[0] + if only_confirmation is not None: + self.assertIn(self.SUMMARY_CONFIRMATION, self.inputs) + if only_confirmation is True: + self.assertEqual(len(self.inputs), 1) + else: + self.assertNotIn(self.SUMMARY_CONFIRMATION, self.inputs) + self.assertEqual(bot.site, self.site) + return bot + + def test_only_cmd(self): + """Test command line replacements only.""" + bot = self._get_bot(True, '1', '2') + self.assertEqual(len(bot.replacements), 1) + self._test_replacement(bot.replacements[0]) + + def test_only_fix_global_message(self): + """Test fixes replacements only.""" + bot = self._get_bot(True, '-fix:has-msg') + self.assertEqual(len(bot.replacements), 1) + self._test_fix_replacement(bot.replacements[0]) + + def test_only_fix_global_message_tw(self): + """Test fixes replacements only.""" + bot = self._get_bot(True, '-fix:has-msg-tw') + self.assertEqual(len(bot.replacements), 1) + self._test_fix_replacement(bot.replacements[0]) + + def test_only_fix_no_message(self): + """Test fixes replacements only.""" + bot = self._get_bot(True, '-fix:no-msg') + self.assertEqual(len(bot.replacements), 1) + self._test_fix_replacement(bot.replacements[0]) + + def test_only_fix_multiple(self): + """Test fixes replacements only.""" + bot = self._get_bot(True, '-fix:has-msg-multiple') + for offset, replacement in enumerate(bot.replacements): + self._test_fix_replacement(replacement, 3, offset) + self.assertEqual(len(bot.replacements), 3) + + def test_cmd_and_fix(self): + """Test command line and fix replacements together.""" + bot = self._get_bot(True, '1', '2', '-fix:has-msg') + self.assertEqual(len(bot.replacements), 2) + self._test_replacement(bot.replacements[0]) + self._test_fix_replacement(bot.replacements[1]) + + +if __name__ == '__main__': + try: + unittest.main() + except SystemExit: + pass
pywikibot-commits@lists.wikimedia.org