~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/script.py

  • Committer: Martin Pool
  • Date: 2010-09-10 06:24:23 UTC
  • mto: This revision was merged to the branch mainline in revision 5426.
  • Revision ID: mbp@sourcefrog.net-20100910062423-8i2bldoclqaf41b6
Remove 'default' parameter from confirm_action
The noninteractive default is to always confirm

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
 
1
# Copyright (C) 2009, 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
import os
26
26
import shlex
27
27
import textwrap
 
28
from cStringIO import StringIO
28
29
 
29
30
from bzrlib import (
30
31
    osutils,
55
56
    Input lines start with '<'.
56
57
    Output lines start with nothing.
57
58
    Error lines start with '2>'.
58
 
 
59
 
    :return: A sequence of ([args], input, output, errors), where the args are
60
 
        split in to words, and the input, output, and errors are just strings,
61
 
        typically containing newlines.
62
59
    """
63
60
 
64
61
    commands = []
78
75
    lineno = 0
79
76
    input, output, error = None, None, None
80
77
    text = textwrap.dedent(text)
81
 
    lines = text.split('\n')
82
 
    # to make use of triple-quoted strings easier, we ignore a blank line
83
 
    # right at the start and right at the end; the rest are meaningful
84
 
    if lines and lines[0] == '':
85
 
        del lines[0]
86
 
    if lines and lines[-1] == '':
87
 
        del lines[-1]
88
 
    for line in lines:
 
78
    for line in text.split('\n'):
89
79
        lineno += 1
90
80
        # Keep a copy for error reporting
91
81
        orig = line
92
82
        comment =  line.find('#')
93
83
        if comment >= 0:
94
84
            # Delete comments
95
 
            # NB: this syntax means comments are allowed inside output, which
96
 
            # may be confusing...
97
85
            line = line[0:comment]
98
86
            line = line.rstrip()
99
 
            if line == '':
100
 
                continue
 
87
        if line == '':
 
88
            # Ignore empty lines
 
89
            continue
101
90
        if line.startswith('$'):
102
91
            # Time to output the current command
103
92
            add_command(cmd_cur, input, output, error)
194
183
        self.output_checker = doctest.OutputChecker()
195
184
        self.check_options = doctest.ELLIPSIS
196
185
 
197
 
    def run_script(self, test_case, text, null_output_matches_anything=False):
 
186
    def run_script(self, test_case, text):
198
187
        """Run a shell-like script as a test.
199
188
 
200
189
        :param test_case: A TestCase instance that should provide the fail(),
202
191
            attribute used as a jail root.
203
192
 
204
193
        :param text: A shell-like script (see _script_to_commands for syntax).
205
 
 
206
 
        :param null_output_matches_anything: For commands with no specified
207
 
            output, ignore any output that does happen, including output on
208
 
            standard error.
209
194
        """
210
 
        self.null_output_matches_anything = null_output_matches_anything
211
195
        for cmd, input, output, error in _script_to_commands(text):
212
196
            self.run_command(test_case, cmd, input, output, error)
213
197
 
216
200
        method = getattr(self, mname, None)
217
201
        if method is None:
218
202
            raise SyntaxError('Command not found "%s"' % (cmd[0],),
219
 
                              (None, 1, 1, ' '.join(cmd)))
 
203
                              None, 1, ' '.join(cmd))
220
204
        if input is None:
221
205
            str_input = ''
222
206
        else:
225
209
        retcode, actual_output, actual_error = method(test_case,
226
210
                                                      str_input, args)
227
211
 
228
 
        try:
229
 
            self._check_output(output, actual_output, test_case)
230
 
        except AssertionError, e:
231
 
            raise AssertionError(str(e) + " in stdout of command %s" % cmd)
232
 
        try:
233
 
            self._check_output(error, actual_error, test_case)
234
 
        except AssertionError, e:
235
 
            raise AssertionError(str(e) +
236
 
                " in stderr of running command %s" % cmd)
 
212
        self._check_output(output, actual_output, test_case)
 
213
        self._check_output(error, actual_error, test_case)
237
214
        if retcode and not error and actual_error:
238
215
            test_case.fail('In \n\t%s\nUnexpected error: %s'
239
216
                           % (' '.join(cmd), actual_error))
240
217
        return retcode, actual_output, actual_error
241
218
 
242
219
    def _check_output(self, expected, actual, test_case):
243
 
        if not actual:
244
 
            if expected is None:
245
 
                return
246
 
            elif expected == '...\n':
247
 
                return
248
 
            else:
249
 
                test_case.fail('expected output: %r, but found nothing'
250
 
                            % (expected,))
251
 
 
252
 
        null_output_matches_anything = getattr(
253
 
            self, 'null_output_matches_anything', False)
254
 
        if null_output_matches_anything and expected is None:
 
220
        if expected is None:
 
221
            # Specifying None means: any output is accepted
255
222
            return
256
 
 
257
 
        expected = expected or ''
 
223
        if actual is None:
 
224
            test_case.fail('We expected output: %r, but found None'
 
225
                           % (expected,))
258
226
        matching = self.output_checker.check_output(
259
227
            expected, actual, self.check_options)
260
228
        if not matching:
264
232
            # 'expected' parameter. So we just fallback to our good old
265
233
            # assertEqualDiff since we know there *are* differences and the
266
234
            # output should be decently readable.
267
 
            #
268
 
            # As a special case, we allow output that's missing a final
269
 
            # newline to match an expected string that does have one, so that
270
 
            # we can match a prompt printed on one line, then input given on
271
 
            # the next line.
272
 
            if expected == actual + '\n':
273
 
                pass
274
 
            else:
275
 
                test_case.assertEqualDiff(expected, actual)
 
235
            test_case.assertEqualDiff(expected, actual)
276
236
 
277
237
    def _pre_process_args(self, args):
278
238
        new_args = []
481
441
    def setUp(self):
482
442
        super(TestCaseWithMemoryTransportAndScript, self).setUp()
483
443
        self.script_runner = ScriptRunner()
484
 
        # FIXME: See shelf_ui.Shelver._char_based. This allow using shelve in
485
 
        # scripts while providing a line-based input (better solution in
486
 
        # progress). -- vila 2011-09-28
487
 
        self.overrideEnv('INSIDE_EMACS', '1')
488
444
 
489
 
    def run_script(self, script, null_output_matches_anything=False):
490
 
        return self.script_runner.run_script(self, script, 
491
 
                   null_output_matches_anything=null_output_matches_anything)
 
445
    def run_script(self, script):
 
446
        return self.script_runner.run_script(self, script)
492
447
 
493
448
    def run_command(self, cmd, input, output, error):
494
449
        return self.script_runner.run_command(self, cmd, input, output, error)
515
470
    def setUp(self):
516
471
        super(TestCaseWithTransportAndScript, self).setUp()
517
472
        self.script_runner = ScriptRunner()
518
 
        # FIXME: See shelf_ui.Shelver._char_based. This allow using shelve in
519
 
        # scripts while providing a line-based input (better solution in
520
 
        # progress). -- vila 2011-09-28
521
 
        self.overrideEnv('INSIDE_EMACS', '1')
522
473
 
523
 
    def run_script(self, script, null_output_matches_anything=False):
524
 
        return self.script_runner.run_script(self, script,
525
 
                   null_output_matches_anything=null_output_matches_anything)
 
474
    def run_script(self, script):
 
475
        return self.script_runner.run_script(self, script)
526
476
 
527
477
    def run_command(self, cmd, input, output, error):
528
478
        return self.script_runner.run_command(self, cmd, input, output, error)
529
479
 
530
480
 
531
 
def run_script(test_case, script_string, null_output_matches_anything=False):
 
481
def run_script(test_case, script_string):
532
482
    """Run the given script within a testcase"""
533
 
    return ScriptRunner().run_script(test_case, script_string,
534
 
               null_output_matches_anything=null_output_matches_anything)
535
 
 
 
483
    return ScriptRunner().run_script(test_case, script_string)