~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_script.py

  • Committer: Robert Collins
  • Date: 2005-12-02 03:23:47 UTC
  • Revision ID: robertc@robertcollins.net-20051202032347-ba08123207a945a0
Test for Jeff Bailey.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
2
 
#
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.
7
 
#
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.
12
 
#
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
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
 
18
 
from bzrlib import (
19
 
    commands,
20
 
    osutils,
21
 
    tests,
22
 
    ui,
23
 
    )
24
 
from bzrlib.tests import script
25
 
 
26
 
 
27
 
class TestSyntax(tests.TestCase):
28
 
 
29
 
    def test_comment_is_ignored(self):
30
 
        self.assertEquals([], script._script_to_commands('#comment\n'))
31
 
 
32
 
    def test_comment_multiple_lines(self):
33
 
        self.assertEquals([
34
 
            (['bar'], None, None, None),
35
 
            ],
36
 
            script._script_to_commands("""
37
 
            # this comment is ignored
38
 
            # so is this
39
 
            # no we run bar
40
 
            $ bar
41
 
            """))
42
 
 
43
 
    def test_trim_blank_lines(self):
44
 
        """Blank lines are respected, but trimmed at the start and end.
45
 
 
46
 
        Python triple-quoted syntax is going to give stubby/empty blank lines 
47
 
        right at the start and the end.  These are cut off so that callers don't 
48
 
        need special syntax to avoid them.
49
 
 
50
 
        However we do want to be able to match commands that emit blank lines.
51
 
        """
52
 
        self.assertEquals([
53
 
            (['bar'], None, '\n', None),
54
 
            ],
55
 
            script._script_to_commands("""
56
 
            $bar
57
 
 
58
 
            """))
59
 
 
60
 
    def test_simple_command(self):
61
 
        self.assertEquals([(['cd', 'trunk'], None, None, None)],
62
 
                           script._script_to_commands('$ cd trunk'))
63
 
 
64
 
    def test_command_with_single_quoted_param(self):
65
 
        story = """$ bzr commit -m 'two words'"""
66
 
        self.assertEquals([(['bzr', 'commit', '-m', "'two words'"],
67
 
                            None, None, None)],
68
 
                           script._script_to_commands(story))
69
 
 
70
 
    def test_command_with_double_quoted_param(self):
71
 
        story = """$ bzr commit -m "two words" """
72
 
        self.assertEquals([(['bzr', 'commit', '-m', '"two words"'],
73
 
                            None, None, None)],
74
 
                           script._script_to_commands(story))
75
 
 
76
 
    def test_command_with_input(self):
77
 
        self.assertEquals(
78
 
            [(['cat', '>file'], 'content\n', None, None)],
79
 
            script._script_to_commands('$ cat >file\n<content\n'))
80
 
 
81
 
    def test_indented(self):
82
 
        # scripts are commonly given indented within the test source code, and
83
 
        # common indentation is stripped off
84
 
        story = """
85
 
            $ bzr add
86
 
            adding file
87
 
            adding file2
88
 
            """
89
 
        self.assertEquals([(['bzr', 'add'], None,
90
 
                            'adding file\nadding file2\n', None)],
91
 
                          script._script_to_commands(story))
92
 
 
93
 
    def test_command_with_output(self):
94
 
        story = """
95
 
$ bzr add
96
 
adding file
97
 
adding file2
98
 
"""
99
 
        self.assertEquals([(['bzr', 'add'], None,
100
 
                            'adding file\nadding file2\n', None)],
101
 
                          script._script_to_commands(story))
102
 
 
103
 
    def test_command_with_error(self):
104
 
        story = """
105
 
$ bzr branch foo
106
 
2>bzr: ERROR: Not a branch: "foo"
107
 
"""
108
 
        self.assertEquals([(['bzr', 'branch', 'foo'],
109
 
                            None, None, 'bzr: ERROR: Not a branch: "foo"\n')],
110
 
                          script._script_to_commands(story))
111
 
 
112
 
    def test_input_without_command(self):
113
 
        self.assertRaises(SyntaxError, script._script_to_commands, '<input')
114
 
 
115
 
    def test_output_without_command(self):
116
 
        self.assertRaises(SyntaxError, script._script_to_commands, '>input')
117
 
 
118
 
    def test_command_with_backquotes(self):
119
 
        story = """
120
 
$ foo = `bzr file-id toto`
121
 
"""
122
 
        self.assertEquals([(['foo', '=', '`bzr file-id toto`'],
123
 
                            None, None, None)],
124
 
                          script._script_to_commands(story))
125
 
 
126
 
 
127
 
class TestRedirections(tests.TestCase):
128
 
 
129
 
    def _check(self, in_name, out_name, out_mode, remaining, args):
130
 
        self.assertEqual(script._scan_redirection_options(args),
131
 
                         (in_name, out_name, out_mode, remaining))
132
 
 
133
 
    def test_no_redirection(self):
134
 
        self._check(None, None, None, [], [])
135
 
        self._check(None, None, None, ['foo', 'bar'], ['foo', 'bar'])
136
 
 
137
 
    def test_input_redirection(self):
138
 
        self._check('foo', None, None, [], ['<foo'])
139
 
        self._check('foo', None, None, ['bar'], ['bar', '<foo'])
140
 
        self._check('foo', None, None, ['bar'], ['bar', '<', 'foo'])
141
 
        self._check('foo', None, None, ['bar'], ['<foo', 'bar'])
142
 
        self._check('foo', None, None, ['bar', 'baz'], ['bar', '<foo', 'baz'])
143
 
 
144
 
    def test_output_redirection(self):
145
 
        self._check(None, 'foo', 'wb+', [], ['>foo'])
146
 
        self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>foo'])
147
 
        self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>', 'foo'])
148
 
        self._check(None, 'foo', 'ab+', [], ['>>foo'])
149
 
        self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>foo'])
150
 
        self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>', 'foo'])
151
 
 
152
 
    def test_redirection_syntax_errors(self):
153
 
        self._check('', None, None, [], ['<'])
154
 
        self._check(None, '', 'wb+', [], ['>'])
155
 
        self._check(None, '', 'ab+', [], ['>>'])
156
 
        self._check('>', '', 'ab+', [], ['<', '>', '>>'])
157
 
 
158
 
 
159
 
 
160
 
class TestExecution(script.TestCaseWithTransportAndScript):
161
 
 
162
 
    def test_unknown_command(self):
163
 
        self.assertRaises(SyntaxError, self.run_script, 'foo')
164
 
 
165
 
    def test_stops_on_unexpected_output(self):
166
 
        story = """
167
 
$ mkdir dir
168
 
$ cd dir
169
 
The cd command ouputs nothing
170
 
"""
171
 
        self.assertRaises(AssertionError, self.run_script, story)
172
 
 
173
 
 
174
 
    def test_stops_on_unexpected_error(self):
175
 
        story = """
176
 
$ cat
177
 
<Hello
178
 
$ bzr not-a-command
179
 
"""
180
 
        self.assertRaises(AssertionError, self.run_script, story)
181
 
 
182
 
    def test_continue_on_expected_error(self):
183
 
        story = """
184
 
$ bzr not-a-command
185
 
2>..."not-a-command"
186
 
"""
187
 
        self.run_script(story)
188
 
 
189
 
    def test_continue_on_error_output(self):
190
 
        # The status matters, not the output
191
 
        story = """
192
 
$ bzr init
193
 
$ cat >file
194
 
<Hello
195
 
$ bzr add file
196
 
$ bzr commit -m 'adding file'
197
 
"""
198
 
        self.run_script(story)
199
 
 
200
 
    def test_ellipsis_output(self):
201
 
        story = """
202
 
$ cat
203
 
<first line
204
 
<second line
205
 
<last line
206
 
first line
207
 
...
208
 
last line
209
 
"""
210
 
        self.run_script(story)
211
 
        story = """
212
 
$ bzr not-a-command
213
 
2>..."not-a-command"
214
 
"""
215
 
        self.run_script(story)
216
 
 
217
 
        story = """
218
 
$ bzr branch not-a-branch
219
 
2>bzr: ERROR: Not a branch...not-a-branch/".
220
 
"""
221
 
        self.run_script(story)
222
 
 
223
 
 
224
 
class TestArgumentProcessing(script.TestCaseWithTransportAndScript):
225
 
 
226
 
    def test_globing(self):
227
 
        self.run_script("""
228
 
$ echo cat >cat
229
 
$ echo dog >dog
230
 
$ cat *
231
 
cat
232
 
dog
233
 
""")
234
 
 
235
 
    def test_quoted_globbing(self):
236
 
        self.run_script("""
237
 
$ echo cat >cat
238
 
$ cat '*'
239
 
2>*: No such file or directory
240
 
""")
241
 
 
242
 
    def test_quotes_removal(self):
243
 
        self.run_script("""
244
 
$ echo 'cat' "dog" '"chicken"' "'dragon'"
245
 
cat dog "chicken" 'dragon'
246
 
""")
247
 
 
248
 
 
249
 
class TestCat(script.TestCaseWithTransportAndScript):
250
 
 
251
 
    def test_cat_usage(self):
252
 
        self.assertRaises(SyntaxError, self.run_script, 'cat foo <bar')
253
 
 
254
 
    def test_cat_input_to_output(self):
255
 
        retcode, out, err = self.run_command(['cat'],
256
 
                                             'content\n', 'content\n', None)
257
 
        self.assertEquals('content\n', out)
258
 
        self.assertEquals(None, err)
259
 
 
260
 
    def test_cat_file_to_output(self):
261
 
        self.build_tree_contents([('file', 'content\n')])
262
 
        retcode, out, err = self.run_command(['cat', 'file'],
263
 
                                             None, 'content\n', None)
264
 
        self.assertEquals('content\n', out)
265
 
        self.assertEquals(None, err)
266
 
 
267
 
    def test_cat_input_to_file(self):
268
 
        retcode, out, err = self.run_command(['cat', '>file'],
269
 
                                             'content\n', None, None)
270
 
        self.assertFileEqual('content\n', 'file')
271
 
        self.assertEquals(None, out)
272
 
        self.assertEquals(None, err)
273
 
        retcode, out, err = self.run_command(['cat', '>>file'],
274
 
                                             'more\n', None, None)
275
 
        self.assertFileEqual('content\nmore\n', 'file')
276
 
        self.assertEquals(None, out)
277
 
        self.assertEquals(None, err)
278
 
 
279
 
    def test_cat_file_to_file(self):
280
 
        self.build_tree_contents([('file', 'content\n')])
281
 
        retcode, out, err = self.run_command(['cat', 'file', '>file2'],
282
 
                                             None, None, None)
283
 
        self.assertFileEqual('content\n', 'file2')
284
 
 
285
 
    def test_cat_files_to_file(self):
286
 
        self.build_tree_contents([('cat', 'cat\n')])
287
 
        self.build_tree_contents([('dog', 'dog\n')])
288
 
        retcode, out, err = self.run_command(['cat', 'cat', 'dog', '>file'],
289
 
                                             None, None, None)
290
 
        self.assertFileEqual('cat\ndog\n', 'file')
291
 
 
292
 
    def test_cat_bogus_input_file(self):
293
 
        self.run_script("""
294
 
$ cat <file
295
 
2>file: No such file or directory
296
 
""")
297
 
 
298
 
    def test_cat_bogus_output_file(self):
299
 
        self.run_script("""
300
 
$ cat >
301
 
2>: No such file or directory
302
 
""")
303
 
 
304
 
    def test_echo_bogus_output_file(self):
305
 
        # We need a backing file sysytem for that test so it can't be in
306
 
        # TestEcho
307
 
        self.run_script("""
308
 
$ echo >
309
 
2>: No such file or directory
310
 
""")
311
 
 
312
 
 
313
 
class TestMkdir(script.TestCaseWithTransportAndScript):
314
 
 
315
 
    def test_mkdir_usage(self):
316
 
        self.assertRaises(SyntaxError, self.run_script, '$ mkdir')
317
 
        self.assertRaises(SyntaxError, self.run_script, '$ mkdir foo bar')
318
 
 
319
 
    def test_mkdir_jailed(self):
320
 
        self.assertRaises(ValueError, self.run_script, '$ mkdir /out-of-jail')
321
 
        self.assertRaises(ValueError, self.run_script, '$ mkdir ../out-of-jail')
322
 
 
323
 
    def test_mkdir_in_jail(self):
324
 
        self.run_script("""
325
 
$ mkdir dir
326
 
$ cd dir
327
 
$ mkdir ../dir2
328
 
$ cd ..
329
 
""")
330
 
        self.failUnlessExists('dir')
331
 
        self.failUnlessExists('dir2')
332
 
 
333
 
 
334
 
class TestCd(script.TestCaseWithTransportAndScript):
335
 
 
336
 
    def test_cd_usage(self):
337
 
        self.assertRaises(SyntaxError, self.run_script, '$ cd foo bar')
338
 
 
339
 
    def test_cd_out_of_jail(self):
340
 
        self.assertRaises(ValueError, self.run_script, '$ cd /out-of-jail')
341
 
        self.assertRaises(ValueError, self.run_script, '$ cd ..')
342
 
 
343
 
    def test_cd_dir_and_back_home(self):
344
 
        self.assertEquals(self.test_dir, osutils.getcwd())
345
 
        self.run_script("""
346
 
$ mkdir dir
347
 
$ cd dir
348
 
""")
349
 
        self.assertEquals(osutils.pathjoin(self.test_dir, 'dir'),
350
 
                          osutils.getcwd())
351
 
 
352
 
        self.run_script('$ cd')
353
 
        self.assertEquals(self.test_dir, osutils.getcwd())
354
 
 
355
 
 
356
 
class TestBzr(script.TestCaseWithTransportAndScript):
357
 
 
358
 
    def test_bzr_smoke(self):
359
 
        self.run_script('$ bzr init branch')
360
 
        self.failUnlessExists('branch')
361
 
 
362
 
 
363
 
class TestEcho(script.TestCaseWithMemoryTransportAndScript):
364
 
 
365
 
    def test_echo_usage(self):
366
 
        story = """
367
 
$ echo foo
368
 
<bar
369
 
"""
370
 
        self.assertRaises(SyntaxError, self.run_script, story)
371
 
 
372
 
    def test_echo_input(self):
373
 
        self.assertRaises(SyntaxError, self.run_script, """
374
 
            $ echo <foo
375
 
            """)
376
 
 
377
 
    def test_echo_to_output(self):
378
 
        retcode, out, err = self.run_command(['echo'], None, '\n', None)
379
 
        self.assertEquals('\n', out)
380
 
        self.assertEquals(None, err)
381
 
 
382
 
    def test_echo_some_to_output(self):
383
 
        retcode, out, err = self.run_command(['echo', 'hello'],
384
 
                                             None, 'hello\n', None)
385
 
        self.assertEquals('hello\n', out)
386
 
        self.assertEquals(None, err)
387
 
 
388
 
    def test_echo_more_output(self):
389
 
        retcode, out, err = self.run_command(
390
 
            ['echo', 'hello', 'happy', 'world'],
391
 
            None, 'hello happy world\n', None)
392
 
        self.assertEquals('hello happy world\n', out)
393
 
        self.assertEquals(None, err)
394
 
 
395
 
    def test_echo_appended(self):
396
 
        retcode, out, err = self.run_command(['echo', 'hello', '>file'],
397
 
                                             None, None, None)
398
 
        self.assertEquals(None, out)
399
 
        self.assertEquals(None, err)
400
 
        self.assertFileEqual('hello\n', 'file')
401
 
        retcode, out, err = self.run_command(['echo', 'happy', '>>file'],
402
 
                                             None, None, None)
403
 
        self.assertEquals(None, out)
404
 
        self.assertEquals(None, err)
405
 
        self.assertFileEqual('hello\nhappy\n', 'file')
406
 
 
407
 
    def test_empty_line_in_output_is_respected(self):
408
 
        self.run_script("""
409
 
            $ echo
410
 
 
411
 
            $ echo bar
412
 
            bar
413
 
            """)
414
 
 
415
 
 
416
 
class TestRm(script.TestCaseWithTransportAndScript):
417
 
 
418
 
    def test_rm_usage(self):
419
 
        self.assertRaises(SyntaxError, self.run_script, '$ rm')
420
 
        self.assertRaises(SyntaxError, self.run_script, '$ rm -ff foo')
421
 
 
422
 
    def test_rm_file(self):
423
 
        self.run_script('$ echo content >file')
424
 
        self.failUnlessExists('file')
425
 
        self.run_script('$ rm file')
426
 
        self.failIfExists('file')
427
 
 
428
 
    def test_rm_file_force(self):
429
 
        self.failIfExists('file')
430
 
        self.run_script('$ rm -f file')
431
 
        self.failIfExists('file')
432
 
 
433
 
    def test_rm_files(self):
434
 
        self.run_script("""
435
 
$ echo content >file
436
 
$ echo content >file2
437
 
""")
438
 
        self.failUnlessExists('file2')
439
 
        self.run_script('$ rm file file2')
440
 
        self.failIfExists('file2')
441
 
 
442
 
    def test_rm_dir(self):
443
 
        self.run_script('$ mkdir dir')
444
 
        self.failUnlessExists('dir')
445
 
        self.run_script("""
446
 
$ rm dir
447
 
2>rm: cannot remove 'dir': Is a directory
448
 
""")
449
 
        self.failUnlessExists('dir')
450
 
 
451
 
    def test_rm_dir_recursive(self):
452
 
        self.run_script("""
453
 
$ mkdir dir
454
 
$ rm -r dir
455
 
""")
456
 
        self.failIfExists('dir')
457
 
 
458
 
 
459
 
class TestMv(script.TestCaseWithTransportAndScript):
460
 
 
461
 
    def test_usage(self):
462
 
        self.assertRaises(SyntaxError, self.run_script, '$ mv')
463
 
        self.assertRaises(SyntaxError, self.run_script, '$ mv f')
464
 
        self.assertRaises(SyntaxError, self.run_script, '$ mv f1 f2 f3')
465
 
 
466
 
    def test_move_file(self):
467
 
        self.run_script('$ echo content >file')
468
 
        self.failUnlessExists('file')
469
 
        self.run_script('$ mv file new_name')
470
 
        self.failIfExists('file')
471
 
        self.failUnlessExists('new_name')
472
 
 
473
 
    def test_move_unknown_file(self):
474
 
        self.assertRaises(AssertionError,
475
 
                          self.run_script, '$ mv unknown does-not-exist')
476
 
 
477
 
    def test_move_dir(self):
478
 
        self.run_script("""
479
 
$ mkdir dir
480
 
$ echo content >dir/file
481
 
""")
482
 
        self.run_script('$ mv dir new_name')
483
 
        self.failIfExists('dir')
484
 
        self.failUnlessExists('new_name')
485
 
        self.failUnlessExists('new_name/file')
486
 
 
487
 
    def test_move_file_into_dir(self):
488
 
        self.run_script("""
489
 
$ mkdir dir
490
 
$ echo content > file
491
 
""")
492
 
        self.run_script('$ mv file dir')
493
 
        self.failUnlessExists('dir')
494
 
        self.failIfExists('file')
495
 
        self.failUnlessExists('dir/file')
496
 
 
497
 
 
498
 
class cmd_test_confirm(commands.Command):
499
 
 
500
 
    def run(self):
501
 
        if ui.ui_factory.get_boolean(
502
 
            'Really do it',
503
 
            # 'bzrlib.tests.test_script.confirm',
504
 
            # {}
505
 
            ):
506
 
            self.outf.write('Do it!\n')
507
 
        else:
508
 
            print 'ok, no'
509
 
 
510
 
 
511
 
class TestUserInteraction(script.TestCaseWithMemoryTransportAndScript):
512
 
 
513
 
    def test_confirm_action(self):
514
 
        """You can write tests that demonstrate user confirmation.
515
 
        
516
 
        Specifically, ScriptRunner does't care if the output line for the prompt
517
 
        isn't terminated by a newline from the program; it's implicitly terminated 
518
 
        by the input.
519
 
        """
520
 
        commands.builtin_command_registry.register(cmd_test_confirm)
521
 
        self.addCleanup(commands.builtin_command_registry.remove, 'test-confirm')
522
 
        self.run_script("""
523
 
            $ bzr test-confirm
524
 
            2>Really do it? [y/n]: 
525
 
            <yes
526
 
            Do it!
527
 
            $ bzr test-confirm
528
 
            2>Really do it? [y/n]: 
529
 
            <no
530
 
            ok, no
531
 
            """)
532