|
1 # Copyright (C) 2009 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 tempfile |
|
34 import unittest |
|
35 |
|
36 from StringIO import StringIO |
|
37 |
|
38 from webkitpy.common.checkout.changelog import * |
|
39 |
|
40 |
|
41 class ChangeLogTest(unittest.TestCase): |
|
42 |
|
43 _example_entry = u'''2009-08-17 Peter Kasting <pkasting@google.com> |
|
44 |
|
45 Reviewed by Tor Arne Vestb\xf8. |
|
46 |
|
47 https://bugs.webkit.org/show_bug.cgi?id=27323 |
|
48 Only add Cygwin to the path when it isn't already there. This avoids |
|
49 causing problems for people who purposefully have non-Cygwin versions of |
|
50 executables like svn in front of the Cygwin ones in their paths. |
|
51 |
|
52 * DumpRenderTree/win/DumpRenderTree.vcproj: |
|
53 * DumpRenderTree/win/ImageDiff.vcproj: |
|
54 * DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj: |
|
55 ''' |
|
56 |
|
57 # More example text than we need. Eventually we need to support parsing this all and write tests for the parsing. |
|
58 _example_changelog = u"""2009-08-17 Tor Arne Vestb\xf8 <vestbo@webkit.org> |
|
59 |
|
60 <http://webkit.org/b/28393> check-webkit-style: add check for use of std::max()/std::min() instead of MAX()/MIN() |
|
61 |
|
62 Reviewed by David Levin. |
|
63 |
|
64 * Scripts/modules/cpp_style.py: |
|
65 (_ERROR_CATEGORIES): Added 'runtime/max_min_macros'. |
|
66 (check_max_min_macros): Added. Returns level 4 error when MAX() |
|
67 and MIN() macros are used in header files and C++ source files. |
|
68 (check_style): Added call to check_max_min_macros(). |
|
69 * Scripts/modules/cpp_style_unittest.py: Added unit tests. |
|
70 (test_max_macro): Added. |
|
71 (test_min_macro): Added. |
|
72 |
|
73 2009-08-16 David Kilzer <ddkilzer@apple.com> |
|
74 |
|
75 Backed out r47343 which was mistakenly committed |
|
76 |
|
77 * Scripts/bugzilla-tool: |
|
78 * Scripts/modules/scm.py: |
|
79 |
|
80 2009-06-18 Darin Adler <darin@apple.com> |
|
81 |
|
82 Rubber stamped by Mark Rowe. |
|
83 |
|
84 * DumpRenderTree/mac/DumpRenderTreeWindow.mm: |
|
85 (-[DumpRenderTreeWindow close]): Resolved crashes seen during regression |
|
86 tests. The close method can be called on a window that's already closed |
|
87 so we can't assert here. |
|
88 |
|
89 == Rolled over to ChangeLog-2009-06-16 == |
|
90 """ |
|
91 |
|
92 def test_latest_entry_parse(self): |
|
93 changelog_contents = u"%s\n%s" % (self._example_entry, self._example_changelog) |
|
94 changelog_file = StringIO(changelog_contents) |
|
95 latest_entry = ChangeLog.parse_latest_entry_from_file(changelog_file) |
|
96 self.assertEquals(latest_entry.contents(), self._example_entry) |
|
97 self.assertEquals(latest_entry.author_name(), "Peter Kasting") |
|
98 self.assertEquals(latest_entry.author_email(), "pkasting@google.com") |
|
99 self.assertEquals(latest_entry.reviewer_text(), u"Tor Arne Vestb\xf8") |
|
100 self.assertTrue(latest_entry.reviewer()) # Make sure that our UTF8-based lookup of Tor works. |
|
101 |
|
102 @staticmethod |
|
103 def _write_tmp_file_with_contents(byte_array): |
|
104 assert(isinstance(byte_array, str)) |
|
105 (file_descriptor, file_path) = tempfile.mkstemp() # NamedTemporaryFile always deletes the file on close in python < 2.6 |
|
106 with os.fdopen(file_descriptor, "w") as file: |
|
107 file.write(byte_array) |
|
108 return file_path |
|
109 |
|
110 @staticmethod |
|
111 def _read_file_contents(file_path, encoding): |
|
112 with codecs.open(file_path, "r", encoding) as file: |
|
113 return file.read() |
|
114 |
|
115 _new_entry_boilerplate = '''2009-08-19 Eric Seidel <eric@webkit.org> |
|
116 |
|
117 Reviewed by NOBODY (OOPS!). |
|
118 |
|
119 Need a short description and bug URL (OOPS!) |
|
120 |
|
121 * Scripts/bugzilla-tool: |
|
122 ''' |
|
123 |
|
124 def test_set_reviewer(self): |
|
125 changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) |
|
126 changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8")) |
|
127 reviewer_name = 'Test Reviewer' |
|
128 ChangeLog(changelog_path).set_reviewer(reviewer_name) |
|
129 actual_contents = self._read_file_contents(changelog_path, "utf-8") |
|
130 expected_contents = changelog_contents.replace('NOBODY (OOPS!)', reviewer_name) |
|
131 os.remove(changelog_path) |
|
132 self.assertEquals(actual_contents, expected_contents) |
|
133 |
|
134 def test_set_short_description_and_bug_url(self): |
|
135 changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) |
|
136 changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8")) |
|
137 short_description = "A short description" |
|
138 bug_url = "http://example.com/b/2344" |
|
139 ChangeLog(changelog_path).set_short_description_and_bug_url(short_description, bug_url) |
|
140 actual_contents = self._read_file_contents(changelog_path, "utf-8") |
|
141 expected_message = "%s\n %s" % (short_description, bug_url) |
|
142 expected_contents = changelog_contents.replace("Need a short description and bug URL (OOPS!)", expected_message) |
|
143 os.remove(changelog_path) |
|
144 self.assertEquals(actual_contents, expected_contents) |
|
145 |
|
146 _revert_message = """ Unreviewed, rolling out r12345. |
|
147 http://trac.webkit.org/changeset/12345 |
|
148 http://example.com/123 |
|
149 |
|
150 This is a very long reason which should be long enough so that |
|
151 _message_for_revert will need to wrap it. We'll also include |
|
152 a |
|
153 https://veryveryveryveryverylongbugurl.com/reallylongbugthingy.cgi?bug_id=12354 |
|
154 link so that we can make sure we wrap that right too. |
|
155 """ |
|
156 |
|
157 def test_message_for_revert(self): |
|
158 changelog = ChangeLog("/fake/path") |
|
159 long_reason = "This is a very long reason which should be long enough so that _message_for_revert will need to wrap it. We'll also include a https://veryveryveryveryverylongbugurl.com/reallylongbugthingy.cgi?bug_id=12354 link so that we can make sure we wrap that right too." |
|
160 message = changelog._message_for_revert(12345, long_reason, "http://example.com/123") |
|
161 self.assertEquals(message, self._revert_message) |
|
162 |
|
163 _revert_entry_with_bug_url = '''2009-08-19 Eric Seidel <eric@webkit.org> |
|
164 |
|
165 Unreviewed, rolling out r12345. |
|
166 http://trac.webkit.org/changeset/12345 |
|
167 http://example.com/123 |
|
168 |
|
169 Reason |
|
170 |
|
171 * Scripts/bugzilla-tool: |
|
172 ''' |
|
173 |
|
174 _revert_entry_without_bug_url = '''2009-08-19 Eric Seidel <eric@webkit.org> |
|
175 |
|
176 Unreviewed, rolling out r12345. |
|
177 http://trac.webkit.org/changeset/12345 |
|
178 |
|
179 Reason |
|
180 |
|
181 * Scripts/bugzilla-tool: |
|
182 ''' |
|
183 |
|
184 def _assert_update_for_revert_output(self, args, expected_entry): |
|
185 changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) |
|
186 changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8")) |
|
187 changelog = ChangeLog(changelog_path) |
|
188 changelog.update_for_revert(*args) |
|
189 actual_entry = changelog.latest_entry() |
|
190 os.remove(changelog_path) |
|
191 self.assertEquals(actual_entry.contents(), expected_entry) |
|
192 self.assertEquals(actual_entry.reviewer_text(), None) |
|
193 # These checks could be removed to allow this to work on other entries: |
|
194 self.assertEquals(actual_entry.author_name(), "Eric Seidel") |
|
195 self.assertEquals(actual_entry.author_email(), "eric@webkit.org") |
|
196 |
|
197 def test_update_for_revert(self): |
|
198 self._assert_update_for_revert_output([12345, "Reason"], self._revert_entry_without_bug_url) |
|
199 self._assert_update_for_revert_output([12345, "Reason", "http://example.com/123"], self._revert_entry_with_bug_url) |
|
200 |
|
201 |
|
202 if __name__ == '__main__': |
|
203 unittest.main() |