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