~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_revisionnamespaces.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-03-28 06:58:22 UTC
  • mfrom: (2379.2.3 hpss-chroot)
  • Revision ID: pqm@pqm.ubuntu.com-20070328065822-999550a858a3ced3
(robertc) Fix chroot urls to not expose the url of the transport they are protecting, allowing regular url operations to work on them. (Robert Collins, Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import datetime
 
18
import os
18
19
import time
19
20
 
20
21
from bzrlib import (
 
22
    branch,
 
23
    bzrdir,
21
24
    errors,
22
 
    revision as _mod_revision,
23
 
    symbol_versioning,
 
25
    repository,
24
26
    )
25
 
from bzrlib.tests import TestCaseWithTransport
 
27
from bzrlib.builtins import merge
 
28
from bzrlib.tests import TestCase, TestCaseWithTransport
26
29
from bzrlib.revisionspec import (
27
 
    RevisionInfo,
28
30
    RevisionSpec,
29
 
    RevisionSpec_dwim,
 
31
    RevisionSpec_revno,
30
32
    RevisionSpec_tag,
31
33
    )
32
34
 
48
50
 
49
51
        self.tree = self.make_branch_and_tree('tree')
50
52
        self.build_tree(['tree/a'])
51
 
        self.tree.lock_write()
52
 
        self.addCleanup(self.tree.unlock)
53
53
        self.tree.add(['a'])
54
54
        self.tree.commit('a', rev_id='r1')
55
55
 
56
56
        self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
57
57
        self.tree2.commit('alt', rev_id='alt_r2')
58
58
 
59
 
        self.tree.merge_from_branch(self.tree2.branch)
 
59
        self.tree.branch.repository.fetch(self.tree2.branch.repository,
 
60
                                          revision_id='alt_r2')
 
61
        self.tree.set_pending_merges(['alt_r2'])
60
62
        self.tree.commit('second', rev_id='r2')
61
63
 
62
64
    def get_in_history(self, revision_spec):
72
74
                         ' %r != %r'
73
75
                         % (revision_spec, exp_revision_id, rev_info.rev_id))
74
76
 
75
 
    def assertInvalid(self, revision_spec, extra='',
76
 
                      invalid_as_revision_id=True):
 
77
    def assertInvalid(self, revision_spec, extra=''):
77
78
        try:
78
79
            self.get_in_history(revision_spec)
79
80
        except errors.InvalidRevisionSpec, e:
80
81
            self.assertEqual(revision_spec, e.spec)
81
82
            self.assertEqual(extra, e.extra)
82
83
        else:
83
 
            self.fail('Expected InvalidRevisionSpec to be raised for'
84
 
                      ' %r.in_history' % (revision_spec,))
85
 
        if invalid_as_revision_id:
86
 
            try:
87
 
                spec = RevisionSpec.from_string(revision_spec)
88
 
                spec.as_revision_id(self.tree.branch)
89
 
            except errors.InvalidRevisionSpec, e:
90
 
                self.assertEqual(revision_spec, e.spec)
91
 
                self.assertEqual(extra, e.extra)
92
 
            else:
93
 
                self.fail('Expected InvalidRevisionSpec to be raised for'
94
 
                          ' %r.as_revision_id' % (revision_spec,))
95
 
 
96
 
    def assertAsRevisionId(self, revision_id, revision_spec):
97
 
        """Calling as_revision_id() should return the specified id."""
98
 
        spec = RevisionSpec.from_string(revision_spec)
99
 
        self.assertEqual(revision_id,
100
 
                         spec.as_revision_id(self.tree.branch))
101
 
 
102
 
    def get_as_tree(self, revision_spec, tree=None):
103
 
        if tree is None:
104
 
            tree = self.tree
105
 
        spec = RevisionSpec.from_string(revision_spec)
106
 
        return spec.as_tree(tree.branch)
107
 
 
108
 
 
109
 
class RevisionSpecMatchOnTrap(RevisionSpec):
110
 
 
111
 
    def _match_on(self, branch, revs):
112
 
        self.last_call = (branch, revs)
113
 
        return super(RevisionSpecMatchOnTrap, self)._match_on(branch, revs)
114
 
 
115
 
 
116
 
class TestRevisionSpecBase(TestRevisionSpec):
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
 
 
130
 
    def test_wants_no_revision_history(self):
131
 
        # If wants_revision_history = False, then _match_on should get None for
132
 
        # the branch revision history
133
 
        spec = RevisionSpecMatchOnTrap('foo', _internal=True)
134
 
        spec.in_history(self.tree.branch)
135
 
 
136
 
        self.assertEqual((self.tree.branch, None), spec.last_call)
137
 
 
 
84
            self.fail('Expected InvalidRevisionSpec to be raised for %s'
 
85
                      % (revision_spec,))
138
86
 
139
87
 
140
88
class TestOddRevisionSpec(TestRevisionSpec):
141
89
    """Test things that aren't normally thought of as revision specs"""
142
90
 
143
91
    def test_none(self):
144
 
        self.assertInHistoryIs(None, None, None)
 
92
        self.assertInHistoryIs(0, None, None)
145
93
 
146
94
    def test_object(self):
147
95
        self.assertRaises(TypeError, RevisionSpec.from_string, object())
148
96
 
149
 
 
150
 
class RevisionSpec_bork(RevisionSpec):
151
 
 
152
 
    prefix = 'irrelevant:'
153
 
 
154
 
    def _match_on(self, branch, revs):
155
 
        if self.spec == "bork":
156
 
            return RevisionInfo.from_revision_id(branch, "r1")
157
 
        else:
158
 
            raise errors.InvalidRevisionSpec(self.spec, branch)
159
 
 
160
 
 
161
 
class TestRevisionSpec_dwim(TestRevisionSpec):
162
 
 
163
 
    # Don't need to test revno's explicitly since TRS_revno already
164
 
    # covers that well for us
165
 
    def test_dwim_spec_revno(self):
166
 
        self.assertInHistoryIs(2, 'r2', '2')
167
 
        self.assertAsRevisionId('alt_r2', '1.1.1')
168
 
 
169
 
    def test_dwim_spec_revid(self):
170
 
        self.assertInHistoryIs(2, 'r2', 'r2')
171
 
 
172
 
    def test_dwim_spec_tag(self):
173
 
        self.tree.branch.tags.set_tag('footag', 'r1')
174
 
        self.assertAsRevisionId('r1', 'footag')
175
 
        self.tree.branch.tags.delete_tag('footag')
176
 
        self.assertRaises(errors.InvalidRevisionSpec,
177
 
                          self.get_in_history, 'footag')
178
 
 
179
 
    def test_dwim_spec_tag_that_looks_like_revno(self):
180
 
        # Test that we slip past revno with things that look like revnos,
181
 
        # but aren't.  Tags are convenient for testing this since we can
182
 
        # make them look however we want.
183
 
        self.tree.branch.tags.set_tag('3', 'r2')
184
 
        self.assertAsRevisionId('r2', '3')
185
 
        self.build_tree(['tree/b'])
186
 
        self.tree.add(['b'])
187
 
        self.tree.commit('b', rev_id='r3')
188
 
        self.assertAsRevisionId('r3', '3')
189
 
 
190
 
    def test_dwim_spec_date(self):
191
 
        self.assertAsRevisionId('r1', 'today')
192
 
 
193
 
    def test_dwim_spec_branch(self):
194
 
        self.assertInHistoryIs(None, 'alt_r2', 'tree2')
195
 
 
196
 
    def test_dwim_spec_nonexistent(self):
197
 
        self.assertInvalid('somethingrandom', invalid_as_revision_id=False)
198
 
        self.assertInvalid('-1.1', invalid_as_revision_id=False)
199
 
        self.assertInvalid('.1', invalid_as_revision_id=False)
200
 
        self.assertInvalid('1..1', invalid_as_revision_id=False)
201
 
        self.assertInvalid('1.2..1', invalid_as_revision_id=False)
202
 
        self.assertInvalid('1.', invalid_as_revision_id=False)
203
 
 
204
 
    def test_append_dwim_revspec(self):
205
 
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
206
 
        def reset_dwim_revspecs():
207
 
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
208
 
        self.addCleanup(reset_dwim_revspecs)
209
 
        RevisionSpec_dwim.append_possible_revspec(RevisionSpec_bork)
210
 
        self.assertAsRevisionId('r1', 'bork')
211
 
 
212
 
    def test_append_lazy_dwim_revspec(self):
213
 
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
214
 
        def reset_dwim_revspecs():
215
 
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
216
 
        self.addCleanup(reset_dwim_revspecs)
217
 
        RevisionSpec_dwim.append_possible_lazy_revspec(
218
 
            "bzrlib.tests.test_revisionspec", "RevisionSpec_bork")
219
 
        self.assertAsRevisionId('r1', 'bork')
 
97
    def test_unregistered_spec(self):
 
98
        self.assertRaises(errors.NoSuchRevisionSpec,
 
99
                          RevisionSpec.from_string, 'foo')
 
100
        self.assertRaises(errors.NoSuchRevisionSpec,
 
101
                          RevisionSpec.from_string, '123a')
 
102
 
 
103
 
 
104
 
 
105
class TestRevnoFromString(TestCase):
 
106
 
 
107
    def test_from_string_dotted_decimal(self):
 
108
        self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '-1.1')
 
109
        self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '.1')
 
110
        self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1..1')
 
111
        self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1.2..1')
 
112
        self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1.')
 
113
        self.assertIsInstance(RevisionSpec.from_string('1.1'), RevisionSpec_revno)
 
114
        self.assertIsInstance(RevisionSpec.from_string('1.1.3'), RevisionSpec_revno)
220
115
 
221
116
 
222
117
class TestRevisionSpec_revno(TestRevisionSpec):
223
118
 
224
119
    def test_positive_int(self):
225
 
        self.assertInHistoryIs(0, 'null:', '0')
 
120
        self.assertInHistoryIs(0, None, '0')
226
121
        self.assertInHistoryIs(1, 'r1', '1')
227
122
        self.assertInHistoryIs(2, 'r2', '2')
228
123
        self.assertInvalid('3')
229
124
 
230
125
    def test_dotted_decimal(self):
231
126
        self.assertInHistoryIs(None, 'alt_r2', '1.1.1')
232
 
        self.assertInvalid('1.1.123')
233
127
 
234
128
    def test_negative_int(self):
235
129
        self.assertInHistoryIs(2, 'r2', '-1')
240
134
        self.assertInHistoryIs(1, 'r1', '-100')
241
135
 
242
136
    def test_positive(self):
243
 
        self.assertInHistoryIs(0, 'null:', 'revno:0')
 
137
        self.assertInHistoryIs(0, None, 'revno:0')
244
138
        self.assertInHistoryIs(1, 'r1', 'revno:1')
245
139
        self.assertInHistoryIs(2, 'r2', 'revno:2')
246
140
 
329
223
        """Old revno:N:path tests"""
330
224
        wta = self.make_branch_and_tree('a')
331
225
        ba = wta.branch
332
 
 
 
226
        
333
227
        wta.commit('Commit one', rev_id='a@r-0-1')
334
228
        wta.commit('Commit two', rev_id='a@r-0-2')
335
229
        wta.commit('Commit three', rev_id='a@r-0-3')
353
247
        self.assertEqual((2, 'b@r-0-2'),
354
248
                         spec_in_history('revno:2:b/', None))
355
249
 
356
 
    def test_as_revision_id(self):
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')
363
 
 
364
 
    def test_as_tree(self):
365
 
        tree = self.get_as_tree('0')
366
 
        self.assertEqual(_mod_revision.NULL_REVISION, tree.get_revision_id())
367
 
        tree = self.get_as_tree('1')
368
 
        self.assertEqual('r1', tree.get_revision_id())
369
 
        tree = self.get_as_tree('2')
370
 
        self.assertEqual('r2', tree.get_revision_id())
371
 
        tree = self.get_as_tree('-2')
372
 
        self.assertEqual('r1', tree.get_revision_id())
373
 
        tree = self.get_as_tree('-1')
374
 
        self.assertEqual('r2', tree.get_revision_id())
375
 
        tree = self.get_as_tree('1.1.1')
376
 
        self.assertEqual('alt_r2', tree.get_revision_id())
377
250
 
378
251
 
379
252
class TestRevisionSpec_revid(TestRevisionSpec):
380
 
 
 
253
    
381
254
    def test_in_history(self):
382
255
        # We should be able to access revisions that are directly
383
256
        # in the history.
384
257
        self.assertInHistoryIs(1, 'r1', 'revid:r1')
385
258
        self.assertInHistoryIs(2, 'r2', 'revid:r2')
386
 
 
 
259
        
387
260
    def test_missing(self):
388
 
        self.assertInvalid('revid:r3', invalid_as_revision_id=False)
 
261
        self.assertInvalid('revid:r3')
389
262
 
390
263
    def test_merged(self):
391
264
        """We can reach revisions in the ancestry"""
394
267
    def test_not_here(self):
395
268
        self.tree2.commit('alt third', rev_id='alt_r3')
396
269
        # It exists in tree2, but not in tree
397
 
        self.assertInvalid('revid:alt_r3', invalid_as_revision_id=False)
 
270
        self.assertInvalid('revid:alt_r3')
398
271
 
399
272
    def test_in_repository(self):
400
273
        """We can get any revision id in the repository"""
401
274
        # XXX: This may change in the future, but for now, it is true
402
275
        self.tree2.commit('alt third', rev_id='alt_r3')
403
 
        self.tree.branch.fetch(self.tree2.branch, 'alt_r3')
 
276
        self.tree.branch.repository.fetch(self.tree2.branch.repository,
 
277
                                          revision_id='alt_r3')
404
278
        self.assertInHistoryIs(None, 'alt_r3', 'revid:alt_r3')
405
279
 
406
280
    def test_unicode(self):
410
284
        self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
411
285
        self.assertInHistoryIs(3, revision_id, 'revid:' + revision_id)
412
286
 
413
 
    def test_as_revision_id(self):
414
 
        self.assertAsRevisionId('r1', 'revid:r1')
415
 
        self.assertAsRevisionId('r2', 'revid:r2')
416
 
        self.assertAsRevisionId('alt_r2', 'revid:alt_r2')
417
 
 
418
287
 
419
288
class TestRevisionSpec_last(TestRevisionSpec):
420
289
 
421
290
    def test_positive(self):
422
291
        self.assertInHistoryIs(2, 'r2', 'last:1')
423
292
        self.assertInHistoryIs(1, 'r1', 'last:2')
424
 
        self.assertInHistoryIs(0, 'null:', 'last:3')
 
293
        self.assertInHistoryIs(0, None, 'last:3')
425
294
 
426
295
    def test_empty(self):
427
296
        self.assertInHistoryIs(2, 'r2', 'last:')
446
315
            pass
447
316
        self.assertInvalid('last:Y', extra='\n' + str(e))
448
317
 
449
 
    def test_as_revision_id(self):
450
 
        self.assertAsRevisionId('r2', 'last:1')
451
 
        self.assertAsRevisionId('r1', 'last:2')
452
 
 
453
318
 
454
319
class TestRevisionSpec_before(TestRevisionSpec):
455
320
 
458
323
        self.assertInHistoryIs(1, 'r1', 'before:-1')
459
324
 
460
325
    def test_before_one(self):
461
 
        self.assertInHistoryIs(0, 'null:', 'before:1')
 
326
        self.assertInHistoryIs(0, None, 'before:1')
462
327
 
463
328
    def test_before_none(self):
464
329
        self.assertInvalid('before:0',
477
342
    def test_alt_no_parents(self):
478
343
        new_tree = self.make_branch_and_tree('new_tree')
479
344
        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')
482
 
 
483
 
    def test_as_revision_id(self):
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')
 
345
        self.tree.branch.repository.fetch(new_tree.branch.repository,
 
346
                                          revision_id='new_r1')
 
347
        self.assertInHistoryIs(0, None, 'before:revid:new_r1')
488
348
 
489
349
 
490
350
class TestRevisionSpec_tag(TestRevisionSpec):
491
 
 
 
351
    
492
352
    def make_branch_and_tree(self, relpath):
493
353
        # override format as the default one may not support tags
494
 
        return TestRevisionSpec.make_branch_and_tree(
495
 
            self, relpath, format='dirstate-tags')
 
354
        control = bzrdir.BzrDir.create(relpath)
 
355
        control.create_repository()
 
356
        branch.BzrBranchExperimental.initialize(control)
 
357
        return control.create_workingtree()
496
358
 
497
359
    def test_from_string_tag(self):
498
360
        spec = RevisionSpec.from_string('tag:bzr-0.14')
502
364
    def test_lookup_tag(self):
503
365
        self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
504
366
        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')
507
367
 
508
368
    def test_failed_lookup(self):
509
369
        # tags that don't exist give a specific message: arguably we should
512
372
            self.get_in_history,
513
373
            'tag:some-random-tag')
514
374
 
515
 
    def test_as_revision_id(self):
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')
521
 
 
522
375
 
523
376
class TestRevisionSpec_date(TestRevisionSpec):
524
377
 
555
408
        self.assertInHistoryIs(2, 'new_r2',
556
409
            'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
557
410
 
558
 
    def test_as_revision_id(self):
559
 
        self.assertAsRevisionId('new_r2', 'date:today')
560
 
 
561
411
 
562
412
class TestRevisionSpec_ancestor(TestRevisionSpec):
563
 
 
 
413
    
564
414
    def test_non_exact_branch(self):
565
415
        # It seems better to require an exact path to the branch
566
416
        # Branch.open() rather than using Branch.open_containing()
596
446
        self.assertRaises(errors.NoCommits,
597
447
                          spec_in_history, 'ancestor:new_tree',
598
448
                                           self.tree.branch)
599
 
 
 
449
                        
600
450
        self.assertRaises(errors.NoCommits,
601
451
                          spec_in_history, 'ancestor:tree',
602
452
                                           new_tree.branch)
603
453
 
604
 
    def test_as_revision_id(self):
605
 
        self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
606
 
 
607
 
    def test_default(self):
608
 
        # We don't have a parent to default to
609
 
        self.assertRaises(errors.NotBranchError, self.get_in_history,
610
 
                          'ancestor:')
611
 
 
612
 
        # Create a branch with a parent to default to
613
 
        tree3 = self.tree.bzrdir.sprout('tree3').open_workingtree()
614
 
        tree3.commit('foo', rev_id='r3')
615
 
        self.tree = tree3
616
 
        self.assertInHistoryIs(2, 'r2', 'ancestor:')
617
 
 
618
454
 
619
455
class TestRevisionSpec_branch(TestRevisionSpec):
620
 
 
 
456
    
621
457
    def test_non_exact_branch(self):
622
458
        # It seems better to require an exact path to the branch
623
459
        # Branch.open() rather than using Branch.open_containing()
642
478
        # XXX: Right now, we use fetch() to make sure the remote revisions
643
479
        # have been pulled into the local branch. We may change that
644
480
        # behavior in the future.
645
 
        self.assertTrue(self.tree.branch.repository.has_revision('new_r3'))
 
481
        self.failUnless(self.tree.branch.repository.has_revision('new_r3'))
646
482
 
647
483
    def test_no_commits(self):
648
484
        new_tree = self.make_branch_and_tree('new_tree')
649
485
        self.assertRaises(errors.NoCommits,
650
486
                          self.get_in_history, 'branch:new_tree')
651
 
        self.assertRaises(errors.NoCommits,
652
 
                          self.get_as_tree, 'branch:new_tree')
653
 
 
654
 
    def test_as_revision_id(self):
655
 
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
656
 
 
657
 
    def test_as_tree(self):
658
 
        tree = self.get_as_tree('branch:tree', self.tree2)
659
 
        self.assertEqual('r2', tree.get_revision_id())
660
 
        self.assertFalse(self.tree2.branch.repository.has_revision('r2'))
661
487
 
662
488
 
663
489
class TestRevisionSpec_submit(TestRevisionSpec):
674
500
        # submit branch overrides parent branch
675
501
        self.tree.branch.set_submit_branch('tree2')
676
502
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
677
 
 
678
 
    def test_as_revision_id(self):
679
 
        self.tree.branch.set_submit_branch('tree2')
680
 
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
681
 
 
682
 
 
683
 
class TestRevisionSpec_mainline(TestRevisionSpec):
684
 
 
685
 
    def test_as_revision_id(self):
686
 
        self.assertAsRevisionId('r1', 'mainline:1')
687
 
        self.assertAsRevisionId('r2', 'mainline:1.1.1')
688
 
        self.assertAsRevisionId('r2', 'mainline:revid:alt_r2')
689
 
        spec = RevisionSpec.from_string('mainline:revid:alt_r22')
690
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
691
 
                              spec.as_revision_id, self.tree.branch)
692
 
        self.assertContainsRe(str(e),
693
 
            "Requested revision: 'mainline:revid:alt_r22' does not exist in"
694
 
            " branch: ")
695
 
 
696
 
    def test_in_history(self):
697
 
        self.assertInHistoryIs(2, 'r2', 'mainline:revid:alt_r2')
698
 
 
699
 
 
700
 
class TestRevisionSpec_annotate(TestRevisionSpec):
701
 
 
702
 
    def setUp(self):
703
 
        super(TestRevisionSpec_annotate, self).setUp()
704
 
        self.tree = self.make_branch_and_tree('annotate-tree')
705
 
        self.build_tree_contents([('annotate-tree/file1', '1\n')])
706
 
        self.tree.add('file1')
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')])
711
 
 
712
 
    def test_as_revision_id_r1(self):
713
 
        self.assertAsRevisionId('r1', 'annotate:annotate-tree/file1:2')
714
 
 
715
 
    def test_as_revision_id_r2(self):
716
 
        self.assertAsRevisionId('r2', 'annotate:annotate-tree/file1:1')
717
 
 
718
 
    def test_as_revision_id_uncommitted(self):
719
 
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:3')
720
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
721
 
                              spec.as_revision_id, self.tree.branch)
722
 
        self.assertContainsRe(str(e),
723
 
            r"Requested revision: \'annotate:annotate-tree/file1:3\' does not"
724
 
            " exist in branch: .*\nLine 3 has not been committed.")
725
 
 
726
 
    def test_non_existent_line(self):
727
 
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:4')
728
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
729
 
                              spec.as_revision_id, self.tree.branch)
730
 
        self.assertContainsRe(str(e),
731
 
            r"Requested revision: \'annotate:annotate-tree/file1:4\' does not"
732
 
            " exist in branch: .*\nNo such line: 4")
733
 
 
734
 
    def test_invalid_line(self):
735
 
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:q')
736
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
737
 
                              spec.as_revision_id, self.tree.branch)
738
 
        self.assertContainsRe(str(e),
739
 
            r"Requested revision: \'annotate:annotate-tree/file1:q\' does not"
740
 
            " exist in branch: .*\nNo such line: q")
741
 
 
742
 
    def test_no_such_file(self):
743
 
        spec = RevisionSpec.from_string('annotate:annotate-tree/file2:1')
744
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
745
 
                              spec.as_revision_id, self.tree.branch)
746
 
        self.assertContainsRe(str(e),
747
 
            r"Requested revision: \'annotate:annotate-tree/file2:1\' does not"
748
 
            " exist in branch: .*\nFile 'file2' is not versioned")
749
 
 
750
 
    def test_no_such_file_with_colon(self):
751
 
        spec = RevisionSpec.from_string('annotate:annotate-tree/fi:le2:1')
752
 
        e = self.assertRaises(errors.InvalidRevisionSpec,
753
 
                              spec.as_revision_id, self.tree.branch)
754
 
        self.assertContainsRe(str(e),
755
 
            r"Requested revision: \'annotate:annotate-tree/fi:le2:1\' does not"
756
 
            " exist in branch: .*\nFile 'fi:le2' is not versioned")