1
 
# Copyright (C) 2005 by Canonical Ltd
 
2
 
# -*- coding: utf-8 -*-
 
4
 
# This program is free software; you can redistribute it and/or modify
 
5
 
# it under the terms of the GNU General Public License as published by
 
6
 
# the Free Software Foundation; either version 2 of the License, or
 
7
 
# (at your option) any later version.
 
9
 
# This program is distributed in the hope that it will be useful,
 
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 
# GNU General Public License for more details.
 
14
 
# You should have received a copy of the GNU General Public License
 
15
 
# along with this program; if not, write to the Free Software
 
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
"""Black-box tests for bzr log."""
 
24
 
from bzrlib.tests.blackbox import ExternalBase
 
25
 
from bzrlib.tests import TestCaseInTempDir
 
28
 
class TestLog(ExternalBase):
 
32
 
        self.build_tree(['hello.txt', 'goodbye.txt', 'meep.txt'])
 
33
 
        self.runbzr("add hello.txt")
 
34
 
        self.runbzr("commit -m message1 hello.txt")
 
35
 
        self.runbzr("add goodbye.txt")
 
36
 
        self.runbzr("commit -m message2 goodbye.txt")
 
37
 
        self.runbzr("add meep.txt")
 
38
 
        self.runbzr("commit -m message3 meep.txt")
 
39
 
        self.full_log = self.runbzr("log")[0]
 
41
 
    def test_log_null_end_revspec(self):
 
43
 
        self.assertTrue('revno: 1\n' in self.full_log)
 
44
 
        self.assertTrue('revno: 2\n' in self.full_log)
 
45
 
        self.assertTrue('revno: 3\n' in self.full_log)
 
46
 
        self.assertTrue('message:\n  message1\n' in self.full_log)
 
47
 
        self.assertTrue('message:\n  message2\n' in self.full_log)
 
48
 
        self.assertTrue('message:\n  message3\n' in self.full_log)
 
50
 
        log = self.runbzr("log -r 1..")[0]
 
51
 
        self.assertEquals(log, self.full_log)
 
53
 
    def test_log_null_begin_revspec(self):
 
55
 
        log = self.runbzr("log -r ..3")[0]
 
56
 
        self.assertEquals(self.full_log, log)
 
58
 
    def test_log_null_both_revspecs(self):
 
60
 
        log = self.runbzr("log -r ..")[0]
 
61
 
        self.assertEquals(self.full_log, log)
 
63
 
    def test_log_negative_begin_revspec_full_log(self):
 
65
 
        log = self.runbzr("log -r -3..")[0]
 
66
 
        self.assertEquals(self.full_log, log)
 
68
 
    def test_log_negative_both_revspec_full_log(self):
 
70
 
        log = self.runbzr("log -r -3..-1")[0]
 
71
 
        self.assertEquals(self.full_log, log)
 
73
 
    def test_log_negative_both_revspec_partial(self):
 
75
 
        log = self.runbzr("log -r -3..-2")[0]
 
76
 
        self.assertTrue('revno: 1\n' in log)
 
77
 
        self.assertTrue('revno: 2\n' in log)
 
78
 
        self.assertTrue('revno: 3\n' not in log)
 
80
 
    def test_log_negative_begin_revspec(self):
 
82
 
        log = self.runbzr("log -r -2..")[0]
 
83
 
        self.assertTrue('revno: 1\n' not in log)
 
84
 
        self.assertTrue('revno: 2\n' in log)
 
85
 
        self.assertTrue('revno: 3\n' in log)
 
87
 
    def test_log_postive_revspecs(self):
 
89
 
        log = self.runbzr("log -r 1..3")[0]
 
90
 
        self.assertEquals(self.full_log, log)
 
92
 
    def test_log_revno_n_path(self):
 
101
 
        log = self.runbzr("log -r revno:2:branch1..revno:3:branch2",
 
103
 
        log = self.runbzr("log -r revno:1:branch2..revno:3:branch2")[0]
 
104
 
        self.assertEquals(self.full_log, log)
 
105
 
        log = self.runbzr("log -r revno:1:branch2")[0]
 
106
 
        self.assertTrue('revno: 1\n' in log)
 
107
 
        self.assertTrue('revno: 2\n' not in log)
 
108
 
        self.assertTrue('branch nick: branch2\n' in log)
 
109
 
        self.assertTrue('branch nick: branch1\n' not in log)
 
112
 
class TestLogMerges(ExternalBase):
 
114
 
    def test_merges_are_indented_by_level(self):
 
115
 
        self.build_tree(['parent/'])
 
116
 
        self.run_bzr('init', 'parent')
 
117
 
        self.run_bzr('commit', '-m', 'first post', '--unchanged', 'parent')
 
118
 
        self.run_bzr('branch', 'parent', 'child')
 
119
 
        self.run_bzr('commit', '-m', 'branch 1', '--unchanged', 'child')
 
120
 
        self.run_bzr('branch', 'child', 'smallerchild')
 
121
 
        self.run_bzr('commit', '-m', 'branch 2', '--unchanged', 'smallerchild')
 
123
 
        self.run_bzr('merge', '../smallerchild')
 
124
 
        self.run_bzr('commit', '-m', 'merge branch 2')
 
125
 
        os.chdir('../parent')
 
126
 
        self.run_bzr('merge', '../child')
 
127
 
        self.run_bzr('commit', '-m', 'merge branch 1')
 
128
 
        out,err = self.run_bzr('log')
 
129
 
        # the log will look something like:
 
130
 
#        self.assertEqual("""\
 
131
 
#------------------------------------------------------------
 
133
 
#committer: Robert Collins <foo@example.com>
 
135
 
#timestamp: Tue 2006-03-28 22:31:40 +1100
 
138
 
#    ------------------------------------------------------------
 
139
 
#    merged: foo@example.com-20060328113140-91f43cfb46dc2863
 
140
 
#    committer: Robert Collins <foo@example.com>
 
142
 
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
145
 
#        ------------------------------------------------------------
 
146
 
#        merged: foo@example.com-20060328113140-1ba24f850a0ef573
 
147
 
#        committer: Robert Collins <foo@example.com>
 
148
 
#        branch nick: smallerchild
 
149
 
#        timestamp: Tue 2006-03-28 22:31:40 +1100
 
152
 
#    ------------------------------------------------------------
 
153
 
#    merged: foo@example.com-20060328113140-5749a4757a8ac792
 
154
 
#    committer: Robert Collins <foo@example.com>
 
156
 
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
159
 
#------------------------------------------------------------
 
161
 
#committer: Robert Collins <foo@example.com>
 
163
 
#timestamp: Tue 2006-03-28 22:31:39 +1100
 
167
 
        # but we dont have a nice pattern matcher hooked up yet, so:
 
168
 
        # we check for the indenting of the commit message:
 
169
 
        self.assertTrue('  merge branch 1' in out)
 
170
 
        self.assertTrue('      merge branch 2' in out)
 
171
 
        self.assertTrue('          branch 2' in out)
 
172
 
        self.assertTrue('      branch 1' in out)
 
173
 
        self.assertTrue('  first post' in out)
 
174
 
        self.assertEqual('', err)
 
177
 
class TestLogEncodings(TestCaseInTempDir):
 
180
 
    _message = u'Message with \xb5'
 
182
 
    # Encodings which can encode mu
 
187
 
        'cp437', # Common windows encoding
 
188
 
        'cp1251', # Alexander Belchenko's windows encoding
 
189
 
        'cp1258', # Common windows encoding
 
191
 
    # Encodings which cannot encode mu
 
199
 
        TestCaseInTempDir.setUp(self)
 
200
 
        self.user_encoding = bzrlib.user_encoding
 
203
 
        bzrlib.user_encoding = self.user_encoding
 
204
 
        TestCaseInTempDir.tearDown(self)
 
206
 
    def create_branch(self):
 
209
 
        open('a', 'wb').write('some stuff\n')
 
211
 
        bzr('commit', '-m', self._message)
 
213
 
    def try_encoding(self, encoding, fail=False):
 
216
 
            self.assertRaises(UnicodeEncodeError,
 
217
 
                self._mu.encode, encoding)
 
218
 
            encoded_msg = self._message.encode(encoding, 'replace')
 
220
 
            encoded_msg = self._message.encode(encoding)
 
222
 
        old_encoding = bzrlib.user_encoding
 
223
 
        # This test requires that 'run_bzr' uses the current
 
224
 
        # bzrlib, because we override user_encoding, and expect
 
227
 
            bzrlib.user_encoding = 'ascii'
 
228
 
            # We should be able to handle any encoding
 
229
 
            out, err = bzr('log', encoding=encoding)
 
231
 
                # Make sure we wrote mu as we expected it to exist
 
232
 
                self.assertNotEqual(-1, out.find(encoded_msg))
 
233
 
                out_unicode = out.decode(encoding)
 
234
 
                self.assertNotEqual(-1, out_unicode.find(self._message))
 
236
 
                self.assertNotEqual(-1, out.find('Message with ?'))
 
238
 
            bzrlib.user_encoding = old_encoding
 
240
 
    def test_log_handles_encoding(self):
 
243
 
        for encoding in self.good_encodings:
 
244
 
            self.try_encoding(encoding)
 
246
 
    def test_log_handles_bad_encoding(self):
 
249
 
        for encoding in self.bad_encodings:
 
250
 
            self.try_encoding(encoding, fail=True)
 
252
 
    def test_stdout_encoding(self):
 
254
 
        bzrlib.user_encoding = "cp1251"
 
257
 
        self.build_tree(['a'])
 
259
 
        bzr('commit', '-m', u'\u0422\u0435\u0441\u0442')
 
260
 
        stdout, stderr = self.run_bzr('log', encoding='cp866')
 
262
 
        message = stdout.splitlines()[-1]
 
264
 
        # explanation of the check:
 
265
 
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
 
266
 
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
 
267
 
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
 
268
 
        # This test should check that output of log command
 
269
 
        # encoded to sys.stdout.encoding
 
270
 
        test_in_cp866 = '\x92\xa5\xe1\xe2'
 
271
 
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
 
272
 
        # Make sure the log string is encoded in cp866
 
273
 
        self.assertEquals(test_in_cp866, message[2:])
 
274
 
        # Make sure the cp1251 string is not found anywhere
 
275
 
        self.assertEquals(-1, stdout.find(test_in_cp1251))