test_magic_terminal.py
170 lines
| 4.6 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r5436 | """Tests for various magic functions specific to the terminal frontend. | ||
Needs to be run by nose (to make ipython session available). | ||||
""" | ||||
from __future__ import absolute_import | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
import sys | ||||
from StringIO import StringIO | ||||
import nose.tools as nt | ||||
from IPython.testing import tools as tt | ||||
#----------------------------------------------------------------------------- | ||||
# Test functions begin | ||||
#----------------------------------------------------------------------------- | ||||
def check_cpaste(code, should_fail=False): | ||||
"""Execute code via 'cpaste' and ensure it was executed, unless | ||||
should_fail is set. | ||||
""" | ||||
_ip.user_ns['code_ran'] = False | ||||
src = StringIO() | ||||
if not hasattr(src, 'encoding'): | ||||
# IPython expects stdin to have an encoding attribute | ||||
src.encoding = None | ||||
src.write('\n') | ||||
src.write(code) | ||||
src.write('\n--\n') | ||||
src.seek(0) | ||||
stdin_save = sys.stdin | ||||
sys.stdin = src | ||||
try: | ||||
context = tt.AssertPrints if should_fail else tt.AssertNotPrints | ||||
with context("Traceback (most recent call last)"): | ||||
_ip.magic('cpaste') | ||||
if not should_fail: | ||||
assert _ip.user_ns['code_ran'] | ||||
finally: | ||||
sys.stdin = stdin_save | ||||
Thomas Kluyver
|
r5935 | PY31 = sys.version_info[:2] == (3,1) | ||
Fernando Perez
|
r5436 | |||
def test_cpaste(): | ||||
"""Test cpaste magic""" | ||||
def run(): | ||||
"""Marker function: sets a flag when executed. | ||||
""" | ||||
_ip.user_ns['code_ran'] = True | ||||
return 'run' # return string so '+ run()' doesn't result in success | ||||
tests = {'pass': ["run()", | ||||
"In [1]: run()", | ||||
"In [1]: if 1:\n ...: run()", | ||||
"> > > run()", | ||||
">>> run()", | ||||
" >>> run()", | ||||
], | ||||
'fail': ["1 + run()", | ||||
Thomas Kluyver
|
r5935 | ]} | ||
# I don't know why this is failing specifically on Python 3.1. I've | ||||
# checked it manually interactively, but we don't care enough about 3.1 | ||||
# to spend time fiddling with the tests, so we just skip it. | ||||
if not PY31: | ||||
tests['fail'].append("++ run()") | ||||
Fernando Perez
|
r5436 | |||
_ip.user_ns['run'] = run | ||||
for code in tests['pass']: | ||||
check_cpaste(code) | ||||
for code in tests['fail']: | ||||
check_cpaste(code, should_fail=True) | ||||
# Multiple tests for clipboard pasting | ||||
def test_paste(): | ||||
_ip = get_ipython() | ||||
def paste(txt, flags='-q'): | ||||
"""Paste input text, by default in quiet mode""" | ||||
hooks.clipboard_get = lambda : txt | ||||
_ip.magic('paste '+flags) | ||||
# Inject fake clipboard hook but save original so we can restore it later | ||||
hooks = _ip.hooks | ||||
user_ns = _ip.user_ns | ||||
original_clip = hooks.clipboard_get | ||||
try: | ||||
# Run tests with fake clipboard function | ||||
user_ns.pop('x', None) | ||||
paste('x=1') | ||||
nt.assert_equal(user_ns['x'], 1) | ||||
user_ns.pop('x', None) | ||||
paste('>>> x=2') | ||||
nt.assert_equal(user_ns['x'], 2) | ||||
paste(""" | ||||
>>> x = [1,2,3] | ||||
>>> y = [] | ||||
>>> for i in x: | ||||
... y.append(i**2) | ||||
... | ||||
""") | ||||
nt.assert_equal(user_ns['x'], [1,2,3]) | ||||
nt.assert_equal(user_ns['y'], [1,4,9]) | ||||
# Now, test that paste -r works | ||||
user_ns.pop('x', None) | ||||
nt.assert_false('x' in user_ns) | ||||
_ip.magic('paste -r') | ||||
nt.assert_equal(user_ns['x'], [1,2,3]) | ||||
# Test pasting of email-quoted contents | ||||
paste(""" | ||||
>> def foo(x): | ||||
>> return x + 1 | ||||
>> x = foo(1.1) | ||||
""") | ||||
nt.assert_equal(user_ns['x'], 2.1) | ||||
# Email again; some programs add a space also at each quoting level | ||||
paste(""" | ||||
> > def foo(x): | ||||
> > return x + 1 | ||||
> > x = foo(2.1) | ||||
""") | ||||
nt.assert_equal(user_ns['x'], 3.1) | ||||
# Email quoting of interactive input | ||||
paste(""" | ||||
>> >>> def f(x): | ||||
>> ... return x+1 | ||||
>> ... | ||||
>> >>> x = f(2.5) | ||||
""") | ||||
nt.assert_equal(user_ns['x'], 3.5) | ||||
# Also test paste echoing, by temporarily faking the writer | ||||
w = StringIO() | ||||
writer = _ip.write | ||||
_ip.write = w.write | ||||
code = """ | ||||
a = 100 | ||||
b = 200""" | ||||
try: | ||||
paste(code,'') | ||||
out = w.getvalue() | ||||
finally: | ||||
_ip.write = writer | ||||
nt.assert_equal(user_ns['a'], 100) | ||||
nt.assert_equal(user_ns['b'], 200) | ||||
nt.assert_equal(out, code+"\n## -- End pasted text --\n") | ||||
finally: | ||||
# Restore original hook | ||||
hooks.clipboard_get = original_clip | ||||