~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_version_info.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-09 21:42:24 UTC
  • mto: This revision was merged to the branch mainline in revision 3543.
  • Revision ID: john@arbash-meinel.com-20080709214224-r75k87r6a01pfc3h
Restore a real weave merge to 'bzr merge --weave'.

To do so efficiently, we only add the simple LCAs to the final weave
object, unless we run into complexities with the merge graph.
This gives the same effective result as adding all the texts,
with the advantage of not having to extract all of them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for version_info"""
18
18
 
23
23
 
24
24
from bzrlib import (
25
25
    errors,
26
 
    registry,
 
26
    symbol_versioning,
27
27
    tests,
28
28
    version_info_formats,
29
29
    )
35
35
from bzrlib.version_info_formats.format_python import PythonVersionInfoBuilder
36
36
 
37
37
 
38
 
class VersionInfoTestCase(TestCaseWithTransport):
 
38
class TestVersionInfo(TestCaseWithTransport):
39
39
 
40
40
    def create_branch(self):
41
41
        wt = self.make_branch_and_tree('branch')
53
53
 
54
54
        return wt
55
55
 
56
 
    def create_tree_with_dotted_revno(self):
57
 
        wt = self.make_branch_and_tree('branch')
58
 
        self.build_tree(['branch/a'])
59
 
        wt.add('a')
60
 
        wt.commit('a', rev_id='r1')
61
 
 
62
 
        other = wt.bzrdir.sprout('other').open_workingtree()
63
 
        self.build_tree(['other/b.a'])
64
 
        other.add(['b.a'])
65
 
        other.commit('b.a', rev_id='o2')
66
 
 
67
 
        os.chdir('branch')
68
 
        self.run_bzr('merge ../other')
69
 
        wt.commit('merge', rev_id='merge')
70
 
 
71
 
        wt.update(revision='o2')
72
 
 
73
 
        return wt
74
 
 
75
 
 
76
 
class TestVersionInfoRio(VersionInfoTestCase):
77
 
 
78
 
    def test_rio_null(self):
79
 
        wt = self.make_branch_and_tree('branch')
80
 
 
81
 
        sio = StringIO()
82
 
        builder = RioVersionInfoBuilder(wt.branch, working_tree=wt)
83
 
        builder.generate(sio)
84
 
        val = sio.getvalue()
85
 
        self.assertContainsRe(val, 'build-date:')
86
 
        self.assertContainsRe(val, 'revno: 0')
87
 
 
88
 
    def test_rio_dotted_revno(self):
89
 
        wt = self.create_tree_with_dotted_revno()
90
 
 
91
 
        sio = StringIO()
92
 
        builder = RioVersionInfoBuilder(wt.branch, working_tree=wt)
93
 
        builder.generate(sio)
94
 
        val = sio.getvalue()
95
 
        self.assertContainsRe(val, 'revno: 1.1.1')
96
 
 
97
 
    def regen_text(self, wt, **kwargs):
98
 
        sio = StringIO()
99
 
        builder = RioVersionInfoBuilder(wt.branch, working_tree=wt, **kwargs)
100
 
        builder.generate(sio)
101
 
        val = sio.getvalue()
102
 
        return val
103
 
 
104
 
    def test_simple(self):
 
56
    def test_rio_version_text(self):
105
57
        wt = self.create_branch()
106
58
 
107
 
        val = self.regen_text(wt)
 
59
        def regen(**kwargs):
 
60
            sio = StringIO()
 
61
            builder = RioVersionInfoBuilder(wt.branch, working_tree=wt,
 
62
                                            **kwargs)
 
63
            builder.generate(sio)
 
64
            val = sio.getvalue()
 
65
            return val
 
66
 
 
67
        val = regen()
108
68
        self.assertContainsRe(val, 'build-date:')
109
69
        self.assertContainsRe(val, 'date:')
110
70
        self.assertContainsRe(val, 'revno: 3')
111
71
        self.assertContainsRe(val, 'revision-id: r3')
112
72
 
113
 
    def test_clean(self):
114
 
        wt = self.create_branch()
115
 
        val = self.regen_text(wt, check_for_clean=True)
 
73
        val = regen(check_for_clean=True)
116
74
        self.assertContainsRe(val, 'clean: True')
117
75
 
118
 
    def test_no_clean(self):
119
 
        wt = self.create_branch()
120
76
        self.build_tree(['branch/c'])
121
 
        val = self.regen_text(wt, check_for_clean=True)
 
77
        val = regen(check_for_clean=True)
122
78
        self.assertContainsRe(val, 'clean: False')
123
 
 
124
 
    def test_history(self):
125
 
        wt = self.create_branch()
126
 
 
127
 
        val = self.regen_text(wt, include_revision_history=True)
 
79
        os.remove('branch/c')
 
80
 
 
81
        val = regen(include_revision_history=True)
128
82
        self.assertContainsRe(val, 'id: r1')
129
83
        self.assertContainsRe(val, 'message: a')
130
84
        self.assertContainsRe(val, 'id: r2')
132
86
        self.assertContainsRe(val, 'id: r3')
133
87
        self.assertContainsRe(val, 'message: \xc3\xa52') # utf8 encoding '\xe5'
134
88
 
135
 
    def regen(self, wt, **kwargs):
136
 
        sio = StringIO()
137
 
        builder = RioVersionInfoBuilder(wt.branch, working_tree=wt, **kwargs)
138
 
        builder.generate(sio)
139
 
        sio.seek(0)
140
 
        stanzas = list(read_stanzas(sio))
141
 
        self.assertEqual(1, len(stanzas))
142
 
        return stanzas[0]
143
 
 
144
 
    def test_rio_version_hook(self):
145
 
        def update_stanza(rev, stanza):
146
 
            stanza.add('bla', 'bloe')
147
 
        RioVersionInfoBuilder.hooks.install_named_hook(
148
 
            'revision', update_stanza, None)
149
 
        wt = self.create_branch()
150
 
 
151
 
        stanza = self.regen(wt)
152
 
        self.assertEqual(['bloe'], stanza.get_all('bla'))
153
 
 
154
 
    def get_one_stanza(self, stanza, key):
155
 
        new_stanzas = list(read_stanzas(StringIO(stanza[key].encode('utf8'))))
156
 
        self.assertEqual(1, len(new_stanzas))
157
 
        return new_stanzas[0]
158
 
 
159
 
    def test_build_date(self):
160
 
        wt = self.create_branch()
161
 
        stanza = self.regen(wt)
162
 
        self.assertTrue('date' in stanza)
163
 
        self.assertTrue('build-date' in stanza)
 
89
    def test_rio_version(self):
 
90
        wt = self.create_branch()
 
91
 
 
92
        def regen(**kwargs):
 
93
            sio = StringIO()
 
94
            builder = RioVersionInfoBuilder(wt.branch, working_tree=wt,
 
95
                                            **kwargs)
 
96
            builder.generate(sio)
 
97
            sio.seek(0)
 
98
            stanzas = list(read_stanzas(sio))
 
99
            self.assertEqual(1, len(stanzas))
 
100
            return stanzas[0]
 
101
 
 
102
        def get_one_stanza(stanza, key):
 
103
            new_stanzas = list(read_stanzas(
 
104
                                StringIO(stanza[key].encode('utf8'))))
 
105
            self.assertEqual(1, len(new_stanzas))
 
106
            return new_stanzas[0]
 
107
 
 
108
        stanza = regen()
 
109
        self.failUnless('date' in stanza)
 
110
        self.failUnless('build-date' in stanza)
164
111
        self.assertEqual(['3'], stanza.get_all('revno'))
165
112
        self.assertEqual(['r3'], stanza.get_all('revision-id'))
166
113
 
167
 
    def test_not_clean(self):
168
 
        wt = self.create_branch()
 
114
        stanza = regen(check_for_clean=True)
 
115
        self.assertEqual(['True'], stanza.get_all('clean'))
 
116
 
169
117
        self.build_tree(['branch/c'])
170
 
        stanza = self.regen(wt, check_for_clean=True, include_file_revisions=True)
 
118
        stanza = regen(check_for_clean=True, include_file_revisions=True)
171
119
        self.assertEqual(['False'], stanza.get_all('clean'))
172
120
 
173
 
    def test_file_revisions(self):
174
 
        wt = self.create_branch()
175
 
        self.build_tree(['branch/c'])
176
 
        stanza = self.regen(wt, check_for_clean=True, include_file_revisions=True)
177
 
        # This assumes it's being run against a tree that does not update the
178
 
        # root revision on every commit.
179
 
        file_rev_stanza = self.get_one_stanza(stanza, 'file-revisions')
 
121
        # XXX: This assumes it's being run against a repository that updates
 
122
        # the root revision on every commit.  Newer ones that use
 
123
        # RootCommitBuilder won't update it on each commit.
 
124
        file_rev_stanza = get_one_stanza(stanza, 'file-revisions')
180
125
        self.assertEqual(['', 'a', 'b', 'c'], file_rev_stanza.get_all('path'))
181
 
        self.assertEqual(['r1', 'r3', 'r2', 'unversioned'],
 
126
        self.assertEqual(['r3', 'r3', 'r2', 'unversioned'],
182
127
            file_rev_stanza.get_all('revision'))
 
128
        os.remove('branch/c')
183
129
 
184
 
    def test_revision_history(self):
185
 
        wt = self.create_branch()
186
 
        stanza = self.regen(wt, include_revision_history=True)
187
 
        revision_stanza = self.get_one_stanza(stanza, 'revisions')
 
130
        stanza = regen(include_revision_history=True)
 
131
        revision_stanza = get_one_stanza(stanza, 'revisions')
188
132
        self.assertEqual(['r1', 'r2', 'r3'], revision_stanza.get_all('id'))
189
133
        self.assertEqual(['a', 'b', u'\xe52'], revision_stanza.get_all('message'))
190
134
        self.assertEqual(3, len(revision_stanza.get_all('date')))
191
135
 
192
 
    def test_file_revisions_with_rename(self):
193
136
        # a was modified, so it should show up modified again
194
 
        wt = self.create_branch()
195
137
        self.build_tree(['branch/a', 'branch/c'])
196
138
        wt.add('c')
197
139
        wt.rename_one('b', 'd')
198
 
        stanza = self.regen(wt, check_for_clean=True, include_file_revisions=True)
199
 
        file_rev_stanza = self.get_one_stanza(stanza, 'file-revisions')
200
 
        self.assertEqual(['', 'a', 'b', 'c', 'd'],
 
140
        stanza = regen(check_for_clean=True, include_file_revisions=True)
 
141
        file_rev_stanza = get_one_stanza(stanza, 'file-revisions')
 
142
        self.assertEqual(['', 'a', 'b', 'c', 'd'], 
201
143
                          file_rev_stanza.get_all('path'))
202
 
        self.assertEqual(['r1', 'modified', 'renamed to d', 'new',
 
144
        self.assertEqual(['r3', 'modified', 'renamed to d', 'new', 
203
145
                          'renamed from b'],
204
146
                         file_rev_stanza.get_all('revision'))
205
147
 
206
 
    def test_file_revisions_with_removal(self):
207
 
        wt = self.create_branch()
208
 
        self.build_tree(['branch/a', 'branch/c'])
209
 
        wt.add('c')
210
 
        wt.rename_one('b', 'd')
211
 
 
212
148
        wt.commit('modified', rev_id='r4')
213
 
 
214
149
        wt.remove(['c', 'd'])
215
150
        os.remove('branch/d')
216
 
        stanza = self.regen(wt, check_for_clean=True, include_file_revisions=True)
217
 
        file_rev_stanza = self.get_one_stanza(stanza, 'file-revisions')
 
151
        stanza = regen(check_for_clean=True, include_file_revisions=True)
 
152
        file_rev_stanza = get_one_stanza(stanza, 'file-revisions')
218
153
        self.assertEqual(['', 'a', 'c', 'd'], file_rev_stanza.get_all('path'))
219
 
        self.assertEqual(['r1', 'r4', 'unversioned', 'removed'],
220
 
                         file_rev_stanza.get_all('revision'))
221
 
 
222
 
    def test_revision(self):
223
 
        wt = self.create_branch()
224
 
        self.build_tree(['branch/a', 'branch/c'])
225
 
        wt.add('c')
226
 
        wt.rename_one('b', 'd')
227
 
 
228
 
        stanza = self.regen(wt, check_for_clean=True,
229
 
            include_file_revisions=True, revision_id=wt.last_revision())
230
 
        file_rev_stanza = self.get_one_stanza(stanza, 'file-revisions')
231
 
        self.assertEqual(['', 'a', 'b'], file_rev_stanza.get_all('path'))
232
 
        self.assertEqual(['r1', 'r3', 'r2'],
233
 
                         file_rev_stanza.get_all('revision'))
234
 
 
235
 
 
236
 
class PythonVersionInfoTests(VersionInfoTestCase):
237
 
 
238
 
    def test_python_null(self):
239
 
        wt = self.make_branch_and_tree('branch')
240
 
 
241
 
        sio = StringIO()
242
 
        builder = PythonVersionInfoBuilder(wt.branch, working_tree=wt)
243
 
        builder.generate(sio)
244
 
        val = sio.getvalue()
245
 
        self.assertContainsRe(val, "'revision_id': None")
246
 
        self.assertContainsRe(val, "'revno': '0'")
247
 
        self.assertNotContainsString(val, '\n\n\n\n')
248
 
 
249
 
    def test_python_dotted_revno(self):
250
 
        wt = self.create_tree_with_dotted_revno()
251
 
 
252
 
        sio = StringIO()
253
 
        builder = PythonVersionInfoBuilder(wt.branch, working_tree=wt)
254
 
        builder.generate(sio)
255
 
        val = sio.getvalue()
256
 
        self.assertContainsRe(val, "'revno': '1.1.1'")
257
 
 
258
 
    def regen(self, wt, **kwargs):
259
 
        """Create a test module, import and return it"""
260
 
        outf = open('test_version_information.py', 'wb')
261
 
        try:
262
 
            builder = PythonVersionInfoBuilder(wt.branch, working_tree=wt,
263
 
                                               **kwargs)
264
 
            builder.generate(outf)
265
 
        finally:
266
 
            outf.close()
267
 
        module_info = imp.find_module('test_version_information',
268
 
                                      [os.getcwdu()])
269
 
        tvi = imp.load_module('tvi', *module_info)
270
 
        # Make sure the module isn't cached
271
 
        sys.modules.pop('tvi', None)
272
 
        sys.modules.pop('test_version_information', None)
273
 
        # Delete the compiled versions, because we are generating
274
 
        # a new file fast enough that python doesn't detect it
275
 
        # needs to recompile, and using sleep() just makes the
276
 
        # test slow
277
 
        if os.path.exists('test_version_information.pyc'):
278
 
            os.remove('test_version_information.pyc')
279
 
        if os.path.exists('test_version_information.pyo'):
280
 
            os.remove('test_version_information.pyo')
281
 
        return tvi
 
154
        self.assertEqual(['r4', 'r4', 'unversioned', 'removed'],
 
155
                         file_rev_stanza.get_all('revision'))
282
156
 
283
157
    def test_python_version(self):
284
158
        wt = self.create_branch()
285
159
 
286
 
        tvi = self.regen(wt)
287
 
        self.assertEqual('3', tvi.version_info['revno'])
 
160
        def regen(**kwargs):
 
161
            """Create a test module, import and return it"""
 
162
            outf = open('test_version_information.py', 'wb')
 
163
            try:
 
164
                builder = PythonVersionInfoBuilder(wt.branch, working_tree=wt,
 
165
                                                   **kwargs)
 
166
                builder.generate(outf)
 
167
            finally:
 
168
                outf.close()
 
169
            module_info = imp.find_module('test_version_information',
 
170
                                          [os.getcwdu()])
 
171
            tvi = imp.load_module('tvi', *module_info)
 
172
            # Make sure the module isn't cached
 
173
            sys.modules.pop('tvi', None)
 
174
            sys.modules.pop('test_version_information', None)
 
175
            # Delete the compiled versions, because we are generating
 
176
            # a new file fast enough that python doesn't detect it
 
177
            # needs to recompile, and using sleep() just makes the
 
178
            # test slow
 
179
            if os.path.exists('test_version_information.pyc'):
 
180
                os.remove('test_version_information.pyc')
 
181
            if os.path.exists('test_version_information.pyo'):
 
182
                os.remove('test_version_information.pyo')
 
183
            return tvi
 
184
 
 
185
        tvi = regen()
 
186
        self.assertEqual(3, tvi.version_info['revno'])
288
187
        self.assertEqual('r3', tvi.version_info['revision_id'])
289
 
        self.assertTrue(tvi.version_info.has_key('date'))
 
188
        self.failUnless(tvi.version_info.has_key('date'))
290
189
        self.assertEqual(None, tvi.version_info['clean'])
291
190
 
292
 
        tvi = self.regen(wt, check_for_clean=True)
 
191
        tvi = regen(check_for_clean=True)
293
192
        self.assertEqual(True, tvi.version_info['clean'])
294
193
 
295
194
        self.build_tree(['branch/c'])
296
 
        tvi = self.regen(wt, check_for_clean=True, include_file_revisions=True)
 
195
        tvi = regen(check_for_clean=True, include_file_revisions=True)
297
196
        self.assertEqual(False, tvi.version_info['clean'])
298
 
        self.assertEqual(['', 'a', 'b', 'c'],
 
197
        self.assertEqual(['', 'a', 'b', 'c'], 
299
198
                         sorted(tvi.file_revisions.keys()))
300
199
        self.assertEqual('r3', tvi.file_revisions['a'])
301
200
        self.assertEqual('r2', tvi.file_revisions['b'])
302
201
        self.assertEqual('unversioned', tvi.file_revisions['c'])
303
202
        os.remove('branch/c')
304
203
 
305
 
        tvi = self.regen(wt, include_revision_history=True)
 
204
        tvi = regen(include_revision_history=True)
306
205
 
307
206
        rev_info = [(rev, message) for rev, message, timestamp, timezone
308
207
                                   in tvi.revisions]
312
211
        self.build_tree(['branch/a', 'branch/c'])
313
212
        wt.add('c')
314
213
        wt.rename_one('b', 'd')
315
 
        tvi = self.regen(wt, check_for_clean=True, include_file_revisions=True)
316
 
        self.assertEqual(['', 'a', 'b', 'c', 'd'],
 
214
        tvi = regen(check_for_clean=True, include_file_revisions=True)
 
215
        self.assertEqual(['', 'a', 'b', 'c', 'd'], 
317
216
                          sorted(tvi.file_revisions.keys()))
318
217
        self.assertEqual('modified', tvi.file_revisions['a'])
319
218
        self.assertEqual('renamed to d', tvi.file_revisions['b'])
323
222
        wt.commit('modified', rev_id='r4')
324
223
        wt.remove(['c', 'd'])
325
224
        os.remove('branch/d')
326
 
        tvi = self.regen(wt, check_for_clean=True, include_file_revisions=True)
327
 
        self.assertEqual(['', 'a', 'c', 'd'],
 
225
        tvi = regen(check_for_clean=True, include_file_revisions=True)
 
226
        self.assertEqual(['', 'a', 'c', 'd'], 
328
227
                          sorted(tvi.file_revisions.keys()))
329
228
        self.assertEqual('r4', tvi.file_revisions['a'])
330
229
        self.assertEqual('unversioned', tvi.file_revisions['c'])
331
230
        self.assertEqual('removed', tvi.file_revisions['d'])
332
231
 
333
 
 
334
 
class CustomVersionInfoTests(VersionInfoTestCase):
335
 
 
336
 
    def test_custom_null(self):
337
 
        sio = StringIO()
338
 
        wt = self.make_branch_and_tree('branch')
339
 
        builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt,
340
 
            template='revno: {revno}')
341
 
        builder.generate(sio)
342
 
        self.assertEqual("revno: 0", sio.getvalue())
343
 
 
344
 
        builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt, 
345
 
            template='{revno} revid: {revision_id}')
346
 
        # revision_id is not available yet
347
 
        self.assertRaises(errors.MissingTemplateVariable, 
348
 
            builder.generate, sio)
349
 
 
350
 
    def test_custom_dotted_revno(self):
351
 
        sio = StringIO()
352
 
        wt = self.create_tree_with_dotted_revno()
353
 
        builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt, 
354
 
            template='{revno} revid: {revision_id}')
355
 
        builder.generate(sio)
356
 
        self.assertEqual("1.1.1 revid: o2", sio.getvalue())
357
 
 
358
 
    def regen(self, wt, tpl, **kwargs):
359
 
        sio = StringIO()
360
 
        builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt,
361
 
                                           template=tpl, **kwargs)
362
 
        builder.generate(sio)
363
 
        val = sio.getvalue()
364
 
        return val
365
 
 
366
 
    def test_build_date(self):
 
232
    def test_custom_version_text(self):
367
233
        wt = self.create_branch()
368
234
 
369
 
        val = self.regen(wt, 'build-date: "{build_date}"\ndate: "{date}"')
 
235
        def regen(tpl, **kwargs):
 
236
            sio = StringIO()
 
237
            builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt,
 
238
                                               template=tpl, **kwargs)
 
239
            builder.generate(sio)
 
240
            val = sio.getvalue()
 
241
            return val
 
242
 
 
243
        val = regen('build-date: "{build_date}"\ndate: "{date}"')
370
244
        self.assertContainsRe(val, 'build-date: "[0-9-+: ]+"')
371
245
        self.assertContainsRe(val, 'date: "[0-9-+: ]+"')
372
246
 
373
 
    def test_revno(self):
374
 
        wt = self.create_branch()
375
 
        val = self.regen(wt, 'revno: {revno}')
 
247
        val = regen('revno: {revno}')
376
248
        self.assertEqual(val, 'revno: 3')
377
249
 
378
 
    def test_revision_id(self):
379
 
        wt = self.create_branch()
380
 
        val = self.regen(wt, 'revision-id: {revision_id}')
 
250
        val = regen('revision-id: {revision_id}')
381
251
        self.assertEqual(val, 'revision-id: r3')
382
252
 
383
 
    def test_clean(self):
384
 
        wt = self.create_branch()
385
 
        val = self.regen(wt, 'clean: {clean}', check_for_clean=True)
 
253
        val = regen('clean: {clean}', check_for_clean=True)
386
254
        self.assertEqual(val, 'clean: 1')
387
255
 
388
 
    def test_not_clean(self):
389
 
        wt = self.create_branch()
390
 
 
391
256
        self.build_tree(['branch/c'])
392
 
        val = self.regen(wt, 'clean: {clean}', check_for_clean=True)
 
257
        val = regen('clean: {clean}', check_for_clean=True)
393
258
        self.assertEqual(val, 'clean: 0')
394
259
        os.remove('branch/c')
395
260
 
407
272
 
408
273
    def setUp(self):
409
274
        super(TestVersionInfoFormatRegistry, self).setUp()
410
 
        self.overrideAttr(version_info_formats,
411
 
                          'format_registry', registry.Registry())
 
275
        registry = version_info_formats.format_registry
 
276
        self._default_key = registry._default_key
 
277
        self._dict = registry._dict.copy()
 
278
        self._help_dict = registry._help_dict.copy()
 
279
        self._info_dict = registry._info_dict.copy()
 
280
        self.addCleanup(self._cleanup)
 
281
 
 
282
    def _cleanup(self):
 
283
        # Restore the registry to pristine state after the test runs
 
284
        registry = version_info_formats.format_registry
 
285
        registry._default_key = self._default_key
 
286
        registry._dict = self._dict
 
287
        registry._help_dict = self._help_dict
 
288
        registry._info_dict = self._info_dict
412
289
 
413
290
    def test_register_remove(self):
414
291
        registry = version_info_formats.format_registry