##// END OF EJS Templates
Add AssertPrints context manager to check output from tests.
Thomas Kluyver -
Show More
@@ -17,6 +17,7 from __future__ import with_statement
17
17
18 import os
18 import os
19 import sys
19 import sys
20 import unittest
20
21
21 import nose.tools as nt
22 import nose.tools as nt
22
23
@@ -71,3 +72,19 def test_temp_pyfile():
71 with open(fname) as fh2:
72 with open(fname) as fh2:
72 src2 = fh2.read()
73 src2 = fh2.read()
73 yield nt.assert_equal(src2, src)
74 yield nt.assert_equal(src2, src)
75
76 class TestAssertPrints(unittest.TestCase):
77 def test_passing(self):
78 with tt.AssertPrints("abc"):
79 print "abcd"
80 print "def"
81 print b"ghi"
82
83 def test_failing(self):
84 def func():
85 with tt.AssertPrints("abc"):
86 print "acd"
87 print "def"
88 print b"ghi"
89
90 self.assertRaises(AssertionError, func)
@@ -34,6 +34,7 import sys
34 import tempfile
34 import tempfile
35
35
36 from contextlib import contextmanager
36 from contextlib import contextmanager
37 from io import StringIO
37
38
38 try:
39 try:
39 # These tools are used by parts of the runtime, so we make the nose
40 # These tools are used by parts of the runtime, so we make the nose
@@ -46,9 +47,9 except ImportError:
46
47
47 from IPython.config.loader import Config
48 from IPython.config.loader import Config
48 from IPython.utils.process import find_cmd, getoutputerror
49 from IPython.utils.process import find_cmd, getoutputerror
49 from IPython.utils.text import list_strings
50 from IPython.utils.text import list_strings, getdefaultencoding
50 from IPython.utils.io import temp_pyfile
51 from IPython.utils.io import temp_pyfile, Tee
51 from IPython.utils.py3compat import PY3
52 from IPython.utils import py3compat
52
53
53 from . import decorators as dec
54 from . import decorators as dec
54 from . import skipdoctest
55 from . import skipdoctest
@@ -210,7 +211,7 def ipexec(fname, options=None):
210 _ip = get_ipython()
211 _ip = get_ipython()
211 test_dir = os.path.dirname(__file__)
212 test_dir = os.path.dirname(__file__)
212
213
213 ipython_cmd = find_cmd('ipython3' if PY3 else 'ipython')
214 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
214 # Absolute path for filename
215 # Absolute path for filename
215 full_fname = os.path.join(test_dir, fname)
216 full_fname = os.path.join(test_dir, fname)
216 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
217 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
@@ -324,6 +325,47 def check_pairs(func, pairs):
324 out = func(inp)
325 out = func(inp)
325 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
326 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
326
327
328 if py3compat.PY3:
329 MyStringIO = StringIO
330 else:
331 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
332 # so we need a class that can handle both.
333 class MyStringIO(StringIO):
334 def write(self, s):
335 s = py3compat.cast_unicode(s, encoding=getdefaultencoding())
336 super(MyStringIO, self).write(s)
337
338 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
339 {2!r}"""
340 class AssertPrints(object):
341 """Context manager for testing that code prints certain text.
342
343 Examples
344 --------
345 >>> with AssertPrints("abc"):
346 ... print "abcd"
347 ... print "def"
348 ...
349 abcd
350 def
351 """
352 def __init__(self, s, channel='stdout'):
353 self.s = s
354 self.channel = channel
355
356 def __enter__(self):
357 self.orig_stream = getattr(sys, self.channel)
358 self.buffer = MyStringIO()
359 self.tee = Tee(self.buffer, channel=self.channel)
360 setattr(sys, self.channel, self.tee)
361
362 def __exit__(self, etype, value, traceback):
363 self.tee.flush()
364 setattr(sys, self.channel, self.orig_stream)
365 printed = self.buffer.getvalue()
366 assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed)
367 return False
368
327 @contextmanager
369 @contextmanager
328 def mute_warn():
370 def mute_warn():
329 from IPython.utils import warn
371 from IPython.utils import warn
@@ -29,7 +29,7 from nose import with_setup
29 import IPython
29 import IPython
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
32 from IPython.testing.tools import make_tempfile
32 from IPython.testing.tools import make_tempfile, AssertPrints
33 from IPython.utils import path, io
33 from IPython.utils import path, io
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35
35
@@ -404,13 +404,8 def test_not_writable_ipdir():
404 ipdir = os.path.join(tmpdir, '.ipython')
404 ipdir = os.path.join(tmpdir, '.ipython')
405 os.mkdir(ipdir)
405 os.mkdir(ipdir)
406 os.chmod(ipdir, 600)
406 os.chmod(ipdir, 600)
407 stderr = io.stderr
407 with AssertPrints('WARNING', channel='stderr'):
408 pipe = StringIO()
408 ipdir = path.get_ipython_dir()
409 io.stderr = pipe
410 ipdir = path.get_ipython_dir()
411 io.stderr.flush()
412 io.stderr = stderr
413 nt.assert_true('WARNING' in pipe.getvalue())
414 env.pop('IPYTHON_DIR', None)
409 env.pop('IPYTHON_DIR', None)
415
410
416 def test_unquote_filename():
411 def test_unquote_filename():
General Comments 0
You need to be logged in to leave comments. Login now