~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

First programmatic generation of completions.

The list of commands is generated, as is the list of possible switches for
each command. Commands requiring arguments aren't treated specially yet.

For every option name there is a list of switches, and if any switch for the
option is given, then the others will be suppressed.  This might be
incorrect in some cases, but closely mimics the old, static function.  The
list of these switch suppressions might be incomplete, as some switches
might have different alternative forms for different commands, in which
cases only the intersection of all alternatives gets suppressed.  A future
version might do this suppression based on the current command, or drop it
completely.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
# -*- coding: utf-8 -*-
3
 
 
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
 
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
 
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 
18
 
 
19
 
"""Black-box tests for bzr.
20
 
 
21
 
These check that it behaves properly when it's invoked through the regular
22
 
command-line interface.
23
 
 
24
 
This always reinvokes bzr through a new Python interpreter, which is a
25
 
bit inefficient but arguably tests in a way more representative of how
26
 
it's normally invoked.
27
 
"""
28
 
 
29
 
import sys
30
 
 
31
 
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
32
 
from bzrlib.branch import Branch
33
 
from bzrlib.commands import run_bzr
34
 
 
35
 
 
36
 
class ExternalBase(TestCaseInTempDir):
37
 
    def runbzr(self, args, retcode=0,backtick=False):
38
 
        if isinstance(args, basestring):
39
 
            args = args.split()
40
 
 
41
 
        if backtick:
42
 
            return self.backtick(['python', self.BZRPATH,] + args,
43
 
                           retcode=retcode)
44
 
        else:
45
 
            return self.runcmd(['python', self.BZRPATH,] + args,
46
 
                           retcode=retcode)
47
 
 
48
 
 
49
 
class TestCommands(ExternalBase):
50
 
 
51
 
    def test_help_commands(self):
52
 
        self.runbzr('--help')
53
 
        self.runbzr('help')
54
 
        self.runbzr('help commands')
55
 
        self.runbzr('help help')
56
 
        self.runbzr('commit -h')
57
 
 
58
 
    def test_init_branch(self):
59
 
        self.runbzr(['init'])
60
 
 
61
 
    def test_whoami(self):
62
 
        # this should always identify something, if only "john@localhost"
63
 
        self.runbzr("whoami")
64
 
        self.runbzr("whoami --email")
65
 
 
66
 
        self.assertEquals(self.runbzr("whoami --email",
67
 
                                      backtick=True).count('@'), 1)
68
 
        
69
 
    def test_whoami_branch(self):
70
 
        """branch specific user identity works."""
71
 
        self.runbzr('init')
72
 
        f = file('.bzr/email', 'wt')
73
 
        f.write('Branch Identity <branch@identi.ty>')
74
 
        f.close()
75
 
        whoami = self.runbzr("whoami",backtick=True)
76
 
        whoami_email = self.runbzr("whoami --email",backtick=True)
77
 
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
78
 
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
79
 
 
80
 
    def test_invalid_commands(self):
81
 
        self.runbzr("pants", retcode=1)
82
 
        self.runbzr("--pants off", retcode=1)
83
 
        self.runbzr("diff --message foo", retcode=1)
84
 
 
85
 
    def test_empty_commit(self):
86
 
        self.runbzr("init")
87
 
        self.build_tree(['hello.txt'])
88
 
        self.runbzr("commit -m empty", retcode=1)
89
 
        self.runbzr("add hello.txt")
90
 
        self.runbzr("commit -m added")
91
 
 
92
 
    def test_ignore_patterns(self):
93
 
        from bzrlib.branch import Branch
94
 
        
95
 
        b = Branch('.', init=True)
96
 
        self.assertEquals(list(b.unknowns()), [])
97
 
 
98
 
        file('foo.tmp', 'wt').write('tmp files are ignored')
99
 
        self.assertEquals(list(b.unknowns()), [])
100
 
        assert self.backtick('bzr unknowns') == ''
101
 
 
102
 
        file('foo.c', 'wt').write('int main() {}')
103
 
        self.assertEquals(list(b.unknowns()), ['foo.c'])
104
 
        assert self.backtick('bzr unknowns') == 'foo.c\n'
105
 
 
106
 
        self.runbzr(['add', 'foo.c'])
107
 
        assert self.backtick('bzr unknowns') == ''
108
 
 
109
 
        # 'ignore' works when creating the .bzignore file
110
 
        file('foo.blah', 'wt').write('blah')
111
 
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
112
 
        self.runbzr('ignore *.blah')
113
 
        self.assertEquals(list(b.unknowns()), [])
114
 
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
115
 
 
116
 
        # 'ignore' works when then .bzrignore file already exists
117
 
        file('garh', 'wt').write('garh')
118
 
        self.assertEquals(list(b.unknowns()), ['garh'])
119
 
        assert self.backtick('bzr unknowns') == 'garh\n'
120
 
        self.runbzr('ignore garh')
121
 
        self.assertEquals(list(b.unknowns()), [])
122
 
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
123
 
 
124
 
    def test_revert(self):
125
 
        import os
126
 
        self.runbzr('init')
127
 
 
128
 
        file('hello', 'wt').write('foo')
129
 
        self.runbzr('add hello')
130
 
        self.runbzr('commit -m setup hello')
131
 
 
132
 
        file('goodbye', 'wt').write('baz')
133
 
        self.runbzr('add goodbye')
134
 
        self.runbzr('commit -m setup goodbye')
135
 
        
136
 
        file('hello', 'wt').write('bar')
137
 
        file('goodbye', 'wt').write('qux')
138
 
        self.runbzr('revert hello')
139
 
        self.check_file_contents('hello', 'foo')
140
 
        self.check_file_contents('goodbye', 'qux')
141
 
        self.runbzr('revert')
142
 
        self.check_file_contents('goodbye', 'baz')
143
 
 
144
 
        os.mkdir('revertdir')
145
 
        self.runbzr('add revertdir')
146
 
        self.runbzr('commit -m f')
147
 
        os.rmdir('revertdir')
148
 
        self.runbzr('revert')
149
 
 
150
 
    def skipped_test_mv_modes(self):
151
 
        """Test two modes of operation for mv"""
152
 
        from bzrlib.branch import Branch
153
 
        b = Branch('.', init=True)
154
 
        self.build_tree(['a', 'c', 'subdir/'])
155
 
        self.run_bzr('mv', 'a', 'b')
156
 
        self.run_bzr('mv', 'b', 'subdir')
157
 
        self.run_bzr('mv', 'subdir/b', 'a')
158
 
        self.run_bzr('mv', 'a', 'b', 'subdir')
159
 
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
160
 
 
161
 
    def test_main_version(self):
162
 
        """Check output from version command and master option is reasonable"""
163
 
        # output is intentionally passed through to stdout so that we
164
 
        # can see the version being tested
165
 
        output = self.runbzr('version', backtick=1)
166
 
        self.log('bzr version output:')
167
 
        self.log(output)
168
 
        self.assert_(output.startswith('bzr (bazaar-ng) '))
169
 
        self.assertNotEqual(output.index('Canonical'), -1)
170
 
        # make sure --version is consistent
171
 
        tmp_output = self.runbzr('--version', backtick=1)
172
 
        self.log('bzr --version output:')
173
 
        self.log(tmp_output)
174
 
        self.assertEquals(output, tmp_output)
175
 
 
176
 
    def example_branch(test):
177
 
        test.runbzr('init')
178
 
        file('hello', 'wt').write('foo')
179
 
        test.runbzr('add hello')
180
 
        test.runbzr('commit -m setup hello')
181
 
        file('goodbye', 'wt').write('baz')
182
 
        test.runbzr('add goodbye')
183
 
        test.runbzr('commit -m setup goodbye')
184
 
 
185
 
    def test_revert(self):
186
 
        self.example_branch()
187
 
        file('hello', 'wt').write('bar')
188
 
        file('goodbye', 'wt').write('qux')
189
 
        self.runbzr('revert hello')
190
 
        self.check_file_contents('hello', 'foo')
191
 
        self.check_file_contents('goodbye', 'qux')
192
 
        self.runbzr('revert')
193
 
        self.check_file_contents('goodbye', 'baz')
194
 
 
195
 
    def test_merge(self):
196
 
        from bzrlib.branch import Branch
197
 
        import os
198
 
        
199
 
        os.mkdir('a')
200
 
        os.chdir('a')
201
 
 
202
 
        self.example_branch()
203
 
        os.chdir('..')
204
 
        self.runbzr('branch a b')
205
 
        os.chdir('b')
206
 
        file('goodbye', 'wt').write('quux')
207
 
        self.runbzr(['commit',  '-m',  "more u's are always good"])
208
 
 
209
 
        os.chdir('../a')
210
 
        file('hello', 'wt').write('quuux')
211
 
        # We can't merge when there are in-tree changes
212
 
        self.runbzr('merge ../b', retcode=1)
213
 
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
214
 
        self.runbzr('merge ../b')
215
 
        self.check_file_contents('goodbye', 'quux')
216
 
        # Merging a branch pulls its revision into the tree
217
 
        a = Branch('.')
218
 
        b = Branch('../b')
219
 
        a.get_revision_xml(b.last_patch())
220
 
 
221
 
        self.log('pending merges: %s', a.pending_merges())
222
 
        #        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
223
 
        #        % (a.pending_merges(), b.last_patch())
224
 
 
225
 
 
226
 
    def test_add_reports(self):
227
 
        """add command prints the names of added files."""
228
 
        b = Branch('.', init=True)
229
 
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
230
 
 
231
 
        from cStringIO import StringIO
232
 
        out = StringIO()
233
 
 
234
 
        ret = self.apply_redirected(None, out, None,
235
 
                                    run_bzr,
236
 
                                    ['add'])
237
 
        self.assertEquals(ret, 0)
238
 
 
239
 
        # the ordering is not defined at the moment
240
 
        results = sorted(out.getvalue().rstrip('\n').split('\n'))
241
 
        self.assertEquals(['added dir',
242
 
                           'added dir/sub.txt',
243
 
                           'added top.txt',],
244
 
                          results)
245
 
 
246
 
 
247
 
class OldTests(ExternalBase):
248
 
    """old tests moved from ./testbzr."""
249
 
 
250
 
    def test_bzr(self):
251
 
        from os import chdir, mkdir
252
 
        from os.path import exists
253
 
        import os
254
 
 
255
 
        runbzr = self.runbzr
256
 
        backtick = self.backtick
257
 
        progress = self.log
258
 
 
259
 
        progress("basic branch creation")
260
 
        mkdir('branch1')
261
 
        chdir('branch1')
262
 
        runbzr('init')
263
 
 
264
 
        self.assertEquals(backtick('bzr root').rstrip(),
265
 
                          os.path.join(self.test_dir, 'branch1'))
266
 
 
267
 
        progress("status of new file")
268
 
 
269
 
        f = file('test.txt', 'wt')
270
 
        f.write('hello world!\n')
271
 
        f.close()
272
 
 
273
 
        out = backtick("bzr unknowns")
274
 
        self.assertEquals(out, 'test.txt\n')
275
 
 
276
 
        out = backtick("bzr status")
277
 
        assert out == 'unknown:\n  test.txt\n'
278
 
 
279
 
        out = backtick("bzr status --all")
280
 
        assert out == "unknown:\n  test.txt\n"
281
 
 
282
 
        out = backtick("bzr status test.txt --all")
283
 
        assert out == "unknown:\n  test.txt\n"
284
 
 
285
 
        f = file('test2.txt', 'wt')
286
 
        f.write('goodbye cruel world...\n')
287
 
        f.close()
288
 
 
289
 
        out = backtick("bzr status test.txt")
290
 
        assert out == "unknown:\n  test.txt\n"
291
 
 
292
 
        out = backtick("bzr status")
293
 
        assert out == ("unknown:\n"
294
 
                       "  test.txt\n"
295
 
                       "  test2.txt\n")
296
 
 
297
 
        os.unlink('test2.txt')
298
 
 
299
 
        progress("command aliases")
300
 
        out = backtick("bzr st --all")
301
 
        assert out == ("unknown:\n"
302
 
                       "  test.txt\n")
303
 
 
304
 
        out = backtick("bzr stat")
305
 
        assert out == ("unknown:\n"
306
 
                       "  test.txt\n")
307
 
 
308
 
        progress("command help")
309
 
        runbzr("help st")
310
 
        runbzr("help")
311
 
        runbzr("help commands")
312
 
        runbzr("help slartibartfast", 1)
313
 
 
314
 
        out = backtick("bzr help ci")
315
 
        out.index('aliases: ')
316
 
 
317
 
        progress("can't rename unversioned file")
318
 
        runbzr("rename test.txt new-test.txt", 1)
319
 
 
320
 
        progress("adding a file")
321
 
 
322
 
        runbzr("add test.txt")
323
 
        assert backtick("bzr unknowns") == ''
324
 
        assert backtick("bzr status --all") == ("added:\n"
325
 
                                                "  test.txt\n")
326
 
 
327
 
        progress("rename newly-added file")
328
 
        runbzr("rename test.txt hello.txt")
329
 
        assert os.path.exists("hello.txt")
330
 
        assert not os.path.exists("test.txt")
331
 
 
332
 
        assert backtick("bzr revno") == '0\n'
333
 
 
334
 
        progress("add first revision")
335
 
        runbzr(['commit', '-m', 'add first revision'])
336
 
 
337
 
        progress("more complex renames")
338
 
        os.mkdir("sub1")
339
 
        runbzr("rename hello.txt sub1", 1)
340
 
        runbzr("rename hello.txt sub1/hello.txt", 1)
341
 
        runbzr("move hello.txt sub1", 1)
342
 
 
343
 
        runbzr("add sub1")
344
 
        runbzr("rename sub1 sub2")
345
 
        runbzr("move hello.txt sub2")
346
 
        assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
347
 
 
348
 
        assert exists("sub2")
349
 
        assert exists("sub2/hello.txt")
350
 
        assert not exists("sub1")
351
 
        assert not exists("hello.txt")
352
 
 
353
 
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
354
 
 
355
 
        mkdir("sub1")
356
 
        runbzr('add sub1')
357
 
        runbzr('move sub2/hello.txt sub1')
358
 
        assert not exists('sub2/hello.txt')
359
 
        assert exists('sub1/hello.txt')
360
 
        runbzr('move sub2 sub1')
361
 
        assert not exists('sub2')
362
 
        assert exists('sub1/sub2')
363
 
 
364
 
        runbzr(['commit', '-m', 'rename nested subdirectories'])
365
 
 
366
 
        chdir('sub1/sub2')
367
 
        self.assertEquals(backtick('bzr root')[:-1],
368
 
                          os.path.join(self.test_dir, 'branch1'))
369
 
        runbzr('move ../hello.txt .')
370
 
        assert exists('./hello.txt')
371
 
        assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
372
 
        assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
373
 
        runbzr(['commit', '-m', 'move to parent directory'])
374
 
        chdir('..')
375
 
        assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
376
 
 
377
 
        runbzr('move sub2/hello.txt .')
378
 
        assert exists('hello.txt')
379
 
 
380
 
        f = file('hello.txt', 'wt')
381
 
        f.write('some nice new content\n')
382
 
        f.close()
383
 
 
384
 
        f = file('msg.tmp', 'wt')
385
 
        f.write('this is my new commit\n')
386
 
        f.close()
387
 
 
388
 
        runbzr('commit -F msg.tmp')
389
 
 
390
 
        assert backtick('bzr revno') == '5\n'
391
 
        runbzr('export -r 5 export-5.tmp')
392
 
        runbzr('export export.tmp')
393
 
 
394
 
        runbzr('log')
395
 
        runbzr('log -v')
396
 
        runbzr('log -v --forward')
397
 
        runbzr('log -m', retcode=1)
398
 
        log_out = backtick('bzr log -m commit')
399
 
        assert "this is my new commit" in log_out
400
 
        assert "rename nested" not in log_out
401
 
        assert 'revision-id' not in log_out
402
 
        assert 'revision-id' in backtick('bzr log --show-ids -m commit')
403
 
 
404
 
 
405
 
        progress("file with spaces in name")
406
 
        mkdir('sub directory')
407
 
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
408
 
        runbzr('add .')
409
 
        runbzr('diff')
410
 
        runbzr('commit -m add-spaces')
411
 
        runbzr('check')
412
 
 
413
 
        runbzr('log')
414
 
        runbzr('log --forward')
415
 
 
416
 
        runbzr('info')
417