##// END OF EJS Templates
update cell magic transform test
MinRK -
Show More
@@ -1,580 +1,582
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the inputsplitter module.
2 """Tests for the inputsplitter module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Fernando Perez
6 * Fernando Perez
7 * Robert Kern
7 * Robert Kern
8 """
8 """
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010-2011 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # stdlib
19 # stdlib
20 import unittest
20 import unittest
21 import sys
21 import sys
22
22
23 # Third party
23 # Third party
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 # Our own
26 # Our own
27 from IPython.core import inputsplitter as isp
27 from IPython.core import inputsplitter as isp
28 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
28 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
29 from IPython.testing import tools as tt
29 from IPython.testing import tools as tt
30 from IPython.utils import py3compat
30 from IPython.utils import py3compat
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Semi-complete examples (also used as tests)
33 # Semi-complete examples (also used as tests)
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 # Note: at the bottom, there's a slightly more complete version of this that
36 # Note: at the bottom, there's a slightly more complete version of this that
37 # can be useful during development of code here.
37 # can be useful during development of code here.
38
38
39 def mini_interactive_loop(input_func):
39 def mini_interactive_loop(input_func):
40 """Minimal example of the logic of an interactive interpreter loop.
40 """Minimal example of the logic of an interactive interpreter loop.
41
41
42 This serves as an example, and it is used by the test system with a fake
42 This serves as an example, and it is used by the test system with a fake
43 raw_input that simulates interactive input."""
43 raw_input that simulates interactive input."""
44
44
45 from IPython.core.inputsplitter import InputSplitter
45 from IPython.core.inputsplitter import InputSplitter
46
46
47 isp = InputSplitter()
47 isp = InputSplitter()
48 # In practice, this input loop would be wrapped in an outside loop to read
48 # In practice, this input loop would be wrapped in an outside loop to read
49 # input indefinitely, until some exit/quit command was issued. Here we
49 # input indefinitely, until some exit/quit command was issued. Here we
50 # only illustrate the basic inner loop.
50 # only illustrate the basic inner loop.
51 while isp.push_accepts_more():
51 while isp.push_accepts_more():
52 indent = ' '*isp.indent_spaces
52 indent = ' '*isp.indent_spaces
53 prompt = '>>> ' + indent
53 prompt = '>>> ' + indent
54 line = indent + input_func(prompt)
54 line = indent + input_func(prompt)
55 isp.push(line)
55 isp.push(line)
56
56
57 # Here we just return input so we can use it in a test suite, but a real
57 # Here we just return input so we can use it in a test suite, but a real
58 # interpreter would instead send it for execution somewhere.
58 # interpreter would instead send it for execution somewhere.
59 src = isp.source_reset()
59 src = isp.source_reset()
60 #print 'Input source was:\n', src # dbg
60 #print 'Input source was:\n', src # dbg
61 return src
61 return src
62
62
63 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
64 # Test utilities, just for local use
64 # Test utilities, just for local use
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66
66
67 def assemble(block):
67 def assemble(block):
68 """Assemble a block into multi-line sub-blocks."""
68 """Assemble a block into multi-line sub-blocks."""
69 return ['\n'.join(sub_block)+'\n' for sub_block in block]
69 return ['\n'.join(sub_block)+'\n' for sub_block in block]
70
70
71
71
72 def pseudo_input(lines):
72 def pseudo_input(lines):
73 """Return a function that acts like raw_input but feeds the input list."""
73 """Return a function that acts like raw_input but feeds the input list."""
74 ilines = iter(lines)
74 ilines = iter(lines)
75 def raw_in(prompt):
75 def raw_in(prompt):
76 try:
76 try:
77 return next(ilines)
77 return next(ilines)
78 except StopIteration:
78 except StopIteration:
79 return ''
79 return ''
80 return raw_in
80 return raw_in
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Tests
83 # Tests
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85 def test_spaces():
85 def test_spaces():
86 tests = [('', 0),
86 tests = [('', 0),
87 (' ', 1),
87 (' ', 1),
88 ('\n', 0),
88 ('\n', 0),
89 (' \n', 1),
89 (' \n', 1),
90 ('x', 0),
90 ('x', 0),
91 (' x', 1),
91 (' x', 1),
92 (' x',2),
92 (' x',2),
93 (' x',4),
93 (' x',4),
94 # Note: tabs are counted as a single whitespace!
94 # Note: tabs are counted as a single whitespace!
95 ('\tx', 1),
95 ('\tx', 1),
96 ('\t x', 2),
96 ('\t x', 2),
97 ]
97 ]
98 tt.check_pairs(isp.num_ini_spaces, tests)
98 tt.check_pairs(isp.num_ini_spaces, tests)
99
99
100
100
101 def test_remove_comments():
101 def test_remove_comments():
102 tests = [('text', 'text'),
102 tests = [('text', 'text'),
103 ('text # comment', 'text '),
103 ('text # comment', 'text '),
104 ('text # comment\n', 'text \n'),
104 ('text # comment\n', 'text \n'),
105 ('text # comment \n', 'text \n'),
105 ('text # comment \n', 'text \n'),
106 ('line # c \nline\n','line \nline\n'),
106 ('line # c \nline\n','line \nline\n'),
107 ('line # c \nline#c2 \nline\nline #c\n\n',
107 ('line # c \nline#c2 \nline\nline #c\n\n',
108 'line \nline\nline\nline \n\n'),
108 'line \nline\nline\nline \n\n'),
109 ]
109 ]
110 tt.check_pairs(isp.remove_comments, tests)
110 tt.check_pairs(isp.remove_comments, tests)
111
111
112
112
113 def test_get_input_encoding():
113 def test_get_input_encoding():
114 encoding = isp.get_input_encoding()
114 encoding = isp.get_input_encoding()
115 nt.assert_true(isinstance(encoding, basestring))
115 nt.assert_true(isinstance(encoding, basestring))
116 # simple-minded check that at least encoding a simple string works with the
116 # simple-minded check that at least encoding a simple string works with the
117 # encoding we got.
117 # encoding we got.
118 nt.assert_equal(u'test'.encode(encoding), b'test')
118 nt.assert_equal(u'test'.encode(encoding), b'test')
119
119
120
120
121 class NoInputEncodingTestCase(unittest.TestCase):
121 class NoInputEncodingTestCase(unittest.TestCase):
122 def setUp(self):
122 def setUp(self):
123 self.old_stdin = sys.stdin
123 self.old_stdin = sys.stdin
124 class X: pass
124 class X: pass
125 fake_stdin = X()
125 fake_stdin = X()
126 sys.stdin = fake_stdin
126 sys.stdin = fake_stdin
127
127
128 def test(self):
128 def test(self):
129 # Verify that if sys.stdin has no 'encoding' attribute we do the right
129 # Verify that if sys.stdin has no 'encoding' attribute we do the right
130 # thing
130 # thing
131 enc = isp.get_input_encoding()
131 enc = isp.get_input_encoding()
132 self.assertEqual(enc, 'ascii')
132 self.assertEqual(enc, 'ascii')
133
133
134 def tearDown(self):
134 def tearDown(self):
135 sys.stdin = self.old_stdin
135 sys.stdin = self.old_stdin
136
136
137
137
138 class InputSplitterTestCase(unittest.TestCase):
138 class InputSplitterTestCase(unittest.TestCase):
139 def setUp(self):
139 def setUp(self):
140 self.isp = isp.InputSplitter()
140 self.isp = isp.InputSplitter()
141
141
142 def test_reset(self):
142 def test_reset(self):
143 isp = self.isp
143 isp = self.isp
144 isp.push('x=1')
144 isp.push('x=1')
145 isp.reset()
145 isp.reset()
146 self.assertEqual(isp._buffer, [])
146 self.assertEqual(isp._buffer, [])
147 self.assertEqual(isp.indent_spaces, 0)
147 self.assertEqual(isp.indent_spaces, 0)
148 self.assertEqual(isp.source, '')
148 self.assertEqual(isp.source, '')
149 self.assertEqual(isp.code, None)
149 self.assertEqual(isp.code, None)
150 self.assertEqual(isp._is_complete, False)
150 self.assertEqual(isp._is_complete, False)
151
151
152 def test_source(self):
152 def test_source(self):
153 self.isp._store('1')
153 self.isp._store('1')
154 self.isp._store('2')
154 self.isp._store('2')
155 self.assertEqual(self.isp.source, '1\n2\n')
155 self.assertEqual(self.isp.source, '1\n2\n')
156 self.assertTrue(len(self.isp._buffer)>0)
156 self.assertTrue(len(self.isp._buffer)>0)
157 self.assertEqual(self.isp.source_reset(), '1\n2\n')
157 self.assertEqual(self.isp.source_reset(), '1\n2\n')
158 self.assertEqual(self.isp._buffer, [])
158 self.assertEqual(self.isp._buffer, [])
159 self.assertEqual(self.isp.source, '')
159 self.assertEqual(self.isp.source, '')
160
160
161 def test_indent(self):
161 def test_indent(self):
162 isp = self.isp # shorthand
162 isp = self.isp # shorthand
163 isp.push('x=1')
163 isp.push('x=1')
164 self.assertEqual(isp.indent_spaces, 0)
164 self.assertEqual(isp.indent_spaces, 0)
165 isp.push('if 1:\n x=1')
165 isp.push('if 1:\n x=1')
166 self.assertEqual(isp.indent_spaces, 4)
166 self.assertEqual(isp.indent_spaces, 4)
167 isp.push('y=2\n')
167 isp.push('y=2\n')
168 self.assertEqual(isp.indent_spaces, 0)
168 self.assertEqual(isp.indent_spaces, 0)
169
169
170 def test_indent2(self):
170 def test_indent2(self):
171 isp = self.isp
171 isp = self.isp
172 isp.push('if 1:')
172 isp.push('if 1:')
173 self.assertEqual(isp.indent_spaces, 4)
173 self.assertEqual(isp.indent_spaces, 4)
174 isp.push(' x=1')
174 isp.push(' x=1')
175 self.assertEqual(isp.indent_spaces, 4)
175 self.assertEqual(isp.indent_spaces, 4)
176 # Blank lines shouldn't change the indent level
176 # Blank lines shouldn't change the indent level
177 isp.push(' '*2)
177 isp.push(' '*2)
178 self.assertEqual(isp.indent_spaces, 4)
178 self.assertEqual(isp.indent_spaces, 4)
179
179
180 def test_indent3(self):
180 def test_indent3(self):
181 isp = self.isp
181 isp = self.isp
182 # When a multiline statement contains parens or multiline strings, we
182 # When a multiline statement contains parens or multiline strings, we
183 # shouldn't get confused.
183 # shouldn't get confused.
184 isp.push("if 1:")
184 isp.push("if 1:")
185 isp.push(" x = (1+\n 2)")
185 isp.push(" x = (1+\n 2)")
186 self.assertEqual(isp.indent_spaces, 4)
186 self.assertEqual(isp.indent_spaces, 4)
187
187
188 def test_indent4(self):
188 def test_indent4(self):
189 isp = self.isp
189 isp = self.isp
190 # whitespace after ':' should not screw up indent level
190 # whitespace after ':' should not screw up indent level
191 isp.push('if 1: \n x=1')
191 isp.push('if 1: \n x=1')
192 self.assertEqual(isp.indent_spaces, 4)
192 self.assertEqual(isp.indent_spaces, 4)
193 isp.push('y=2\n')
193 isp.push('y=2\n')
194 self.assertEqual(isp.indent_spaces, 0)
194 self.assertEqual(isp.indent_spaces, 0)
195 isp.push('if 1:\t\n x=1')
195 isp.push('if 1:\t\n x=1')
196 self.assertEqual(isp.indent_spaces, 4)
196 self.assertEqual(isp.indent_spaces, 4)
197 isp.push('y=2\n')
197 isp.push('y=2\n')
198 self.assertEqual(isp.indent_spaces, 0)
198 self.assertEqual(isp.indent_spaces, 0)
199
199
200 def test_dedent_pass(self):
200 def test_dedent_pass(self):
201 isp = self.isp # shorthand
201 isp = self.isp # shorthand
202 # should NOT cause dedent
202 # should NOT cause dedent
203 isp.push('if 1:\n passes = 5')
203 isp.push('if 1:\n passes = 5')
204 self.assertEqual(isp.indent_spaces, 4)
204 self.assertEqual(isp.indent_spaces, 4)
205 isp.push('if 1:\n pass')
205 isp.push('if 1:\n pass')
206 self.assertEqual(isp.indent_spaces, 0)
206 self.assertEqual(isp.indent_spaces, 0)
207 isp.push('if 1:\n pass ')
207 isp.push('if 1:\n pass ')
208 self.assertEqual(isp.indent_spaces, 0)
208 self.assertEqual(isp.indent_spaces, 0)
209
209
210 def test_dedent_break(self):
210 def test_dedent_break(self):
211 isp = self.isp # shorthand
211 isp = self.isp # shorthand
212 # should NOT cause dedent
212 # should NOT cause dedent
213 isp.push('while 1:\n breaks = 5')
213 isp.push('while 1:\n breaks = 5')
214 self.assertEqual(isp.indent_spaces, 4)
214 self.assertEqual(isp.indent_spaces, 4)
215 isp.push('while 1:\n break')
215 isp.push('while 1:\n break')
216 self.assertEqual(isp.indent_spaces, 0)
216 self.assertEqual(isp.indent_spaces, 0)
217 isp.push('while 1:\n break ')
217 isp.push('while 1:\n break ')
218 self.assertEqual(isp.indent_spaces, 0)
218 self.assertEqual(isp.indent_spaces, 0)
219
219
220 def test_dedent_continue(self):
220 def test_dedent_continue(self):
221 isp = self.isp # shorthand
221 isp = self.isp # shorthand
222 # should NOT cause dedent
222 # should NOT cause dedent
223 isp.push('while 1:\n continues = 5')
223 isp.push('while 1:\n continues = 5')
224 self.assertEqual(isp.indent_spaces, 4)
224 self.assertEqual(isp.indent_spaces, 4)
225 isp.push('while 1:\n continue')
225 isp.push('while 1:\n continue')
226 self.assertEqual(isp.indent_spaces, 0)
226 self.assertEqual(isp.indent_spaces, 0)
227 isp.push('while 1:\n continue ')
227 isp.push('while 1:\n continue ')
228 self.assertEqual(isp.indent_spaces, 0)
228 self.assertEqual(isp.indent_spaces, 0)
229
229
230 def test_dedent_raise(self):
230 def test_dedent_raise(self):
231 isp = self.isp # shorthand
231 isp = self.isp # shorthand
232 # should NOT cause dedent
232 # should NOT cause dedent
233 isp.push('if 1:\n raised = 4')
233 isp.push('if 1:\n raised = 4')
234 self.assertEqual(isp.indent_spaces, 4)
234 self.assertEqual(isp.indent_spaces, 4)
235 isp.push('if 1:\n raise TypeError()')
235 isp.push('if 1:\n raise TypeError()')
236 self.assertEqual(isp.indent_spaces, 0)
236 self.assertEqual(isp.indent_spaces, 0)
237 isp.push('if 1:\n raise')
237 isp.push('if 1:\n raise')
238 self.assertEqual(isp.indent_spaces, 0)
238 self.assertEqual(isp.indent_spaces, 0)
239 isp.push('if 1:\n raise ')
239 isp.push('if 1:\n raise ')
240 self.assertEqual(isp.indent_spaces, 0)
240 self.assertEqual(isp.indent_spaces, 0)
241
241
242 def test_dedent_return(self):
242 def test_dedent_return(self):
243 isp = self.isp # shorthand
243 isp = self.isp # shorthand
244 # should NOT cause dedent
244 # should NOT cause dedent
245 isp.push('if 1:\n returning = 4')
245 isp.push('if 1:\n returning = 4')
246 self.assertEqual(isp.indent_spaces, 4)
246 self.assertEqual(isp.indent_spaces, 4)
247 isp.push('if 1:\n return 5 + 493')
247 isp.push('if 1:\n return 5 + 493')
248 self.assertEqual(isp.indent_spaces, 0)
248 self.assertEqual(isp.indent_spaces, 0)
249 isp.push('if 1:\n return')
249 isp.push('if 1:\n return')
250 self.assertEqual(isp.indent_spaces, 0)
250 self.assertEqual(isp.indent_spaces, 0)
251 isp.push('if 1:\n return ')
251 isp.push('if 1:\n return ')
252 self.assertEqual(isp.indent_spaces, 0)
252 self.assertEqual(isp.indent_spaces, 0)
253 isp.push('if 1:\n return(0)')
253 isp.push('if 1:\n return(0)')
254 self.assertEqual(isp.indent_spaces, 0)
254 self.assertEqual(isp.indent_spaces, 0)
255
255
256 def test_push(self):
256 def test_push(self):
257 isp = self.isp
257 isp = self.isp
258 self.assertTrue(isp.push('x=1'))
258 self.assertTrue(isp.push('x=1'))
259
259
260 def test_push2(self):
260 def test_push2(self):
261 isp = self.isp
261 isp = self.isp
262 self.assertFalse(isp.push('if 1:'))
262 self.assertFalse(isp.push('if 1:'))
263 for line in [' x=1', '# a comment', ' y=2']:
263 for line in [' x=1', '# a comment', ' y=2']:
264 print(line)
264 print(line)
265 self.assertTrue(isp.push(line))
265 self.assertTrue(isp.push(line))
266
266
267 def test_push3(self):
267 def test_push3(self):
268 isp = self.isp
268 isp = self.isp
269 isp.push('if True:')
269 isp.push('if True:')
270 isp.push(' a = 1')
270 isp.push(' a = 1')
271 self.assertFalse(isp.push('b = [1,'))
271 self.assertFalse(isp.push('b = [1,'))
272
272
273 def test_push_accepts_more(self):
273 def test_push_accepts_more(self):
274 isp = self.isp
274 isp = self.isp
275 isp.push('x=1')
275 isp.push('x=1')
276 self.assertFalse(isp.push_accepts_more())
276 self.assertFalse(isp.push_accepts_more())
277
277
278 def test_push_accepts_more2(self):
278 def test_push_accepts_more2(self):
279 isp = self.isp
279 isp = self.isp
280 isp.push('if 1:')
280 isp.push('if 1:')
281 self.assertTrue(isp.push_accepts_more())
281 self.assertTrue(isp.push_accepts_more())
282 isp.push(' x=1')
282 isp.push(' x=1')
283 self.assertTrue(isp.push_accepts_more())
283 self.assertTrue(isp.push_accepts_more())
284 isp.push('')
284 isp.push('')
285 self.assertFalse(isp.push_accepts_more())
285 self.assertFalse(isp.push_accepts_more())
286
286
287 def test_push_accepts_more3(self):
287 def test_push_accepts_more3(self):
288 isp = self.isp
288 isp = self.isp
289 isp.push("x = (2+\n3)")
289 isp.push("x = (2+\n3)")
290 self.assertFalse(isp.push_accepts_more())
290 self.assertFalse(isp.push_accepts_more())
291
291
292 def test_push_accepts_more4(self):
292 def test_push_accepts_more4(self):
293 isp = self.isp
293 isp = self.isp
294 # When a multiline statement contains parens or multiline strings, we
294 # When a multiline statement contains parens or multiline strings, we
295 # shouldn't get confused.
295 # shouldn't get confused.
296 # FIXME: we should be able to better handle de-dents in statements like
296 # FIXME: we should be able to better handle de-dents in statements like
297 # multiline strings and multiline expressions (continued with \ or
297 # multiline strings and multiline expressions (continued with \ or
298 # parens). Right now we aren't handling the indentation tracking quite
298 # parens). Right now we aren't handling the indentation tracking quite
299 # correctly with this, though in practice it may not be too much of a
299 # correctly with this, though in practice it may not be too much of a
300 # problem. We'll need to see.
300 # problem. We'll need to see.
301 isp.push("if 1:")
301 isp.push("if 1:")
302 isp.push(" x = (2+")
302 isp.push(" x = (2+")
303 isp.push(" 3)")
303 isp.push(" 3)")
304 self.assertTrue(isp.push_accepts_more())
304 self.assertTrue(isp.push_accepts_more())
305 isp.push(" y = 3")
305 isp.push(" y = 3")
306 self.assertTrue(isp.push_accepts_more())
306 self.assertTrue(isp.push_accepts_more())
307 isp.push('')
307 isp.push('')
308 self.assertFalse(isp.push_accepts_more())
308 self.assertFalse(isp.push_accepts_more())
309
309
310 def test_push_accepts_more5(self):
310 def test_push_accepts_more5(self):
311 isp = self.isp
311 isp = self.isp
312 isp.push('try:')
312 isp.push('try:')
313 isp.push(' a = 5')
313 isp.push(' a = 5')
314 isp.push('except:')
314 isp.push('except:')
315 isp.push(' raise')
315 isp.push(' raise')
316 # We want to be able to add an else: block at this point, so it should
316 # We want to be able to add an else: block at this point, so it should
317 # wait for a blank line.
317 # wait for a blank line.
318 self.assertTrue(isp.push_accepts_more())
318 self.assertTrue(isp.push_accepts_more())
319
319
320 def test_continuation(self):
320 def test_continuation(self):
321 isp = self.isp
321 isp = self.isp
322 isp.push("import os, \\")
322 isp.push("import os, \\")
323 self.assertTrue(isp.push_accepts_more())
323 self.assertTrue(isp.push_accepts_more())
324 isp.push("sys")
324 isp.push("sys")
325 self.assertFalse(isp.push_accepts_more())
325 self.assertFalse(isp.push_accepts_more())
326
326
327 def test_syntax_error(self):
327 def test_syntax_error(self):
328 isp = self.isp
328 isp = self.isp
329 # Syntax errors immediately produce a 'ready' block, so the invalid
329 # Syntax errors immediately produce a 'ready' block, so the invalid
330 # Python can be sent to the kernel for evaluation with possible ipython
330 # Python can be sent to the kernel for evaluation with possible ipython
331 # special-syntax conversion.
331 # special-syntax conversion.
332 isp.push('run foo')
332 isp.push('run foo')
333 self.assertFalse(isp.push_accepts_more())
333 self.assertFalse(isp.push_accepts_more())
334
334
335 def test_unicode(self):
335 def test_unicode(self):
336 self.isp.push(u"PΓ©rez")
336 self.isp.push(u"PΓ©rez")
337 self.isp.push(u'\xc3\xa9')
337 self.isp.push(u'\xc3\xa9')
338 self.isp.push(u"u'\xc3\xa9'")
338 self.isp.push(u"u'\xc3\xa9'")
339
339
340 def test_line_continuation(self):
340 def test_line_continuation(self):
341 """ Test issue #2108."""
341 """ Test issue #2108."""
342 isp = self.isp
342 isp = self.isp
343 # A blank line after a line continuation should not accept more
343 # A blank line after a line continuation should not accept more
344 isp.push("1 \\\n\n")
344 isp.push("1 \\\n\n")
345 self.assertFalse(isp.push_accepts_more())
345 self.assertFalse(isp.push_accepts_more())
346 # Whitespace after a \ is a SyntaxError. The only way to test that
346 # Whitespace after a \ is a SyntaxError. The only way to test that
347 # here is to test that push doesn't accept more (as with
347 # here is to test that push doesn't accept more (as with
348 # test_syntax_error() above).
348 # test_syntax_error() above).
349 isp.push(r"1 \ ")
349 isp.push(r"1 \ ")
350 self.assertFalse(isp.push_accepts_more())
350 self.assertFalse(isp.push_accepts_more())
351 # Even if the line is continuable (c.f. the regular Python
351 # Even if the line is continuable (c.f. the regular Python
352 # interpreter)
352 # interpreter)
353 isp.push(r"(1 \ ")
353 isp.push(r"(1 \ ")
354 self.assertFalse(isp.push_accepts_more())
354 self.assertFalse(isp.push_accepts_more())
355
355
356 class InteractiveLoopTestCase(unittest.TestCase):
356 class InteractiveLoopTestCase(unittest.TestCase):
357 """Tests for an interactive loop like a python shell.
357 """Tests for an interactive loop like a python shell.
358 """
358 """
359 def check_ns(self, lines, ns):
359 def check_ns(self, lines, ns):
360 """Validate that the given input lines produce the resulting namespace.
360 """Validate that the given input lines produce the resulting namespace.
361
361
362 Note: the input lines are given exactly as they would be typed in an
362 Note: the input lines are given exactly as they would be typed in an
363 auto-indenting environment, as mini_interactive_loop above already does
363 auto-indenting environment, as mini_interactive_loop above already does
364 auto-indenting and prepends spaces to the input.
364 auto-indenting and prepends spaces to the input.
365 """
365 """
366 src = mini_interactive_loop(pseudo_input(lines))
366 src = mini_interactive_loop(pseudo_input(lines))
367 test_ns = {}
367 test_ns = {}
368 exec src in test_ns
368 exec src in test_ns
369 # We can't check that the provided ns is identical to the test_ns,
369 # We can't check that the provided ns is identical to the test_ns,
370 # because Python fills test_ns with extra keys (copyright, etc). But
370 # because Python fills test_ns with extra keys (copyright, etc). But
371 # we can check that the given dict is *contained* in test_ns
371 # we can check that the given dict is *contained* in test_ns
372 for k,v in ns.iteritems():
372 for k,v in ns.iteritems():
373 self.assertEqual(test_ns[k], v)
373 self.assertEqual(test_ns[k], v)
374
374
375 def test_simple(self):
375 def test_simple(self):
376 self.check_ns(['x=1'], dict(x=1))
376 self.check_ns(['x=1'], dict(x=1))
377
377
378 def test_simple2(self):
378 def test_simple2(self):
379 self.check_ns(['if 1:', 'x=2'], dict(x=2))
379 self.check_ns(['if 1:', 'x=2'], dict(x=2))
380
380
381 def test_xy(self):
381 def test_xy(self):
382 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
382 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
383
383
384 def test_abc(self):
384 def test_abc(self):
385 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
385 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
386
386
387 def test_multi(self):
387 def test_multi(self):
388 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
388 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
389
389
390
390
391 class IPythonInputTestCase(InputSplitterTestCase):
391 class IPythonInputTestCase(InputSplitterTestCase):
392 """By just creating a new class whose .isp is a different instance, we
392 """By just creating a new class whose .isp is a different instance, we
393 re-run the same test battery on the new input splitter.
393 re-run the same test battery on the new input splitter.
394
394
395 In addition, this runs the tests over the syntax and syntax_ml dicts that
395 In addition, this runs the tests over the syntax and syntax_ml dicts that
396 were tested by individual functions, as part of the OO interface.
396 were tested by individual functions, as part of the OO interface.
397
397
398 It also makes some checks on the raw buffer storage.
398 It also makes some checks on the raw buffer storage.
399 """
399 """
400
400
401 def setUp(self):
401 def setUp(self):
402 self.isp = isp.IPythonInputSplitter()
402 self.isp = isp.IPythonInputSplitter()
403
403
404 def test_syntax(self):
404 def test_syntax(self):
405 """Call all single-line syntax tests from the main object"""
405 """Call all single-line syntax tests from the main object"""
406 isp = self.isp
406 isp = self.isp
407 for example in syntax.itervalues():
407 for example in syntax.itervalues():
408 for raw, out_t in example:
408 for raw, out_t in example:
409 if raw.startswith(' '):
409 if raw.startswith(' '):
410 continue
410 continue
411
411
412 isp.push(raw+'\n')
412 isp.push(raw+'\n')
413 out, out_raw = isp.source_raw_reset()
413 out, out_raw = isp.source_raw_reset()
414 self.assertEqual(out.rstrip(), out_t,
414 self.assertEqual(out.rstrip(), out_t,
415 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
415 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
416 self.assertEqual(out_raw.rstrip(), raw.rstrip())
416 self.assertEqual(out_raw.rstrip(), raw.rstrip())
417
417
418 def test_syntax_multiline(self):
418 def test_syntax_multiline(self):
419 isp = self.isp
419 isp = self.isp
420 for example in syntax_ml.itervalues():
420 for example in syntax_ml.itervalues():
421 for line_pairs in example:
421 for line_pairs in example:
422 out_t_parts = []
422 out_t_parts = []
423 raw_parts = []
423 raw_parts = []
424 for lraw, out_t_part in line_pairs:
424 for lraw, out_t_part in line_pairs:
425 if out_t_part is not None:
425 if out_t_part is not None:
426 out_t_parts.append(out_t_part)
426 out_t_parts.append(out_t_part)
427
427
428 if lraw is not None:
428 if lraw is not None:
429 isp.push(lraw)
429 isp.push(lraw)
430 raw_parts.append(lraw)
430 raw_parts.append(lraw)
431
431
432 out, out_raw = isp.source_raw_reset()
432 out, out_raw = isp.source_raw_reset()
433 out_t = '\n'.join(out_t_parts).rstrip()
433 out_t = '\n'.join(out_t_parts).rstrip()
434 raw = '\n'.join(raw_parts).rstrip()
434 raw = '\n'.join(raw_parts).rstrip()
435 self.assertEqual(out.rstrip(), out_t)
435 self.assertEqual(out.rstrip(), out_t)
436 self.assertEqual(out_raw.rstrip(), raw)
436 self.assertEqual(out_raw.rstrip(), raw)
437
437
438 def test_syntax_multiline_cell(self):
438 def test_syntax_multiline_cell(self):
439 isp = self.isp
439 isp = self.isp
440 for example in syntax_ml.itervalues():
440 for example in syntax_ml.itervalues():
441
441
442 out_t_parts = []
442 out_t_parts = []
443 for line_pairs in example:
443 for line_pairs in example:
444 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
444 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
445 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
445 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
446 out = isp.transform_cell(raw)
446 out = isp.transform_cell(raw)
447 # Match ignoring trailing whitespace
447 # Match ignoring trailing whitespace
448 self.assertEqual(out.rstrip(), out_t.rstrip())
448 self.assertEqual(out.rstrip(), out_t.rstrip())
449
449
450 def test_cellmagic_preempt(self):
450 def test_cellmagic_preempt(self):
451 isp = self.isp
451 isp = self.isp
452 for raw, name, line, cell in [
452 for raw, name, line, cell in [
453 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
453 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
454 ("%%cellm \n...:", u'cellm', u'', u'...:'),
454 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
455 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
456 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
455 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
457 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
456 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
458 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
457 ]:
459 ]:
458 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
460 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
459 name, line, cell
461 name, line, cell
460 )
462 )
461 out = isp.transform_cell(raw)
463 out = isp.transform_cell(raw)
462 self.assertEqual(out.rstrip(), expected.rstrip())
464 self.assertEqual(out.rstrip(), expected.rstrip())
463
465
464
466
465
467
466 #-----------------------------------------------------------------------------
468 #-----------------------------------------------------------------------------
467 # Main - use as a script, mostly for developer experiments
469 # Main - use as a script, mostly for developer experiments
468 #-----------------------------------------------------------------------------
470 #-----------------------------------------------------------------------------
469
471
470 if __name__ == '__main__':
472 if __name__ == '__main__':
471 # A simple demo for interactive experimentation. This code will not get
473 # A simple demo for interactive experimentation. This code will not get
472 # picked up by any test suite.
474 # picked up by any test suite.
473 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
475 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
474
476
475 # configure here the syntax to use, prompt and whether to autoindent
477 # configure here the syntax to use, prompt and whether to autoindent
476 #isp, start_prompt = InputSplitter(), '>>> '
478 #isp, start_prompt = InputSplitter(), '>>> '
477 isp, start_prompt = IPythonInputSplitter(), 'In> '
479 isp, start_prompt = IPythonInputSplitter(), 'In> '
478
480
479 autoindent = True
481 autoindent = True
480 #autoindent = False
482 #autoindent = False
481
483
482 try:
484 try:
483 while True:
485 while True:
484 prompt = start_prompt
486 prompt = start_prompt
485 while isp.push_accepts_more():
487 while isp.push_accepts_more():
486 indent = ' '*isp.indent_spaces
488 indent = ' '*isp.indent_spaces
487 if autoindent:
489 if autoindent:
488 line = indent + raw_input(prompt+indent)
490 line = indent + raw_input(prompt+indent)
489 else:
491 else:
490 line = raw_input(prompt)
492 line = raw_input(prompt)
491 isp.push(line)
493 isp.push(line)
492 prompt = '... '
494 prompt = '... '
493
495
494 # Here we just return input so we can use it in a test suite, but a
496 # Here we just return input so we can use it in a test suite, but a
495 # real interpreter would instead send it for execution somewhere.
497 # real interpreter would instead send it for execution somewhere.
496 #src = isp.source; raise EOFError # dbg
498 #src = isp.source; raise EOFError # dbg
497 src, raw = isp.source_raw_reset()
499 src, raw = isp.source_raw_reset()
498 print 'Input source was:\n', src
500 print 'Input source was:\n', src
499 print 'Raw source was:\n', raw
501 print 'Raw source was:\n', raw
500 except EOFError:
502 except EOFError:
501 print 'Bye'
503 print 'Bye'
502
504
503 # Tests for cell magics support
505 # Tests for cell magics support
504
506
505 def test_last_blank():
507 def test_last_blank():
506 nt.assert_false(isp.last_blank(''))
508 nt.assert_false(isp.last_blank(''))
507 nt.assert_false(isp.last_blank('abc'))
509 nt.assert_false(isp.last_blank('abc'))
508 nt.assert_false(isp.last_blank('abc\n'))
510 nt.assert_false(isp.last_blank('abc\n'))
509 nt.assert_false(isp.last_blank('abc\na'))
511 nt.assert_false(isp.last_blank('abc\na'))
510
512
511 nt.assert_true(isp.last_blank('\n'))
513 nt.assert_true(isp.last_blank('\n'))
512 nt.assert_true(isp.last_blank('\n '))
514 nt.assert_true(isp.last_blank('\n '))
513 nt.assert_true(isp.last_blank('abc\n '))
515 nt.assert_true(isp.last_blank('abc\n '))
514 nt.assert_true(isp.last_blank('abc\n\n'))
516 nt.assert_true(isp.last_blank('abc\n\n'))
515 nt.assert_true(isp.last_blank('abc\nd\n\n'))
517 nt.assert_true(isp.last_blank('abc\nd\n\n'))
516 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
518 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
517 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
519 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
518
520
519
521
520 def test_last_two_blanks():
522 def test_last_two_blanks():
521 nt.assert_false(isp.last_two_blanks(''))
523 nt.assert_false(isp.last_two_blanks(''))
522 nt.assert_false(isp.last_two_blanks('abc'))
524 nt.assert_false(isp.last_two_blanks('abc'))
523 nt.assert_false(isp.last_two_blanks('abc\n'))
525 nt.assert_false(isp.last_two_blanks('abc\n'))
524 nt.assert_false(isp.last_two_blanks('abc\n\na'))
526 nt.assert_false(isp.last_two_blanks('abc\n\na'))
525 nt.assert_false(isp.last_two_blanks('abc\n \n'))
527 nt.assert_false(isp.last_two_blanks('abc\n \n'))
526 nt.assert_false(isp.last_two_blanks('abc\n\n'))
528 nt.assert_false(isp.last_two_blanks('abc\n\n'))
527
529
528 nt.assert_true(isp.last_two_blanks('\n\n'))
530 nt.assert_true(isp.last_two_blanks('\n\n'))
529 nt.assert_true(isp.last_two_blanks('\n\n '))
531 nt.assert_true(isp.last_two_blanks('\n\n '))
530 nt.assert_true(isp.last_two_blanks('\n \n'))
532 nt.assert_true(isp.last_two_blanks('\n \n'))
531 nt.assert_true(isp.last_two_blanks('abc\n\n '))
533 nt.assert_true(isp.last_two_blanks('abc\n\n '))
532 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
534 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
533 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
535 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
534 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
536 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
535 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
537 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
536 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
538 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
537 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
539 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
538
540
539
541
540 class CellMagicsCommon(object):
542 class CellMagicsCommon(object):
541
543
542 def test_whole_cell(self):
544 def test_whole_cell(self):
543 src = "%%cellm line\nbody\n"
545 src = "%%cellm line\nbody\n"
544 sp = self.sp
546 sp = self.sp
545 sp.push(src)
547 sp.push(src)
546 out = sp.source_reset()
548 out = sp.source_reset()
547 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
549 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
548 nt.assert_equal(out, py3compat.u_format(ref))
550 nt.assert_equal(out, py3compat.u_format(ref))
549
551
550 def test_cellmagic_help(self):
552 def test_cellmagic_help(self):
551 self.sp.push('%%cellm?')
553 self.sp.push('%%cellm?')
552 nt.assert_false(self.sp.push_accepts_more())
554 nt.assert_false(self.sp.push_accepts_more())
553
555
554 def tearDown(self):
556 def tearDown(self):
555 self.sp.reset()
557 self.sp.reset()
556
558
557
559
558 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
560 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
559 sp = isp.IPythonInputSplitter(line_input_checker=False)
561 sp = isp.IPythonInputSplitter(line_input_checker=False)
560
562
561 def test_incremental(self):
563 def test_incremental(self):
562 sp = self.sp
564 sp = self.sp
563 sp.push('%%cellm firstline\n')
565 sp.push('%%cellm firstline\n')
564 nt.assert_true(sp.push_accepts_more()) #1
566 nt.assert_true(sp.push_accepts_more()) #1
565 sp.push('line2\n')
567 sp.push('line2\n')
566 nt.assert_true(sp.push_accepts_more()) #2
568 nt.assert_true(sp.push_accepts_more()) #2
567 sp.push('\n')
569 sp.push('\n')
568 # This should accept a blank line and carry on until the cell is reset
570 # This should accept a blank line and carry on until the cell is reset
569 nt.assert_true(sp.push_accepts_more()) #3
571 nt.assert_true(sp.push_accepts_more()) #3
570
572
571 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
573 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
572 sp = isp.IPythonInputSplitter(line_input_checker=True)
574 sp = isp.IPythonInputSplitter(line_input_checker=True)
573
575
574 def test_incremental(self):
576 def test_incremental(self):
575 sp = self.sp
577 sp = self.sp
576 sp.push('%%cellm line2\n')
578 sp.push('%%cellm line2\n')
577 nt.assert_true(sp.push_accepts_more()) #1
579 nt.assert_true(sp.push_accepts_more()) #1
578 sp.push('\n')
580 sp.push('\n')
579 # In this case, a blank line should end the cell magic
581 # In this case, a blank line should end the cell magic
580 nt.assert_false(sp.push_accepts_more()) #2
582 nt.assert_false(sp.push_accepts_more()) #2
General Comments 0
You need to be logged in to leave comments. Login now