15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
from breezy.tests import script
22
from bzrlib.tests import script
28
25
class TestSyntax(tests.TestCase):
30
27
def test_comment_is_ignored(self):
31
self.assertEqual([], script._script_to_commands('#comment\n'))
33
def test_comment_multiple_lines(self):
35
(['bar'], None, None, None),
37
script._script_to_commands("""
38
# this comment is ignored
44
def test_trim_blank_lines(self):
45
"""Blank lines are respected, but trimmed at the start and end.
47
Python triple-quoted syntax is going to give stubby/empty blank lines
48
right at the start and the end. These are cut off so that callers don't
49
need special syntax to avoid them.
51
However we do want to be able to match commands that emit blank lines.
54
(['bar'], None, '\n', None),
56
script._script_to_commands("""
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'))
61
33
def test_simple_command(self):
62
self.assertEqual([(['cd', 'trunk'], None, None, None)],
63
script._script_to_commands('$ cd trunk'))
34
self.assertEquals([(['cd', 'trunk'], None, None, None)],
35
script._script_to_commands('$ cd trunk'))
65
37
def test_command_with_single_quoted_param(self):
66
story = """$ brz commit -m 'two words'"""
67
self.assertEqual([(['brz', 'commit', '-m', "'two words'"],
69
script._script_to_commands(story))
38
story = """$ bzr commit -m 'two words'"""
39
self.assertEquals([(['bzr', 'commit', '-m', "'two words'"],
41
script._script_to_commands(story))
71
43
def test_command_with_double_quoted_param(self):
72
story = """$ brz commit -m "two words" """
73
self.assertEqual([(['brz', 'commit', '-m', '"two words"'],
75
script._script_to_commands(story))
44
story = """$ bzr commit -m "two words" """
45
self.assertEquals([(['bzr', 'commit', '-m', '"two words"'],
47
script._script_to_commands(story))
77
49
def test_command_with_input(self):
79
51
[(['cat', '>file'], 'content\n', None, None)],
80
52
script._script_to_commands('$ cat >file\n<content\n'))
83
55
# scripts are commonly given indented within the test source code, and
84
56
# common indentation is stripped off
90
self.assertEqual([(['brz', 'add'], None,
91
'adding file\nadding file2\n', None)],
92
script._script_to_commands(story))
62
self.assertEquals([(['bzr', 'add'], None,
63
'adding file\nadding file2\n', None)],
64
script._script_to_commands(story))
94
66
def test_command_with_output(self):
100
self.assertEqual([(['brz', 'add'], None,
101
'adding file\nadding file2\n', None)],
102
script._script_to_commands(story))
72
self.assertEquals([(['bzr', 'add'], None,
73
'adding file\nadding file2\n', None)],
74
script._script_to_commands(story))
104
76
def test_command_with_error(self):
107
2>brz: ERROR: Not a branch: "foo"
79
2>bzr: ERROR: Not a branch: "foo"
109
self.assertEqual([(['brz', 'branch', 'foo'],
110
None, None, 'brz: ERROR: Not a branch: "foo"\n')],
111
script._script_to_commands(story))
81
self.assertEquals([(['bzr', 'branch', 'foo'],
82
None, None, 'bzr: ERROR: Not a branch: "foo"\n')],
83
script._script_to_commands(story))
113
85
def test_input_without_command(self):
114
86
self.assertRaises(SyntaxError, script._script_to_commands, '<input')
143
115
self._check('foo', None, None, ['bar', 'baz'], ['bar', '<foo', 'baz'])
145
117
def test_output_redirection(self):
146
self._check(None, 'foo', 'w+', [], ['>foo'])
147
self._check(None, 'foo', 'w+', ['bar'], ['bar', '>foo'])
148
self._check(None, 'foo', 'w+', ['bar'], ['bar', '>', 'foo'])
149
self._check(None, 'foo', 'a+', [], ['>>foo'])
150
self._check(None, 'foo', 'a+', ['bar'], ['bar', '>>foo'])
151
self._check(None, 'foo', 'a+', ['bar'], ['bar', '>>', 'foo'])
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'])
153
125
def test_redirection_syntax_errors(self):
154
126
self._check('', None, None, [], ['<'])
155
self._check(None, '', 'w+', [], ['>'])
156
self._check(None, '', 'a+', [], ['>>'])
157
self._check('>', '', 'a+', [], ['<', '>', '>>'])
127
self._check(None, '', 'wb+', [], ['>'])
128
self._check(None, '', 'ab+', [], ['>>'])
129
self._check('>', '', 'ab+', [], ['<', '>', '>>'])
160
133
class TestExecution(script.TestCaseWithTransportAndScript):
162
135
def test_unknown_command(self):
163
"""A clear error is reported for commands that aren't recognised
165
Testing the attributes of the SyntaxError instance is equivalent to
166
using traceback.format_exception_only and comparing with:
167
File "<string>", line 1
170
SyntaxError: Command not found "foo"
172
e = self.assertRaises(SyntaxError, self.run_script, "$ foo --frob")
173
self.assertContainsRe(e.msg, "not found.*foo")
174
self.assertEqual(e.text, "foo --frob")
176
def test_blank_output_mismatches_output(self):
177
"""If you give output, the output must actually be blank.
179
See <https://bugs.launchpad.net/bzr/+bug/637830>: previously blank
180
output was a wildcard. Now you must say ... if you want that.
182
self.assertRaises(AssertionError,
188
def test_null_output_matches_option(self):
189
"""If you want null output to be a wild card, you can pass
190
null_output_matches_anything to run_script"""
194
""", null_output_matches_anything=True)
196
def test_ellipsis_everything(self):
197
"""A simple ellipsis matches everything."""
203
def test_ellipsis_matches_empty(self):
136
self.assertRaises(SyntaxError, self.run_script, 'foo')
209
138
def test_stops_on_unexpected_output(self):
309
227
def test_cat_input_to_output(self):
310
228
retcode, out, err = self.run_command(['cat'],
311
229
'content\n', 'content\n', None)
312
self.assertEqual('content\n', out)
313
self.assertEqual(None, err)
230
self.assertEquals('content\n', out)
231
self.assertEquals(None, err)
315
233
def test_cat_file_to_output(self):
316
self.build_tree_contents([('file', b'content\n')])
234
self.build_tree_contents([('file', 'content\n')])
317
235
retcode, out, err = self.run_command(['cat', 'file'],
318
236
None, 'content\n', None)
319
self.assertEqual('content\n', out)
320
self.assertEqual(None, err)
237
self.assertEquals('content\n', out)
238
self.assertEquals(None, err)
322
240
def test_cat_input_to_file(self):
323
241
retcode, out, err = self.run_command(['cat', '>file'],
324
242
'content\n', None, None)
325
243
self.assertFileEqual('content\n', 'file')
326
self.assertEqual(None, out)
327
self.assertEqual(None, err)
244
self.assertEquals(None, out)
245
self.assertEquals(None, err)
328
246
retcode, out, err = self.run_command(['cat', '>>file'],
329
247
'more\n', None, None)
330
248
self.assertFileEqual('content\nmore\n', 'file')
331
self.assertEqual(None, out)
332
self.assertEqual(None, err)
249
self.assertEquals(None, out)
250
self.assertEquals(None, err)
334
252
def test_cat_file_to_file(self):
335
self.build_tree_contents([('file', b'content\n')])
253
self.build_tree_contents([('file', 'content\n')])
336
254
retcode, out, err = self.run_command(['cat', 'file', '>file2'],
337
255
None, None, None)
338
self.assertFileEqual(b'content\n', 'file2')
256
self.assertFileEqual('content\n', 'file2')
340
258
def test_cat_files_to_file(self):
341
self.build_tree_contents([('cat', b'cat\n')])
342
self.build_tree_contents([('dog', b'dog\n')])
259
self.build_tree_contents([('cat', 'cat\n')])
260
self.build_tree_contents([('dog', 'dog\n')])
343
261
retcode, out, err = self.run_command(['cat', 'cat', 'dog', '>file'],
344
262
None, None, None)
345
self.assertFileEqual(b'cat\ndog\n', 'file')
263
self.assertFileEqual('cat\ndog\n', 'file')
347
265
def test_cat_bogus_input_file(self):
348
266
self.run_script("""
397
314
self.assertRaises(ValueError, self.run_script, '$ cd ..')
399
316
def test_cd_dir_and_back_home(self):
400
self.assertEqual(self.test_dir, osutils.getcwd())
317
self.assertEquals(self.test_dir, osutils.getcwd())
401
318
self.run_script("""
405
self.assertEqual(osutils.pathjoin(self.test_dir, 'dir'),
322
self.assertEquals(osutils.pathjoin(self.test_dir, 'dir'),
408
325
self.run_script('$ cd')
409
self.assertEqual(self.test_dir, osutils.getcwd())
412
class TestBrz(script.TestCaseWithTransportAndScript):
414
def test_brz_smoke(self):
417
Created a standalone tree (format: ...)
419
self.assertPathExists('branch')
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')
422
336
class TestEcho(script.TestCaseWithMemoryTransportAndScript):
436
350
def test_echo_to_output(self):
437
351
retcode, out, err = self.run_command(['echo'], None, '\n', None)
438
self.assertEqual('\n', out)
439
self.assertEqual(None, err)
352
self.assertEquals('\n', out)
353
self.assertEquals(None, err)
441
355
def test_echo_some_to_output(self):
442
356
retcode, out, err = self.run_command(['echo', 'hello'],
443
357
None, 'hello\n', None)
444
self.assertEqual('hello\n', out)
445
self.assertEqual(None, err)
358
self.assertEquals('hello\n', out)
359
self.assertEquals(None, err)
447
361
def test_echo_more_output(self):
448
362
retcode, out, err = self.run_command(
449
363
['echo', 'hello', 'happy', 'world'],
450
364
None, 'hello happy world\n', None)
451
self.assertEqual('hello happy world\n', out)
452
self.assertEqual(None, err)
365
self.assertEquals('hello happy world\n', out)
366
self.assertEquals(None, err)
454
368
def test_echo_appended(self):
455
369
retcode, out, err = self.run_command(['echo', 'hello', '>file'],
456
370
None, None, None)
457
self.assertEqual(None, out)
458
self.assertEqual(None, err)
459
self.assertFileEqual(b'hello\n', 'file')
371
self.assertEquals(None, out)
372
self.assertEquals(None, err)
373
self.assertFileEqual('hello\n', 'file')
460
374
retcode, out, err = self.run_command(['echo', 'happy', '>>file'],
461
375
None, None, None)
462
self.assertEqual(None, out)
463
self.assertEqual(None, err)
464
self.assertFileEqual(b'hello\nhappy\n', 'file')
466
def test_empty_line_in_output_is_respected(self):
376
self.assertEquals(None, out)
377
self.assertEquals(None, err)
378
self.assertFileEqual('hello\nhappy\n', 'file')
475
381
class TestRm(script.TestCaseWithTransportAndScript):
481
387
def test_rm_file(self):
482
388
self.run_script('$ echo content >file')
483
self.assertPathExists('file')
389
self.failUnlessExists('file')
484
390
self.run_script('$ rm file')
485
self.assertPathDoesNotExist('file')
391
self.failIfExists('file')
487
393
def test_rm_file_force(self):
488
self.assertPathDoesNotExist('file')
394
self.failIfExists('file')
489
395
self.run_script('$ rm -f file')
490
self.assertPathDoesNotExist('file')
396
self.failIfExists('file')
492
398
def test_rm_files(self):
493
399
self.run_script("""
494
400
$ echo content >file
495
401
$ echo content >file2
497
self.assertPathExists('file2')
403
self.failUnlessExists('file2')
498
404
self.run_script('$ rm file file2')
499
self.assertPathDoesNotExist('file2')
405
self.failIfExists('file2')
501
407
def test_rm_dir(self):
502
408
self.run_script('$ mkdir dir')
503
self.assertPathExists('dir')
409
self.failUnlessExists('dir')
504
410
self.run_script("""
506
412
2>rm: cannot remove 'dir': Is a directory
508
self.assertPathExists('dir')
414
self.failUnlessExists('dir')
510
416
def test_rm_dir_recursive(self):
511
417
self.run_script("""
515
self.assertPathDoesNotExist('dir')
421
self.failIfExists('dir')
518
424
class TestMv(script.TestCaseWithTransportAndScript):
549
455
$ echo content > file
551
457
self.run_script('$ mv file dir')
552
self.assertPathExists('dir')
553
self.assertPathDoesNotExist('file')
554
self.assertPathExists('dir/file')
557
class cmd_test_confirm(commands.Command):
560
if ui.ui_factory.get_boolean(
562
# 'breezy.tests.test_script.confirm',
565
self.outf.write('Do it!\n')
570
class TestUserInteraction(script.TestCaseWithMemoryTransportAndScript):
572
def test_confirm_action(self):
573
"""You can write tests that demonstrate user confirmation.
575
Specifically, ScriptRunner does't care if the output line for the
576
prompt isn't terminated by a newline from the program; it's implicitly
577
terminated by the input.
579
commands.builtin_command_registry.register(cmd_test_confirm)
581
commands.builtin_command_registry.remove, 'test-confirm')
584
2>Really do it? ([y]es, [n]o): yes
588
2>Really do it? ([y]es, [n]o): no
594
class TestShelve(script.TestCaseWithTransportAndScript):
597
super(TestShelve, self).setUp()
600
Created a standalone tree (format: 2a)
605
$ brz commit -m 'file added'
606
2>Committing to:...test/
608
2>Committed revision 1.
612
def test_shelve(self):
614
$ brz shelve -m 'shelve bar'
615
2>Shelve? ([y]es, [N]o, [f]inish, [q]uit): yes
619
2>Shelve 1 change(s)? ([y]es, [N]o, [f]inish, [q]uit): yes
621
2>Changes shelved with id "1".
623
null_output_matches_anything=True)
629
def test_dont_shelve(self):
630
# We intentionally provide no input here to test EOF
632
"$ brz shelve -m 'shelve bar'\n"
633
"2>Shelve? ([y]es, [N]o, [f]inish, [q]uit): \n"
634
"2>No changes to shelve.\n"
635
), null_output_matches_anything=True)
458
self.failUnlessExists('dir')
459
self.failIfExists('file')
460
self.failUnlessExists('dir/file')