~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2005-2011 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
897 by Martin Pool
- merge john's revision-naming code
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
897 by Martin Pool
- merge john's revision-naming code
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
897 by Martin Pool
- merge john's revision-naming code
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
897 by Martin Pool
- merge john's revision-naming code
16
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
17
import datetime
1185.1.39 by Robert Collins
Robey Pointers before: namespace to clear up usage of dates in revision parameters
18
import time
1432 by Robert Collins
branch: namespace
19
1948.4.1 by John Arbash Meinel
Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers
20
from bzrlib import (
21
    errors,
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
22
    revision as _mod_revision,
1948.4.1 by John Arbash Meinel
Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers
23
    )
5579.3.1 by Jelmer Vernooij
Remove unused imports.
24
from bzrlib.tests import TestCaseWithTransport
2220.2.3 by Martin Pool
Add tag: revision namespace.
25
from bzrlib.revisionspec import (
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
26
    RevisionInfo,
2220.2.3 by Martin Pool
Add tag: revision namespace.
27
    RevisionSpec,
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
28
    RevisionSpec_dwim,
2220.2.3 by Martin Pool
Add tag: revision namespace.
29
    RevisionSpec_tag,
30
    )
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
31
32
33
def spec_in_history(spec, branch):
34
    """A simple helper to change a revision spec into a branch search"""
35
    return RevisionSpec.from_string(spec).in_history(branch)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
36
37
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
38
# Basic class, which just creates a really basic set of revisions
39
class TestRevisionSpec(TestCaseWithTransport):
40
41
    def setUp(self):
42
        super(TestRevisionSpec, self).setUp()
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
43
        # this sets up a revision graph:
44
        # r1: []             1
45
        # alt_r2: [r1]       1.1.1
46
        # r2: [r1, alt_r2]   2
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
47
48
        self.tree = self.make_branch_and_tree('tree')
49
        self.build_tree(['tree/a'])
3298.2.3 by John Arbash Meinel
Add tests that all RevisionSpecs implement in_branch(b, needs_revno)
50
        self.tree.lock_write()
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
51
        self.addCleanup(self.tree.unlock)
52
        self.tree.add(['a'])
53
        self.tree.commit('a', rev_id='r1')
54
55
        self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
56
        self.tree2.commit('alt', rev_id='alt_r2')
57
58
        self.tree.merge_from_branch(self.tree2.branch)
59
        self.tree.commit('second', rev_id='r2')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
60
61
    def get_in_history(self, revision_spec):
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
62
        return spec_in_history(revision_spec, self.tree.branch)
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
63
64
    def assertInHistoryIs(self, exp_revno, exp_revision_id, revision_spec):
65
        rev_info = self.get_in_history(revision_spec)
66
        self.assertEqual(exp_revno, rev_info.revno,
2325.2.1 by Marien Zwart
Make the test suite failure reporting a bit more robust.
67
                         'Revision spec: %r returned wrong revno: %r != %r'
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
68
                         % (revision_spec, exp_revno, rev_info.revno))
69
        self.assertEqual(exp_revision_id, rev_info.rev_id,
2325.2.1 by Marien Zwart
Make the test suite failure reporting a bit more robust.
70
                         'Revision spec: %r returned wrong revision id:'
71
                         ' %r != %r'
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
72
                         % (revision_spec, exp_revision_id, rev_info.rev_id))
73
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
74
    def assertInvalid(self, revision_spec, extra='',
75
                      invalid_as_revision_id=True):
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
76
        try:
77
            self.get_in_history(revision_spec)
78
        except errors.InvalidRevisionSpec, e:
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
79
            self.assertEqual(revision_spec, e.spec)
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
80
            self.assertEqual(extra, e.extra)
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
81
        else:
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
82
            self.fail('Expected InvalidRevisionSpec to be raised for'
83
                      ' %r.in_history' % (revision_spec,))
84
        if invalid_as_revision_id:
85
            try:
86
                spec = RevisionSpec.from_string(revision_spec)
87
                spec.as_revision_id(self.tree.branch)
88
            except errors.InvalidRevisionSpec, e:
89
                self.assertEqual(revision_spec, e.spec)
90
                self.assertEqual(extra, e.extra)
91
            else:
92
                self.fail('Expected InvalidRevisionSpec to be raised for'
3495.1.2 by John Arbash Meinel
tweak
93
                          ' %r.as_revision_id' % (revision_spec,))
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
94
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
95
    def assertAsRevisionId(self, revision_id, revision_spec):
96
        """Calling as_revision_id() should return the specified id."""
97
        spec = RevisionSpec.from_string(revision_spec)
98
        self.assertEqual(revision_id,
99
                         spec.as_revision_id(self.tree.branch))
100
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
101
    def get_as_tree(self, revision_spec, tree=None):
102
        if tree is None:
103
            tree = self.tree
104
        spec = RevisionSpec.from_string(revision_spec)
105
        return spec.as_tree(tree.branch)
106
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
107
3460.1.2 by John Arbash Meinel
Add a test for wants_revision_history
108
class RevisionSpecMatchOnTrap(RevisionSpec):
109
110
    def _match_on(self, branch, revs):
111
        self.last_call = (branch, revs)
112
        return super(RevisionSpecMatchOnTrap, self)._match_on(branch, revs)
113
114
115
class TestRevisionSpecBase(TestRevisionSpec):
116
117
    def test_wants_revision_history(self):
118
        # If wants_revision_history = True, then _match_on should get the
119
        # branch revision history
120
        spec = RevisionSpecMatchOnTrap('foo', _internal=True)
121
        spec.in_history(self.tree.branch)
122
123
        self.assertEqual((self.tree.branch, ['r1' ,'r2']),
124
                         spec.last_call)
125
126
    def test_wants_no_revision_history(self):
127
        # If wants_revision_history = False, then _match_on should get None for
128
        # the branch revision history
129
        spec = RevisionSpecMatchOnTrap('foo', _internal=True)
130
        spec.wants_revision_history = False
131
        spec.in_history(self.tree.branch)
132
133
        self.assertEqual((self.tree.branch, None), spec.last_call)
134
135
136
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
137
class TestOddRevisionSpec(TestRevisionSpec):
138
    """Test things that aren't normally thought of as revision specs"""
139
140
    def test_none(self):
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
141
        self.assertInHistoryIs(None, None, None)
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
142
143
    def test_object(self):
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
144
        self.assertRaises(TypeError, RevisionSpec.from_string, object())
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
145
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
146
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
147
class RevisionSpec_bork(RevisionSpec):
148
149
    prefix = 'irrelevant:'
150
151
    def _match_on(self, branch, revs):
152
        if self.spec == "bork":
153
            return RevisionInfo.from_revision_id(branch, "r1", revs)
154
        else:
155
            raise errors.InvalidRevisionSpec(self.spec, branch)
156
157
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
158
class TestRevisionSpec_dwim(TestRevisionSpec):
159
160
    # Don't need to test revno's explicitly since TRS_revno already
161
    # covers that well for us
4569.2.11 by Matthew Fuller
Eliminate the TestRevnoFromString() test class by moving all its tests
162
    def test_dwim_spec_revno(self):
163
        self.assertInHistoryIs(2, 'r2', '2')
164
        self.assertAsRevisionId('alt_r2', '1.1.1')
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
165
166
    def test_dwim_spec_revid(self):
167
        self.assertInHistoryIs(2, 'r2', 'r2')
168
169
    def test_dwim_spec_tag(self):
170
        self.tree.branch.tags.set_tag('footag', 'r1')
171
        self.assertAsRevisionId('r1', 'footag')
172
        self.tree.branch.tags.delete_tag('footag')
173
        self.assertRaises(errors.InvalidRevisionSpec,
174
                          self.get_in_history, 'footag')
175
4569.2.16 by Matthew Fuller
Add a test that we slip past the revno-checking stage when we're
176
    def test_dwim_spec_tag_that_looks_like_revno(self):
177
        # Test that we slip past revno with things that look like revnos,
178
        # but aren't.  Tags are convenient for testing this since we can
179
        # make them look however we want.
180
        self.tree.branch.tags.set_tag('3', 'r2')
181
        self.assertAsRevisionId('r2', '3')
182
        self.build_tree(['tree/b'])
183
        self.tree.add(['b'])
184
        self.tree.commit('b', rev_id='r3')
185
        self.assertAsRevisionId('r3', '3')
186
4569.2.4 by Matthew Fuller
Add date: to the list of things DWIM auto-tries.
187
    def test_dwim_spec_date(self):
188
        self.assertAsRevisionId('r1', 'today')
189
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
190
    def test_dwim_spec_branch(self):
191
        self.assertInHistoryIs(None, 'alt_r2', 'tree2')
192
193
    def test_dwim_spec_nonexistent(self):
4569.2.8 by Matthew Fuller
Use a more precise nonexistent thing in test_dwim_spec_nonexistent().
194
        self.assertInvalid('somethingrandom', invalid_as_revision_id=False)
4569.2.11 by Matthew Fuller
Eliminate the TestRevnoFromString() test class by moving all its tests
195
        self.assertInvalid('-1.1', invalid_as_revision_id=False)
196
        self.assertInvalid('.1', invalid_as_revision_id=False)
197
        self.assertInvalid('1..1', invalid_as_revision_id=False)
198
        self.assertInvalid('1.2..1', invalid_as_revision_id=False)
199
        self.assertInvalid('1.', invalid_as_revision_id=False)
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
200
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
201
    def test_append_dwim_revspec(self):
202
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
203
        def reset_dwim_revspecs():
204
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
205
        self.addCleanup(reset_dwim_revspecs)
206
        RevisionSpec_dwim.append_possible_revspec(RevisionSpec_bork)
207
        self.assertAsRevisionId('r1', 'bork')
208
209
    def test_append_lazy_dwim_revspec(self):
210
        original_dwim_revspecs = list(RevisionSpec_dwim._possible_revspecs)
211
        def reset_dwim_revspecs():
212
            RevisionSpec_dwim._possible_revspecs = original_dwim_revspecs
213
        self.addCleanup(reset_dwim_revspecs)
5671.5.3 by Jelmer Vernooij
Fix test.. not sure how I missed this.
214
        RevisionSpec_dwim.append_possible_lazy_revspec(
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
215
            "bzrlib.tests.test_revisionspec", "RevisionSpec_bork")
216
        self.assertAsRevisionId('r1', 'bork')
217
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
218
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
219
class TestRevisionSpec_revno(TestRevisionSpec):
220
221
    def test_positive_int(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
222
        self.assertInHistoryIs(0, 'null:', '0')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
223
        self.assertInHistoryIs(1, 'r1', '1')
224
        self.assertInHistoryIs(2, 'r2', '2')
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
225
        self.assertInvalid('3')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
226
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
227
    def test_dotted_decimal(self):
228
        self.assertInHistoryIs(None, 'alt_r2', '1.1.1')
3878.3.1 by Marius Kruger
Test invalid dotted revion number directly in TestRevisionSpec_revno
229
        self.assertInvalid('1.1.123')
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
230
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
231
    def test_negative_int(self):
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
232
        self.assertInHistoryIs(2, 'r2', '-1')
233
        self.assertInHistoryIs(1, 'r1', '-2')
234
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
235
        self.assertInHistoryIs(1, 'r1', '-3')
236
        self.assertInHistoryIs(1, 'r1', '-4')
237
        self.assertInHistoryIs(1, 'r1', '-100')
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
238
239
    def test_positive(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
240
        self.assertInHistoryIs(0, 'null:', 'revno:0')
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
241
        self.assertInHistoryIs(1, 'r1', 'revno:1')
242
        self.assertInHistoryIs(2, 'r2', 'revno:2')
243
244
        self.assertInvalid('revno:3')
245
246
    def test_negative(self):
247
        self.assertInHistoryIs(2, 'r2', 'revno:-1')
248
        self.assertInHistoryIs(1, 'r1', 'revno:-2')
249
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
250
        self.assertInHistoryIs(1, 'r1', 'revno:-3')
251
        self.assertInHistoryIs(1, 'r1', 'revno:-4')
1948.4.6 by John Arbash Meinel
A small bugfix, and more tests for revno:
252
253
    def test_invalid_number(self):
254
        # Get the right exception text
255
        try:
256
            int('X')
257
        except ValueError, e:
258
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
259
        self.assertInvalid('revno:X', extra='\n' + str(e))
1948.4.6 by John Arbash Meinel
A small bugfix, and more tests for revno:
260
261
    def test_missing_number_and_branch(self):
262
        self.assertInvalid('revno::',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
263
                           extra='\ncannot have an empty revno and no branch')
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
264
265
    def test_invalid_number_with_branch(self):
266
        try:
267
            int('X')
268
        except ValueError, e:
269
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
270
        self.assertInvalid('revno:X:tree2', extra='\n' + str(e))
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
271
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
272
    def test_non_exact_branch(self):
273
        # It seems better to require an exact path to the branch
274
        # Branch.open() rather than using Branch.open_containing()
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
275
        spec = RevisionSpec.from_string('revno:2:tree2/a')
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
276
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
277
                          spec.in_history, self.tree.branch)
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
278
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
279
    def test_with_branch(self):
280
        # Passing a URL overrides the supplied branch path
281
        revinfo = self.get_in_history('revno:2:tree2')
282
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
283
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
284
        self.assertEqual(2, revinfo.revno)
285
        self.assertEqual('alt_r2', revinfo.rev_id)
286
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
287
    def test_int_with_branch(self):
288
        revinfo = self.get_in_history('2:tree2')
289
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
290
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
291
        self.assertEqual(2, revinfo.revno)
292
        self.assertEqual('alt_r2', revinfo.rev_id)
293
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
294
    def test_with_url(self):
295
        url = self.get_url() + '/tree2'
296
        revinfo = self.get_in_history('revno:2:%s' % (url,))
297
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
298
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
299
        self.assertEqual(2, revinfo.revno)
300
        self.assertEqual('alt_r2', revinfo.rev_id)
301
302
    def test_negative_with_url(self):
303
        url = self.get_url() + '/tree2'
304
        revinfo = self.get_in_history('revno:-1:%s' % (url,))
305
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
306
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
307
        self.assertEqual(2, revinfo.revno)
308
        self.assertEqual('alt_r2', revinfo.rev_id)
309
1948.4.22 by John Arbash Meinel
Refactor common code from integer revno handlers
310
    def test_different_history_lengths(self):
311
        # Make sure we use the revisions and offsets in the supplied branch
312
        # not the ones in the original branch.
313
        self.tree2.commit('three', rev_id='r3')
314
        self.assertInHistoryIs(3, 'r3', 'revno:3:tree2')
315
        self.assertInHistoryIs(3, 'r3', 'revno:-1:tree2')
316
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
317
    def test_invalid_branch(self):
318
        self.assertRaises(errors.NotBranchError,
319
                          self.get_in_history, 'revno:-1:tree3')
320
321
    def test_invalid_revno_in_branch(self):
322
        self.tree.commit('three', rev_id='r3')
323
        self.assertInvalid('revno:3:tree2')
1948.4.8 by John Arbash Meinel
Testing the revid: spec
324
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
325
    def test_revno_n_path(self):
326
        """Old revno:N:path tests"""
327
        wta = self.make_branch_and_tree('a')
328
        ba = wta.branch
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
329
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
330
        wta.commit('Commit one', rev_id='a@r-0-1')
331
        wta.commit('Commit two', rev_id='a@r-0-2')
332
        wta.commit('Commit three', rev_id='a@r-0-3')
333
334
        wtb = self.make_branch_and_tree('b')
335
        bb = wtb.branch
336
337
        wtb.commit('Commit one', rev_id='b@r-0-1')
338
        wtb.commit('Commit two', rev_id='b@r-0-2')
339
        wtb.commit('Commit three', rev_id='b@r-0-3')
340
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
341
342
        self.assertEqual((1, 'a@r-0-1'),
343
                         spec_in_history('revno:1:a/', ba))
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
344
        # The argument of in_history should be ignored since it is
345
        # redundant with the path in the spec.
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
346
        self.assertEqual((1, 'a@r-0-1'),
347
                         spec_in_history('revno:1:a/', None))
348
        self.assertEqual((1, 'a@r-0-1'),
349
                         spec_in_history('revno:1:a/', bb))
350
        self.assertEqual((2, 'b@r-0-2'),
351
                         spec_in_history('revno:2:b/', None))
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
352
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
353
    def test_as_revision_id(self):
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
354
        self.assertAsRevisionId('null:', '0')
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
355
        self.assertAsRevisionId('r1', '1')
356
        self.assertAsRevisionId('r2', '2')
357
        self.assertAsRevisionId('r1', '-2')
358
        self.assertAsRevisionId('r2', '-1')
359
        self.assertAsRevisionId('alt_r2', '1.1.1')
360
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
361
    def test_as_tree(self):
362
        tree = self.get_as_tree('0')
363
        self.assertEquals(_mod_revision.NULL_REVISION, tree.get_revision_id())
364
        tree = self.get_as_tree('1')
365
        self.assertEquals('r1', tree.get_revision_id())
366
        tree = self.get_as_tree('2')
367
        self.assertEquals('r2', tree.get_revision_id())
368
        tree = self.get_as_tree('-2')
369
        self.assertEquals('r1', tree.get_revision_id())
370
        tree = self.get_as_tree('-1')
371
        self.assertEquals('r2', tree.get_revision_id())
372
        tree = self.get_as_tree('1.1.1')
373
        self.assertEquals('alt_r2', tree.get_revision_id())
374
1948.4.8 by John Arbash Meinel
Testing the revid: spec
375
376
class TestRevisionSpec_revid(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
377
1948.4.8 by John Arbash Meinel
Testing the revid: spec
378
    def test_in_history(self):
379
        # We should be able to access revisions that are directly
380
        # in the history.
381
        self.assertInHistoryIs(1, 'r1', 'revid:r1')
382
        self.assertInHistoryIs(2, 'r2', 'revid:r2')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
383
1948.4.8 by John Arbash Meinel
Testing the revid: spec
384
    def test_missing(self):
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
385
        self.assertInvalid('revid:r3', invalid_as_revision_id=False)
1948.4.8 by John Arbash Meinel
Testing the revid: spec
386
387
    def test_merged(self):
388
        """We can reach revisions in the ancestry"""
389
        self.assertInHistoryIs(None, 'alt_r2', 'revid:alt_r2')
390
391
    def test_not_here(self):
392
        self.tree2.commit('alt third', rev_id='alt_r3')
393
        # It exists in tree2, but not in tree
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
394
        self.assertInvalid('revid:alt_r3', invalid_as_revision_id=False)
1948.4.8 by John Arbash Meinel
Testing the revid: spec
395
396
    def test_in_repository(self):
397
        """We can get any revision id in the repository"""
398
        # XXX: This may change in the future, but for now, it is true
399
        self.tree2.commit('alt third', rev_id='alt_r3')
5741.1.5 by Jelmer Vernooij
Have Branch.fetch() take a fetch_tags argument rather than a fetch_spec argument.
400
        self.tree.branch.fetch(self.tree2.branch, 'alt_r3')
1948.4.8 by John Arbash Meinel
Testing the revid: spec
401
        self.assertInHistoryIs(None, 'alt_r3', 'revid:alt_r3')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
402
2325.2.2 by Marien Zwart
Make the revid RevisionSpec always return a str object, not a unicode object.
403
    def test_unicode(self):
404
        """We correctly convert a unicode ui string to an encoded revid."""
2325.2.4 by Marien Zwart
Rename rev_id to revision_id because HACKING says so.
405
        revision_id = u'\N{SNOWMAN}'.encode('utf-8')
406
        self.tree.commit('unicode', rev_id=revision_id)
407
        self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
408
        self.assertInHistoryIs(3, revision_id, 'revid:' + revision_id)
2325.2.2 by Marien Zwart
Make the revid RevisionSpec always return a str object, not a unicode object.
409
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
410
    def test_as_revision_id(self):
411
        self.assertAsRevisionId('r1', 'revid:r1')
412
        self.assertAsRevisionId('r2', 'revid:r2')
413
        self.assertAsRevisionId('alt_r2', 'revid:alt_r2')
414
1948.4.9 by John Arbash Meinel
Cleanup and test last:
415
416
class TestRevisionSpec_last(TestRevisionSpec):
417
418
    def test_positive(self):
419
        self.assertInHistoryIs(2, 'r2', 'last:1')
420
        self.assertInHistoryIs(1, 'r1', 'last:2')
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
421
        self.assertInHistoryIs(0, 'null:', 'last:3')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
422
423
    def test_empty(self):
424
        self.assertInHistoryIs(2, 'r2', 'last:')
425
426
    def test_negative(self):
427
        self.assertInvalid('last:-1',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
428
                           extra='\nyou must supply a positive value')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
429
430
    def test_missing(self):
431
        self.assertInvalid('last:4')
432
433
    def test_no_history(self):
434
        tree = self.make_branch_and_tree('tree3')
435
436
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
437
                          spec_in_history, 'last:', tree.branch)
1948.4.9 by John Arbash Meinel
Cleanup and test last:
438
439
    def test_not_a_number(self):
440
        try:
441
            int('Y')
442
        except ValueError, e:
443
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
444
        self.assertInvalid('last:Y', extra='\n' + str(e))
1948.4.10 by John Arbash Meinel
test the before: spec, currently asserting what seems to be buggy behavior
445
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
446
    def test_as_revision_id(self):
447
        self.assertAsRevisionId('r2', 'last:1')
448
        self.assertAsRevisionId('r1', 'last:2')
449
1948.4.10 by John Arbash Meinel
test the before: spec, currently asserting what seems to be buggy behavior
450
451
class TestRevisionSpec_before(TestRevisionSpec):
452
453
    def test_int(self):
454
        self.assertInHistoryIs(1, 'r1', 'before:2')
455
        self.assertInHistoryIs(1, 'r1', 'before:-1')
456
457
    def test_before_one(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
458
        self.assertInHistoryIs(0, 'null:', 'before:1')
1948.4.10 by John Arbash Meinel
test the before: spec, currently asserting what seems to be buggy behavior
459
460
    def test_before_none(self):
1948.4.13 by John Arbash Meinel
Going before:0 is an error, and if you are on another history, use the leftmost parent
461
        self.assertInvalid('before:0',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
462
                           extra='\ncannot go before the null: revision')
1948.4.10 by John Arbash Meinel
test the before: spec, currently asserting what seems to be buggy behavior
463
464
    def test_revid(self):
465
        self.assertInHistoryIs(1, 'r1', 'before:revid:r2')
466
467
    def test_last(self):
468
        self.assertInHistoryIs(1, 'r1', 'before:last:1')
469
470
    def test_alt_revid(self):
1948.4.13 by John Arbash Meinel
Going before:0 is an error, and if you are on another history, use the leftmost parent
471
        # This will grab the left-most ancestor for alternate histories
472
        self.assertInHistoryIs(1, 'r1', 'before:revid:alt_r2')
1948.4.11 by John Arbash Meinel
Update and test the tag: spec
473
1948.4.14 by John Arbash Meinel
Test the code path for a no-parent alternate history
474
    def test_alt_no_parents(self):
475
        new_tree = self.make_branch_and_tree('new_tree')
476
        new_tree.commit('first', rev_id='new_r1')
5741.1.5 by Jelmer Vernooij
Have Branch.fetch() take a fetch_tags argument rather than a fetch_spec argument.
477
        self.tree.branch.fetch(new_tree.branch, 'new_r1')
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
478
        self.assertInHistoryIs(0, 'null:', 'before:revid:new_r1')
1948.4.14 by John Arbash Meinel
Test the code path for a no-parent alternate history
479
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
480
    def test_as_revision_id(self):
481
        self.assertAsRevisionId('r1', 'before:revid:r2')
482
        self.assertAsRevisionId('r1', 'before:2')
483
        self.assertAsRevisionId('r1', 'before:1.1.1')
484
        self.assertAsRevisionId('r1', 'before:revid:alt_r2')
485
1948.4.11 by John Arbash Meinel
Update and test the tag: spec
486
487
class TestRevisionSpec_tag(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
488
2220.2.3 by Martin Pool
Add tag: revision namespace.
489
    def make_branch_and_tree(self, relpath):
490
        # override format as the default one may not support tags
3031.3.1 by Robert Collins
Remove the unneeded ExperimentalBranch class.
491
        return TestRevisionSpec.make_branch_and_tree(
492
            self, relpath, format='dirstate-tags')
2220.2.3 by Martin Pool
Add tag: revision namespace.
493
494
    def test_from_string_tag(self):
495
        spec = RevisionSpec.from_string('tag:bzr-0.14')
496
        self.assertIsInstance(spec, RevisionSpec_tag)
497
        self.assertEqual(spec.spec, 'bzr-0.14')
498
499
    def test_lookup_tag(self):
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
500
        self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
2220.2.3 by Martin Pool
Add tag: revision namespace.
501
        self.assertInHistoryIs(1, 'r1', 'tag:bzr-0.14')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
502
        self.tree.branch.tags.set_tag('null_rev', 'null:')
503
        self.assertInHistoryIs(0, 'null:', 'tag:null_rev')
2220.2.3 by Martin Pool
Add tag: revision namespace.
504
505
    def test_failed_lookup(self):
506
        # tags that don't exist give a specific message: arguably we should
507
        # just give InvalidRevisionSpec but I think this is more helpful
508
        self.assertRaises(errors.NoSuchTag,
509
            self.get_in_history,
510
            'tag:some-random-tag')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
511
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
512
    def test_as_revision_id(self):
513
        self.tree.branch.tags.set_tag('my-tag', 'r2')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
514
        self.tree.branch.tags.set_tag('null_rev', 'null:')
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
515
        self.assertAsRevisionId('r2', 'tag:my-tag')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
516
        self.assertAsRevisionId('null:', 'tag:null_rev')
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
517
        self.assertAsRevisionId('r1', 'before:tag:my-tag')
518
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
519
520
class TestRevisionSpec_date(TestRevisionSpec):
521
522
    def setUp(self):
523
        super(TestRevisionSpec, self).setUp()
524
525
        new_tree = self.make_branch_and_tree('new_tree')
526
        new_tree.commit('Commit one', rev_id='new_r1',
527
                        timestamp=time.time() - 60*60*24)
528
        new_tree.commit('Commit two', rev_id='new_r2')
529
        new_tree.commit('Commit three', rev_id='new_r3')
530
531
        self.tree = new_tree
532
533
    def test_tomorrow(self):
534
        self.assertInvalid('date:tomorrow')
535
536
    def test_today(self):
537
        self.assertInHistoryIs(2, 'new_r2', 'date:today')
538
        self.assertInHistoryIs(1, 'new_r1', 'before:date:today')
539
540
    def test_yesterday(self):
541
        self.assertInHistoryIs(1, 'new_r1', 'date:yesterday')
542
543
    def test_invalid(self):
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
544
        self.assertInvalid('date:foobar', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
545
        # You must have '-' between year/month/day
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
546
        self.assertInvalid('date:20040404', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
547
        # Need 2 digits for each date piece
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
548
        self.assertInvalid('date:2004-4-4', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
549
550
    def test_day(self):
551
        now = datetime.datetime.now()
552
        self.assertInHistoryIs(2, 'new_r2',
553
            'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
554
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
555
    def test_as_revision_id(self):
556
        self.assertAsRevisionId('new_r2', 'date:today')
557
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
558
559
class TestRevisionSpec_ancestor(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
560
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
561
    def test_non_exact_branch(self):
562
        # It seems better to require an exact path to the branch
563
        # Branch.open() rather than using Branch.open_containing()
564
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
565
                          self.get_in_history, 'ancestor:tree2/a')
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
566
567
    def test_simple(self):
568
        # Common ancestor of trees is 'alt_r2'
569
        self.assertInHistoryIs(None, 'alt_r2', 'ancestor:tree2')
570
571
        # Going the other way, we get a valid revno
572
        tmp = self.tree
573
        self.tree = self.tree2
574
        self.tree2 = tmp
575
        self.assertInHistoryIs(2, 'alt_r2', 'ancestor:tree')
576
577
    def test_self(self):
578
        self.assertInHistoryIs(2, 'r2', 'ancestor:tree')
579
580
    def test_unrelated(self):
581
        new_tree = self.make_branch_and_tree('new_tree')
582
583
        new_tree.commit('Commit one', rev_id='new_r1')
584
        new_tree.commit('Commit two', rev_id='new_r2')
585
        new_tree.commit('Commit three', rev_id='new_r3')
586
587
        # With no common ancestor, we should raise another user error
588
        self.assertRaises(errors.NoCommonAncestor,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
589
                          self.get_in_history, 'ancestor:new_tree')
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
590
591
    def test_no_commits(self):
592
        new_tree = self.make_branch_and_tree('new_tree')
593
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
594
                          spec_in_history, 'ancestor:new_tree',
595
                                           self.tree.branch)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
596
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
597
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
598
                          spec_in_history, 'ancestor:tree',
599
                                           new_tree.branch)
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
600
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
601
    def test_as_revision_id(self):
602
        self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
603
3984.1.1 by Daniel Watkins
Added test.
604
    def test_default(self):
605
        # We don't have a parent to default to
606
        self.assertRaises(errors.NotBranchError, self.get_in_history,
607
                          'ancestor:')
608
609
        # Create a branch with a parent to default to
610
        tree3 = self.tree.bzrdir.sprout('tree3').open_workingtree()
611
        tree3.commit('foo', rev_id='r3')
612
        self.tree = tree3
613
        self.assertInHistoryIs(2, 'r2', 'ancestor:')
614
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
615
616
class TestRevisionSpec_branch(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
617
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
618
    def test_non_exact_branch(self):
619
        # It seems better to require an exact path to the branch
620
        # Branch.open() rather than using Branch.open_containing()
621
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
622
                          self.get_in_history, 'branch:tree2/a')
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
623
624
    def test_simple(self):
625
        self.assertInHistoryIs(None, 'alt_r2', 'branch:tree2')
626
627
    def test_self(self):
628
        self.assertInHistoryIs(2, 'r2', 'branch:tree')
629
630
    def test_unrelated(self):
631
        new_tree = self.make_branch_and_tree('new_tree')
632
633
        new_tree.commit('Commit one', rev_id='new_r1')
634
        new_tree.commit('Commit two', rev_id='new_r2')
635
        new_tree.commit('Commit three', rev_id='new_r3')
636
637
        self.assertInHistoryIs(None, 'new_r3', 'branch:new_tree')
638
639
        # XXX: Right now, we use fetch() to make sure the remote revisions
640
        # have been pulled into the local branch. We may change that
641
        # behavior in the future.
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
642
        self.assertTrue(self.tree.branch.repository.has_revision('new_r3'))
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
643
644
    def test_no_commits(self):
645
        new_tree = self.make_branch_and_tree('new_tree')
646
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
647
                          self.get_in_history, 'branch:new_tree')
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
648
        self.assertRaises(errors.NoCommits,
649
                          self.get_as_tree, 'branch:new_tree')
1551.10.32 by Aaron Bentley
Add submit: specifier, for merge-directive-like diffs
650
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
651
    def test_as_revision_id(self):
652
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
653
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
654
    def test_as_tree(self):
655
        tree = self.get_as_tree('branch:tree', self.tree2)
656
        self.assertEquals('r2', tree.get_revision_id())
657
        self.assertFalse(self.tree2.branch.repository.has_revision('r2'))
658
1551.10.32 by Aaron Bentley
Add submit: specifier, for merge-directive-like diffs
659
660
class TestRevisionSpec_submit(TestRevisionSpec):
661
662
    def test_submit_branch(self):
663
        # Common ancestor of trees is 'alt_r2'
664
        self.assertRaises(errors.NoSubmitBranch, self.get_in_history,
665
                          'submit:')
666
        self.tree.branch.set_parent('../tree2')
667
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
668
        self.tree.branch.set_parent('bogus')
669
        self.assertRaises(errors.NotBranchError, self.get_in_history,
670
            'submit:')
671
        # submit branch overrides parent branch
672
        self.tree.branch.set_submit_branch('tree2')
673
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
3298.2.3 by John Arbash Meinel
Add tests that all RevisionSpecs implement in_branch(b, needs_revno)
674
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
675
    def test_as_revision_id(self):
676
        self.tree.branch.set_submit_branch('tree2')
677
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
5365.6.4 by Aaron Bentley
Implement mainline revision spec.
678
679
680
class TestRevisionSpec_mainline(TestRevisionSpec):
681
682
    def test_as_revision_id(self):
683
        self.assertAsRevisionId('r1', 'mainline:1')
684
        self.assertAsRevisionId('r2', 'mainline:1.1.1')
685
        self.assertAsRevisionId('r2', 'mainline:revid:alt_r2')
686
        spec = RevisionSpec.from_string('mainline:revid:alt_r22')
687
        e = self.assertRaises(errors.InvalidRevisionSpec,
688
                              spec.as_revision_id, self.tree.branch)
689
        self.assertContainsRe(str(e),
690
            "Requested revision: 'mainline:revid:alt_r22' does not exist in"
691
            " branch: ")
692
693
    def test_in_history(self):
694
        self.assertInHistoryIs(2, 'r2', 'mainline:revid:alt_r2')
5365.6.6 by Aaron Bentley
Implement 'annotate' revision-id.
695
696
697
class TestRevisionSpec_annotate(TestRevisionSpec):
698
699
    def setUp(self):
700
        TestRevisionSpec.setUp(self)
701
        self.tree = self.make_branch_and_tree('annotate-tree')
702
        self.build_tree_contents([('annotate-tree/file1', '1\n')])
703
        self.tree.add('file1')
704
        self.tree.commit('r1', rev_id='r1')
705
        self.build_tree_contents([('annotate-tree/file1', '2\n1\n')])
706
        self.tree.commit('r2', rev_id='r2')
707
        self.build_tree_contents([('annotate-tree/file1', '2\n1\n3\n')])
708
709
    def test_as_revision_id_r1(self):
710
        self.assertAsRevisionId('r1', 'annotate:annotate-tree/file1:2')
711
712
    def test_as_revision_id_r2(self):
713
        self.assertAsRevisionId('r2', 'annotate:annotate-tree/file1:1')
714
715
    def test_as_revision_id_uncommitted(self):
716
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:3')
717
        e = self.assertRaises(errors.InvalidRevisionSpec,
718
                              spec.as_revision_id, self.tree.branch)
719
        self.assertContainsRe(str(e),
720
            r"Requested revision: \'annotate:annotate-tree/file1:3\' does not"
721
            " exist in branch: .*\nLine 3 has not been committed.")
722
5365.6.10 by Andrew Bennetts
Fix typo in test method name.
723
    def test_non_existent_line(self):
5365.6.6 by Aaron Bentley
Implement 'annotate' revision-id.
724
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:4')
725
        e = self.assertRaises(errors.InvalidRevisionSpec,
726
                              spec.as_revision_id, self.tree.branch)
727
        self.assertContainsRe(str(e),
728
            r"Requested revision: \'annotate:annotate-tree/file1:4\' does not"
729
            " exist in branch: .*\nNo such line: 4")
730
731
    def test_invalid_line(self):
732
        spec = RevisionSpec.from_string('annotate:annotate-tree/file1:q')
733
        e = self.assertRaises(errors.InvalidRevisionSpec,
734
                              spec.as_revision_id, self.tree.branch)
735
        self.assertContainsRe(str(e),
736
            r"Requested revision: \'annotate:annotate-tree/file1:q\' does not"
737
            " exist in branch: .*\nNo such line: q")
738
739
    def test_no_such_file(self):
740
        spec = RevisionSpec.from_string('annotate:annotate-tree/file2:1')
741
        e = self.assertRaises(errors.InvalidRevisionSpec,
742
                              spec.as_revision_id, self.tree.branch)
743
        self.assertContainsRe(str(e),
744
            r"Requested revision: \'annotate:annotate-tree/file2:1\' does not"
745
            " exist in branch: .*\nFile 'file2' is not versioned")
746
747
    def test_no_such_file_with_colon(self):
748
        spec = RevisionSpec.from_string('annotate:annotate-tree/fi:le2:1')
749
        e = self.assertRaises(errors.InvalidRevisionSpec,
750
                              spec.as_revision_id, self.tree.branch)
751
        self.assertContainsRe(str(e),
752
            r"Requested revision: \'annotate:annotate-tree/fi:le2:1\' does not"
753
            " exist in branch: .*\nFile 'fi:le2' is not versioned")