/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to brzlib/tests/test_revisionspec.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import datetime
18
18
import time
19
19
 
20
 
from breezy import (
 
20
from brzlib import (
21
21
    errors,
22
22
    revision as _mod_revision,
 
23
    symbol_versioning,
23
24
    )
24
 
from breezy.tests import TestCaseWithTransport
25
 
from breezy.revisionspec import (
 
25
from brzlib.tests import TestCaseWithTransport
 
26
from brzlib.revisionspec import (
26
27
    RevisionInfo,
27
28
    RevisionSpec,
28
29
    RevisionSpec_dwim,
50
51
        self.tree.lock_write()
51
52
        self.addCleanup(self.tree.unlock)
52
53
        self.tree.add(['a'])
53
 
        self.tree.commit('a', rev_id=b'r1')
 
54
        self.tree.commit('a', rev_id='r1')
54
55
 
55
 
        self.tree2 = self.tree.controldir.sprout('tree2').open_workingtree()
56
 
        self.tree2.commit('alt', rev_id=b'alt_r2')
 
56
        self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
 
57
        self.tree2.commit('alt', rev_id='alt_r2')
57
58
 
58
59
        self.tree.merge_from_branch(self.tree2.branch)
59
 
        self.tree.commit('second', rev_id=b'r2')
 
60
        self.tree.commit('second', rev_id='r2')
60
61
 
61
62
    def get_in_history(self, revision_spec):
62
63
        return spec_in_history(revision_spec, self.tree.branch)
75
76
                      invalid_as_revision_id=True):
76
77
        try:
77
78
            self.get_in_history(revision_spec)
78
 
        except errors.InvalidRevisionSpec as e:
 
79
        except errors.InvalidRevisionSpec, e:
79
80
            self.assertEqual(revision_spec, e.spec)
80
81
            self.assertEqual(extra, e.extra)
81
82
        else:
85
86
            try:
86
87
                spec = RevisionSpec.from_string(revision_spec)
87
88
                spec.as_revision_id(self.tree.branch)
88
 
            except errors.InvalidRevisionSpec as e:
 
89
            except errors.InvalidRevisionSpec, e:
89
90
                self.assertEqual(revision_spec, e.spec)
90
91
                self.assertEqual(extra, e.extra)
91
92
            else:
114
115
 
115
116
class TestRevisionSpecBase(TestRevisionSpec):
116
117
 
 
118
    def test_wants_revision_history(self):
 
119
        # If wants_revision_history = True, then _match_on should get the
 
120
        # branch revision history
 
121
        spec = RevisionSpecMatchOnTrap('foo', _internal=True)
 
122
        spec.wants_revision_history = True
 
123
        self.callDeprecated(['RevisionSpec.wants_revision_history was '
 
124
            'deprecated in 2.5 (RevisionSpecMatchOnTrap).'],
 
125
            spec.in_history, self.tree.branch)
 
126
 
 
127
        self.assertEqual((self.tree.branch, ['r1' ,'r2']),
 
128
                         spec.last_call)
 
129
 
117
130
    def test_wants_no_revision_history(self):
118
131
        # If wants_revision_history = False, then _match_on should get None for
119
132
        # the branch revision history
123
136
        self.assertEqual((self.tree.branch, None), spec.last_call)
124
137
 
125
138
 
 
139
 
126
140
class TestOddRevisionSpec(TestRevisionSpec):
127
141
    """Test things that aren't normally thought of as revision specs"""
128
142
 
139
153
 
140
154
    def _match_on(self, branch, revs):
141
155
        if self.spec == "bork":
142
 
            return RevisionInfo.from_revision_id(branch, b"r1")
 
156
            return RevisionInfo.from_revision_id(branch, "r1")
143
157
        else:
144
158
            raise errors.InvalidRevisionSpec(self.spec, branch)
145
159
 
149
163
    # Don't need to test revno's explicitly since TRS_revno already
150
164
    # covers that well for us
151
165
    def test_dwim_spec_revno(self):
152
 
        self.assertInHistoryIs(2, b'r2', '2')
153
 
        self.assertAsRevisionId(b'alt_r2', '1.1.1')
 
166
        self.assertInHistoryIs(2, 'r2', '2')
 
167
        self.assertAsRevisionId('alt_r2', '1.1.1')
154
168
 
155
169
    def test_dwim_spec_revid(self):
156
 
        self.assertInHistoryIs(2, b'r2', 'r2')
 
170
        self.assertInHistoryIs(2, 'r2', 'r2')
157
171
 
158
172
    def test_dwim_spec_tag(self):
159
 
        self.tree.branch.tags.set_tag('footag', b'r1')
160
 
        self.assertAsRevisionId(b'r1', 'footag')
 
173
        self.tree.branch.tags.set_tag('footag', 'r1')
 
174
        self.assertAsRevisionId('r1', 'footag')
161
175
        self.tree.branch.tags.delete_tag('footag')
162
176
        self.assertRaises(errors.InvalidRevisionSpec,
163
177
                          self.get_in_history, 'footag')
166
180
        # Test that we slip past revno with things that look like revnos,
167
181
        # but aren't.  Tags are convenient for testing this since we can
168
182
        # make them look however we want.
169
 
        self.tree.branch.tags.set_tag('3', b'r2')
170
 
        self.assertAsRevisionId(b'r2', '3')
 
183
        self.tree.branch.tags.set_tag('3', 'r2')
 
184
        self.assertAsRevisionId('r2', '3')
171
185
        self.build_tree(['tree/b'])
172
186
        self.tree.add(['b'])
173
 
        self.tree.commit('b', rev_id=b'r3')
174
 
        self.assertAsRevisionId(b'r3', '3')
 
187
        self.tree.commit('b', rev_id='r3')
 
188
        self.assertAsRevisionId('r3', '3')
175
189
 
176
190
    def test_dwim_spec_date(self):
177
 
        self.assertAsRevisionId(b'r1', 'today')
 
191
        self.assertAsRevisionId('r1', 'today')
178
192
 
179
193
    def test_dwim_spec_branch(self):
180
 
        self.assertInHistoryIs(None, b'alt_r2', 'tree2')
 
194
        self.assertInHistoryIs(None, 'alt_r2', 'tree2')
181
195
 
182
196
    def test_dwim_spec_nonexistent(self):
183
197
        self.assertInvalid('somethingrandom', invalid_as_revision_id=False)
189
203
 
190
204
    def test_append_dwim_revspec(self):
191
205
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
192
 
 
193
206
        def reset_dwim_revspecs():
194
207
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
195
208
        self.addCleanup(reset_dwim_revspecs)
196
209
        RevisionSpec_dwim.append_possible_revspec(RevisionSpec_bork)
197
 
        self.assertAsRevisionId(b'r1', 'bork')
 
210
        self.assertAsRevisionId('r1', 'bork')
198
211
 
199
212
    def test_append_lazy_dwim_revspec(self):
200
213
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
201
 
 
202
214
        def reset_dwim_revspecs():
203
215
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
204
216
        self.addCleanup(reset_dwim_revspecs)
205
217
        RevisionSpec_dwim.append_possible_lazy_revspec(
206
 
            "breezy.tests.test_revisionspec", "RevisionSpec_bork")
207
 
        self.assertAsRevisionId(b'r1', 'bork')
 
218
            "brzlib.tests.test_revisionspec", "RevisionSpec_bork")
 
219
        self.assertAsRevisionId('r1', 'bork')
208
220
 
209
221
 
210
222
class TestRevisionSpec_revno(TestRevisionSpec):
211
223
 
212
224
    def test_positive_int(self):
213
 
        self.assertInHistoryIs(0, b'null:', '0')
214
 
        self.assertInHistoryIs(1, b'r1', '1')
215
 
        self.assertInHistoryIs(2, b'r2', '2')
 
225
        self.assertInHistoryIs(0, 'null:', '0')
 
226
        self.assertInHistoryIs(1, 'r1', '1')
 
227
        self.assertInHistoryIs(2, 'r2', '2')
216
228
        self.assertInvalid('3')
217
229
 
218
230
    def test_dotted_decimal(self):
219
 
        self.assertInHistoryIs(None, b'alt_r2', '1.1.1')
 
231
        self.assertInHistoryIs(None, 'alt_r2', '1.1.1')
220
232
        self.assertInvalid('1.1.123')
221
233
 
222
234
    def test_negative_int(self):
223
 
        self.assertInHistoryIs(2, b'r2', '-1')
224
 
        self.assertInHistoryIs(1, b'r1', '-2')
 
235
        self.assertInHistoryIs(2, 'r2', '-1')
 
236
        self.assertInHistoryIs(1, 'r1', '-2')
225
237
 
226
 
        self.assertInHistoryIs(1, b'r1', '-3')
227
 
        self.assertInHistoryIs(1, b'r1', '-4')
228
 
        self.assertInHistoryIs(1, b'r1', '-100')
 
238
        self.assertInHistoryIs(1, 'r1', '-3')
 
239
        self.assertInHistoryIs(1, 'r1', '-4')
 
240
        self.assertInHistoryIs(1, 'r1', '-100')
229
241
 
230
242
    def test_positive(self):
231
 
        self.assertInHistoryIs(0, b'null:', 'revno:0')
232
 
        self.assertInHistoryIs(1, b'r1', 'revno:1')
233
 
        self.assertInHistoryIs(2, b'r2', 'revno:2')
 
243
        self.assertInHistoryIs(0, 'null:', 'revno:0')
 
244
        self.assertInHistoryIs(1, 'r1', 'revno:1')
 
245
        self.assertInHistoryIs(2, 'r2', 'revno:2')
234
246
 
235
247
        self.assertInvalid('revno:3')
236
248
 
237
249
    def test_negative(self):
238
 
        self.assertInHistoryIs(2, b'r2', 'revno:-1')
239
 
        self.assertInHistoryIs(1, b'r1', 'revno:-2')
 
250
        self.assertInHistoryIs(2, 'r2', 'revno:-1')
 
251
        self.assertInHistoryIs(1, 'r1', 'revno:-2')
240
252
 
241
 
        self.assertInHistoryIs(1, b'r1', 'revno:-3')
242
 
        self.assertInHistoryIs(1, b'r1', 'revno:-4')
 
253
        self.assertInHistoryIs(1, 'r1', 'revno:-3')
 
254
        self.assertInHistoryIs(1, 'r1', 'revno:-4')
243
255
 
244
256
    def test_invalid_number(self):
245
257
        # Get the right exception text
246
258
        try:
247
259
            int('X')
248
 
        except ValueError as e:
249
 
            self.assertInvalid('revno:X', extra='\n' + str(e))
250
 
        else:
251
 
            self.fail()
 
260
        except ValueError, e:
 
261
            pass
 
262
        self.assertInvalid('revno:X', extra='\n' + str(e))
252
263
 
253
264
    def test_missing_number_and_branch(self):
254
265
        self.assertInvalid('revno::',
257
268
    def test_invalid_number_with_branch(self):
258
269
        try:
259
270
            int('X')
260
 
        except ValueError as e:
261
 
            self.assertInvalid('revno:X:tree2', extra='\n' + str(e))
262
 
        else:
263
 
            self.fail()
 
271
        except ValueError, e:
 
272
            pass
 
273
        self.assertInvalid('revno:X:tree2', extra='\n' + str(e))
264
274
 
265
275
    def test_non_exact_branch(self):
266
276
        # It seems better to require an exact path to the branch
275
285
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
276
286
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
277
287
        self.assertEqual(2, revinfo.revno)
278
 
        self.assertEqual(b'alt_r2', revinfo.rev_id)
 
288
        self.assertEqual('alt_r2', revinfo.rev_id)
279
289
 
280
290
    def test_int_with_branch(self):
281
291
        revinfo = self.get_in_history('2:tree2')
282
292
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
283
293
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
284
294
        self.assertEqual(2, revinfo.revno)
285
 
        self.assertEqual(b'alt_r2', revinfo.rev_id)
 
295
        self.assertEqual('alt_r2', revinfo.rev_id)
286
296
 
287
297
    def test_with_url(self):
288
298
        url = self.get_url() + '/tree2'
290
300
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
291
301
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
292
302
        self.assertEqual(2, revinfo.revno)
293
 
        self.assertEqual(b'alt_r2', revinfo.rev_id)
 
303
        self.assertEqual('alt_r2', revinfo.rev_id)
294
304
 
295
305
    def test_negative_with_url(self):
296
306
        url = self.get_url() + '/tree2'
298
308
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
299
309
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
300
310
        self.assertEqual(2, revinfo.revno)
301
 
        self.assertEqual(b'alt_r2', revinfo.rev_id)
 
311
        self.assertEqual('alt_r2', revinfo.rev_id)
302
312
 
303
313
    def test_different_history_lengths(self):
304
314
        # Make sure we use the revisions and offsets in the supplied branch
305
315
        # not the ones in the original branch.
306
 
        self.tree2.commit('three', rev_id=b'r3')
307
 
        self.assertInHistoryIs(3, b'r3', 'revno:3:tree2')
308
 
        self.assertInHistoryIs(3, b'r3', 'revno:-1:tree2')
 
316
        self.tree2.commit('three', rev_id='r3')
 
317
        self.assertInHistoryIs(3, 'r3', 'revno:3:tree2')
 
318
        self.assertInHistoryIs(3, 'r3', 'revno:-1:tree2')
309
319
 
310
320
    def test_invalid_branch(self):
311
321
        self.assertRaises(errors.NotBranchError,
312
322
                          self.get_in_history, 'revno:-1:tree3')
313
323
 
314
324
    def test_invalid_revno_in_branch(self):
315
 
        self.tree.commit('three', rev_id=b'r3')
 
325
        self.tree.commit('three', rev_id='r3')
316
326
        self.assertInvalid('revno:3:tree2')
317
327
 
318
328
    def test_revno_n_path(self):
320
330
        wta = self.make_branch_and_tree('a')
321
331
        ba = wta.branch
322
332
 
323
 
        wta.commit('Commit one', rev_id=b'a@r-0-1')
324
 
        wta.commit('Commit two', rev_id=b'a@r-0-2')
325
 
        wta.commit('Commit three', rev_id=b'a@r-0-3')
 
333
        wta.commit('Commit one', rev_id='a@r-0-1')
 
334
        wta.commit('Commit two', rev_id='a@r-0-2')
 
335
        wta.commit('Commit three', rev_id='a@r-0-3')
326
336
 
327
337
        wtb = self.make_branch_and_tree('b')
328
338
        bb = wtb.branch
329
339
 
330
 
        wtb.commit('Commit one', rev_id=b'b@r-0-1')
331
 
        wtb.commit('Commit two', rev_id=b'b@r-0-2')
332
 
        wtb.commit('Commit three', rev_id=b'b@r-0-3')
333
 
 
334
 
        self.assertEqual((1, b'a@r-0-1'),
 
340
        wtb.commit('Commit one', rev_id='b@r-0-1')
 
341
        wtb.commit('Commit two', rev_id='b@r-0-2')
 
342
        wtb.commit('Commit three', rev_id='b@r-0-3')
 
343
 
 
344
 
 
345
        self.assertEqual((1, 'a@r-0-1'),
335
346
                         spec_in_history('revno:1:a/', ba))
336
347
        # The argument of in_history should be ignored since it is
337
348
        # redundant with the path in the spec.
338
 
        self.assertEqual((1, b'a@r-0-1'),
 
349
        self.assertEqual((1, 'a@r-0-1'),
339
350
                         spec_in_history('revno:1:a/', None))
340
 
        self.assertEqual((1, b'a@r-0-1'),
 
351
        self.assertEqual((1, 'a@r-0-1'),
341
352
                         spec_in_history('revno:1:a/', bb))
342
 
        self.assertEqual((2, b'b@r-0-2'),
 
353
        self.assertEqual((2, 'b@r-0-2'),
343
354
                         spec_in_history('revno:2:b/', None))
344
355
 
345
356
    def test_as_revision_id(self):
346
 
        self.assertAsRevisionId(b'null:', '0')
347
 
        self.assertAsRevisionId(b'r1', '1')
348
 
        self.assertAsRevisionId(b'r2', '2')
349
 
        self.assertAsRevisionId(b'r1', '-2')
350
 
        self.assertAsRevisionId(b'r2', '-1')
351
 
        self.assertAsRevisionId(b'alt_r2', '1.1.1')
 
357
        self.assertAsRevisionId('null:', '0')
 
358
        self.assertAsRevisionId('r1', '1')
 
359
        self.assertAsRevisionId('r2', '2')
 
360
        self.assertAsRevisionId('r1', '-2')
 
361
        self.assertAsRevisionId('r2', '-1')
 
362
        self.assertAsRevisionId('alt_r2', '1.1.1')
352
363
 
353
364
    def test_as_tree(self):
354
365
        tree = self.get_as_tree('0')
355
366
        self.assertEqual(_mod_revision.NULL_REVISION, tree.get_revision_id())
356
367
        tree = self.get_as_tree('1')
357
 
        self.assertEqual(b'r1', tree.get_revision_id())
 
368
        self.assertEqual('r1', tree.get_revision_id())
358
369
        tree = self.get_as_tree('2')
359
 
        self.assertEqual(b'r2', tree.get_revision_id())
 
370
        self.assertEqual('r2', tree.get_revision_id())
360
371
        tree = self.get_as_tree('-2')
361
 
        self.assertEqual(b'r1', tree.get_revision_id())
 
372
        self.assertEqual('r1', tree.get_revision_id())
362
373
        tree = self.get_as_tree('-1')
363
 
        self.assertEqual(b'r2', tree.get_revision_id())
 
374
        self.assertEqual('r2', tree.get_revision_id())
364
375
        tree = self.get_as_tree('1.1.1')
365
 
        self.assertEqual(b'alt_r2', tree.get_revision_id())
 
376
        self.assertEqual('alt_r2', tree.get_revision_id())
366
377
 
367
378
 
368
379
class TestRevisionSpec_revid(TestRevisionSpec):
370
381
    def test_in_history(self):
371
382
        # We should be able to access revisions that are directly
372
383
        # in the history.
373
 
        self.assertInHistoryIs(1, b'r1', 'revid:r1')
374
 
        self.assertInHistoryIs(2, b'r2', 'revid:r2')
 
384
        self.assertInHistoryIs(1, 'r1', 'revid:r1')
 
385
        self.assertInHistoryIs(2, 'r2', 'revid:r2')
375
386
 
376
387
    def test_missing(self):
377
388
        self.assertInvalid('revid:r3', invalid_as_revision_id=False)
378
389
 
379
390
    def test_merged(self):
380
391
        """We can reach revisions in the ancestry"""
381
 
        self.assertInHistoryIs(None, b'alt_r2', 'revid:alt_r2')
 
392
        self.assertInHistoryIs(None, 'alt_r2', 'revid:alt_r2')
382
393
 
383
394
    def test_not_here(self):
384
 
        self.tree2.commit('alt third', rev_id=b'alt_r3')
 
395
        self.tree2.commit('alt third', rev_id='alt_r3')
385
396
        # It exists in tree2, but not in tree
386
397
        self.assertInvalid('revid:alt_r3', invalid_as_revision_id=False)
387
398
 
388
399
    def test_in_repository(self):
389
400
        """We can get any revision id in the repository"""
390
401
        # XXX: This may change in the future, but for now, it is true
391
 
        self.tree2.commit('alt third', rev_id=b'alt_r3')
392
 
        self.tree.branch.fetch(self.tree2.branch, b'alt_r3')
393
 
        self.assertInHistoryIs(None, b'alt_r3', 'revid:alt_r3')
 
402
        self.tree2.commit('alt third', rev_id='alt_r3')
 
403
        self.tree.branch.fetch(self.tree2.branch, 'alt_r3')
 
404
        self.assertInHistoryIs(None, 'alt_r3', 'revid:alt_r3')
394
405
 
395
406
    def test_unicode(self):
396
407
        """We correctly convert a unicode ui string to an encoded revid."""
397
408
        revision_id = u'\N{SNOWMAN}'.encode('utf-8')
398
409
        self.tree.commit('unicode', rev_id=revision_id)
399
410
        self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
400
 
        self.assertInHistoryIs(3, revision_id, 'revid:' +
401
 
                               revision_id.decode('utf-8'))
 
411
        self.assertInHistoryIs(3, revision_id, 'revid:' + revision_id)
402
412
 
403
413
    def test_as_revision_id(self):
404
 
        self.assertAsRevisionId(b'r1', 'revid:r1')
405
 
        self.assertAsRevisionId(b'r2', 'revid:r2')
406
 
        self.assertAsRevisionId(b'alt_r2', 'revid:alt_r2')
 
414
        self.assertAsRevisionId('r1', 'revid:r1')
 
415
        self.assertAsRevisionId('r2', 'revid:r2')
 
416
        self.assertAsRevisionId('alt_r2', 'revid:alt_r2')
407
417
 
408
418
 
409
419
class TestRevisionSpec_last(TestRevisionSpec):
410
420
 
411
421
    def test_positive(self):
412
 
        self.assertInHistoryIs(2, b'r2', 'last:1')
413
 
        self.assertInHistoryIs(1, b'r1', 'last:2')
414
 
        self.assertInHistoryIs(0, b'null:', 'last:3')
 
422
        self.assertInHistoryIs(2, 'r2', 'last:1')
 
423
        self.assertInHistoryIs(1, 'r1', 'last:2')
 
424
        self.assertInHistoryIs(0, 'null:', 'last:3')
415
425
 
416
426
    def test_empty(self):
417
 
        self.assertInHistoryIs(2, b'r2', 'last:')
 
427
        self.assertInHistoryIs(2, 'r2', 'last:')
418
428
 
419
429
    def test_negative(self):
420
430
        self.assertInvalid('last:-1',
430
440
                          spec_in_history, 'last:', tree.branch)
431
441
 
432
442
    def test_not_a_number(self):
433
 
        last_e = None
434
443
        try:
435
444
            int('Y')
436
 
        except ValueError as e:
437
 
            last_e = e
438
 
        self.assertInvalid('last:Y', extra='\n' + str(last_e))
 
445
        except ValueError, e:
 
446
            pass
 
447
        self.assertInvalid('last:Y', extra='\n' + str(e))
439
448
 
440
449
    def test_as_revision_id(self):
441
 
        self.assertAsRevisionId(b'r2', 'last:1')
442
 
        self.assertAsRevisionId(b'r1', 'last:2')
 
450
        self.assertAsRevisionId('r2', 'last:1')
 
451
        self.assertAsRevisionId('r1', 'last:2')
443
452
 
444
453
 
445
454
class TestRevisionSpec_before(TestRevisionSpec):
446
455
 
447
456
    def test_int(self):
448
 
        self.assertInHistoryIs(1, b'r1', 'before:2')
449
 
        self.assertInHistoryIs(1, b'r1', 'before:-1')
 
457
        self.assertInHistoryIs(1, 'r1', 'before:2')
 
458
        self.assertInHistoryIs(1, 'r1', 'before:-1')
450
459
 
451
460
    def test_before_one(self):
452
 
        self.assertInHistoryIs(0, b'null:', 'before:1')
 
461
        self.assertInHistoryIs(0, 'null:', 'before:1')
453
462
 
454
463
    def test_before_none(self):
455
464
        self.assertInvalid('before:0',
456
465
                           extra='\ncannot go before the null: revision')
457
466
 
458
467
    def test_revid(self):
459
 
        self.assertInHistoryIs(1, b'r1', 'before:revid:r2')
 
468
        self.assertInHistoryIs(1, 'r1', 'before:revid:r2')
460
469
 
461
470
    def test_last(self):
462
 
        self.assertInHistoryIs(1, b'r1', 'before:last:1')
 
471
        self.assertInHistoryIs(1, 'r1', 'before:last:1')
463
472
 
464
473
    def test_alt_revid(self):
465
474
        # This will grab the left-most ancestor for alternate histories
466
 
        self.assertInHistoryIs(1, b'r1', 'before:revid:alt_r2')
 
475
        self.assertInHistoryIs(1, 'r1', 'before:revid:alt_r2')
467
476
 
468
477
    def test_alt_no_parents(self):
469
478
        new_tree = self.make_branch_and_tree('new_tree')
470
 
        new_tree.commit('first', rev_id=b'new_r1')
471
 
        self.tree.branch.fetch(new_tree.branch, b'new_r1')
472
 
        self.assertInHistoryIs(0, b'null:', 'before:revid:new_r1')
 
479
        new_tree.commit('first', rev_id='new_r1')
 
480
        self.tree.branch.fetch(new_tree.branch, 'new_r1')
 
481
        self.assertInHistoryIs(0, 'null:', 'before:revid:new_r1')
473
482
 
474
483
    def test_as_revision_id(self):
475
 
        self.assertAsRevisionId(b'r1', 'before:revid:r2')
476
 
        self.assertAsRevisionId(b'r1', 'before:2')
477
 
        self.assertAsRevisionId(b'r1', 'before:1.1.1')
478
 
        self.assertAsRevisionId(b'r1', 'before:revid:alt_r2')
 
484
        self.assertAsRevisionId('r1', 'before:revid:r2')
 
485
        self.assertAsRevisionId('r1', 'before:2')
 
486
        self.assertAsRevisionId('r1', 'before:1.1.1')
 
487
        self.assertAsRevisionId('r1', 'before:revid:alt_r2')
479
488
 
480
489
 
481
490
class TestRevisionSpec_tag(TestRevisionSpec):
491
500
        self.assertEqual(spec.spec, 'bzr-0.14')
492
501
 
493
502
    def test_lookup_tag(self):
494
 
        self.tree.branch.tags.set_tag('bzr-0.14', b'r1')
495
 
        self.assertInHistoryIs(1, b'r1', 'tag:bzr-0.14')
496
 
        self.tree.branch.tags.set_tag('null_rev', b'null:')
497
 
        self.assertInHistoryIs(0, b'null:', 'tag:null_rev')
 
503
        self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
 
504
        self.assertInHistoryIs(1, 'r1', 'tag:bzr-0.14')
 
505
        self.tree.branch.tags.set_tag('null_rev', 'null:')
 
506
        self.assertInHistoryIs(0, 'null:', 'tag:null_rev')
498
507
 
499
508
    def test_failed_lookup(self):
500
509
        # tags that don't exist give a specific message: arguably we should
501
510
        # just give InvalidRevisionSpec but I think this is more helpful
502
511
        self.assertRaises(errors.NoSuchTag,
503
 
                          self.get_in_history,
504
 
                          'tag:some-random-tag')
 
512
            self.get_in_history,
 
513
            'tag:some-random-tag')
505
514
 
506
515
    def test_as_revision_id(self):
507
 
        self.tree.branch.tags.set_tag('my-tag', b'r2')
508
 
        self.tree.branch.tags.set_tag('null_rev', b'null:')
509
 
        self.assertAsRevisionId(b'r2', 'tag:my-tag')
510
 
        self.assertAsRevisionId(b'null:', 'tag:null_rev')
511
 
        self.assertAsRevisionId(b'r1', 'before:tag:my-tag')
 
516
        self.tree.branch.tags.set_tag('my-tag', 'r2')
 
517
        self.tree.branch.tags.set_tag('null_rev', 'null:')
 
518
        self.assertAsRevisionId('r2', 'tag:my-tag')
 
519
        self.assertAsRevisionId('null:', 'tag:null_rev')
 
520
        self.assertAsRevisionId('r1', 'before:tag:my-tag')
512
521
 
513
522
 
514
523
class TestRevisionSpec_date(TestRevisionSpec):
517
526
        super(TestRevisionSpec, self).setUp()
518
527
 
519
528
        new_tree = self.make_branch_and_tree('new_tree')
520
 
        new_tree.commit('Commit one', rev_id=b'new_r1',
521
 
                        timestamp=time.time() - 60 * 60 * 24)
522
 
        new_tree.commit('Commit two', rev_id=b'new_r2')
523
 
        new_tree.commit('Commit three', rev_id=b'new_r3')
 
529
        new_tree.commit('Commit one', rev_id='new_r1',
 
530
                        timestamp=time.time() - 60*60*24)
 
531
        new_tree.commit('Commit two', rev_id='new_r2')
 
532
        new_tree.commit('Commit three', rev_id='new_r3')
524
533
 
525
534
        self.tree = new_tree
526
535
 
528
537
        self.assertInvalid('date:tomorrow')
529
538
 
530
539
    def test_today(self):
531
 
        self.assertInHistoryIs(2, b'new_r2', 'date:today')
532
 
        self.assertInHistoryIs(1, b'new_r1', 'before:date:today')
 
540
        self.assertInHistoryIs(2, 'new_r2', 'date:today')
 
541
        self.assertInHistoryIs(1, 'new_r1', 'before:date:today')
533
542
 
534
543
    def test_yesterday(self):
535
 
        self.assertInHistoryIs(1, b'new_r1', 'date:yesterday')
 
544
        self.assertInHistoryIs(1, 'new_r1', 'date:yesterday')
536
545
 
537
546
    def test_invalid(self):
538
547
        self.assertInvalid('date:foobar', extra='\ninvalid date')
543
552
 
544
553
    def test_day(self):
545
554
        now = datetime.datetime.now()
546
 
        self.assertInHistoryIs(2, b'new_r2',
547
 
                               'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
 
555
        self.assertInHistoryIs(2, 'new_r2',
 
556
            'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
548
557
 
549
558
    def test_as_revision_id(self):
550
 
        self.assertAsRevisionId(b'new_r2', 'date:today')
 
559
        self.assertAsRevisionId('new_r2', 'date:today')
551
560
 
552
561
 
553
562
class TestRevisionSpec_ancestor(TestRevisionSpec):
560
569
 
561
570
    def test_simple(self):
562
571
        # Common ancestor of trees is 'alt_r2'
563
 
        self.assertInHistoryIs(None, b'alt_r2', 'ancestor:tree2')
 
572
        self.assertInHistoryIs(None, 'alt_r2', 'ancestor:tree2')
564
573
 
565
574
        # Going the other way, we get a valid revno
566
575
        tmp = self.tree
567
576
        self.tree = self.tree2
568
577
        self.tree2 = tmp
569
 
        self.assertInHistoryIs(2, b'alt_r2', 'ancestor:tree')
 
578
        self.assertInHistoryIs(2, 'alt_r2', 'ancestor:tree')
570
579
 
571
580
    def test_self(self):
572
 
        self.assertInHistoryIs(2, b'r2', 'ancestor:tree')
 
581
        self.assertInHistoryIs(2, 'r2', 'ancestor:tree')
573
582
 
574
583
    def test_unrelated(self):
575
584
        new_tree = self.make_branch_and_tree('new_tree')
576
585
 
577
 
        new_tree.commit('Commit one', rev_id=b'new_r1')
578
 
        new_tree.commit('Commit two', rev_id=b'new_r2')
579
 
        new_tree.commit('Commit three', rev_id=b'new_r3')
 
586
        new_tree.commit('Commit one', rev_id='new_r1')
 
587
        new_tree.commit('Commit two', rev_id='new_r2')
 
588
        new_tree.commit('Commit three', rev_id='new_r3')
580
589
 
581
590
        # With no common ancestor, we should raise another user error
582
591
        self.assertRaises(errors.NoCommonAncestor,
593
602
                                           new_tree.branch)
594
603
 
595
604
    def test_as_revision_id(self):
596
 
        self.assertAsRevisionId(b'alt_r2', 'ancestor:tree2')
 
605
        self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
597
606
 
598
607
    def test_default(self):
599
608
        # We don't have a parent to default to
601
610
                          'ancestor:')
602
611
 
603
612
        # Create a branch with a parent to default to
604
 
        tree3 = self.tree.controldir.sprout('tree3').open_workingtree()
605
 
        tree3.commit('foo', rev_id=b'r3')
 
613
        tree3 = self.tree.bzrdir.sprout('tree3').open_workingtree()
 
614
        tree3.commit('foo', rev_id='r3')
606
615
        self.tree = tree3
607
 
        self.assertInHistoryIs(2, b'r2', 'ancestor:')
 
616
        self.assertInHistoryIs(2, 'r2', 'ancestor:')
608
617
 
609
618
 
610
619
class TestRevisionSpec_branch(TestRevisionSpec):
616
625
                          self.get_in_history, 'branch:tree2/a')
617
626
 
618
627
    def test_simple(self):
619
 
        self.assertInHistoryIs(None, b'alt_r2', 'branch:tree2')
 
628
        self.assertInHistoryIs(None, 'alt_r2', 'branch:tree2')
620
629
 
621
630
    def test_self(self):
622
 
        self.assertInHistoryIs(2, b'r2', 'branch:tree')
 
631
        self.assertInHistoryIs(2, 'r2', 'branch:tree')
623
632
 
624
633
    def test_unrelated(self):
625
634
        new_tree = self.make_branch_and_tree('new_tree')
626
635
 
627
 
        new_tree.commit('Commit one', rev_id=b'new_r1')
628
 
        new_tree.commit('Commit two', rev_id=b'new_r2')
629
 
        new_tree.commit('Commit three', rev_id=b'new_r3')
 
636
        new_tree.commit('Commit one', rev_id='new_r1')
 
637
        new_tree.commit('Commit two', rev_id='new_r2')
 
638
        new_tree.commit('Commit three', rev_id='new_r3')
630
639
 
631
 
        self.assertInHistoryIs(None, b'new_r3', 'branch:new_tree')
 
640
        self.assertInHistoryIs(None, 'new_r3', 'branch:new_tree')
632
641
 
633
642
        # XXX: Right now, we use fetch() to make sure the remote revisions
634
643
        # have been pulled into the local branch. We may change that
635
644
        # behavior in the future.
636
 
        self.assertTrue(self.tree.branch.repository.has_revision(b'new_r3'))
 
645
        self.assertTrue(self.tree.branch.repository.has_revision('new_r3'))
637
646
 
638
647
    def test_no_commits(self):
639
 
        self.make_branch_and_tree('new_tree')
 
648
        new_tree = self.make_branch_and_tree('new_tree')
640
649
        self.assertRaises(errors.NoCommits,
641
650
                          self.get_in_history, 'branch:new_tree')
642
651
        self.assertRaises(errors.NoCommits,
643
652
                          self.get_as_tree, 'branch:new_tree')
644
653
 
645
654
    def test_as_revision_id(self):
646
 
        self.assertAsRevisionId(b'alt_r2', 'branch:tree2')
 
655
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
647
656
 
648
657
    def test_as_tree(self):
649
658
        tree = self.get_as_tree('branch:tree', self.tree2)
650
 
        self.assertEqual(b'r2', tree.get_revision_id())
651
 
        self.assertFalse(self.tree2.branch.repository.has_revision(b'r2'))
 
659
        self.assertEqual('r2', tree.get_revision_id())
 
660
        self.assertFalse(self.tree2.branch.repository.has_revision('r2'))
652
661
 
653
662
 
654
663
class TestRevisionSpec_submit(TestRevisionSpec):
658
667
        self.assertRaises(errors.NoSubmitBranch, self.get_in_history,
659
668
                          'submit:')
660
669
        self.tree.branch.set_parent('../tree2')
661
 
        self.assertInHistoryIs(None, b'alt_r2', 'submit:')
 
670
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
662
671
        self.tree.branch.set_parent('bogus')
663
672
        self.assertRaises(errors.NotBranchError, self.get_in_history,
664
 
                          'submit:')
 
673
            'submit:')
665
674
        # submit branch overrides parent branch
666
675
        self.tree.branch.set_submit_branch('tree2')
667
 
        self.assertInHistoryIs(None, b'alt_r2', 'submit:')
 
676
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
668
677
 
669
678
    def test_as_revision_id(self):
670
679
        self.tree.branch.set_submit_branch('tree2')
671
 
        self.assertAsRevisionId(b'alt_r2', 'branch:tree2')
 
680
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
672
681
 
673
682
 
674
683
class TestRevisionSpec_mainline(TestRevisionSpec):
675
684
 
676
685
    def test_as_revision_id(self):
677
 
        self.assertAsRevisionId(b'r1', 'mainline:1')
678
 
        self.assertAsRevisionId(b'r2', 'mainline:1.1.1')
679
 
        self.assertAsRevisionId(b'r2', 'mainline:revid:alt_r2')
 
686
        self.assertAsRevisionId('r1', 'mainline:1')
 
687
        self.assertAsRevisionId('r2', 'mainline:1.1.1')
 
688
        self.assertAsRevisionId('r2', 'mainline:revid:alt_r2')
680
689
        spec = RevisionSpec.from_string('mainline:revid:alt_r22')
681
690
        e = self.assertRaises(errors.InvalidRevisionSpec,
682
691
                              spec.as_revision_id, self.tree.branch)
683
692
        self.assertContainsRe(str(e),
684
 
                              "Requested revision: 'mainline:revid:alt_r22' does not exist in"
685
 
                              " branch: ")
 
693
            "Requested revision: 'mainline:revid:alt_r22' does not exist in"
 
694
            " branch: ")
686
695
 
687
696
    def test_in_history(self):
688
 
        self.assertInHistoryIs(2, b'r2', 'mainline:revid:alt_r2')
 
697
        self.assertInHistoryIs(2, 'r2', 'mainline:revid:alt_r2')
689
698
 
690
699
 
691
700
class TestRevisionSpec_annotate(TestRevisionSpec):
693
702
    def setUp(self):
694
703
        super(TestRevisionSpec_annotate, self).setUp()
695
704
        self.tree = self.make_branch_and_tree('annotate-tree')
696
 
        self.build_tree_contents([('annotate-tree/file1', b'1\n')])
 
705
        self.build_tree_contents([('annotate-tree/file1', '1\n')])
697
706
        self.tree.add('file1')
698
 
        self.tree.commit('r1', rev_id=b'r1')
699
 
        self.build_tree_contents([('annotate-tree/file1', b'2\n1\n')])
700
 
        self.tree.commit('r2', rev_id=b'r2')
701
 
        self.build_tree_contents([('annotate-tree/file1', b'2\n1\n3\n')])
 
707
        self.tree.commit('r1', rev_id='r1')
 
708
        self.build_tree_contents([('annotate-tree/file1', '2\n1\n')])
 
709
        self.tree.commit('r2', rev_id='r2')
 
710
        self.build_tree_contents([('annotate-tree/file1', '2\n1\n3\n')])
702
711
 
703
712
    def test_as_revision_id_r1(self):
704
 
        self.assertAsRevisionId(b'r1', 'annotate:annotate-tree/file1:2')
 
713
        self.assertAsRevisionId('r1', 'annotate:annotate-tree/file1:2')
705
714
 
706
715
    def test_as_revision_id_r2(self):
707
 
        self.assertAsRevisionId(b'r2', 'annotate:annotate-tree/file1:1')
 
716
        self.assertAsRevisionId('r2', 'annotate:annotate-tree/file1:1')
708
717
 
709
718
    def test_as_revision_id_uncommitted(self):
710
719
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:3')
711
720
        e = self.assertRaises(errors.InvalidRevisionSpec,
712
721
                              spec.as_revision_id, self.tree.branch)
713
722
        self.assertContainsRe(str(e),
714
 
                              r"Requested revision: \'annotate:annotate-tree/file1:3\' does not"
715
 
                              " exist in branch: .*\nLine 3 has not been committed.")
 
723
            r"Requested revision: \'annotate:annotate-tree/file1:3\' does not"
 
724
            " exist in branch: .*\nLine 3 has not been committed.")
716
725
 
717
726
    def test_non_existent_line(self):
718
727
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:4')
719
728
        e = self.assertRaises(errors.InvalidRevisionSpec,
720
729
                              spec.as_revision_id, self.tree.branch)
721
730
        self.assertContainsRe(str(e),
722
 
                              r"Requested revision: \'annotate:annotate-tree/file1:4\' does not"
723
 
                              " exist in branch: .*\nNo such line: 4")
 
731
            r"Requested revision: \'annotate:annotate-tree/file1:4\' does not"
 
732
            " exist in branch: .*\nNo such line: 4")
724
733
 
725
734
    def test_invalid_line(self):
726
735
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:q')
727
736
        e = self.assertRaises(errors.InvalidRevisionSpec,
728
737
                              spec.as_revision_id, self.tree.branch)
729
738
        self.assertContainsRe(str(e),
730
 
                              r"Requested revision: \'annotate:annotate-tree/file1:q\' does not"
731
 
                              " exist in branch: .*\nNo such line: q")
 
739
            r"Requested revision: \'annotate:annotate-tree/file1:q\' does not"
 
740
            " exist in branch: .*\nNo such line: q")
732
741
 
733
742
    def test_no_such_file(self):
734
743
        spec = RevisionSpec.from_string('annotate:annotate-tree/file2:1')
735
744
        e = self.assertRaises(errors.InvalidRevisionSpec,
736
745
                              spec.as_revision_id, self.tree.branch)
737
746
        self.assertContainsRe(str(e),
738
 
                              r"Requested revision: \'annotate:annotate-tree/file2:1\' does not"
739
 
                              " exist in branch: .*\nFile 'file2' is not versioned")
 
747
            r"Requested revision: \'annotate:annotate-tree/file2:1\' does not"
 
748
            " exist in branch: .*\nFile 'file2' is not versioned")
740
749
 
741
750
    def test_no_such_file_with_colon(self):
742
751
        spec = RevisionSpec.from_string('annotate:annotate-tree/fi:le2:1')
743
752
        e = self.assertRaises(errors.InvalidRevisionSpec,
744
753
                              spec.as_revision_id, self.tree.branch)
745
754
        self.assertContainsRe(str(e),
746
 
                              r"Requested revision: \'annotate:annotate-tree/fi:le2:1\' does not"
747
 
                              " exist in branch: .*\nFile 'fi:le2' is not versioned")
 
755
            r"Requested revision: \'annotate:annotate-tree/fi:le2:1\' does not"
 
756
            " exist in branch: .*\nFile 'fi:le2' is not versioned")