test_magic_terminal.py
216 lines
| 5.9 KiB
| text/x-python
|
PythonLexer
Nikita Kniazev
|
r27042 | """Tests for various magic functions specific to the terminal frontend.""" | ||
Fernando Perez
|
r5436 | |||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
import sys | ||||
Srinivas Reddy Thatiparthy
|
r23081 | from io import StringIO | ||
Fernando Perez
|
r7662 | from unittest import TestCase | ||
Fernando Perez
|
r5436 | |||
from IPython.testing import tools as tt | ||||
#----------------------------------------------------------------------------- | ||||
# Test functions begin | ||||
#----------------------------------------------------------------------------- | ||||
Matthias Bussonnier
|
r27503 | |||
MINIMAL_LAZY_MAGIC = """ | ||||
from IPython.core.magic import ( | ||||
Magics, | ||||
magics_class, | ||||
line_magic, | ||||
cell_magic, | ||||
) | ||||
@magics_class | ||||
class LazyMagics(Magics): | ||||
@line_magic | ||||
def lazy_line(self, line): | ||||
print("Lazy Line") | ||||
@cell_magic | ||||
def lazy_cell(self, line, cell): | ||||
print("Lazy Cell") | ||||
def load_ipython_extension(ipython): | ||||
ipython.register_magics(LazyMagics) | ||||
""" | ||||
Fernando Perez
|
r5436 | def check_cpaste(code, should_fail=False): | ||
"""Execute code via 'cpaste' and ensure it was executed, unless | ||||
should_fail is set. | ||||
""" | ||||
Fernando Perez
|
r7735 | ip.user_ns['code_ran'] = False | ||
Fernando Perez
|
r5436 | |||
src = StringIO() | ||||
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)"): | ||||
Matthias Bussonnier
|
r27503 | ip.run_line_magic("cpaste", "") | ||
Fernando Perez
|
r5436 | |||
if not should_fail: | ||||
Thomas Kluyver
|
r10754 | assert ip.user_ns['code_ran'], "%r failed" % code | ||
Fernando Perez
|
r5436 | finally: | ||
sys.stdin = stdin_save | ||||
def test_cpaste(): | ||||
"""Test cpaste magic""" | ||||
Fernando Perez
|
r7716 | def runf(): | ||
Fernando Perez
|
r5436 | """Marker function: sets a flag when executed. | ||
""" | ||||
Fernando Perez
|
r7735 | ip.user_ns['code_ran'] = True | ||
Fernando Perez
|
r7716 | return 'runf' # return string so '+ runf()' doesn't result in success | ||
tests = {'pass': ["runf()", | ||||
"In [1]: runf()", | ||||
"In [1]: if 1:\n ...: runf()", | ||||
"> > > runf()", | ||||
">>> runf()", | ||||
" >>> runf()", | ||||
Fernando Perez
|
r5436 | ], | ||
Fernando Perez
|
r7716 | 'fail': ["1 + runf()", | ||
Paul Ivanov
|
r22959 | "++ runf()", | ||
Thomas Kluyver
|
r5935 | ]} | ||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7735 | ip.user_ns['runf'] = runf | ||
Fernando Perez
|
r5436 | |||
for code in tests['pass']: | ||||
check_cpaste(code) | ||||
for code in tests['fail']: | ||||
check_cpaste(code, should_fail=True) | ||||
Matthias Bussonnier
|
r27503 | |||
Fernando Perez
|
r7662 | class PasteTestCase(TestCase): | ||
"""Multiple tests for clipboard pasting""" | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def paste(self, txt, flags='-q'): | ||
Fernando Perez
|
r5436 | """Paste input text, by default in quiet mode""" | ||
Matthias Bussonnier
|
r27503 | ip.hooks.clipboard_get = lambda: txt | ||
ip.run_line_magic("paste", flags) | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def setUp(self): | ||
# Inject fake clipboard hook but save original so we can restore it later | ||||
self.original_clip = ip.hooks.clipboard_get | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def tearDown(self): | ||
# Restore original hook | ||||
ip.hooks.clipboard_get = self.original_clip | ||||
def test_paste(self): | ||||
Samuel Gaist
|
r26903 | ip.user_ns.pop("x", None) | ||
self.paste("x = 1") | ||||
self.assertEqual(ip.user_ns["x"], 1) | ||||
ip.user_ns.pop("x") | ||||
Fernando Perez
|
r7662 | |||
def test_paste_pyprompt(self): | ||||
Samuel Gaist
|
r26903 | ip.user_ns.pop("x", None) | ||
self.paste(">>> x=2") | ||||
self.assertEqual(ip.user_ns["x"], 2) | ||||
ip.user_ns.pop("x") | ||||
Fernando Perez
|
r7662 | |||
def test_paste_py_multi(self): | ||||
Matthias Bussonnier
|
r27639 | self.paste( | ||
""" | ||||
Fernando Perez
|
r5436 | >>> x = [1,2,3] | ||
>>> y = [] | ||||
>>> for i in x: | ||||
... y.append(i**2) | ||||
Fernando Perez
|
r7716 | ... | ||
Samuel Gaist
|
r26903 | """ | ||
) | ||||
self.assertEqual(ip.user_ns["x"], [1, 2, 3]) | ||||
self.assertEqual(ip.user_ns["y"], [1, 4, 9]) | ||||
Fernando Perez
|
r7662 | |||
def test_paste_py_multi_r(self): | ||||
"Now, test that self.paste -r works" | ||||
Thomas Kluyver
|
r10754 | self.test_paste_py_multi() | ||
Samuel Gaist
|
r26903 | self.assertEqual(ip.user_ns.pop("x"), [1, 2, 3]) | ||
self.assertEqual(ip.user_ns.pop("y"), [1, 4, 9]) | ||||
self.assertFalse("x" in ip.user_ns) | ||||
Matthias Bussonnier
|
r27503 | ip.run_line_magic("paste", "-r") | ||
Samuel Gaist
|
r26903 | self.assertEqual(ip.user_ns["x"], [1, 2, 3]) | ||
self.assertEqual(ip.user_ns["y"], [1, 4, 9]) | ||||
Fernando Perez
|
r7662 | |||
def test_paste_email(self): | ||||
"Test pasting of email-quoted contents" | ||||
Matthias Bussonnier
|
r27639 | self.paste( | ||
"""\ | ||||
Fernando Perez
|
r5436 | >> def foo(x): | ||
>> return x + 1 | ||||
Samuel Gaist
|
r26903 | >> xx = foo(1.1)""" | ||
) | ||||
self.assertEqual(ip.user_ns["xx"], 2.1) | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def test_paste_email2(self): | ||
"Email again; some programs add a space also at each quoting level" | ||||
Matthias Bussonnier
|
r27639 | self.paste( | ||
"""\ | ||||
Fernando Perez
|
r5436 | > > def foo(x): | ||
> > return x + 1 | ||||
Samuel Gaist
|
r26903 | > > yy = foo(2.1) """ | ||
) | ||||
self.assertEqual(ip.user_ns["yy"], 3.1) | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def test_paste_email_py(self): | ||
"Email quoting of interactive input" | ||||
Matthias Bussonnier
|
r27639 | self.paste( | ||
"""\ | ||||
Fernando Perez
|
r5436 | >> >>> def f(x): | ||
>> ... return x+1 | ||||
Fernando Perez
|
r7716 | >> ... | ||
Samuel Gaist
|
r26903 | >> >>> zz = f(2.5) """ | ||
) | ||||
self.assertEqual(ip.user_ns["zz"], 3.5) | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7662 | def test_paste_echo(self): | ||
"Also test self.paste echoing, by temporarily faking the writer" | ||||
Fernando Perez
|
r5436 | w = StringIO() | ||
Matthias Bussonnier
|
r27205 | old_write = sys.stdout.write | ||
sys.stdout.write = w.write | ||||
Fernando Perez
|
r5436 | code = """ | ||
a = 100 | ||||
b = 200""" | ||||
try: | ||||
Fernando Perez
|
r7662 | self.paste(code,'') | ||
Fernando Perez
|
r5436 | out = w.getvalue() | ||
finally: | ||||
Matthias Bussonnier
|
r27205 | sys.stdout.write = old_write | ||
Samuel Gaist
|
r26903 | self.assertEqual(ip.user_ns["a"], 100) | ||
self.assertEqual(ip.user_ns["b"], 200) | ||||
assert out == code + "\n## -- End pasted text --\n" | ||||
Fernando Perez
|
r5436 | |||
Fernando Perez
|
r7663 | def test_paste_leading_commas(self): | ||
"Test multiline strings with leading commas" | ||||
tm = ip.magics_manager.registry['TerminalMagics'] | ||||
Fernando Perez
|
r7703 | s = '''\ | ||
Fernando Perez
|
r7663 | a = """ | ||
,1,2,3 | ||||
"""''' | ||||
Samuel Gaist
|
r26903 | ip.user_ns.pop("foo", None) | ||
tm.store_or_execute(s, "foo") | ||||
self.assertIn("foo", ip.user_ns) | ||||
Fernando Perez
|
r7703 | |||
def test_paste_trailing_question(self): | ||||
"Test pasting sources with trailing question marks" | ||||
tm = ip.magics_manager.registry['TerminalMagics'] | ||||
s = '''\ | ||||
def funcfoo(): | ||||
if True: #am i true? | ||||
return 'fooresult' | ||||
''' | ||||
ip.user_ns.pop('funcfoo', None) | ||||
Fernando Perez
|
r7716 | self.paste(s) | ||
Samuel Gaist
|
r26903 | self.assertEqual(ip.user_ns["funcfoo"](), "fooresult") | ||