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))