From bc79e41a6b498a2d399df830211f7d773cf41510 Mon Sep 17 00:00:00 2001 From: "levin@chromium.org" Date: Wed, 28 Sep 2011 17:05:55 +0000 Subject: [PATCH] watchlist: Add support for matching added or deleted lines. https://bugs.webkit.org/show_bug.cgi?id=68972 Reviewed by Adam Barth. * Scripts/webkitpy/common/watchlist/changedlinepattern.py: Added. * Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py: Added. * Scripts/webkitpy/common/watchlist/watchlist.py: Comment fix up and fix input to the pattern match to only have the diff lines instead of the DiffFile. * Scripts/webkitpy/common/watchlist/watchlist_unittest.py: Add tests for the new patterns and combinations of the patterns. * Scripts/webkitpy/common/watchlist/watchlistparser.py: Sort imports. Add changeline support. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96228 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Tools/ChangeLog | 16 +++++ .../common/watchlist/changedlinepattern.py | 43 ++++++++++++ .../watchlist/changedlinepattern_unittest.py | 62 +++++++++++++++++ .../Scripts/webkitpy/common/watchlist/watchlist.py | 4 +- .../common/watchlist/watchlist_unittest.py | 77 ++++++++++++++++++++++ .../webkitpy/common/watchlist/watchlistparser.py | 9 ++- 6 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py create mode 100644 Tools/Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py diff --git a/Tools/ChangeLog b/Tools/ChangeLog index b6ea07f..b046a6b 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,19 @@ +2011-09-28 David Levin + + watchlist: Add support for matching added or deleted lines. + https://bugs.webkit.org/show_bug.cgi?id=68972 + + Reviewed by Adam Barth. + + * Scripts/webkitpy/common/watchlist/changedlinepattern.py: Added. + * Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py: Added. + * Scripts/webkitpy/common/watchlist/watchlist.py: Comment fix up and fix input + to the pattern match to only have the diff lines instead of the DiffFile. + * Scripts/webkitpy/common/watchlist/watchlist_unittest.py: + Add tests for the new patterns and combinations of the patterns. + * Scripts/webkitpy/common/watchlist/watchlistparser.py: + Sort imports. Add changeline support. + 2011-09-28 Carlos Garcia Campos [GTK] Add WebKitError to GTK+ WebKit2 API diff --git a/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py b/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py new file mode 100644 index 0000000..dd47578 --- /dev/null +++ b/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py @@ -0,0 +1,43 @@ +# Copyright (C) 2011 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import re + + +class ChangedLinePattern: + def __init__(self, regex, index_for_zero_value): + self._regex = re.compile(regex) + self._index_for_zero_value = index_for_zero_value + + def match(self, path, diff_file): + for diff_line in diff_file: + if diff_line[self._index_for_zero_value]: + continue + if self._regex.search(diff_line[2]): + return True + return False diff --git a/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py b/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py new file mode 100644 index 0000000..0017045 --- /dev/null +++ b/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py @@ -0,0 +1,62 @@ +# Copyright (C) 2011 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +'''Unit tests for changedlinepattern.py.''' + +import unittest +from webkitpy.common.watchlist.changedlinepattern import ChangedLinePattern + + +class ChangedLinePatternTest(unittest.TestCase): + + # A quick note about the diff file structure. + # The first column indicated the old line number. + # The second column indicates the new line number. + # 0 in either column indicates it had no old or new line number. + _DIFF_FILE = ((0, 1, 'hi'), + (1, 0, 'bye'), + (2, 2, 'other'), + (3, 0, 'both'), + (0, 3, 'both'), + ) + + def test_added_lines(self): + self.assertTrue(ChangedLinePattern('hi', 0).match(None, self._DIFF_FILE)) + self.assertTrue(ChangedLinePattern('h.', 0).match(None, self._DIFF_FILE)) + self.assertTrue(ChangedLinePattern('both', 0).match(None, self._DIFF_FILE)) + self.assertFalse(ChangedLinePattern('bye', 0).match(None, self._DIFF_FILE)) + self.assertFalse(ChangedLinePattern('y', 0).match(None, self._DIFF_FILE)) + self.assertFalse(ChangedLinePattern('other', 0).match(None, self._DIFF_FILE)) + + def test_removed_lines(self): + self.assertFalse(ChangedLinePattern('hi', 1).match(None, self._DIFF_FILE)) + self.assertFalse(ChangedLinePattern('h.', 1).match(None, self._DIFF_FILE)) + self.assertTrue(ChangedLinePattern('both', 1).match(None, self._DIFF_FILE)) + self.assertTrue(ChangedLinePattern('bye', 1).match(None, self._DIFF_FILE)) + self.assertTrue(ChangedLinePattern('y', 1).match(None, self._DIFF_FILE)) + self.assertFalse(ChangedLinePattern('other', 1).match(None, self._DIFF_FILE)) diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlist.py b/Tools/Scripts/webkitpy/common/watchlist/watchlist.py index c000dfb..8a06c58 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlist.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlist.py @@ -54,9 +54,9 @@ class WatchList(object): if definition in matching_definitions: continue - # See if the definition matches. + # See if the definition matches within one file. for pattern in self._definitions[definition]: - if not pattern.match(path, diff_file): + if not pattern.match(path, diff_file.lines): break else: matching_definitions.add(definition) diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py b/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py index f6e8be6..598746c 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py @@ -139,3 +139,80 @@ class WatchListTest(unittest.TestCase): 'cc_set': set(), 'messages': set(), }, cc_set_and_messages) + + def test_added_match(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "in_added_lines": r"RenderStyle::initialBoxOrient",' + ' },' + ' "WatchList2": {' + ' "in_deleted_lines": r"RenderStyle::initialBoxOrient",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList1": [ "eric@webkit.org", ],' + ' "WatchList2": [ "abarth@webkit.org", ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['eric@webkit.org']), + 'messages': set(), + }, cc_set_and_messages) + + def test_deleted_match(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "in_added_lines": r"unsigned orient: 1;",' + ' },' + ' "WatchList2": {' + ' "in_deleted_lines": r"unsigned orient: 1;",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList1": [ "eric@webkit.org", ],' + ' "WatchList2": [ "abarth@webkit.org", ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['abarth@webkit.org']), + 'messages': set(), + }, cc_set_and_messages) + + def test_complex_match(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "filename": r"WebCore/rendering/style/StyleRareInheritedData\.cpp",' + ' "in_added_lines": r"\&\& boxOrient == o.boxOrient;",' + ' "in_deleted_lines": r"\&\& userSelect == o.userSelect;",' + ' },' + ' "WatchList2": {' + ' "filename": r"WebCore/rendering/style/StyleRareInheritedData\.cpp",' + ' "in_added_lines": r"RenderStyle::initialBoxOrient",' + ' },' + # WatchList3 won't match because these two patterns aren't in the same file. + ' "WatchList3": {' + ' "in_added_lines": r"RenderStyle::initialBoxOrient",' + ' "in_deleted_lines": r"unsigned orient: 1;",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList1": [ "eric@webkit.org", ],' + ' "WatchList3": [ "abarth@webkit.org", ],' + ' },' + ' "MESSAGE_RULES": {' + ' "WatchList2": ["This is a test message."],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['eric@webkit.org']), + 'messages': set(["This is a test message."]), + }, cc_set_and_messages) diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py b/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py index f3cc118..08d0bc2 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py @@ -27,8 +27,9 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import re -from webkitpy.common.watchlist.watchlist import WatchList +from webkitpy.common.watchlist.changedlinepattern import ChangedLinePattern from webkitpy.common.watchlist.filenamepattern import FilenamePattern +from webkitpy.common.watchlist.watchlist import WatchList from webkitpy.common.watchlist.watchlistrule import WatchListRule @@ -44,7 +45,11 @@ class WatchListParser(object): self._CC_RULES: self._parse_cc_rules, self._MESSAGE_RULES: self._parse_message_rules, } - self._definition_pattern_parsers = {'filename': FilenamePattern, } + self._definition_pattern_parsers = { + 'filename': FilenamePattern, + 'in_added_lines': (lambda regex: ChangedLinePattern(regex, 0)), + 'in_deleted_lines': (lambda regex: ChangedLinePattern(regex, 1)), + } def parse(self, watch_list_contents): watch_list = WatchList() -- 2.7.4