~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,
6336.1.1 by Jelmer Vernooij
Deprecate ``RevisionSpec.wants_revision_history`` and remove any uses of it.
23
    symbol_versioning,
1948.4.1 by John Arbash Meinel
Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers
24
    )
5579.3.1 by Jelmer Vernooij
Remove unused imports.
25
from bzrlib.tests import TestCaseWithTransport
2220.2.3 by Martin Pool
Add tag: revision namespace.
26
from bzrlib.revisionspec import (
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
27
    RevisionInfo,
2220.2.3 by Martin Pool
Add tag: revision namespace.
28
    RevisionSpec,
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
29
    RevisionSpec_dwim,
2220.2.3 by Martin Pool
Add tag: revision namespace.
30
    RevisionSpec_tag,
31
    )
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
32
33
34
def spec_in_history(spec, branch):
35
    """A simple helper to change a revision spec into a branch search"""
36
    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.
37
38
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
39
# Basic class, which just creates a really basic set of revisions
40
class TestRevisionSpec(TestCaseWithTransport):
41
42
    def setUp(self):
43
        super(TestRevisionSpec, self).setUp()
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
44
        # this sets up a revision graph:
45
        # r1: []             1
46
        # alt_r2: [r1]       1.1.1
47
        # r2: [r1, alt_r2]   2
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
48
49
        self.tree = self.make_branch_and_tree('tree')
50
        self.build_tree(['tree/a'])
3298.2.3 by John Arbash Meinel
Add tests that all RevisionSpecs implement in_branch(b, needs_revno)
51
        self.tree.lock_write()
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
52
        self.addCleanup(self.tree.unlock)
53
        self.tree.add(['a'])
54
        self.tree.commit('a', rev_id='r1')
55
56
        self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
57
        self.tree2.commit('alt', rev_id='alt_r2')
58
59
        self.tree.merge_from_branch(self.tree2.branch)
60
        self.tree.commit('second', rev_id='r2')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
61
62
    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)
63
        return spec_in_history(revision_spec, self.tree.branch)
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
64
65
    def assertInHistoryIs(self, exp_revno, exp_revision_id, revision_spec):
66
        rev_info = self.get_in_history(revision_spec)
67
        self.assertEqual(exp_revno, rev_info.revno,
2325.2.1 by Marien Zwart
Make the test suite failure reporting a bit more robust.
68
                         'Revision spec: %r returned wrong revno: %r != %r'
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
69
                         % (revision_spec, exp_revno, rev_info.revno))
70
        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.
71
                         'Revision spec: %r returned wrong revision id:'
72
                         ' %r != %r'
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
73
                         % (revision_spec, exp_revision_id, rev_info.rev_id))
74
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
75
    def assertInvalid(self, revision_spec, extra='',
76
                      invalid_as_revision_id=True):
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
77
        try:
78
            self.get_in_history(revision_spec)
79
        except errors.InvalidRevisionSpec, e:
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
80
            self.assertEqual(revision_spec, e.spec)
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
81
            self.assertEqual(extra, e.extra)
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
82
        else:
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
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'
3495.1.2 by John Arbash Meinel
tweak
94
                          ' %r.as_revision_id' % (revision_spec,))
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
95
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
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
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
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
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
108
3460.1.2 by John Arbash Meinel
Add a test for wants_revision_history
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)
6336.1.1 by Jelmer Vernooij
Deprecate ``RevisionSpec.wants_revision_history`` and remove any uses of it.
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)
3460.1.2 by John Arbash Meinel
Add a test for wants_revision_history
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
138
139
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
140
class TestOddRevisionSpec(TestRevisionSpec):
141
    """Test things that aren't normally thought of as revision specs"""
142
143
    def test_none(self):
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
144
        self.assertInHistoryIs(None, None, None)
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
145
146
    def test_object(self):
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
147
        self.assertRaises(TypeError, RevisionSpec.from_string, object())
1948.4.19 by John Arbash Meinel
All old tests are covered elsewhere
148
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
149
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
150
class RevisionSpec_bork(RevisionSpec):
151
152
    prefix = 'irrelevant:'
153
154
    def _match_on(self, branch, revs):
155
        if self.spec == "bork":
6336.1.1 by Jelmer Vernooij
Deprecate ``RevisionSpec.wants_revision_history`` and remove any uses of it.
156
            return RevisionInfo.from_revision_id(branch, "r1")
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
157
        else:
158
            raise errors.InvalidRevisionSpec(self.spec, branch)
159
160
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
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
4569.2.11 by Matthew Fuller
Eliminate the TestRevnoFromString() test class by moving all its tests
165
    def test_dwim_spec_revno(self):
166
        self.assertInHistoryIs(2, 'r2', '2')
167
        self.assertAsRevisionId('alt_r2', '1.1.1')
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
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
4569.2.16 by Matthew Fuller
Add a test that we slip past the revno-checking stage when we're
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
4569.2.4 by Matthew Fuller
Add date: to the list of things DWIM auto-tries.
190
    def test_dwim_spec_date(self):
191
        self.assertAsRevisionId('r1', 'today')
192
4569.2.2 by Matthew Fuller
Add tests for DWIM revspecs.
193
    def test_dwim_spec_branch(self):
194
        self.assertInHistoryIs(None, 'alt_r2', 'tree2')
195
196
    def test_dwim_spec_nonexistent(self):
4569.2.8 by Matthew Fuller
Use a more precise nonexistent thing in test_dwim_spec_nonexistent().
197
        self.assertInvalid('somethingrandom', invalid_as_revision_id=False)
4569.2.11 by Matthew Fuller
Eliminate the TestRevnoFromString() test class by moving all its tests
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)
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
203
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
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)
5671.5.3 by Jelmer Vernooij
Fix test.. not sure how I missed this.
217
        RevisionSpec_dwim.append_possible_lazy_revspec(
5671.5.1 by Jelmer Vernooij
Allow lazily registering possible DWIM revspecs.
218
            "bzrlib.tests.test_revisionspec", "RevisionSpec_bork")
219
        self.assertAsRevisionId('r1', 'bork')
220
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
221
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
222
class TestRevisionSpec_revno(TestRevisionSpec):
223
224
    def test_positive_int(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
225
        self.assertInHistoryIs(0, 'null:', '0')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
226
        self.assertInHistoryIs(1, 'r1', '1')
227
        self.assertInHistoryIs(2, 'r2', '2')
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
228
        self.assertInvalid('3')
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
229
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
230
    def test_dotted_decimal(self):
231
        self.assertInHistoryIs(None, 'alt_r2', '1.1.1')
3878.3.1 by Marius Kruger
Test invalid dotted revion number directly in TestRevisionSpec_revno
232
        self.assertInvalid('1.1.123')
1988.4.5 by Robert Collins
revisions can now be specified using dotted-decimal revision numbers.
233
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
234
    def test_negative_int(self):
1948.4.3 by John Arbash Meinel
Create direct tests for RevisionSpec_int
235
        self.assertInHistoryIs(2, 'r2', '-1')
236
        self.assertInHistoryIs(1, 'r1', '-2')
237
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
238
        self.assertInHistoryIs(1, 'r1', '-3')
239
        self.assertInHistoryIs(1, 'r1', '-4')
240
        self.assertInHistoryIs(1, 'r1', '-100')
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
241
242
    def test_positive(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
243
        self.assertInHistoryIs(0, 'null:', 'revno:0')
1948.4.5 by John Arbash Meinel
Fix tests for negative entries, and add tests for revno:
244
        self.assertInHistoryIs(1, 'r1', 'revno:1')
245
        self.assertInHistoryIs(2, 'r2', 'revno:2')
246
247
        self.assertInvalid('revno:3')
248
249
    def test_negative(self):
250
        self.assertInHistoryIs(2, 'r2', 'revno:-1')
251
        self.assertInHistoryIs(1, 'r1', 'revno:-2')
252
1948.4.23 by John Arbash Meinel
Change the handling of negative numbers, to be trapped at revno 1
253
        self.assertInHistoryIs(1, 'r1', 'revno:-3')
254
        self.assertInHistoryIs(1, 'r1', 'revno:-4')
1948.4.6 by John Arbash Meinel
A small bugfix, and more tests for revno:
255
256
    def test_invalid_number(self):
257
        # Get the right exception text
258
        try:
259
            int('X')
260
        except ValueError, e:
261
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
262
        self.assertInvalid('revno:X', extra='\n' + str(e))
1948.4.6 by John Arbash Meinel
A small bugfix, and more tests for revno:
263
264
    def test_missing_number_and_branch(self):
265
        self.assertInvalid('revno::',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
266
                           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
267
268
    def test_invalid_number_with_branch(self):
269
        try:
270
            int('X')
271
        except ValueError, e:
272
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
273
        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
274
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
275
    def test_non_exact_branch(self):
276
        # It seems better to require an exact path to the branch
277
        # 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)
278
        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
279
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
280
                          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
281
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
282
    def test_with_branch(self):
283
        # Passing a URL overrides the supplied branch path
284
        revinfo = self.get_in_history('revno:2:tree2')
285
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
286
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
287
        self.assertEqual(2, revinfo.revno)
288
        self.assertEqual('alt_r2', revinfo.rev_id)
289
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
290
    def test_int_with_branch(self):
291
        revinfo = self.get_in_history('2:tree2')
292
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
293
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
294
        self.assertEqual(2, revinfo.revno)
295
        self.assertEqual('alt_r2', revinfo.rev_id)
296
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
297
    def test_with_url(self):
298
        url = self.get_url() + '/tree2'
299
        revinfo = self.get_in_history('revno:2:%s' % (url,))
300
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
301
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
302
        self.assertEqual(2, revinfo.revno)
303
        self.assertEqual('alt_r2', revinfo.rev_id)
304
305
    def test_negative_with_url(self):
306
        url = self.get_url() + '/tree2'
307
        revinfo = self.get_in_history('revno:-1:%s' % (url,))
308
        self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
309
        self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
310
        self.assertEqual(2, revinfo.revno)
311
        self.assertEqual('alt_r2', revinfo.rev_id)
312
1948.4.22 by John Arbash Meinel
Refactor common code from integer revno handlers
313
    def test_different_history_lengths(self):
314
        # Make sure we use the revisions and offsets in the supplied branch
315
        # not the ones in the original branch.
316
        self.tree2.commit('three', rev_id='r3')
317
        self.assertInHistoryIs(3, 'r3', 'revno:3:tree2')
318
        self.assertInHistoryIs(3, 'r3', 'revno:-1:tree2')
319
1948.4.7 by John Arbash Meinel
More revno: tests, now testing the branch/url parameter
320
    def test_invalid_branch(self):
321
        self.assertRaises(errors.NotBranchError,
322
                          self.get_in_history, 'revno:-1:tree3')
323
324
    def test_invalid_revno_in_branch(self):
325
        self.tree.commit('three', rev_id='r3')
326
        self.assertInvalid('revno:3:tree2')
1948.4.8 by John Arbash Meinel
Testing the revid: spec
327
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
328
    def test_revno_n_path(self):
329
        """Old revno:N:path tests"""
330
        wta = self.make_branch_and_tree('a')
331
        ba = wta.branch
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
332
1948.4.16 by John Arbash Meinel
Move the tests into the associated tester, remove redundant tests, some small PEP8 changes
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')
336
337
        wtb = self.make_branch_and_tree('b')
338
        bb = wtb.branch
339
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
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
344
345
        self.assertEqual((1, 'a@r-0-1'),
346
                         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
347
        # The argument of in_history should be ignored since it is
348
        # 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)
349
        self.assertEqual((1, 'a@r-0-1'),
350
                         spec_in_history('revno:1:a/', None))
351
        self.assertEqual((1, 'a@r-0-1'),
352
                         spec_in_history('revno:1:a/', bb))
353
        self.assertEqual((2, 'b@r-0-2'),
354
                         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
355
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
356
    def test_as_revision_id(self):
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
357
        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)
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
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
364
    def test_as_tree(self):
365
        tree = self.get_as_tree('0')
366
        self.assertEquals(_mod_revision.NULL_REVISION, tree.get_revision_id())
367
        tree = self.get_as_tree('1')
368
        self.assertEquals('r1', tree.get_revision_id())
369
        tree = self.get_as_tree('2')
370
        self.assertEquals('r2', tree.get_revision_id())
371
        tree = self.get_as_tree('-2')
372
        self.assertEquals('r1', tree.get_revision_id())
373
        tree = self.get_as_tree('-1')
374
        self.assertEquals('r2', tree.get_revision_id())
375
        tree = self.get_as_tree('1.1.1')
376
        self.assertEquals('alt_r2', tree.get_revision_id())
377
1948.4.8 by John Arbash Meinel
Testing the revid: spec
378
379
class TestRevisionSpec_revid(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
380
1948.4.8 by John Arbash Meinel
Testing the revid: spec
381
    def test_in_history(self):
382
        # We should be able to access revisions that are directly
383
        # in the history.
384
        self.assertInHistoryIs(1, 'r1', 'revid:r1')
385
        self.assertInHistoryIs(2, 'r2', 'revid:r2')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
386
1948.4.8 by John Arbash Meinel
Testing the revid: spec
387
    def test_missing(self):
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
388
        self.assertInvalid('revid:r3', invalid_as_revision_id=False)
1948.4.8 by John Arbash Meinel
Testing the revid: spec
389
390
    def test_merged(self):
391
        """We can reach revisions in the ancestry"""
392
        self.assertInHistoryIs(None, 'alt_r2', 'revid:alt_r2')
393
394
    def test_not_here(self):
395
        self.tree2.commit('alt third', rev_id='alt_r3')
396
        # It exists in tree2, but not in tree
3495.1.1 by John Arbash Meinel
Fix bug #239933, use the right exception for -c0
397
        self.assertInvalid('revid:alt_r3', invalid_as_revision_id=False)
1948.4.8 by John Arbash Meinel
Testing the revid: spec
398
399
    def test_in_repository(self):
400
        """We can get any revision id in the repository"""
401
        # XXX: This may change in the future, but for now, it is true
402
        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.
403
        self.tree.branch.fetch(self.tree2.branch, 'alt_r3')
1948.4.8 by John Arbash Meinel
Testing the revid: spec
404
        self.assertInHistoryIs(None, 'alt_r3', 'revid:alt_r3')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
405
2325.2.2 by Marien Zwart
Make the revid RevisionSpec always return a str object, not a unicode object.
406
    def test_unicode(self):
407
        """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.
408
        revision_id = u'\N{SNOWMAN}'.encode('utf-8')
409
        self.tree.commit('unicode', rev_id=revision_id)
410
        self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
411
        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.
412
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
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
1948.4.9 by John Arbash Meinel
Cleanup and test last:
418
419
class TestRevisionSpec_last(TestRevisionSpec):
420
421
    def test_positive(self):
422
        self.assertInHistoryIs(2, 'r2', 'last:1')
423
        self.assertInHistoryIs(1, 'r1', 'last:2')
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
424
        self.assertInHistoryIs(0, 'null:', 'last:3')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
425
426
    def test_empty(self):
427
        self.assertInHistoryIs(2, 'r2', 'last:')
428
429
    def test_negative(self):
430
        self.assertInvalid('last:-1',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
431
                           extra='\nyou must supply a positive value')
1948.4.9 by John Arbash Meinel
Cleanup and test last:
432
433
    def test_missing(self):
434
        self.assertInvalid('last:4')
435
436
    def test_no_history(self):
437
        tree = self.make_branch_and_tree('tree3')
438
439
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
440
                          spec_in_history, 'last:', tree.branch)
1948.4.9 by John Arbash Meinel
Cleanup and test last:
441
442
    def test_not_a_number(self):
443
        try:
444
            int('Y')
445
        except ValueError, e:
446
            pass
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
447
        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
448
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
449
    def test_as_revision_id(self):
450
        self.assertAsRevisionId('r2', 'last:1')
451
        self.assertAsRevisionId('r1', 'last:2')
452
1948.4.10 by John Arbash Meinel
test the before: spec, currently asserting what seems to be buggy behavior
453
454
class TestRevisionSpec_before(TestRevisionSpec):
455
456
    def test_int(self):
457
        self.assertInHistoryIs(1, 'r1', 'before:2')
458
        self.assertInHistoryIs(1, 'r1', 'before:-1')
459
460
    def test_before_one(self):
2598.5.10 by Aaron Bentley
Return NULL_REVISION instead of None for the null revision
461
        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
462
463
    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
464
        self.assertInvalid('before:0',
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
465
                           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
466
467
    def test_revid(self):
468
        self.assertInHistoryIs(1, 'r1', 'before:revid:r2')
469
470
    def test_last(self):
471
        self.assertInHistoryIs(1, 'r1', 'before:last:1')
472
473
    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
474
        # This will grab the left-most ancestor for alternate histories
475
        self.assertInHistoryIs(1, 'r1', 'before:revid:alt_r2')
1948.4.11 by John Arbash Meinel
Update and test the tag: spec
476
1948.4.14 by John Arbash Meinel
Test the code path for a no-parent alternate history
477
    def test_alt_no_parents(self):
478
        new_tree = self.make_branch_and_tree('new_tree')
479
        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.
480
        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
481
        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
482
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
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')
488
1948.4.11 by John Arbash Meinel
Update and test the tag: spec
489
490
class TestRevisionSpec_tag(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
491
2220.2.3 by Martin Pool
Add tag: revision namespace.
492
    def make_branch_and_tree(self, relpath):
493
        # override format as the default one may not support tags
3031.3.1 by Robert Collins
Remove the unneeded ExperimentalBranch class.
494
        return TestRevisionSpec.make_branch_and_tree(
495
            self, relpath, format='dirstate-tags')
2220.2.3 by Martin Pool
Add tag: revision namespace.
496
497
    def test_from_string_tag(self):
498
        spec = RevisionSpec.from_string('tag:bzr-0.14')
499
        self.assertIsInstance(spec, RevisionSpec_tag)
500
        self.assertEqual(spec.spec, 'bzr-0.14')
501
502
    def test_lookup_tag(self):
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
503
        self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
2220.2.3 by Martin Pool
Add tag: revision namespace.
504
        self.assertInHistoryIs(1, 'r1', 'tag:bzr-0.14')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
505
        self.tree.branch.tags.set_tag('null_rev', 'null:')
506
        self.assertInHistoryIs(0, 'null:', 'tag:null_rev')
2220.2.3 by Martin Pool
Add tag: revision namespace.
507
508
    def test_failed_lookup(self):
509
        # tags that don't exist give a specific message: arguably we should
510
        # just give InvalidRevisionSpec but I think this is more helpful
511
        self.assertRaises(errors.NoSuchTag,
512
            self.get_in_history,
513
            'tag:some-random-tag')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
514
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
515
    def test_as_revision_id(self):
516
        self.tree.branch.tags.set_tag('my-tag', 'r2')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
517
        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)
518
        self.assertAsRevisionId('r2', 'tag:my-tag')
3298.2.11 by Aaron Bentley
Update tests for null:, clea up slightly
519
        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)
520
        self.assertAsRevisionId('r1', 'before:tag:my-tag')
521
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
522
523
class TestRevisionSpec_date(TestRevisionSpec):
524
525
    def setUp(self):
526
        super(TestRevisionSpec, self).setUp()
527
528
        new_tree = self.make_branch_and_tree('new_tree')
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')
533
534
        self.tree = new_tree
535
536
    def test_tomorrow(self):
537
        self.assertInvalid('date:tomorrow')
538
539
    def test_today(self):
540
        self.assertInHistoryIs(2, 'new_r2', 'date:today')
541
        self.assertInHistoryIs(1, 'new_r1', 'before:date:today')
542
543
    def test_yesterday(self):
544
        self.assertInHistoryIs(1, 'new_r1', 'date:yesterday')
545
546
    def test_invalid(self):
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
547
        self.assertInvalid('date:foobar', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
548
        # You must have '-' between year/month/day
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
549
        self.assertInvalid('date:20040404', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
550
        # Need 2 digits for each date piece
1948.4.15 by John Arbash Meinel
Change the InvalidRevisionSpec formatting to be more readable
551
        self.assertInvalid('date:2004-4-4', extra='\ninvalid date')
1948.4.12 by John Arbash Meinel
Some tests for the date: spec
552
553
    def test_day(self):
554
        now = datetime.datetime.now()
555
        self.assertInHistoryIs(2, 'new_r2',
556
            'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
557
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
558
    def test_as_revision_id(self):
559
        self.assertAsRevisionId('new_r2', 'date:today')
560
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
561
562
class TestRevisionSpec_ancestor(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
563
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
564
    def test_non_exact_branch(self):
565
        # It seems better to require an exact path to the branch
566
        # Branch.open() rather than using Branch.open_containing()
567
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
568
                          self.get_in_history, 'ancestor:tree2/a')
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
569
570
    def test_simple(self):
571
        # Common ancestor of trees is 'alt_r2'
572
        self.assertInHistoryIs(None, 'alt_r2', 'ancestor:tree2')
573
574
        # Going the other way, we get a valid revno
575
        tmp = self.tree
576
        self.tree = self.tree2
577
        self.tree2 = tmp
578
        self.assertInHistoryIs(2, 'alt_r2', 'ancestor:tree')
579
580
    def test_self(self):
581
        self.assertInHistoryIs(2, 'r2', 'ancestor:tree')
582
583
    def test_unrelated(self):
584
        new_tree = self.make_branch_and_tree('new_tree')
585
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')
589
590
        # With no common ancestor, we should raise another user error
591
        self.assertRaises(errors.NoCommonAncestor,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
592
                          self.get_in_history, 'ancestor:new_tree')
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
593
594
    def test_no_commits(self):
595
        new_tree = self.make_branch_and_tree('new_tree')
596
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
597
                          spec_in_history, 'ancestor:new_tree',
598
                                           self.tree.branch)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
599
1948.4.17 by John Arbash Meinel
Update tests for ancestor: spec
600
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
601
                          spec_in_history, 'ancestor:tree',
602
                                           new_tree.branch)
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
603
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
604
    def test_as_revision_id(self):
605
        self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
606
3984.1.1 by Daniel Watkins
Added test.
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
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
618
619
class TestRevisionSpec_branch(TestRevisionSpec):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
620
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
621
    def test_non_exact_branch(self):
622
        # It seems better to require an exact path to the branch
623
        # Branch.open() rather than using Branch.open_containing()
624
        self.assertRaises(errors.NotBranchError,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
625
                          self.get_in_history, 'branch:tree2/a')
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
626
627
    def test_simple(self):
628
        self.assertInHistoryIs(None, 'alt_r2', 'branch:tree2')
629
630
    def test_self(self):
631
        self.assertInHistoryIs(2, 'r2', 'branch:tree')
632
633
    def test_unrelated(self):
634
        new_tree = self.make_branch_and_tree('new_tree')
635
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')
639
640
        self.assertInHistoryIs(None, 'new_r3', 'branch:new_tree')
641
642
        # XXX: Right now, we use fetch() to make sure the remote revisions
643
        # have been pulled into the local branch. We may change that
644
        # behavior in the future.
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
645
        self.assertTrue(self.tree.branch.repository.has_revision('new_r3'))
1948.4.18 by John Arbash Meinel
Update branch: spec and tests
646
647
    def test_no_commits(self):
648
        new_tree = self.make_branch_and_tree('new_tree')
649
        self.assertRaises(errors.NoCommits,
1948.4.33 by John Arbash Meinel
Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin)
650
                          self.get_in_history, 'branch:new_tree')
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
651
        self.assertRaises(errors.NoCommits,
652
                          self.get_as_tree, 'branch:new_tree')
1551.10.32 by Aaron Bentley
Add submit: specifier, for merge-directive-like diffs
653
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
654
    def test_as_revision_id(self):
655
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
656
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
657
    def test_as_tree(self):
658
        tree = self.get_as_tree('branch:tree', self.tree2)
659
        self.assertEquals('r2', tree.get_revision_id())
660
        self.assertFalse(self.tree2.branch.repository.has_revision('r2'))
661
1551.10.32 by Aaron Bentley
Add submit: specifier, for merge-directive-like diffs
662
663
class TestRevisionSpec_submit(TestRevisionSpec):
664
665
    def test_submit_branch(self):
666
        # Common ancestor of trees is 'alt_r2'
667
        self.assertRaises(errors.NoSubmitBranch, self.get_in_history,
668
                          'submit:')
669
        self.tree.branch.set_parent('../tree2')
670
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
671
        self.tree.branch.set_parent('bogus')
672
        self.assertRaises(errors.NotBranchError, self.get_in_history,
673
            'submit:')
674
        # submit branch overrides parent branch
675
        self.tree.branch.set_submit_branch('tree2')
676
        self.assertInHistoryIs(None, 'alt_r2', 'submit:')
3298.2.3 by John Arbash Meinel
Add tests that all RevisionSpecs implement in_branch(b, needs_revno)
677
3298.2.4 by John Arbash Meinel
Introduce as_revision_id() as a function instead of in_branch(need_revno=False)
678
    def test_as_revision_id(self):
679
        self.tree.branch.set_submit_branch('tree2')
680
        self.assertAsRevisionId('alt_r2', 'branch:tree2')
5365.6.4 by Aaron Bentley
Implement mainline revision spec.
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')
5365.6.6 by Aaron Bentley
Implement 'annotate' revision-id.
698
699
700
class TestRevisionSpec_annotate(TestRevisionSpec):
701
702
    def setUp(self):
703
        TestRevisionSpec.setUp(self)
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
5365.6.10 by Andrew Bennetts
Fix typo in test method name.
726
    def test_non_existent_line(self):
5365.6.6 by Aaron Bentley
Implement 'annotate' revision-id.
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")