##// END OF EJS Templates
test that `-h` and `--help-all` work for various IPython entry points...
MinRK -
Show More
@@ -0,0 +1,29 b''
1 """Test NotebookApp"""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 import nose.tools as nt
15
16 import IPython.testing.tools as tt
17
18 #-----------------------------------------------------------------------------
19 # Test functions
20 #-----------------------------------------------------------------------------
21
22 def test_help_output():
23 """ipython notebook -h works"""
24 tt.help_output_test('notebook')
25
26 def test_help_all_output():
27 """ipython notebook --help-all works"""
28 tt.help_all_output_test('notebook')
29
@@ -0,0 +1,29 b''
1 """Test QtConsoleApp"""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 import nose.tools as nt
15
16 import IPython.testing.tools as tt
17
18 #-----------------------------------------------------------------------------
19 # Test functions
20 #-----------------------------------------------------------------------------
21
22 def test_help_output():
23 """ipython qtconsole -h works"""
24 tt.help_output_test('qtconsole')
25
26 def test_help_all_output():
27 """ipython qtconsole --help-all works"""
28 tt.help_all_output_test('qtconsole')
29
@@ -0,0 +1,67 b''
1 """Test help output of various IPython entry points"""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 from IPython.testing.tools import help, help_all
15
16 #-----------------------------------------------------------------------------
17 # Tests
18 #-----------------------------------------------------------------------------
19
20
21 @help()
22 def test_ipython_help():
23 pass
24
25 @help_all()
26 def test_ipython_help_all():
27 pass
28
29 @help("profile")
30 def test_profile_help():
31 pass
32
33 @help_all("profile")
34 def test_profile_help_all():
35 pass
36
37 @help("profile list")
38 def test_profile_list_help():
39 pass
40
41 @help_all("profile list")
42 def test_profile_list_help_all():
43 pass
44
45 @help("profile create")
46 def test_profile_create_help():
47 pass
48
49 @help_all("profile create")
50 def test_profile_create_help_all():
51 pass
52
53 @help("locate")
54 def test_locate_help():
55 pass
56
57 @help_all("locate")
58 def test_locate_help_all():
59 pass
60
61 @help("locate profile")
62 def test_locate_profile_help():
63 pass
64
65 @help_all("locate profile")
66 def test_locate_profile_all():
67 pass
@@ -1,160 +1,164 b''
1 """
2 Contains tests for the nbconvertapp
3 """
1 """Test NbConvertApp"""
2
4 3 #-----------------------------------------------------------------------------
5 #Copyright (c) 2013, the IPython Development Team.
6 #
7 #Distributed under the terms of the Modified BSD License.
4 # Copyright (C) 2013 The IPython Development Team
8 5 #
9 #The full license is in the file COPYING.txt, distributed with this software.
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
10 8 #-----------------------------------------------------------------------------
11 9
12 10 #-----------------------------------------------------------------------------
13 11 # Imports
14 12 #-----------------------------------------------------------------------------
15 13
16 14 import os
17 15 import glob
18 16
19 17 from .base import TestsBase
20 18
19 import IPython.testing.tools as tt
21 20 from IPython.testing import decorators as dec
22 21
23 22
24 23 #-----------------------------------------------------------------------------
25 24 # Constants
26 25 #-----------------------------------------------------------------------------
27 26
28 27
29 28 #-----------------------------------------------------------------------------
30 29 # Classes and functions
31 30 #-----------------------------------------------------------------------------
32 31
33 32 class TestNbConvertApp(TestsBase):
34 33 """Collection of NbConvertApp tests"""
35 34
36 35
37 36 def test_notebook_help(self):
38 """
39 Will help show if no notebooks are specified?
40 """
37 """Will help show if no notebooks are specified?"""
41 38 with self.create_temp_cwd():
42 39 out, err = self.call('nbconvert --log-level 0', ignore_return_code=True)
43 assert "see '--help-all'" in out
40 self.assertIn("see '--help-all'", out)
41
42 def test_help_output(self):
43 """ipython nbconvert -h works"""
44 tt.help_output_test('nbconvert')
44 45
46 def test_help_all_output(self):
47 """ipython nbconvert --help-all works"""
48 tt.help_all_output_test('nbconvert')
45 49
46 50 def test_glob(self):
47 51 """
48 52 Do search patterns work for notebook names?
49 53 """
50 54 with self.create_temp_cwd(['notebook*.ipynb']):
51 55 self.call('nbconvert --to python *.ipynb --log-level 0')
52 56 assert os.path.isfile('notebook1.py')
53 57 assert os.path.isfile('notebook2.py')
54 58
55 59
56 60 def test_glob_subdir(self):
57 61 """
58 62 Do search patterns work for subdirectory notebook names?
59 63 """
60 64 with self.create_temp_cwd():
61 65 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
62 66 self.call('nbconvert --to python --log-level 0 ' +
63 67 os.path.join('subdir', '*.ipynb'))
64 68 assert os.path.isfile('notebook1.py')
65 69 assert os.path.isfile('notebook2.py')
66 70
67 71
68 72 def test_explicit(self):
69 73 """
70 74 Do explicit notebook names work?
71 75 """
72 76 with self.create_temp_cwd(['notebook*.ipynb']):
73 77 self.call('nbconvert --log-level 0 --to python notebook2')
74 78 assert not os.path.isfile('notebook1.py')
75 79 assert os.path.isfile('notebook2.py')
76 80
77 81
78 82 @dec.onlyif_cmds_exist('pdflatex')
79 83 @dec.onlyif_cmds_exist('pandoc')
80 84 def test_filename_spaces(self):
81 85 """
82 86 Generate PDFs with graphics if notebooks have spaces in the name?
83 87 """
84 88 with self.create_temp_cwd(['notebook2.ipynb']):
85 89 os.rename('notebook2.ipynb', 'notebook with spaces.ipynb')
86 90 o,e = self.call('nbconvert --log-level 0 --to latex '
87 91 '"notebook with spaces" --post PDF '
88 92 '--PDFPostProcessor.verbose=True')
89 93 assert os.path.isfile('notebook with spaces.tex')
90 94 assert os.path.isdir('notebook with spaces_files')
91 95 assert os.path.isfile('notebook with spaces.pdf')
92 96
93 97 @dec.onlyif_cmds_exist('pdflatex')
94 98 @dec.onlyif_cmds_exist('pandoc')
95 99 def test_post_processor(self):
96 100 """
97 101 Do post processors work?
98 102 """
99 103 with self.create_temp_cwd(['notebook1.ipynb']):
100 104 self.call('nbconvert --log-level 0 --to latex notebook1 '
101 105 '--post PDF --PDFPostProcessor.verbose=True')
102 106 assert os.path.isfile('notebook1.tex')
103 107 assert os.path.isfile('notebook1.pdf')
104 108
105 109
106 110 @dec.onlyif_cmds_exist('pandoc')
107 111 def test_template(self):
108 112 """
109 113 Do export templates work?
110 114 """
111 115 with self.create_temp_cwd(['notebook2.ipynb']):
112 116 self.call('nbconvert --log-level 0 --to slides '
113 117 'notebook2.ipynb --template reveal')
114 118 assert os.path.isfile('notebook2.slides.html')
115 119 with open('notebook2.slides.html') as f:
116 120 assert '/reveal.css' in f.read()
117 121
118 122
119 123 def test_glob_explicit(self):
120 124 """
121 125 Can a search pattern be used along with matching explicit notebook names?
122 126 """
123 127 with self.create_temp_cwd(['notebook*.ipynb']):
124 128 self.call('nbconvert --log-level 0 --to python '
125 129 '*.ipynb notebook1.ipynb notebook2.ipynb')
126 130 assert os.path.isfile('notebook1.py')
127 131 assert os.path.isfile('notebook2.py')
128 132
129 133
130 134 def test_explicit_glob(self):
131 135 """
132 136 Can explicit notebook names be used and then a matching search pattern?
133 137 """
134 138 with self.create_temp_cwd(['notebook*.ipynb']):
135 139 self.call('nbconvert --log-level 0 --to=python '
136 140 'notebook1.ipynb notebook2.ipynb *.ipynb')
137 141 assert os.path.isfile('notebook1.py')
138 142 assert os.path.isfile('notebook2.py')
139 143
140 144
141 145 def test_default_config(self):
142 146 """
143 147 Does the default config work?
144 148 """
145 149 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
146 150 self.call('nbconvert --log-level 0')
147 151 assert os.path.isfile('notebook1.py')
148 152 assert not os.path.isfile('notebook2.py')
149 153
150 154
151 155 def test_override_config(self):
152 156 """
153 157 Can the default config be overriden?
154 158 """
155 159 with self.create_temp_cwd(['notebook*.ipynb',
156 160 'ipython_nbconvert_config.py',
157 161 'override.py']):
158 162 self.call('nbconvert --log-level 0 --config="override.py"')
159 163 assert not os.path.isfile('notebook1.py')
160 164 assert os.path.isfile('notebook2.py')
@@ -1,57 +1,67 b''
1 1 """Tests for two-process terminal frontend
2 2
3 3 Currently only has the most simple test possible, starting a console and running
4 4 a single command.
5 5
6 6 Authors:
7 7
8 8 * Min RK
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 import sys
16 16 import time
17 17
18 18 import nose.tools as nt
19 19 from nose import SkipTest
20 20
21 import IPython.testing.tools as tt
21 22 from IPython.testing import decorators as dec
22 23 from IPython.utils import py3compat
23 24
24 25 #-----------------------------------------------------------------------------
25 # Test functions begin
26 # Tests
26 27 #-----------------------------------------------------------------------------
27 28
28 29 @dec.skip_win32
29 30 def test_console_starts():
30 31 """test that `ipython console` starts a terminal"""
31 32 from IPython.external import pexpect
32 33
33 34 args = ['console', '--colors=NoColor']
34 35 # FIXME: remove workaround for 2.6 support
35 36 if sys.version_info[:2] > (2,6):
36 37 args = ['-m', 'IPython'] + args
37 38 cmd = sys.executable
38 39 else:
39 40 cmd = 'ipython'
40 41
41 42 try:
42 43 p = pexpect.spawn(cmd, args=args)
43 44 except IOError:
44 45 raise SkipTest("Couldn't find command %s" % cmd)
45 46
46 47 # timeout after one minute
47 48 t = 60
48 49 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=t)
49 50 p.sendline('5')
50 51 idx = p.expect([r'Out\[\d+\]: 5', pexpect.EOF], timeout=t)
51 52 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=t)
52 53 # send ctrl-D;ctrl-D to exit
53 54 p.sendeof()
54 55 p.sendeof()
55 56 p.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=t)
56 57 if p.isalive():
57 58 p.terminate()
59
60 def test_help_output():
61 """ipython console -h works"""
62 tt.help_output_test('console')
63
64 def test_help_all_output():
65 """ipython console --help-all works"""
66 tt.help_all_output_test('console')
67
@@ -1,410 +1,465 b''
1 1 """Generic testing tools.
2 2
3 3 Authors
4 4 -------
5 5 - Fernando Perez <Fernando.Perez@berkeley.edu>
6 6 """
7 7
8 8 from __future__ import absolute_import
9 9
10 10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2009-2011 The IPython Development Team
11 # Copyright (C) 2009 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 import inspect
21 22 import os
22 23 import re
23 24 import sys
24 25 import tempfile
25 26
26 27 from contextlib import contextmanager
27 28 from io import StringIO
28 29 from subprocess import Popen, PIPE
29 30
30 31 try:
31 32 # These tools are used by parts of the runtime, so we make the nose
32 33 # dependency optional at this point. Nose is a hard dependency to run the
33 34 # test suite, but NOT to use ipython itself.
34 35 import nose.tools as nt
35 36 has_nose = True
36 37 except ImportError:
37 38 has_nose = False
38 39
39 40 from IPython.config.loader import Config
41 from IPython.utils.process import get_output_error_code
40 42 from IPython.utils.text import list_strings
41 43 from IPython.utils.io import temp_pyfile, Tee
42 44 from IPython.utils import py3compat
43 45 from IPython.utils.encoding import DEFAULT_ENCODING
44 46
45 47 from . import decorators as dec
46 48 from . import skipdoctest
47 49
48 50 #-----------------------------------------------------------------------------
49 51 # Functions and classes
50 52 #-----------------------------------------------------------------------------
51 53
52 54 # The docstring for full_path doctests differently on win32 (different path
53 55 # separator) so just skip the doctest there. The example remains informative.
54 56 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
55 57
56 58 @doctest_deco
57 59 def full_path(startPath,files):
58 60 """Make full paths for all the listed files, based on startPath.
59 61
60 62 Only the base part of startPath is kept, since this routine is typically
61 63 used with a script's __file__ variable as startPath. The base of startPath
62 64 is then prepended to all the listed files, forming the output list.
63 65
64 66 Parameters
65 67 ----------
66 68 startPath : string
67 69 Initial path to use as the base for the results. This path is split
68 70 using os.path.split() and only its first component is kept.
69 71
70 72 files : string or list
71 73 One or more files.
72 74
73 75 Examples
74 76 --------
75 77
76 78 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
77 79 ['/foo/a.txt', '/foo/b.txt']
78 80
79 81 >>> full_path('/foo',['a.txt','b.txt'])
80 82 ['/a.txt', '/b.txt']
81 83
82 84 If a single file is given, the output is still a list:
83 85 >>> full_path('/foo','a.txt')
84 86 ['/a.txt']
85 87 """
86 88
87 89 files = list_strings(files)
88 90 base = os.path.split(startPath)[0]
89 91 return [ os.path.join(base,f) for f in files ]
90 92
91 93
92 94 def parse_test_output(txt):
93 95 """Parse the output of a test run and return errors, failures.
94 96
95 97 Parameters
96 98 ----------
97 99 txt : str
98 100 Text output of a test run, assumed to contain a line of one of the
99 101 following forms::
100 102
101 103 'FAILED (errors=1)'
102 104 'FAILED (failures=1)'
103 105 'FAILED (errors=1, failures=1)'
104 106
105 107 Returns
106 108 -------
107 109 nerr, nfail: number of errors and failures.
108 110 """
109 111
110 112 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
111 113 if err_m:
112 114 nerr = int(err_m.group(1))
113 115 nfail = 0
114 116 return nerr, nfail
115 117
116 118 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
117 119 if fail_m:
118 120 nerr = 0
119 121 nfail = int(fail_m.group(1))
120 122 return nerr, nfail
121 123
122 124 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
123 125 re.MULTILINE)
124 126 if both_m:
125 127 nerr = int(both_m.group(1))
126 128 nfail = int(both_m.group(2))
127 129 return nerr, nfail
128 130
129 131 # If the input didn't match any of these forms, assume no error/failures
130 132 return 0, 0
131 133
132 134
133 135 # So nose doesn't think this is a test
134 136 parse_test_output.__test__ = False
135 137
136 138
137 139 def default_argv():
138 140 """Return a valid default argv for creating testing instances of ipython"""
139 141
140 142 return ['--quick', # so no config file is loaded
141 143 # Other defaults to minimize side effects on stdout
142 144 '--colors=NoColor', '--no-term-title','--no-banner',
143 145 '--autocall=0']
144 146
145 147
146 148 def default_config():
147 149 """Return a config object with good defaults for testing."""
148 150 config = Config()
149 151 config.TerminalInteractiveShell.colors = 'NoColor'
150 152 config.TerminalTerminalInteractiveShell.term_title = False,
151 153 config.TerminalInteractiveShell.autocall = 0
152 154 config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
153 155 config.HistoryManager.db_cache_size = 10000
154 156 return config
155 157
156 158
157 159 def get_ipython_cmd(as_string=False):
158 160 """
159 161 Return appropriate IPython command line name. By default, this will return
160 162 a list that can be used with subprocess.Popen, for example, but passing
161 163 `as_string=True` allows for returning the IPython command as a string.
162 164
163 165 Parameters
164 166 ----------
165 167 as_string: bool
166 168 Flag to allow to return the command as a string.
167 169 """
168 170 ipython_cmd = [sys.executable, "-m", "IPython"]
169 171
170 172 if as_string:
171 173 ipython_cmd = " ".join(ipython_cmd)
172 174
173 175 return ipython_cmd
174 176
175 177 def ipexec(fname, options=None):
176 178 """Utility to call 'ipython filename'.
177 179
178 180 Starts IPython with a minimal and safe configuration to make startup as fast
179 181 as possible.
180 182
181 183 Note that this starts IPython in a subprocess!
182 184
183 185 Parameters
184 186 ----------
185 187 fname : str
186 188 Name of file to be executed (should have .py or .ipy extension).
187 189
188 190 options : optional, list
189 191 Extra command-line flags to be passed to IPython.
190 192
191 193 Returns
192 194 -------
193 195 (stdout, stderr) of ipython subprocess.
194 196 """
195 197 if options is None: options = []
196 198
197 199 # For these subprocess calls, eliminate all prompt printing so we only see
198 200 # output from script execution
199 201 prompt_opts = [ '--PromptManager.in_template=""',
200 202 '--PromptManager.in2_template=""',
201 203 '--PromptManager.out_template=""'
202 204 ]
203 205 cmdargs = default_argv() + prompt_opts + options
204 206
205 207 test_dir = os.path.dirname(__file__)
206 208
207 209 ipython_cmd = get_ipython_cmd()
208 210 # Absolute path for filename
209 211 full_fname = os.path.join(test_dir, fname)
210 212 full_cmd = ipython_cmd + cmdargs + [full_fname]
211 213 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
212 214 out, err = p.communicate()
213 215 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
214 216 # `import readline` causes 'ESC[?1034h' to be output sometimes,
215 217 # so strip that out before doing comparisons
216 218 if out:
217 219 out = re.sub(r'\x1b\[[^h]+h', '', out)
218 220 return out, err
219 221
220 222
221 223 def ipexec_validate(fname, expected_out, expected_err='',
222 224 options=None):
223 225 """Utility to call 'ipython filename' and validate output/error.
224 226
225 227 This function raises an AssertionError if the validation fails.
226 228
227 229 Note that this starts IPython in a subprocess!
228 230
229 231 Parameters
230 232 ----------
231 233 fname : str
232 234 Name of the file to be executed (should have .py or .ipy extension).
233 235
234 236 expected_out : str
235 237 Expected stdout of the process.
236 238
237 239 expected_err : optional, str
238 240 Expected stderr of the process.
239 241
240 242 options : optional, list
241 243 Extra command-line flags to be passed to IPython.
242 244
243 245 Returns
244 246 -------
245 247 None
246 248 """
247 249
248 250 import nose.tools as nt
249 251
250 252 out, err = ipexec(fname, options)
251 253 #print 'OUT', out # dbg
252 254 #print 'ERR', err # dbg
253 255 # If there are any errors, we must check those befor stdout, as they may be
254 256 # more informative than simply having an empty stdout.
255 257 if err:
256 258 if expected_err:
257 259 nt.assert_equal("\n".join(err.strip().splitlines()), "\n".join(expected_err.strip().splitlines()))
258 260 else:
259 261 raise ValueError('Running file %r produced error: %r' %
260 262 (fname, err))
261 263 # If no errors or output on stderr was expected, match stdout
262 264 nt.assert_equal("\n".join(out.strip().splitlines()), "\n".join(expected_out.strip().splitlines()))
263 265
264 266
265 267 class TempFileMixin(object):
266 268 """Utility class to create temporary Python/IPython files.
267 269
268 270 Meant as a mixin class for test cases."""
269 271
270 272 def mktmp(self, src, ext='.py'):
271 273 """Make a valid python temp file."""
272 274 fname, f = temp_pyfile(src, ext)
273 275 self.tmpfile = f
274 276 self.fname = fname
275 277
276 278 def tearDown(self):
277 279 if hasattr(self, 'tmpfile'):
278 280 # If the tmpfile wasn't made because of skipped tests, like in
279 281 # win32, there's nothing to cleanup.
280 282 self.tmpfile.close()
281 283 try:
282 284 os.unlink(self.fname)
283 285 except:
284 286 # On Windows, even though we close the file, we still can't
285 287 # delete it. I have no clue why
286 288 pass
287 289
288 290 pair_fail_msg = ("Testing {0}\n\n"
289 291 "In:\n"
290 292 " {1!r}\n"
291 293 "Expected:\n"
292 294 " {2!r}\n"
293 295 "Got:\n"
294 296 " {3!r}\n")
295 297 def check_pairs(func, pairs):
296 298 """Utility function for the common case of checking a function with a
297 299 sequence of input/output pairs.
298 300
299 301 Parameters
300 302 ----------
301 303 func : callable
302 304 The function to be tested. Should accept a single argument.
303 305 pairs : iterable
304 306 A list of (input, expected_output) tuples.
305 307
306 308 Returns
307 309 -------
308 310 None. Raises an AssertionError if any output does not match the expected
309 311 value.
310 312 """
311 313 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
312 314 for inp, expected in pairs:
313 315 out = func(inp)
314 316 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
315 317
316 318
317 319 if py3compat.PY3:
318 320 MyStringIO = StringIO
319 321 else:
320 322 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
321 323 # so we need a class that can handle both.
322 324 class MyStringIO(StringIO):
323 325 def write(self, s):
324 326 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
325 327 super(MyStringIO, self).write(s)
326 328
327 329 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
328 330 -------
329 331 {2!s}
330 332 -------
331 333 """
332 334
333 335 class AssertPrints(object):
334 336 """Context manager for testing that code prints certain text.
335 337
336 338 Examples
337 339 --------
338 340 >>> with AssertPrints("abc", suppress=False):
339 341 ... print "abcd"
340 342 ... print "def"
341 343 ...
342 344 abcd
343 345 def
344 346 """
345 347 def __init__(self, s, channel='stdout', suppress=True):
346 348 self.s = s
347 349 self.channel = channel
348 350 self.suppress = suppress
349 351
350 352 def __enter__(self):
351 353 self.orig_stream = getattr(sys, self.channel)
352 354 self.buffer = MyStringIO()
353 355 self.tee = Tee(self.buffer, channel=self.channel)
354 356 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
355 357
356 358 def __exit__(self, etype, value, traceback):
357 359 self.tee.flush()
358 360 setattr(sys, self.channel, self.orig_stream)
359 361 printed = self.buffer.getvalue()
360 362 assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed)
361 363 return False
362 364
363 365 printed_msg = """Found {0!r} in printed output (on {1}):
364 366 -------
365 367 {2!s}
366 368 -------
367 369 """
368 370
369 371 class AssertNotPrints(AssertPrints):
370 372 """Context manager for checking that certain output *isn't* produced.
371 373
372 374 Counterpart of AssertPrints"""
373 375 def __exit__(self, etype, value, traceback):
374 376 self.tee.flush()
375 377 setattr(sys, self.channel, self.orig_stream)
376 378 printed = self.buffer.getvalue()
377 379 assert self.s not in printed, printed_msg.format(self.s, self.channel, printed)
378 380 return False
379 381
380 382 @contextmanager
381 383 def mute_warn():
382 384 from IPython.utils import warn
383 385 save_warn = warn.warn
384 386 warn.warn = lambda *a, **kw: None
385 387 try:
386 388 yield
387 389 finally:
388 390 warn.warn = save_warn
389 391
390 392 @contextmanager
391 393 def make_tempfile(name):
392 394 """ Create an empty, named, temporary file for the duration of the context.
393 395 """
394 396 f = open(name, 'w')
395 397 f.close()
396 398 try:
397 399 yield
398 400 finally:
399 401 os.unlink(name)
400 402
401 403
402 404 @contextmanager
403 405 def monkeypatch(obj, name, attr):
404 406 """
405 407 Context manager to replace attribute named `name` in `obj` with `attr`.
406 408 """
407 409 orig = getattr(obj, name)
408 410 setattr(obj, name, attr)
409 411 yield
410 412 setattr(obj, name, orig)
413
414
415 def help_output_test(subcommand=''):
416 """test that `ipython [subcommand] -h` works"""
417 cmd = ' '.join(get_ipython_cmd() + [subcommand, '-h'])
418 out, err, rc = get_output_error_code(cmd)
419 nt.assert_equal(rc, 0, err)
420 nt.assert_not_in("Traceback", err)
421 nt.assert_in("Options", out)
422 nt.assert_in("--help-all", out)
423 return out, err
424
425
426 def help_all_output_test(subcommand=''):
427 """test that `ipython [subcommand] --help-all` works"""
428 cmd = ' '.join(get_ipython_cmd() + [subcommand, '--help-all'])
429 out, err, rc = get_output_error_code(cmd)
430 nt.assert_equal(rc, 0, err)
431 nt.assert_not_in("Traceback", err)
432 nt.assert_in("Options", out)
433 nt.assert_in("Class parameters", out)
434 return out, err
435
436
437 def help(cmd=''):
438 """decorator for making a test for `ipython cmd -h`"""
439 def wrap_help_test(f):
440 def test_help_output():
441 out, err = help_output_test(cmd)
442 if inspect.getargspec(f).args:
443 return f(out, err)
444 else:
445 return f()
446 cmds = cmd + ' ' if cmd else ''
447 test_help_output.__doc__ = "ipython {cmds}--help-all works".format(cmds=cmds)
448
449 return test_help_output
450 return wrap_help_test
451
452
453 def help_all(cmd=''):
454 """decorator for making a test for `ipython [cmd] --help-all`"""
455 def wrap_help_test(f):
456 def test_help_output():
457 out, err = help_all_output_test(cmd)
458 if inspect.getargspec(f).args:
459 return f(out, err)
460 else:
461 return f()
462 cmds = cmd + ' ' if cmd else ''
463 test_help_output.__doc__ = "ipython {cmds}--help-all works".format(cmds=cmds)
464 return test_help_output
465 return wrap_help_test
General Comments 0
You need to be logged in to leave comments. Login now