watchlist: Add support for matching added or deleted lines.
authorlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Sep 2011 17:05:55 +0000 (17:05 +0000)
committerlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Sep 2011 17:05:55 +0000 (17:05 +0000)
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
Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py [new file with mode: 0644]
Tools/Scripts/webkitpy/common/watchlist/changedlinepattern_unittest.py [new file with mode: 0644]
Tools/Scripts/webkitpy/common/watchlist/watchlist.py
Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py
Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py

index b6ea07f..b046a6b 100644 (file)
@@ -1,3 +1,19 @@
+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
diff --git a/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py b/Tools/Scripts/webkitpy/common/watchlist/changedlinepattern.py
new file mode 100644 (file)
index 0000000..dd47578
--- /dev/null
@@ -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 (file)
index 0000000..0017045
--- /dev/null
@@ -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))
index c000dfb..8a06c58 100644 (file)
@@ -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)
index f6e8be6..598746c 100644 (file)
@@ -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)
index f3cc118..08d0bc2 100644 (file)
@@ -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()