~bzr-pqm/bzr/bzr.dev

974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
1
# Copyright (C) 2005 by Canonical Ltd
1185.85.4 by John Arbash Meinel
currently broken, trying to fix things up.
2
# -*- coding: utf-8 -*-
3
# vim: encoding=utf-8
1685.1.80 by Wouter van Heyst
more code cleanup
4
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
1685.1.80 by Wouter van Heyst
more code cleanup
9
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
1685.1.80 by Wouter van Heyst
more code cleanup
14
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
import os
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
20
from cStringIO import StringIO
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
21
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
22
from bzrlib.tests import BzrTestBase, TestCaseWithTransport
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
23
from bzrlib.log import (LogFormatter, show_log, LongLogFormatter,
24
                        ShortLogFormatter, LineLogFormatter)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
25
from bzrlib.branch import Branch
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
26
from bzrlib.errors import InvalidRevisionNumber
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
27
1685.1.69 by Wouter van Heyst
merge bzr.dev 1740
28
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
29
class _LogEntry(object):
30
    # should probably move into bzrlib.log?
31
    pass
32
33
34
class LogCatcher(LogFormatter):
35
    """Pull log messages into list rather than displaying them.
36
37
    For ease of testing we save log messages here rather than actually
38
    formatting them, so that we can precisely check the result without
39
    being too dependent on the exact formatting.
40
41
    We should also test the LogFormatter.
42
    """
43
    def __init__(self):
44
        super(LogCatcher, self).__init__(to_file=None)
45
        self.logs = []
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
46
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
47
    def show(self, revno, rev, delta):
48
        le = _LogEntry()
49
        le.revno = revno
50
        le.rev = rev
51
        le.delta = delta
52
        self.logs.append(le)
53
54
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
55
class SimpleLogTest(TestCaseWithTransport):
1102 by Martin Pool
- merge test refactoring from robertc
56
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
57
    def checkDelta(self, delta, **kw):
58
        """Check the filenames touched by a delta are as expected."""
59
        for n in 'added', 'removed', 'renamed', 'modified', 'unchanged':
60
            expected = kw.get(n, [])
61
62
            # tests are written with unix paths; fix them up for windows
1185.31.34 by John Arbash Meinel
Removing instances of os.sep
63
            #if os.sep != '/':
64
            #    expected = [x.replace('/', os.sep) for x in expected]
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
65
66
            # strip out only the path components
67
            got = [x[0] for x in getattr(delta, n)]
68
            self.assertEquals(expected, got)
69
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
70
    def test_cur_revno(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
71
        wt = self.make_branch_and_tree('.')
72
        b = wt.branch
1092.3.4 by Robert Collins
update symlink branch to integration
73
74
        lf = LogCatcher()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
75
        wt.commit('empty commit')
1092.3.4 by Robert Collins
update symlink branch to integration
76
        show_log(b, lf, verbose=True, start_revision=1, end_revision=1)
77
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
78
                          start_revision=2, end_revision=1) 
79
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
80
                          start_revision=1, end_revision=2) 
81
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
82
                          start_revision=0, end_revision=2) 
83
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
84
                          start_revision=1, end_revision=0) 
85
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
86
                          start_revision=-1, end_revision=1) 
87
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
88
                          start_revision=1, end_revision=-1) 
89
90
    def test_cur_revno(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
91
        wt = self.make_branch_and_tree('.')
92
        b = wt.branch
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
93
94
        lf = LogCatcher()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
95
        wt.commit('empty commit')
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
96
        show_log(b, lf, verbose=True, start_revision=1, end_revision=1)
97
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
98
                          start_revision=2, end_revision=1) 
99
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
100
                          start_revision=1, end_revision=2) 
101
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
102
                          start_revision=0, end_revision=2) 
103
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
104
                          start_revision=1, end_revision=0) 
105
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
106
                          start_revision=-1, end_revision=1) 
107
        self.assertRaises(InvalidRevisionNumber, show_log, b, lf,
108
                          start_revision=1, end_revision=-1) 
109
1102 by Martin Pool
- merge test refactoring from robertc
110
    def test_simple_log(self):
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
111
        eq = self.assertEquals
112
        
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
113
        wt = self.make_branch_and_tree('.')
114
        b = wt.branch
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
115
116
        lf = LogCatcher()
117
        show_log(b, lf)
118
        # no entries yet
119
        eq(lf.logs, [])
120
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
121
        wt.commit('empty commit')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
122
        lf = LogCatcher()
123
        show_log(b, lf, verbose=True)
124
        eq(len(lf.logs), 1)
125
        eq(lf.logs[0].revno, 1)
126
        eq(lf.logs[0].rev.message, 'empty commit')
127
        d = lf.logs[0].delta
128
        self.log('log delta: %r' % d)
129
        self.checkDelta(d)
130
131
        self.build_tree(['hello'])
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
132
        wt.add('hello')
133
        wt.commit('add one file')
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
134
135
        lf = StringIO()
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
136
        # log using regular thing
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
137
        show_log(b, LongLogFormatter(lf))
138
        lf.seek(0)
139
        for l in lf.readlines():
140
            self.log(l)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
141
142
        # get log as data structure
143
        lf = LogCatcher()
144
        show_log(b, lf, verbose=True)
145
        eq(len(lf.logs), 2)
146
        self.log('log entries:')
147
        for logentry in lf.logs:
148
            self.log('%4d %s' % (logentry.revno, logentry.rev.message))
149
        
150
        # first one is most recent
151
        logentry = lf.logs[0]
152
        eq(logentry.revno, 2)
153
        eq(logentry.rev.message, 'add one file')
154
        d = logentry.delta
155
        self.log('log 2 delta: %r' % d)
156
        # self.checkDelta(d, added=['hello'])
157
        
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
158
        # commit a log message with control characters
159
        msg = "All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
160
        self.log("original commit message: %r", msg)
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
161
        wt.commit(msg)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
162
        lf = LogCatcher()
163
        show_log(b, lf, verbose=True)
164
        committed_msg = lf.logs[0].rev.message
165
        self.log("escaped commit message: %r", committed_msg)
166
        self.assert_(msg != committed_msg)
167
        self.assert_(len(committed_msg) > len(msg))
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
168
169
        # Check that log message with only XML-valid characters isn't
170
        # escaped.  As ElementTree apparently does some kind of
171
        # newline conversion, neither LF (\x0A) nor CR (\x0D) are
172
        # included in the test commit message, even though they are
173
        # valid XML 1.0 characters.
174
        msg = "\x09" + ''.join([unichr(x) for x in range(0x20, 256)])
175
        self.log("original commit message: %r", msg)
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
176
        wt.commit(msg)
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
177
        lf = LogCatcher()
178
        show_log(b, lf, verbose=True)
179
        committed_msg = lf.logs[0].rev.message
180
        self.log("escaped commit message: %r", committed_msg)
181
        self.assert_(msg == committed_msg)
1185.31.22 by John Arbash Meinel
[merge] bzr.dev
182
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
183
    def test_trailing_newlines(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
184
        wt = self.make_branch_and_tree('.')
185
        b = wt.branch
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
186
        b.nick='test'
187
        open('a', 'wb').write('hello moto\n')
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
188
        wt.add('a')
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
189
        wt.commit('simple log message', rev_id='a1'
190
                , timestamp=1132586655.459960938, timezone=-6*3600
191
                , committer='Joe Foo <joe@foo.com>')
192
        open('b', 'wb').write('goodbye\n')
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
193
        wt.add('b')
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
194
        wt.commit('multiline\nlog\nmessage\n', rev_id='a2'
195
                , timestamp=1132586842.411175966, timezone=-6*3600
196
                , committer='Joe Foo <joe@foo.com>')
197
198
        open('c', 'wb').write('just another manic monday\n')
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
199
        wt.add('c')
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
200
        wt.commit('single line with trailing newline\n', rev_id='a3'
201
                , timestamp=1132587176.835228920, timezone=-6*3600
202
                , committer = 'Joe Foo <joe@foo.com>')
203
204
        sio = StringIO()
205
        lf = ShortLogFormatter(to_file=sio)
206
        show_log(b, lf)
207
        self.assertEquals(sio.getvalue(), """\
208
    3 Joe Foo\t2005-11-21
209
      single line with trailing newline
210
211
    2 Joe Foo\t2005-11-21
212
      multiline
213
      log
214
      message
215
216
    1 Joe Foo\t2005-11-21
217
      simple log message
218
219
""")
220
221
        sio = StringIO()
222
        lf = LongLogFormatter(to_file=sio)
223
        show_log(b, lf)
224
        self.assertEquals(sio.getvalue(), """\
225
------------------------------------------------------------
226
revno: 3
227
committer: Joe Foo <joe@foo.com>
228
branch nick: test
229
timestamp: Mon 2005-11-21 09:32:56 -0600
230
message:
231
  single line with trailing newline
232
------------------------------------------------------------
233
revno: 2
234
committer: Joe Foo <joe@foo.com>
235
branch nick: test
236
timestamp: Mon 2005-11-21 09:27:22 -0600
237
message:
238
  multiline
239
  log
240
  message
241
------------------------------------------------------------
242
revno: 1
243
committer: Joe Foo <joe@foo.com>
244
branch nick: test
245
timestamp: Mon 2005-11-21 09:24:15 -0600
246
message:
247
  simple log message
248
""")
249
        
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
250
    def test_verbose_log(self):
251
        """Verbose log includes changed files
252
        
253
        bug #4676
254
        """
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
255
        wt = self.make_branch_and_tree('.')
256
        b = wt.branch
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
257
        self.build_tree(['a'])
1185.33.45 by Martin Pool
[merge] refactoring of branch vs working tree, etc (robertc)
258
        wt.add('a')
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
259
        # XXX: why does a longer nick show up?
260
        b.nick = 'test_verbose_log'
261
        wt.commit(message='add a', 
262
                  timestamp=1132711707, 
263
                  timezone=36000,
264
                  committer='Lorem Ipsum <test@example.com>')
265
        logfile = file('out.tmp', 'w+')
266
        formatter = LongLogFormatter(to_file=logfile)
267
        show_log(b, formatter, verbose=True)
268
        logfile.flush()
269
        logfile.seek(0)
270
        log_contents = logfile.read()
271
        self.assertEqualDiff(log_contents, '''\
272
------------------------------------------------------------
273
revno: 1
274
committer: Lorem Ipsum <test@example.com>
275
branch nick: test_verbose_log
276
timestamp: Wed 2005-11-23 12:08:27 +1000
277
message:
278
  add a
279
added:
280
  a
281
''')
1185.85.4 by John Arbash Meinel
currently broken, trying to fix things up.
282
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
283
    def test_line_log(self):
284
        """Line log should show revno
285
        
286
        bug #5162
287
        """
288
        wt = self.make_branch_and_tree('.')
289
        b = wt.branch
290
        self.build_tree(['a'])
291
        wt.add('a')
292
        b.nick = 'test-line-log'
293
        wt.commit(message='add a', 
294
                  timestamp=1132711707, 
295
                  timezone=36000,
296
                  committer='Line-Log-Formatter Tester <test@line.log>')
297
        logfile = file('out.tmp', 'w+')
298
        formatter = LineLogFormatter(to_file=logfile)
299
        show_log(b, formatter)
300
        logfile.flush()
301
        logfile.seek(0)
302
        log_contents = logfile.read()
303
        self.assertEqualDiff(log_contents, '1: Line-Log-Formatte... 2005-11-23 add a\n')