1
# Copyright (C) 2009 Canonical Ltd
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.
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.
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
22
from bzrlib.tests import script
25
class TestSyntax(tests.TestCase):
27
def test_comment_is_ignored(self):
28
self.assertEquals([], script._script_to_commands('#comment\n'))
30
def test_empty_line_is_ignored(self):
31
self.assertEquals([], script._script_to_commands('\n'))
33
def test_simple_command(self):
34
self.assertEquals([(['cd', 'trunk'], None, None, None)],
35
script._script_to_commands('$ cd trunk'))
37
def test_command_with_single_quoted_param(self):
38
story = """$ bzr commit -m 'two words'"""
39
self.assertEquals([(['bzr', 'commit', '-m', "'two words'"],
41
script._script_to_commands(story))
43
def test_command_with_double_quoted_param(self):
44
story = """$ bzr commit -m "two words" """
45
self.assertEquals([(['bzr', 'commit', '-m', '"two words"'],
47
script._script_to_commands(story))
49
def test_command_with_input(self):
51
[(['cat', '>file'], 'content\n', None, None)],
52
script._script_to_commands('$ cat >file\n<content\n'))
54
def test_command_with_output(self):
60
self.assertEquals([(['bzr', 'add'], None,
61
'adding file\nadding file2\n', None)],
62
script._script_to_commands(story))
64
def test_command_with_error(self):
67
2>bzr: ERROR: Not a branch: "foo"
69
self.assertEquals([(['bzr', 'branch', 'foo'],
70
None, None, 'bzr: ERROR: Not a branch: "foo"\n')],
71
script._script_to_commands(story))
73
def test_input_without_command(self):
74
self.assertRaises(SyntaxError, script._script_to_commands, '<input')
76
def test_output_without_command(self):
77
self.assertRaises(SyntaxError, script._script_to_commands, '>input')
79
def test_command_with_backquotes(self):
81
$ foo = `bzr file-id toto`
83
self.assertEquals([(['foo', '=', '`bzr file-id toto`'],
85
script._script_to_commands(story))
88
class TestRedirections(tests.TestCase):
90
def _check(self, in_name, out_name, out_mode, remaining, args):
91
self.assertEqual(script._scan_redirection_options(args),
92
(in_name, out_name, out_mode, remaining))
94
def test_no_redirection(self):
95
self._check(None, None, None, [], [])
96
self._check(None, None, None, ['foo', 'bar'], ['foo', 'bar'])
98
def test_input_redirection(self):
99
self._check('foo', None, None, [], ['<foo'])
100
self._check('foo', None, None, ['bar'], ['bar', '<foo'])
101
self._check('foo', None, None, ['bar'], ['bar', '<', 'foo'])
102
self._check('foo', None, None, ['bar'], ['<foo', 'bar'])
103
self._check('foo', None, None, ['bar', 'baz'], ['bar', '<foo', 'baz'])
105
def test_output_redirection(self):
106
self._check(None, 'foo', 'wb+', [], ['>foo'])
107
self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>foo'])
108
self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>', 'foo'])
109
self._check(None, 'foo', 'ab+', [], ['>>foo'])
110
self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>foo'])
111
self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>', 'foo'])
113
def test_redirection_syntax_errors(self):
114
self._check('', None, None, [], ['<'])
115
self._check(None, '', 'wb+', [], ['>'])
116
self._check(None, '', 'ab+', [], ['>>'])
117
self._check('>', '', 'ab+', [], ['<', '>', '>>'])
121
class TestExecution(script.TestCaseWithTransportAndScript):
123
def test_unknown_command(self):
124
self.assertRaises(SyntaxError, self.run_script, 'foo')
126
def test_stops_on_unexpected_output(self):
130
The cd command ouputs nothing
132
self.assertRaises(AssertionError, self.run_script, story)
135
def test_stops_on_unexpected_error(self):
141
self.assertRaises(AssertionError, self.run_script, story)
143
def test_continue_on_expected_error(self):
148
self.run_script(story)
150
def test_continue_on_error_output(self):
151
# The status matters, not the output
157
$ bzr commit -m 'adding file'
159
self.run_script(story)
161
def test_ellipsis_output(self):
171
self.run_script(story)
176
self.run_script(story)
179
$ bzr branch not-a-branch
180
2>bzr: ERROR: Not a branch...not-a-branch/".
182
self.run_script(story)
185
class TestArgumentProcessing(script.TestCaseWithTransportAndScript):
187
def test_globing(self):
196
def test_quoted_globbing(self):
200
2>*: No such file or directory
203
def test_quotes_removal(self):
205
$ echo 'cat' "dog" '"chicken"' "'dragon'"
206
cat dog "chicken" 'dragon'
210
class TestCat(script.TestCaseWithTransportAndScript):
212
def test_cat_usage(self):
213
self.assertRaises(SyntaxError, self.run_script, 'cat foo <bar')
215
def test_cat_input_to_output(self):
216
retcode, out, err = self.run_command(['cat'],
217
'content\n', 'content\n', None)
218
self.assertEquals('content\n', out)
219
self.assertEquals(None, err)
221
def test_cat_file_to_output(self):
222
self.build_tree_contents([('file', 'content\n')])
223
retcode, out, err = self.run_command(['cat', 'file'],
224
None, 'content\n', None)
225
self.assertEquals('content\n', out)
226
self.assertEquals(None, err)
228
def test_cat_input_to_file(self):
229
retcode, out, err = self.run_command(['cat', '>file'],
230
'content\n', None, None)
231
self.assertFileEqual('content\n', 'file')
232
self.assertEquals(None, out)
233
self.assertEquals(None, err)
234
retcode, out, err = self.run_command(['cat', '>>file'],
235
'more\n', None, None)
236
self.assertFileEqual('content\nmore\n', 'file')
237
self.assertEquals(None, out)
238
self.assertEquals(None, err)
240
def test_cat_file_to_file(self):
241
self.build_tree_contents([('file', 'content\n')])
242
retcode, out, err = self.run_command(['cat', 'file', '>file2'],
244
self.assertFileEqual('content\n', 'file2')
246
def test_cat_files_to_file(self):
247
self.build_tree_contents([('cat', 'cat\n')])
248
self.build_tree_contents([('dog', 'dog\n')])
249
retcode, out, err = self.run_command(['cat', 'cat', 'dog', '>file'],
251
self.assertFileEqual('cat\ndog\n', 'file')
253
def test_cat_bogus_input_file(self):
256
2>file: No such file or directory
259
def test_cat_bogus_output_file(self):
262
2>: No such file or directory
265
def test_echo_bogus_output_file(self):
266
# We need a backing file sysytem for that test so it can't be in
270
2>: No such file or directory
274
class TestMkdir(script.TestCaseWithTransportAndScript):
276
def test_mkdir_usage(self):
277
self.assertRaises(SyntaxError, self.run_script, '$ mkdir')
278
self.assertRaises(SyntaxError, self.run_script, '$ mkdir foo bar')
280
def test_mkdir_jailed(self):
281
self.assertRaises(ValueError, self.run_script, '$ mkdir /out-of-jail')
282
self.assertRaises(ValueError, self.run_script, '$ mkdir ../out-of-jail')
284
def test_mkdir_in_jail(self):
291
self.failUnlessExists('dir')
292
self.failUnlessExists('dir2')
295
class TestCd(script.TestCaseWithTransportAndScript):
297
def test_cd_usage(self):
298
self.assertRaises(SyntaxError, self.run_script, '$ cd foo bar')
300
def test_cd_out_of_jail(self):
301
self.assertRaises(ValueError, self.run_script, '$ cd /out-of-jail')
302
self.assertRaises(ValueError, self.run_script, '$ cd ..')
304
def test_cd_dir_and_back_home(self):
305
self.assertEquals(self.test_dir, osutils.getcwd())
310
self.assertEquals(osutils.pathjoin(self.test_dir, 'dir'),
313
self.run_script('$ cd')
314
self.assertEquals(self.test_dir, osutils.getcwd())
317
class TestBzr(script.TestCaseWithTransportAndScript):
319
def test_bzr_smoke(self):
320
self.run_script('$ bzr init branch')
321
self.failUnlessExists('branch')
324
class TestEcho(script.TestCaseWithMemoryTransportAndScript):
326
def test_echo_usage(self):
331
self.assertRaises(SyntaxError, self.run_script, story)
333
def test_echo_input(self):
334
self.assertRaises(SyntaxError, self.run_script, """
338
def test_echo_to_output(self):
339
retcode, out, err = self.run_command(['echo'], None, '\n', None)
340
self.assertEquals('\n', out)
341
self.assertEquals(None, err)
343
def test_echo_some_to_output(self):
344
retcode, out, err = self.run_command(['echo', 'hello'],
345
None, 'hello\n', None)
346
self.assertEquals('hello\n', out)
347
self.assertEquals(None, err)
349
def test_echo_more_output(self):
350
retcode, out, err = self.run_command(
351
['echo', 'hello', 'happy', 'world'],
352
None, 'hello happy world\n', None)
353
self.assertEquals('hello happy world\n', out)
354
self.assertEquals(None, err)
356
def test_echo_appended(self):
357
retcode, out, err = self.run_command(['echo', 'hello', '>file'],
359
self.assertEquals(None, out)
360
self.assertEquals(None, err)
361
self.assertFileEqual('hello\n', 'file')
362
retcode, out, err = self.run_command(['echo', 'happy', '>>file'],
364
self.assertEquals(None, out)
365
self.assertEquals(None, err)
366
self.assertFileEqual('hello\nhappy\n', 'file')
369
class TestRm(script.TestCaseWithTransportAndScript):
371
def test_rm_usage(self):
372
self.assertRaises(SyntaxError, self.run_script, '$ rm')
373
self.assertRaises(SyntaxError, self.run_script, '$ rm -ff foo')
375
def test_rm_file(self):
376
self.run_script('$ echo content >file')
377
self.failUnlessExists('file')
378
self.run_script('$ rm file')
379
self.failIfExists('file')
381
def test_rm_file_force(self):
382
self.failIfExists('file')
383
self.run_script('$ rm -f file')
384
self.failIfExists('file')
386
def test_rm_files(self):
389
$ echo content >file2
391
self.failUnlessExists('file2')
392
self.run_script('$ rm file file2')
393
self.failIfExists('file2')
395
def test_rm_dir(self):
396
self.run_script('$ mkdir dir')
397
self.failUnlessExists('dir')
400
2>rm: cannot remove 'dir': Is a directory
402
self.failUnlessExists('dir')
404
def test_rm_dir_recursive(self):
409
self.failIfExists('dir')
412
class TestMv(script.TestCaseWithTransportAndScript):
414
def test_usage(self):
415
self.assertRaises(SyntaxError, self.run_script, '$ mv')
416
self.assertRaises(SyntaxError, self.run_script, '$ mv f')
417
self.assertRaises(SyntaxError, self.run_script, '$ mv f1 f2 f3')
419
def test_move_file(self):
420
self.run_script('$ echo content >file')
421
self.failUnlessExists('file')
422
self.run_script('$ mv file new_name')
423
self.failIfExists('file')
424
self.failUnlessExists('new_name')
426
def test_move_unknown_file(self):
427
self.assertRaises(AssertionError,
428
self.run_script, '$ mv unknown does-not-exist')
430
def test_move_dir(self):
433
$ echo content >dir/file
435
self.run_script('$ mv dir new_name')
436
self.failIfExists('dir')
437
self.failUnlessExists('new_name')
438
self.failUnlessExists('new_name/file')
440
def test_move_file_into_dir(self):
443
$ echo content > file
445
self.run_script('$ mv file dir')
446
self.failUnlessExists('dir')
447
self.failIfExists('file')
448
self.failUnlessExists('dir/file')