1
# Copyright (C) 2009, 2010 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_indented(self):
55
# scripts are commonly given indented within the test source code, and
56
# common indentation is stripped off
62
self.assertEquals([(['bzr', 'add'], None,
63
'adding file\nadding file2\n', None)],
64
script._script_to_commands(story))
66
def test_command_with_output(self):
72
self.assertEquals([(['bzr', 'add'], None,
73
'adding file\nadding file2\n', None)],
74
script._script_to_commands(story))
76
def test_command_with_error(self):
79
2>bzr: ERROR: Not a branch: "foo"
81
self.assertEquals([(['bzr', 'branch', 'foo'],
82
None, None, 'bzr: ERROR: Not a branch: "foo"\n')],
83
script._script_to_commands(story))
85
def test_input_without_command(self):
86
self.assertRaises(SyntaxError, script._script_to_commands, '<input')
88
def test_output_without_command(self):
89
self.assertRaises(SyntaxError, script._script_to_commands, '>input')
91
def test_command_with_backquotes(self):
93
$ foo = `bzr file-id toto`
95
self.assertEquals([(['foo', '=', '`bzr file-id toto`'],
97
script._script_to_commands(story))
100
class TestRedirections(tests.TestCase):
102
def _check(self, in_name, out_name, out_mode, remaining, args):
103
self.assertEqual(script._scan_redirection_options(args),
104
(in_name, out_name, out_mode, remaining))
106
def test_no_redirection(self):
107
self._check(None, None, None, [], [])
108
self._check(None, None, None, ['foo', 'bar'], ['foo', 'bar'])
110
def test_input_redirection(self):
111
self._check('foo', None, None, [], ['<foo'])
112
self._check('foo', None, None, ['bar'], ['bar', '<foo'])
113
self._check('foo', None, None, ['bar'], ['bar', '<', 'foo'])
114
self._check('foo', None, None, ['bar'], ['<foo', 'bar'])
115
self._check('foo', None, None, ['bar', 'baz'], ['bar', '<foo', 'baz'])
117
def test_output_redirection(self):
118
self._check(None, 'foo', 'wb+', [], ['>foo'])
119
self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>foo'])
120
self._check(None, 'foo', 'wb+', ['bar'], ['bar', '>', 'foo'])
121
self._check(None, 'foo', 'ab+', [], ['>>foo'])
122
self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>foo'])
123
self._check(None, 'foo', 'ab+', ['bar'], ['bar', '>>', 'foo'])
125
def test_redirection_syntax_errors(self):
126
self._check('', None, None, [], ['<'])
127
self._check(None, '', 'wb+', [], ['>'])
128
self._check(None, '', 'ab+', [], ['>>'])
129
self._check('>', '', 'ab+', [], ['<', '>', '>>'])
133
class TestExecution(script.TestCaseWithTransportAndScript):
135
def test_unknown_command(self):
136
self.assertRaises(SyntaxError, self.run_script, 'foo')
138
def test_stops_on_unexpected_output(self):
142
The cd command ouputs nothing
144
self.assertRaises(AssertionError, self.run_script, story)
147
def test_stops_on_unexpected_error(self):
153
self.assertRaises(AssertionError, self.run_script, story)
155
def test_continue_on_expected_error(self):
160
self.run_script(story)
162
def test_continue_on_error_output(self):
163
# The status matters, not the output
169
$ bzr commit -m 'adding file'
171
self.run_script(story)
173
def test_ellipsis_output(self):
183
self.run_script(story)
188
self.run_script(story)
191
$ bzr branch not-a-branch
192
2>bzr: ERROR: Not a branch...not-a-branch/".
194
self.run_script(story)
197
class TestArgumentProcessing(script.TestCaseWithTransportAndScript):
199
def test_globing(self):
208
def test_quoted_globbing(self):
212
2>*: No such file or directory
215
def test_quotes_removal(self):
217
$ echo 'cat' "dog" '"chicken"' "'dragon'"
218
cat dog "chicken" 'dragon'
222
class TestCat(script.TestCaseWithTransportAndScript):
224
def test_cat_usage(self):
225
self.assertRaises(SyntaxError, self.run_script, 'cat foo <bar')
227
def test_cat_input_to_output(self):
228
retcode, out, err = self.run_command(['cat'],
229
'content\n', 'content\n', None)
230
self.assertEquals('content\n', out)
231
self.assertEquals(None, err)
233
def test_cat_file_to_output(self):
234
self.build_tree_contents([('file', 'content\n')])
235
retcode, out, err = self.run_command(['cat', 'file'],
236
None, 'content\n', None)
237
self.assertEquals('content\n', out)
238
self.assertEquals(None, err)
240
def test_cat_input_to_file(self):
241
retcode, out, err = self.run_command(['cat', '>file'],
242
'content\n', None, None)
243
self.assertFileEqual('content\n', 'file')
244
self.assertEquals(None, out)
245
self.assertEquals(None, err)
246
retcode, out, err = self.run_command(['cat', '>>file'],
247
'more\n', None, None)
248
self.assertFileEqual('content\nmore\n', 'file')
249
self.assertEquals(None, out)
250
self.assertEquals(None, err)
252
def test_cat_file_to_file(self):
253
self.build_tree_contents([('file', 'content\n')])
254
retcode, out, err = self.run_command(['cat', 'file', '>file2'],
256
self.assertFileEqual('content\n', 'file2')
258
def test_cat_files_to_file(self):
259
self.build_tree_contents([('cat', 'cat\n')])
260
self.build_tree_contents([('dog', 'dog\n')])
261
retcode, out, err = self.run_command(['cat', 'cat', 'dog', '>file'],
263
self.assertFileEqual('cat\ndog\n', 'file')
265
def test_cat_bogus_input_file(self):
268
2>file: No such file or directory
271
def test_cat_bogus_output_file(self):
274
2>: No such file or directory
277
def test_echo_bogus_output_file(self):
278
# We need a backing file sysytem for that test so it can't be in
282
2>: No such file or directory
286
class TestMkdir(script.TestCaseWithTransportAndScript):
288
def test_mkdir_usage(self):
289
self.assertRaises(SyntaxError, self.run_script, '$ mkdir')
290
self.assertRaises(SyntaxError, self.run_script, '$ mkdir foo bar')
292
def test_mkdir_jailed(self):
293
self.assertRaises(ValueError, self.run_script, '$ mkdir /out-of-jail')
294
self.assertRaises(ValueError, self.run_script, '$ mkdir ../out-of-jail')
296
def test_mkdir_in_jail(self):
303
self.failUnlessExists('dir')
304
self.failUnlessExists('dir2')
307
class TestCd(script.TestCaseWithTransportAndScript):
309
def test_cd_usage(self):
310
self.assertRaises(SyntaxError, self.run_script, '$ cd foo bar')
312
def test_cd_out_of_jail(self):
313
self.assertRaises(ValueError, self.run_script, '$ cd /out-of-jail')
314
self.assertRaises(ValueError, self.run_script, '$ cd ..')
316
def test_cd_dir_and_back_home(self):
317
self.assertEquals(self.test_dir, osutils.getcwd())
322
self.assertEquals(osutils.pathjoin(self.test_dir, 'dir'),
325
self.run_script('$ cd')
326
self.assertEquals(self.test_dir, osutils.getcwd())
329
class TestBzr(script.TestCaseWithTransportAndScript):
331
def test_bzr_smoke(self):
332
self.run_script('$ bzr init branch')
333
self.failUnlessExists('branch')
336
class TestEcho(script.TestCaseWithMemoryTransportAndScript):
338
def test_echo_usage(self):
343
self.assertRaises(SyntaxError, self.run_script, story)
345
def test_echo_input(self):
346
self.assertRaises(SyntaxError, self.run_script, """
350
def test_echo_to_output(self):
351
retcode, out, err = self.run_command(['echo'], None, '\n', None)
352
self.assertEquals('\n', out)
353
self.assertEquals(None, err)
355
def test_echo_some_to_output(self):
356
retcode, out, err = self.run_command(['echo', 'hello'],
357
None, 'hello\n', None)
358
self.assertEquals('hello\n', out)
359
self.assertEquals(None, err)
361
def test_echo_more_output(self):
362
retcode, out, err = self.run_command(
363
['echo', 'hello', 'happy', 'world'],
364
None, 'hello happy world\n', None)
365
self.assertEquals('hello happy world\n', out)
366
self.assertEquals(None, err)
368
def test_echo_appended(self):
369
retcode, out, err = self.run_command(['echo', 'hello', '>file'],
371
self.assertEquals(None, out)
372
self.assertEquals(None, err)
373
self.assertFileEqual('hello\n', 'file')
374
retcode, out, err = self.run_command(['echo', 'happy', '>>file'],
376
self.assertEquals(None, out)
377
self.assertEquals(None, err)
378
self.assertFileEqual('hello\nhappy\n', 'file')
381
class TestRm(script.TestCaseWithTransportAndScript):
383
def test_rm_usage(self):
384
self.assertRaises(SyntaxError, self.run_script, '$ rm')
385
self.assertRaises(SyntaxError, self.run_script, '$ rm -ff foo')
387
def test_rm_file(self):
388
self.run_script('$ echo content >file')
389
self.failUnlessExists('file')
390
self.run_script('$ rm file')
391
self.failIfExists('file')
393
def test_rm_file_force(self):
394
self.failIfExists('file')
395
self.run_script('$ rm -f file')
396
self.failIfExists('file')
398
def test_rm_files(self):
401
$ echo content >file2
403
self.failUnlessExists('file2')
404
self.run_script('$ rm file file2')
405
self.failIfExists('file2')
407
def test_rm_dir(self):
408
self.run_script('$ mkdir dir')
409
self.failUnlessExists('dir')
412
2>rm: cannot remove 'dir': Is a directory
414
self.failUnlessExists('dir')
416
def test_rm_dir_recursive(self):
421
self.failIfExists('dir')
424
class TestMv(script.TestCaseWithTransportAndScript):
426
def test_usage(self):
427
self.assertRaises(SyntaxError, self.run_script, '$ mv')
428
self.assertRaises(SyntaxError, self.run_script, '$ mv f')
429
self.assertRaises(SyntaxError, self.run_script, '$ mv f1 f2 f3')
431
def test_move_file(self):
432
self.run_script('$ echo content >file')
433
self.failUnlessExists('file')
434
self.run_script('$ mv file new_name')
435
self.failIfExists('file')
436
self.failUnlessExists('new_name')
438
def test_move_unknown_file(self):
439
self.assertRaises(AssertionError,
440
self.run_script, '$ mv unknown does-not-exist')
442
def test_move_dir(self):
445
$ echo content >dir/file
447
self.run_script('$ mv dir new_name')
448
self.failIfExists('dir')
449
self.failUnlessExists('new_name')
450
self.failUnlessExists('new_name/file')
452
def test_move_file_into_dir(self):
455
$ echo content > file
457
self.run_script('$ mv file dir')
458
self.failUnlessExists('dir')
459
self.failIfExists('file')
460
self.failUnlessExists('dir/file')