##// END OF EJS Templates
Reuse common code for inputsplitter and prefilter.
Reuse common code for inputsplitter and prefilter.

File last commit:

r4746:76b84816
r4746:76b84816
Show More
tools.py
345 lines | 10.3 KiB | text/x-python | PythonLexer
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 """Generic testing tools that do NOT depend on Twisted.
In particular, this module exposes a set of top-level assert* functions that
can be used in place of nose.tools.assert* in method generators (the ones in
nose can not, at least as of nose 0.10.4).
Note: our testing package contains testing.util, which does depend on Twisted
and provides utilities for tests that manage Deferreds. All testing support
tools that only depend on nose, IPython or the standard library should go here
instead.
Authors
-------
- Fernando Perez <Fernando.Perez@berkeley.edu>
"""
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 from __future__ import absolute_import
#-----------------------------------------------------------------------------
# Copyright (C) 2009 The IPython Development Team
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 #-----------------------------------------------------------------------------
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
#-----------------------------------------------------------------------------
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 # Imports
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #-----------------------------------------------------------------------------
import os
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 import re
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 import sys
MinRK
put test_hist.sqlite in tempdir, to prevent polluting filesystem
r4486 import tempfile
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 from contextlib import contextmanager
Fernando Perez
Remove accidentally introduced runtime nose dependencies.
r2442 try:
# These tools are used by parts of the runtime, so we make the nose
# dependency optional at this point. Nose is a hard dependency to run the
# test suite, but NOT to use ipython itself.
import nose.tools as nt
has_nose = True
except ImportError:
has_nose = False
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 from IPython.config.loader import Config
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 from IPython.utils.process import find_cmd, getoutputerror
from IPython.utils.text import list_strings
from IPython.utils.io import temp_pyfile
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 from . import decorators as dec
MinRK
fix skip_doctest import in testing.tools
r3905 from . import skipdoctest
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 #-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------
# Make a bunch of nose.tools assert wrappers that can be used in test
# generators. This will expose an assert* function for each one in nose.tools.
_tpl = """
def %(name)s(*a,**kw):
return nt.%(name)s(*a,**kw)
"""
Fernando Perez
Remove accidentally introduced runtime nose dependencies.
r2442 if has_nose:
for _x in [a for a in dir(nt) if a.startswith('assert')]:
exec _tpl % dict(name=_x)
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
#-----------------------------------------------------------------------------
# Functions and classes
#-----------------------------------------------------------------------------
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 # The docstring for full_path doctests differently on win32 (different path
# separator) so just skip the doctest there. The example remains informative.
MinRK
fix skip_doctest import in testing.tools
r3905 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
Brian Granger
Fixing tests in IPython.testing.
r1982
Fernando Perez
Fixes for test suite in win32 when all dependencies (esp. Twisted) are...
r2461 @doctest_deco
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 def full_path(startPath,files):
"""Make full paths for all the listed files, based on startPath.
Only the base part of startPath is kept, since this routine is typically
used with a script's __file__ variable as startPath. The base of startPath
is then prepended to all the listed files, forming the output list.
Brian Granger
Merging Fernando's fixes from his trunk-dev and fixing testing things....
r1973 Parameters
----------
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 startPath : string
Initial path to use as the base for the results. This path is split
using os.path.split() and only its first component is kept.
files : string or list
One or more files.
Brian Granger
Merging Fernando's fixes from his trunk-dev and fixing testing things....
r1973 Examples
--------
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955
>>> full_path('/foo/bar.py',['a.txt','b.txt'])
['/foo/a.txt', '/foo/b.txt']
>>> full_path('/foo',['a.txt','b.txt'])
['/a.txt', '/b.txt']
If a single file is given, the output is still a list:
>>> full_path('/foo','a.txt')
['/a.txt']
"""
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 files = list_strings(files)
Fernando Perez
Ensure that we don't damage the __builtins__ object after %run....
r1955 base = os.path.split(startPath)[0]
return [ os.path.join(base,f) for f in files ]
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353
def parse_test_output(txt):
"""Parse the output of a test run and return errors, failures.
Parameters
----------
txt : str
Text output of a test run, assumed to contain a line of one of the
following forms::
'FAILED (errors=1)'
'FAILED (failures=1)'
'FAILED (errors=1, failures=1)'
Returns
-------
nerr, nfail: number of errors and failures.
"""
err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
if err_m:
nerr = int(err_m.group(1))
nfail = 0
return nerr, nfail
fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
if fail_m:
nerr = 0
nfail = int(fail_m.group(1))
return nerr, nfail
both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
re.MULTILINE)
if both_m:
nerr = int(both_m.group(1))
nfail = int(both_m.group(2))
return nerr, nfail
# If the input didn't match any of these forms, assume no error/failures
return 0, 0
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Fernando Perez
Add test utility for parsing test output from stdout/stderr
r2353 # So nose doesn't think this is a test
parse_test_output.__test__ = False
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
def default_argv():
"""Return a valid default argv for creating testing instances of ipython"""
Fernando Perez
Minimize stdout side effects in testing instances.
r2477 return ['--quick', # so no config file is loaded
# Other defaults to minimize side effects on stdout
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 '--colors=NoColor', '--no-term-title','--no-banner',
'--autocall=0']
Brian Granger
More work addressing review comments for Fernando's branch....
r2499
def default_config():
"""Return a config object with good defaults for testing."""
config = Config()
Brian Granger
Complete reorganization of InteractiveShell....
r2761 config.TerminalInteractiveShell.colors = 'NoColor'
config.TerminalTerminalInteractiveShell.term_title = False,
config.TerminalInteractiveShell.autocall = 0
MinRK
add test history db to shell.tempfiles for cleanup...
r4602 config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
Thomas Kluyver
Tests can no longer use db in memory: doesn't work with multiple threads.
r3712 config.HistoryManager.db_cache_size = 10000
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 return config
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 def ipexec(fname, options=None):
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 """Utility to call 'ipython filename'.
Starts IPython witha minimal and safe configuration to make startup as fast
as possible.
Note that this starts IPython in a subprocess!
Parameters
----------
fname : str
Name of file to be executed (should have .py or .ipy extension).
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 options : optional, list
Extra command-line flags to be passed to IPython.
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 Returns
-------
(stdout, stderr) of ipython subprocess.
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 """
if options is None: options = []
Fernando Perez
Minimize stdout side effects in testing instances.
r2477
# For these subprocess calls, eliminate all prompt printing so we only see
# output from script execution
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 prompt_opts = [ '--InteractiveShell.prompt_in1=""',
'--InteractiveShell.prompt_in2=""',
'--InteractiveShell.prompt_out=""'
MinRK
catch up tests to recent changes...
r4029 ]
Fernando Perez
Minimize stdout side effects in testing instances.
r2477 cmdargs = ' '.join(default_argv() + prompt_opts + options)
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 _ip = get_ipython()
test_dir = os.path.dirname(__file__)
Fernando Perez
Make it possible to run the tests from the source dir without installation....
r2481
Brian Granger
Removed the top-level iptest.py and INSTALLED logic....
r2507 ipython_cmd = find_cmd('ipython')
Fernando Perez
Various fixes for IPython.core tests to pass under win32.
r2446 # Absolute path for filename
Brian Granger
Removed the top-level iptest.py and INSTALLED logic....
r2507 full_fname = os.path.join(test_dir, fname)
Fernando Perez
Robustness fixes in test suite machinery....
r2494 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
#print >> sys.stderr, 'FULL CMD:', full_cmd # dbg
MinRK
strip leading 'ESC[?1034h' in tests caused by `import readline`...
r4470 out = getoutputerror(full_cmd)
# `import readline` causes 'ESC[?1034h' to be the first output sometimes,
# so strip that off the front of the first line if it is found
if out:
first = out[0]
m = re.match(r'\x1b\[[^h]+h', first)
if m:
# strip initial readline escape
out = list(out)
out[0] = first[len(m.group()):]
out = tuple(out)
return out
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414
Fernando Perez
Robustness fixes in test suite machinery....
r2494 def ipexec_validate(fname, expected_out, expected_err='',
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 options=None):
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 """Utility to call 'ipython filename' and validate output/error.
This function raises an AssertionError if the validation fails.
Note that this starts IPython in a subprocess!
Parameters
----------
fname : str
Name of the file to be executed (should have .py or .ipy extension).
expected_out : str
Expected stdout of the process.
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415 expected_err : optional, str
Expected stderr of the process.
options : optional, list
Extra command-line flags to be passed to IPython.
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 Returns
-------
None
"""
Fernando Perez
Remove accidentally introduced runtime nose dependencies.
r2442 import nose.tools as nt
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 out, err = ipexec(fname)
Fernando Perez
Robustness fixes in test suite machinery....
r2494 #print 'OUT', out # dbg
#print 'ERR', err # dbg
# If there are any errors, we must check those befor stdout, as they may be
# more informative than simply having an empty stdout.
if err:
if expected_err:
nt.assert_equals(err.strip(), expected_err.strip())
else:
raise ValueError('Running file %r produced error: %r' %
(fname, err))
# If no errors or output on stderr was expected, match stdout
Fernando Perez
Massive amount of work to improve the test suite, restores doctests....
r2414 nt.assert_equals(out.strip(), expected_out.strip())
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415
class TempFileMixin(object):
"""Utility class to create temporary Python/IPython files.
Meant as a mixin class for test cases."""
def mktmp(self, src, ext='.py'):
"""Make a valid python temp file."""
fname, f = temp_pyfile(src, ext)
self.tmpfile = f
self.fname = fname
Fernando Perez
Make our temp file mixin unittest-friendly....
r2907 def tearDown(self):
Fernando Perez
Various fixes for IPython.core tests to pass under win32.
r2446 if hasattr(self, 'tmpfile'):
# If the tmpfile wasn't made because of skipped tests, like in
# win32, there's nothing to cleanup.
self.tmpfile.close()
try:
os.unlink(self.fname)
except:
# On Windows, even though we close the file, we still can't
# delete it. I have no clue why
pass
Fernando Perez
Fix extensions test suite (small, but now it runs and passes!)
r2415
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 pair_fail_msg = ("Testing {0}\n\n"
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 "In:\n"
" {1!r}\n"
"Expected:\n"
" {2!r}\n"
"Got:\n"
" {3!r}\n")
def check_pairs(func, pairs):
"""Utility function for the common case of checking a function with a
sequence of input/output pairs.
Parameters
----------
func : callable
The function to be tested. Should accept a single argument.
pairs : iterable
A list of (input, expected_output) tuples.
Returns
-------
None. Raises an AssertionError if any output does not match the expected
value.
"""
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
Thomas Kluyver
Add testing function check_pairs to check input/output pairs against a function, and produce useful failure messages.
r4079 for inp, expected in pairs:
out = func(inp)
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214
@contextmanager
def mute_warn():
from IPython.utils import warn
save_warn = warn.warn
warn.warn = lambda *a, **kw: None
try:
yield
finally:
Robert Kern
BUG: Allow %magic argument filenames with spaces to be specified with quotes under win32.
r4688 warn.warn = save_warn
@contextmanager
def make_tempfile(name):
""" Create an empty, named, temporary file for the duration of the context.
"""
f = open(name, 'w')
f.close()
try:
yield
finally:
os.unlink(name)