tizen beta release
[profile/ivi/webkit-efl.git] / Tools / Scripts / webkitpy / common / checkout / checkout_unittest.py
1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #    * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #    * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 #    * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
28
29 from __future__ import with_statement
30
31 import codecs
32 import os
33 import shutil
34 import tempfile
35 import unittest
36
37 from .checkout import Checkout
38 from .changelog import ChangeLogEntry
39 from .scm import CommitMessage, SCMDetector
40 from .scm.scm_mock import MockSCM
41 from webkitpy.common.system.executive import Executive, ScriptError
42 from webkitpy.common.system.filesystem import FileSystem  # FIXME: This should not be needed.
43 from webkitpy.common.system.filesystem_mock import MockFileSystem
44 from webkitpy.common.system.executive_mock import MockExecutive
45 from webkitpy.thirdparty.mock import Mock
46
47
48 _changelog1entry1 = u"""2010-03-25  Tor Arne Vestb\u00f8  <vestbo@webkit.org>
49
50         Unreviewed build fix to un-break webkit-patch land.
51
52         Move commit_message_for_this_commit from scm to checkout
53         https://bugs.webkit.org/show_bug.cgi?id=36629
54
55         * Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage
56 """
57 _changelog1entry2 = u"""2010-03-25  Adam Barth  <abarth@webkit.org>
58
59         Reviewed by Eric Seidel.
60
61         Move commit_message_for_this_commit from scm to checkout
62         https://bugs.webkit.org/show_bug.cgi?id=36629
63
64         * Scripts/webkitpy/common/checkout/api.py:
65 """
66 _changelog1 = u"\n".join([_changelog1entry1, _changelog1entry2])
67 _changelog2 = u"""2010-03-25  Tor Arne Vestb\u00f8  <vestbo@webkit.org>
68
69         Unreviewed build fix to un-break webkit-patch land.
70
71         Second part of this complicated change by me, Tor Arne Vestb\u00f8!
72
73         * Path/To/Complicated/File: Added.
74
75 2010-03-25  Adam Barth  <abarth@webkit.org>
76
77         Reviewed by Eric Seidel.
78
79         Filler change.
80 """
81
82 class CommitMessageForThisCommitTest(unittest.TestCase):
83     expected_commit_message = u"""Unreviewed build fix to un-break webkit-patch land.
84
85 Tools: 
86
87 Move commit_message_for_this_commit from scm to checkout
88 https://bugs.webkit.org/show_bug.cgi?id=36629
89
90 * Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage
91
92 LayoutTests: 
93
94 Second part of this complicated change by me, Tor Arne Vestb\u00f8!
95
96 * Path/To/Complicated/File: Added.
97 """
98
99     def setUp(self):
100         # FIXME: This should not need to touch the filesystem, however
101         # ChangeLog is difficult to mock at current.
102         self.filesystem = FileSystem()
103         self.temp_dir = str(self.filesystem.mkdtemp(suffix="changelogs"))
104         self.old_cwd = self.filesystem.getcwd()
105         self.filesystem.chdir(self.temp_dir)
106
107         # Trick commit-log-editor into thinking we're in a Subversion working copy so it won't
108         # complain about not being able to figure out what SCM is in use.
109         # FIXME: VCSTools.pm is no longer so easily fooled.  It logs because "svn info" doesn't
110         # treat a bare .svn directory being part of an svn checkout.
111         self.filesystem.maybe_make_directory(".svn")
112
113         self.changelogs = map(self.filesystem.abspath, (self.filesystem.join("Tools", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))
114         for path, contents in zip(self.changelogs, (_changelog1, _changelog2)):
115             self.filesystem.maybe_make_directory(self.filesystem.dirname(path))
116             self.filesystem.write_text_file(path, contents)
117
118     def tearDown(self):
119         self.filesystem.rmtree(self.temp_dir)
120         self.filesystem.chdir(self.old_cwd)
121
122     def test_commit_message_for_this_commit(self):
123         executive = Executive()
124
125         def mock_run(*args, **kwargs):
126             # Note that we use a real Executive here, not a MockExecutive, so we can test that we're
127             # invoking commit-log-editor correctly.
128             env = os.environ.copy()
129             env['CHANGE_LOG_EMAIL_ADDRESS'] = 'vestbo@webkit.org'
130             kwargs['env'] = env
131             return executive.run_command(*args, **kwargs)
132
133         detector = SCMDetector(self.filesystem, executive)
134         real_scm = detector.detect_scm_system(self.old_cwd)
135
136         mock_scm = MockSCM()
137         mock_scm.run = mock_run
138         mock_scm.script_path = real_scm.script_path
139
140         checkout = Checkout(mock_scm)
141         checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelogs
142         commit_message = checkout.commit_message_for_this_commit(git_commit=None)
143         self.assertEqual(commit_message.message(), self.expected_commit_message)
144
145
146 class CheckoutTest(unittest.TestCase):
147     def _make_checkout(self):
148         return Checkout(scm=MockSCM(), filesystem=MockFileSystem(), executive=MockExecutive())
149
150     def test_latest_entry_for_changelog_at_revision(self):
151         def mock_contents_at_revision(changelog_path, revision):
152             self.assertEqual(changelog_path, "foo")
153             self.assertEqual(revision, "bar")
154             # contents_at_revision is expected to return a byte array (str)
155             # so we encode our unicode ChangeLog down to a utf-8 stream.
156             # The ChangeLog utf-8 decoding should ignore invalid codepoints.
157             invalid_utf8 = "\255"
158             return _changelog1.encode("utf-8") + invalid_utf8
159         checkout = self._make_checkout()
160         checkout._scm.contents_at_revision = mock_contents_at_revision
161         entry = checkout._latest_entry_for_changelog_at_revision("foo", "bar")
162         self.assertEqual(entry.contents(), _changelog1entry1)
163
164     # FIXME: This tests a hack around our current changed_files handling.
165     # Right now changelog_entries_for_revision tries to fetch deleted files
166     # from revisions, resulting in a ScriptError exception.  Test that we
167     # recover from those and still return the other ChangeLog entries.
168     def test_changelog_entries_for_revision(self):
169         checkout = self._make_checkout()
170         checkout._scm.changed_files_for_revision = lambda revision: ['foo/ChangeLog', 'bar/ChangeLog']
171
172         def mock_latest_entry_for_changelog_at_revision(path, revision):
173             if path == "foo/ChangeLog":
174                 return 'foo'
175             raise ScriptError()
176
177         checkout._latest_entry_for_changelog_at_revision = mock_latest_entry_for_changelog_at_revision
178
179         # Even though fetching one of the entries failed, the other should succeed.
180         entries = checkout.changelog_entries_for_revision(1)
181         self.assertEqual(len(entries), 1)
182         self.assertEqual(entries[0], 'foo')
183
184     def test_commit_info_for_revision(self):
185         checkout = self._make_checkout()
186         checkout._scm.changed_files_for_revision = lambda revision: ['path/to/file', 'another/file']
187         checkout._scm.committer_email_for_revision = lambda revision, changed_files=None: "committer@example.com"
188         checkout.changelog_entries_for_revision = lambda revision, changed_files=None: [ChangeLogEntry(_changelog1entry1)]
189         commitinfo = checkout.commit_info_for_revision(4)
190         self.assertEqual(commitinfo.bug_id(), 36629)
191         self.assertEqual(commitinfo.author_name(), u"Tor Arne Vestb\u00f8")
192         self.assertEqual(commitinfo.author_email(), "vestbo@webkit.org")
193         self.assertEqual(commitinfo.reviewer_text(), None)
194         self.assertEqual(commitinfo.reviewer(), None)
195         self.assertEqual(commitinfo.committer_email(), "committer@example.com")
196         self.assertEqual(commitinfo.committer(), None)
197         self.assertEqual(commitinfo.to_json(), {
198             'bug_id': 36629,
199             'author_email': 'vestbo@webkit.org',
200             'changed_files': [
201                 'path/to/file',
202                 'another/file',
203             ],
204             'reviewer_text': None,
205             'author_name': u'Tor Arne Vestb\xf8',
206         })
207
208         checkout.changelog_entries_for_revision = lambda revision, changed_files=None: []
209         self.assertEqual(checkout.commit_info_for_revision(1), None)
210
211     def test_bug_id_for_revision(self):
212         checkout = self._make_checkout()
213         checkout._scm.committer_email_for_revision = lambda revision: "committer@example.com"
214         checkout.changelog_entries_for_revision = lambda revision, changed_files=None: [ChangeLogEntry(_changelog1entry1)]
215         self.assertEqual(checkout.bug_id_for_revision(4), 36629)
216
217     def test_bug_id_for_this_commit(self):
218         checkout = self._make_checkout()
219         checkout.commit_message_for_this_commit = lambda git_commit, changed_files=None: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines())
220         self.assertEqual(checkout.bug_id_for_this_commit(git_commit=None), 36629)
221
222     def test_modified_changelogs(self):
223         checkout = self._make_checkout()
224         checkout._scm.checkout_root = "/foo/bar"
225         checkout._scm.changed_files = lambda git_commit: ["file1", "ChangeLog", "relative/path/ChangeLog"]
226         expected_changlogs = ["/foo/bar/ChangeLog", "/foo/bar/relative/path/ChangeLog"]
227         self.assertEqual(checkout.modified_changelogs(git_commit=None), expected_changlogs)
228
229     def test_suggested_reviewers(self):
230         def mock_changelog_entries_for_revision(revision, changed_files=None):
231             if revision % 2 == 0:
232                 return [ChangeLogEntry(_changelog1entry1)]
233             return [ChangeLogEntry(_changelog1entry2)]
234
235         def mock_revisions_changing_file(path, limit=5):
236             if path.endswith("ChangeLog"):
237                 return [3]
238             return [4, 8]
239
240         checkout = self._make_checkout()
241         checkout._scm.checkout_root = "/foo/bar"
242         checkout._scm.changed_files = lambda git_commit: ["file1", "file2", "relative/path/ChangeLog"]
243         checkout._scm.revisions_changing_file = mock_revisions_changing_file
244         checkout.changelog_entries_for_revision = mock_changelog_entries_for_revision
245         reviewers = checkout.suggested_reviewers(git_commit=None)
246         reviewer_names = [reviewer.full_name for reviewer in reviewers]
247         self.assertEqual(reviewer_names, [u'Tor Arne Vestb\xf8'])
248
249     def test_chromium_deps(self):
250         checkout = self._make_checkout()
251         checkout._scm.checkout_root = "/foo/bar"
252         self.assertEqual(checkout.chromium_deps()._path, '/foo/bar/Source/WebKit/chromium/DEPS')