| OLD | NEW |
| 1 # Copyright (C) 2009 Google Inc. All rights reserved. | 1 # Copyright (C) 2009 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| 11 # in the documentation and/or other materials provided with the | 11 # in the documentation and/or other materials provided with the |
| 12 # distribution. | 12 # distribution. |
| 13 # * Neither the name of Google Inc. nor the names of its | 13 # * Neither the name of Google Inc. nor the names of its |
| 14 # contributors may be used to endorse or promote products derived from | 14 # contributors may be used to endorse or promote products derived from |
| 15 # this software without specific prior written permission. | 15 # this software without specific prior written permission. |
| 16 # | 16 # |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | 28 |
| 29 import cStringIO as StringIO | |
| 30 import re | 29 import re |
| 31 import unittest | 30 import unittest |
| 32 | 31 |
| 33 from webkitpy.common.checkout import diff_parser | 32 from webkitpy.common.checkout.diff_parser import DiffParser |
| 34 from webkitpy.common.checkout.diff_test_data import DIFF_TEST_DATA | 33 from webkitpy.common.checkout.diff_test_data import DIFF_TEST_DATA |
| 35 | 34 |
| 36 | 35 |
| 37 class DiffParserTest(unittest.TestCase): | 36 class DiffParserTest(unittest.TestCase): |
| 38 maxDiff = None | |
| 39 | 37 |
| 40 def test_diff_parser(self, parser=None): | 38 def test_diff_parser(self, parser=None): |
| 41 if not parser: | 39 if not parser: |
| 42 parser = diff_parser.DiffParser(DIFF_TEST_DATA.splitlines()) | 40 parser = DiffParser(DIFF_TEST_DATA.splitlines()) |
| 43 self.assertEqual(3, len(parser.files)) | 41 self.assertEqual(3, len(parser.files)) |
| 44 | 42 |
| 45 self.assertIn('WebCore/style/StyleFlexibleBoxData.h', parser.files) | 43 self.assertIn('WebCore/style/StyleFlexibleBoxData.h', parser.files) |
| 46 diff = parser.files['WebCore/style/StyleFlexibleBoxData.h'] | 44 diff = parser.files['WebCore/style/StyleFlexibleBoxData.h'] |
| 47 self.assertEqual(7, len(diff.lines)) | 45 self.assertEqual(7, len(diff.lines)) |
| 46 |
| 48 # The first two unchanged lines. | 47 # The first two unchanged lines. |
| 49 self.assertEqual((47, 47), diff.lines[0][0:2]) | 48 self.assertEqual((47, 47), diff.lines[0][0:2]) |
| 50 self.assertEqual('', diff.lines[0][2]) | 49 self.assertEqual('', diff.lines[0][2]) |
| 51 self.assertEqual((48, 48), diff.lines[1][0:2]) | 50 self.assertEqual((48, 48), diff.lines[1][0:2]) |
| 52 self.assertEqual(' unsigned align : 3; // EBoxAlignment', diff.lines[
1][2]) | 51 self.assertEqual(' unsigned align : 3; // EBoxAlignment', diff.lines[
1][2]) |
| 53 # The deleted line | 52 |
| 53 # The deleted line. |
| 54 self.assertEqual((50, 0), diff.lines[3][0:2]) | 54 self.assertEqual((50, 0), diff.lines[3][0:2]) |
| 55 self.assertEqual(' unsigned orient: 1; // EBoxOrient', diff.lines[3][
2]) | 55 self.assertEqual(' unsigned orient: 1; // EBoxOrient', diff.lines[3][
2]) |
| 56 | 56 |
| 57 # The first file looks OK. Let's check the next, more complicated file. | 57 # The first file looks OK. Let's check the next, more complicated file. |
| 58 self.assertIn('WebCore/style/StyleRareInheritedData.cpp', parser.files) | 58 self.assertIn('WebCore/style/StyleRareInheritedData.cpp', parser.files) |
| 59 diff = parser.files['WebCore/style/StyleRareInheritedData.cpp'] | 59 diff = parser.files['WebCore/style/StyleRareInheritedData.cpp'] |
| 60 |
| 60 # There are 3 chunks. | 61 # There are 3 chunks. |
| 61 self.assertEqual(7 + 7 + 9, len(diff.lines)) | 62 self.assertEqual(7 + 7 + 9, len(diff.lines)) |
| 63 |
| 62 # Around an added line. | 64 # Around an added line. |
| 63 self.assertEqual((60, 61), diff.lines[9][0:2]) | 65 self.assertEqual((60, 61), diff.lines[9][0:2]) |
| 64 self.assertEqual((0, 62), diff.lines[10][0:2]) | 66 self.assertEqual((0, 62), diff.lines[10][0:2]) |
| 65 self.assertEqual((61, 63), diff.lines[11][0:2]) | 67 self.assertEqual((61, 63), diff.lines[11][0:2]) |
| 66 # Look through the last chunk, which contains both add's and delete's. | 68 |
| 69 # Look through the last chunk, which contains both adds and deletes. |
| 67 self.assertEqual((81, 83), diff.lines[14][0:2]) | 70 self.assertEqual((81, 83), diff.lines[14][0:2]) |
| 68 self.assertEqual((82, 84), diff.lines[15][0:2]) | 71 self.assertEqual((82, 84), diff.lines[15][0:2]) |
| 69 self.assertEqual((83, 85), diff.lines[16][0:2]) | 72 self.assertEqual((83, 85), diff.lines[16][0:2]) |
| 70 self.assertEqual((84, 0), diff.lines[17][0:2]) | 73 self.assertEqual((84, 0), diff.lines[17][0:2]) |
| 71 self.assertEqual((0, 86), diff.lines[18][0:2]) | 74 self.assertEqual((0, 86), diff.lines[18][0:2]) |
| 72 self.assertEqual((0, 87), diff.lines[19][0:2]) | 75 self.assertEqual((0, 87), diff.lines[19][0:2]) |
| 73 self.assertEqual((85, 88), diff.lines[20][0:2]) | 76 self.assertEqual((85, 88), diff.lines[20][0:2]) |
| 74 self.assertEqual((86, 89), diff.lines[21][0:2]) | 77 self.assertEqual((86, 89), diff.lines[21][0:2]) |
| 75 self.assertEqual((87, 90), diff.lines[22][0:2]) | 78 self.assertEqual((87, 90), diff.lines[22][0:2]) |
| 76 | 79 |
| 77 # Check if a newly added file is correctly handled. | 80 # Check if a newly added file is correctly handled. |
| 78 diff = parser.files['LayoutTests/platform/mac/fast/flexbox/box-orient-bu
tton-expected.checksum'] | 81 diff = parser.files['LayoutTests/platform/mac/fast/flexbox/box-orient-bu
tton-expected.checksum'] |
| 79 self.assertEqual(1, len(diff.lines)) | 82 self.assertEqual(1, len(diff.lines)) |
| 80 self.assertEqual((0, 1), diff.lines[0][0:2]) | 83 self.assertEqual((0, 1), diff.lines[0][0:2]) |
| 81 | 84 |
| 82 def test_diff_converter(self): | 85 def test_diff_parser_with_different_mnemonic_prefixes(self): |
| 83 comment_lines = [ | 86 # This repeats test_diff_parser but with different versions |
| 84 "Hey people,\n", | 87 # of DIFF_TEST_DATA that use other prefixes instead of a/b. |
| 85 "\n", | 88 prefixes = ( |
| 86 "See my awesome patch below!\n", | 89 ('i', 'w'), # git-diff (compares the (i)ndex and the (w)ork tree) |
| 87 "\n", | 90 ('c', 'w'), # git-diff HEAD (compares a (c)ommit and the (w)ork tre
e) |
| 88 " - Cool Hacker\n", | 91 ('c', 'i'), # git diff --cached (compares a (c)ommit and the (i)nde
x) |
| 89 "\n", | 92 ('o', 'w'), # git-diff HEAD:file1 file2 (compares an (o)bject and a
(w)ork tree entity) |
| 90 ] | 93 ('1', '2'), # git diff --no-index a b (compares two non-git things
(1) and (2)) |
| 94 ) |
| 95 for a_replacement, b_replacement in prefixes: |
| 96 patch = self._patch(a_replacement, b_replacement) |
| 97 self.test_diff_parser(DiffParser(patch.splitlines())) |
| 91 | 98 |
| 92 revision_lines = [ | 99 @staticmethod |
| 93 "Subversion Revision 289799\n", | 100 def _patch(a_replacement='a', b_replacement='b'): |
| 94 ] | 101 """Returns a version of the example patch with mnemonic prefixes a/b cha
nged.""" |
| 95 | 102 patch = re.sub(r' a/', ' %s/' % a_replacement, DIFF_TEST_DATA) |
| 96 svn_diff_lines = [ | 103 return re.sub(r' b/', ' %s/' % b_replacement, patch) |
| 97 "Index: Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", | |
| 98 "===================================================================
\n", | |
| 99 "--- Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", | |
| 100 "+++ Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", | |
| 101 "@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):\n", | |
| 102 ] | |
| 103 self.assertEqual(diff_parser.get_diff_converter(svn_diff_lines), diff_pa
rser.svn_diff_to_svn_diff) | |
| 104 self.assertEqual(diff_parser.get_diff_converter(comment_lines + svn_diff
_lines), diff_parser.svn_diff_to_svn_diff) | |
| 105 self.assertEqual(diff_parser.get_diff_converter(revision_lines + svn_dif
f_lines), diff_parser.svn_diff_to_svn_diff) | |
| 106 | |
| 107 git_diff_lines = [ | |
| 108 ("diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py
" | |
| 109 "b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n"), | |
| 110 "index 3c5b45b..0197ead 100644\n", | |
| 111 "--- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", | |
| 112 "+++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", | |
| 113 "@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):\n", | |
| 114 ] | |
| 115 self.assertEqual(diff_parser.get_diff_converter(git_diff_lines), diff_pa
rser.git_diff_to_svn_diff) | |
| 116 self.assertEqual(diff_parser.get_diff_converter(comment_lines + git_diff
_lines), diff_parser.git_diff_to_svn_diff) | |
| 117 self.assertEqual(diff_parser.get_diff_converter(revision_lines + git_dif
f_lines), diff_parser.git_diff_to_svn_diff) | |
| 118 | |
| 119 def test_git_mnemonicprefix(self): | |
| 120 p = re.compile(r' ([a|b])/') | |
| 121 | |
| 122 prefixes = [ | |
| 123 {'a': 'i', 'b': 'w'}, # git-diff (compares the (i)ndex and the (w)o
rk tree) | |
| 124 {'a': 'c', 'b': 'w'}, # git-diff HEAD (compares a (c)ommit and the
(w)ork tree) | |
| 125 {'a': 'c', 'b': 'i'}, # git diff --cached (compares a (c)ommit and
the (i)ndex) | |
| 126 {'a': 'o', 'b': 'w'}, # git-diff HEAD:file1 file2 (compares an (o)b
ject and a (w)ork tree entity) | |
| 127 {'a': '1', 'b': '2'}, # git diff --no-index a b (compares two non-g
it things (1) and (2)) | |
| 128 ] | |
| 129 | |
| 130 for prefix in prefixes: | |
| 131 patch = p.sub(lambda x: " %s/" % prefix[x.group(1)], DIFF_TEST_DATA) | |
| 132 self.test_diff_parser(diff_parser.DiffParser(patch.splitlines())) | |
| 133 | |
| 134 def test_git_diff_to_svn_diff(self): | |
| 135 output = """\ | |
| 136 Index: Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 137 =================================================================== | |
| 138 --- Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 139 +++ Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 140 @@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line): | |
| 141 A | |
| 142 B | |
| 143 C | |
| 144 +D | |
| 145 E | |
| 146 F | |
| 147 """ | |
| 148 | |
| 149 inputfmt = StringIO.StringIO("""\ | |
| 150 diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scrip
ts/webkitpy/common/checkout/diff_parser.py | |
| 151 index 2ed552c4555db72df16b212547f2c125ae301a04..72870482000c0dba64ce4300ed782c03
ee79b74f 100644 | |
| 152 --- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 153 +++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 154 @@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line): | |
| 155 A | |
| 156 B | |
| 157 C | |
| 158 +D | |
| 159 E | |
| 160 F | |
| 161 """) | |
| 162 shortfmt = StringIO.StringIO("""\ | |
| 163 diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scrip
ts/webkitpy/common/checkout/diff_parser.py | |
| 164 index b48b162..f300960 100644 | |
| 165 --- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 166 +++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py | |
| 167 @@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line): | |
| 168 A | |
| 169 B | |
| 170 C | |
| 171 +D | |
| 172 E | |
| 173 F | |
| 174 """) | |
| 175 | |
| 176 self.assertMultiLineEqual(output, ''.join(diff_parser.git_diff_to_svn_di
ff(x) for x in shortfmt.readlines())) | |
| 177 self.assertMultiLineEqual(output, ''.join(diff_parser.git_diff_to_svn_di
ff(x) for x in inputfmt.readlines())) | |
| OLD | NEW |