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_input_file(self):
266
# We need a backing file sysytem for that test so it can't be in
270
2>file: No such file or directory
273
def test_echo_bogus_output_file(self):
274
# We need a backing file sysytem for that test so it can't be in
278
2>: No such file or directory
282
class TestMkdir(script.TestCaseWithTransportAndScript):
284
def test_mkdir_usage(self):
285
self.assertRaises(SyntaxError, self.run_script, '$ mkdir')
286
self.assertRaises(SyntaxError, self.run_script, '$ mkdir foo bar')
288
def test_mkdir_jailed(self):
289
self.assertRaises(ValueError, self.run_script, '$ mkdir /out-of-jail')
290
self.assertRaises(ValueError, self.run_script, '$ mkdir ../out-of-jail')
292
def test_mkdir_in_jail(self):
299
self.failUnlessExists('dir')
300
self.failUnlessExists('dir2')
303
class TestCd(script.TestCaseWithTransportAndScript):
305
def test_cd_usage(self):
306
self.assertRaises(SyntaxError, self.run_script, '$ cd foo bar')
308
def test_cd_out_of_jail(self):
309
self.assertRaises(ValueError, self.run_script, '$ cd /out-of-jail')
310
self.assertRaises(ValueError, self.run_script, '$ cd ..')
312
def test_cd_dir_and_back_home(self):
313
self.assertEquals(self.test_dir, osutils.getcwd())
318
self.assertEquals(osutils.pathjoin(self.test_dir, 'dir'),
321
self.run_script('$ cd')
322
self.assertEquals(self.test_dir, osutils.getcwd())
325
class TestBzr(script.TestCaseWithTransportAndScript):
327
def test_bzr_smoke(self):
328
self.run_script('$ bzr init branch')
329
self.failUnlessExists('branch')
332
class TestEcho(script.TestCaseWithMemoryTransportAndScript):
334
def test_echo_usage(self):
339
self.assertRaises(SyntaxError, self.run_script, story)
341
def test_echo_to_output(self):
342
retcode, out, err = self.run_command(['echo'], None, '\n', None)
343
self.assertEquals('\n', out)
344
self.assertEquals(None, err)
346
def test_echo_some_to_output(self):
347
retcode, out, err = self.run_command(['echo', 'hello'],
348
None, 'hello\n', None)
349
self.assertEquals('hello\n', out)
350
self.assertEquals(None, err)
352
def test_echo_more_output(self):
353
retcode, out, err = self.run_command(
354
['echo', 'hello', 'happy', 'world'],
355
None, 'hello happy world\n', None)
356
self.assertEquals('hello happy world\n', out)
357
self.assertEquals(None, err)
359
def test_echo_appended(self):
360
retcode, out, err = self.run_command(['echo', 'hello', '>file'],
362
self.assertEquals(None, out)
363
self.assertEquals(None, err)
364
self.assertFileEqual('hello\n', 'file')
365
retcode, out, err = self.run_command(['echo', 'happy', '>>file'],
367
self.assertEquals(None, out)
368
self.assertEquals(None, err)
369
self.assertFileEqual('hello\nhappy\n', 'file')
372
class TestRm(script.TestCaseWithTransportAndScript):
374
def test_rm_usage(self):
375
self.assertRaises(SyntaxError, self.run_script, '$ rm')
376
self.assertRaises(SyntaxError, self.run_script, '$ rm -ff foo')
378
def test_rm_file(self):
379
self.run_script('$ echo content >file')
380
self.failUnlessExists('file')
381
self.run_script('$ rm file')
382
self.failIfExists('file')
384
def test_rm_file_force(self):
385
self.failIfExists('file')
386
self.run_script('$ rm -f file')
387
self.failIfExists('file')
389
def test_rm_files(self):
392
$ echo content >file2
394
self.failUnlessExists('file2')
395
self.run_script('$ rm file file2')
396
self.failIfExists('file2')
398
def test_rm_dir(self):
399
self.run_script('$ mkdir dir')
400
self.failUnlessExists('dir')
403
2>rm: cannot remove 'dir': Is a directory
405
self.failUnlessExists('dir')
407
def test_rm_dir_recursive(self):
412
self.failIfExists('dir')