+2011-09-28 David Levin <levin@chromium.org>
+
+ 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 <cgarcia@igalia.com>
[GTK] Add WebKitError to GTK+ WebKit2 API
--- /dev/null
+# 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
--- /dev/null
+# 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))
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)
'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)
# 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
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()