1# Copyright (C) 2011 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
29from __future__ import with_statement
30
31import codecs
32import os
33import tempfile
34import unittest
35
36from webkitpy.common.checkout.changelog import ChangeLog
37from webkitpy.common.checkout.changelog_unittest import ChangeLogTest
38from webkitpy.tool.steps.preparechangelogforrevert import *
39
40
41class UpdateChangeLogsForRevertTest(unittest.TestCase):
42    @staticmethod
43    def _write_tmp_file_with_contents(byte_array):
44        assert(isinstance(byte_array, str))
45        (file_descriptor, file_path) = tempfile.mkstemp()  # NamedTemporaryFile always deletes the file on close in python < 2.6
46        with os.fdopen(file_descriptor, "w") as file:
47            file.write(byte_array)
48        return file_path
49
50    _revert_entry_with_bug_url = '''2009-08-19  Eric Seidel  <eric@webkit.org>
51
52        Unreviewed, rolling out r12345.
53        http://trac.webkit.org/changeset/12345
54        http://example.com/123
55
56        Reason
57
58        * Scripts/bugzilla-tool:
59'''
60
61    _revert_entry_without_bug_url = '''2009-08-19  Eric Seidel  <eric@webkit.org>
62
63        Unreviewed, rolling out r12345.
64        http://trac.webkit.org/changeset/12345
65
66        Reason
67
68        * Scripts/bugzilla-tool:
69'''
70
71    _multiple_revert_entry_with_bug_url = '''2009-08-19  Eric Seidel  <eric@webkit.org>
72
73        Unreviewed, rolling out r12345, r12346, and r12347.
74        http://trac.webkit.org/changeset/12345
75        http://trac.webkit.org/changeset/12346
76        http://trac.webkit.org/changeset/12347
77        http://example.com/123
78
79        Reason
80
81        * Scripts/bugzilla-tool:
82'''
83
84    _multiple_revert_entry_without_bug_url = '''2009-08-19  Eric Seidel  <eric@webkit.org>
85
86        Unreviewed, rolling out r12345, r12346, and r12347.
87        http://trac.webkit.org/changeset/12345
88        http://trac.webkit.org/changeset/12346
89        http://trac.webkit.org/changeset/12347
90
91        Reason
92
93        * Scripts/bugzilla-tool:
94'''
95
96    _revert_with_log_reason = """2009-08-19  Eric Seidel  <eric@webkit.org>
97
98        Unreviewed, rolling out r12345.
99        http://trac.webkit.org/changeset/12345
100        http://example.com/123
101
102        This is a very long reason which should be long enough so that
103        _message_for_revert will need to wrap it.  We'll also include
104        a
105        https://veryveryveryveryverylongbugurl.com/reallylongbugthingy.cgi?bug_id=12354
106        link so that we can make sure we wrap that right too.
107
108        * Scripts/bugzilla-tool:
109"""
110
111    def _assert_message_for_revert_output(self, args, expected_entry):
112        changelog_contents = u"%s\n%s" % (ChangeLogTest._new_entry_boilerplate, ChangeLogTest._example_changelog)
113        changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8"))
114        changelog = ChangeLog(changelog_path)
115        changelog.update_with_unreviewed_message(PrepareChangeLogForRevert._message_for_revert(*args))
116        actual_entry = changelog.latest_entry()
117        os.remove(changelog_path)
118        self.assertEquals(actual_entry.contents(), expected_entry)
119        self.assertEquals(actual_entry.reviewer_text(), None)
120        # These checks could be removed to allow this to work on other entries:
121        self.assertEquals(actual_entry.author_name(), "Eric Seidel")
122        self.assertEquals(actual_entry.author_email(), "eric@webkit.org")
123
124    def test_message_for_revert(self):
125        self._assert_message_for_revert_output([[12345], "Reason"], self._revert_entry_without_bug_url)
126        self._assert_message_for_revert_output([[12345], "Reason", "http://example.com/123"], self._revert_entry_with_bug_url)
127        self._assert_message_for_revert_output([[12345, 12346, 12347], "Reason"], self._multiple_revert_entry_without_bug_url)
128        self._assert_message_for_revert_output([[12345, 12346, 12347], "Reason", "http://example.com/123"], self._multiple_revert_entry_with_bug_url)
129        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."
130        self._assert_message_for_revert_output([[12345], long_reason, "http://example.com/123"], self._revert_with_log_reason)
131