Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for %paste with special transformations #2015

Merged
merged 13 commits into from
Jun 28, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
182 changes: 108 additions & 74 deletions IPython/core/tests/test_magic_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@

import sys
from StringIO import StringIO
from unittest import TestCase

import nose.tools as nt

from IPython.testing import tools as tt

#-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------
ip = get_ipython()

#-----------------------------------------------------------------------------
# Test functions begin
#-----------------------------------------------------------------------------
Expand All @@ -23,13 +29,12 @@ 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
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)
Expand All @@ -40,10 +45,10 @@ def check_cpaste(code, should_fail=False):
try:
context = tt.AssertPrints if should_fail else tt.AssertNotPrints
with context("Traceback (most recent call last)"):
_ip.magic('cpaste')
ip.magic('cpaste')

if not should_fail:
assert _ip.user_ns['code_ran']
assert ip.user_ns['code_ran']
finally:
sys.stdin = stdin_save

Expand All @@ -52,30 +57,30 @@ def check_cpaste(code, should_fail=False):
def test_cpaste():
"""Test cpaste magic"""

def run():
def runf():
"""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()",
ip.user_ns['code_ran'] = True
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()",
],

'fail': ["1 + run()",
'fail': ["1 + runf()",
]}

# 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()")
tests['fail'].append("++ runf()")

_ip.user_ns['run'] = run
ip.user_ns['runf'] = runf

for code in tests['pass']:
check_cpaste(code)
Expand All @@ -84,87 +89,116 @@ def run():
check_cpaste(code, should_fail=True)


# Multiple tests for clipboard pasting
def test_paste():
_ip = get_ipython()
class PasteTestCase(TestCase):
"""Multiple tests for clipboard pasting"""

def paste(txt, flags='-q'):
def paste(self, txt, flags='-q'):
"""Paste input text, by default in quiet mode"""
hooks.clipboard_get = lambda : txt
_ip.magic('paste '+flags)
ip.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
def setUp(self):
# Inject fake clipboard hook but save original so we can restore it later
self.original_clip = ip.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("""
def tearDown(self):
# Restore original hook
ip.hooks.clipboard_get = self.original_clip

def test_paste(self):
ip.user_ns.pop('x', None)
self.paste('x = 1')
nt.assert_equal(ip.user_ns['x'], 1)
ip.user_ns.pop('x')

def test_paste_pyprompt(self):
ip.user_ns.pop('x', None)
self.paste('>>> x=2')
nt.assert_equal(ip.user_ns['x'], 2)
ip.user_ns.pop('x')

def test_paste_py_multi(self):
self.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("""
nt.assert_equal(ip.user_ns['x'], [1,2,3])
nt.assert_equal(ip.user_ns['y'], [1,4,9])

def test_paste_py_multi_r(self):
"Now, test that self.paste -r works"
nt.assert_equal(ip.user_ns.pop('x'), [1,2,3])
nt.assert_equal(ip.user_ns.pop('y'), [1,4,9])
nt.assert_false('x' in ip.user_ns)
ip.magic('paste -r')
nt.assert_equal(ip.user_ns['x'], [1,2,3])
nt.assert_equal(ip.user_ns['y'], [1,4,9])

def test_paste_email(self):
"Test pasting of email-quoted contents"
self.paste("""\
>> def foo(x):
>> return x + 1
>> x = foo(1.1)
""")
nt.assert_equal(user_ns['x'], 2.1)
>> xx = foo(1.1)""")
nt.assert_equal(ip.user_ns['xx'], 2.1)

# Email again; some programs add a space also at each quoting level
paste("""
def test_paste_email2(self):
"Email again; some programs add a space also at each quoting level"
self.paste("""\
> > def foo(x):
> > return x + 1
> > x = foo(2.1)
""")
nt.assert_equal(user_ns['x'], 3.1)
> > yy = foo(2.1) """)
nt.assert_equal(ip.user_ns['yy'], 3.1)

# Email quoting of interactive input
paste("""
def test_paste_email_py(self):
"Email quoting of interactive input"
self.paste("""\
>> >>> def f(x):
>> ... return x+1
>> ...
>> >>> x = f(2.5)
""")
nt.assert_equal(user_ns['x'], 3.5)
>> ...
>> >>> zz = f(2.5) """)
nt.assert_equal(ip.user_ns['zz'], 3.5)

# Also test paste echoing, by temporarily faking the writer
def test_paste_echo(self):
"Also test self.paste echoing, by temporarily faking the writer"
w = StringIO()
writer = _ip.write
_ip.write = w.write
writer = ip.write
ip.write = w.write
code = """
a = 100
b = 200"""
try:
paste(code,'')
self.paste(code,'')
out = w.getvalue()
finally:
_ip.write = writer
nt.assert_equal(user_ns['a'], 100)
nt.assert_equal(user_ns['b'], 200)
ip.write = writer
nt.assert_equal(ip.user_ns['a'], 100)
nt.assert_equal(ip.user_ns['b'], 200)
nt.assert_equal(out, code+"\n## -- End pasted text --\n")

finally:
# Restore original hook
hooks.clipboard_get = original_clip
def test_paste_leading_commas(self):
"Test multiline strings with leading commas"
tm = ip.magics_manager.registry['TerminalMagics']
s = '''\
a = """
,1,2,3
"""'''
ip.user_ns.pop('foo', None)
tm.store_or_execute(s, 'foo')
nt.assert_in('foo', ip.user_ns)


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)
self.paste(s)
nt.assert_equals(ip.user_ns['funcfoo'](), 'fooresult')