##// END OF EJS Templates
Move and combine transformer tests
Thomas Kluyver -
Show More
@@ -1,845 +1,637 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module.
3 3
4 4 Authors
5 5 -------
6 6 * Fernando Perez
7 7 * Robert Kern
8 8 """
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2010-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19 # stdlib
20 20 import unittest
21 21 import sys
22 22
23 23 # Third party
24 24 import nose.tools as nt
25 25
26 26 # Our own
27 27 from IPython.core import inputsplitter as isp
28 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
28 29 from IPython.testing import tools as tt
29 30 from IPython.utils import py3compat
30 31
31 32 #-----------------------------------------------------------------------------
32 33 # Semi-complete examples (also used as tests)
33 34 #-----------------------------------------------------------------------------
34 35
35 36 # Note: at the bottom, there's a slightly more complete version of this that
36 37 # can be useful during development of code here.
37 38
38 39 def mini_interactive_loop(input_func):
39 40 """Minimal example of the logic of an interactive interpreter loop.
40 41
41 42 This serves as an example, and it is used by the test system with a fake
42 43 raw_input that simulates interactive input."""
43 44
44 45 from IPython.core.inputsplitter import InputSplitter
45 46
46 47 isp = InputSplitter()
47 48 # In practice, this input loop would be wrapped in an outside loop to read
48 49 # input indefinitely, until some exit/quit command was issued. Here we
49 50 # only illustrate the basic inner loop.
50 51 while isp.push_accepts_more():
51 52 indent = ' '*isp.indent_spaces
52 53 prompt = '>>> ' + indent
53 54 line = indent + input_func(prompt)
54 55 isp.push(line)
55 56
56 57 # Here we just return input so we can use it in a test suite, but a real
57 58 # interpreter would instead send it for execution somewhere.
58 59 src = isp.source_reset()
59 60 #print 'Input source was:\n', src # dbg
60 61 return src
61 62
62 63 #-----------------------------------------------------------------------------
63 64 # Test utilities, just for local use
64 65 #-----------------------------------------------------------------------------
65 66
66 67 def assemble(block):
67 68 """Assemble a block into multi-line sub-blocks."""
68 69 return ['\n'.join(sub_block)+'\n' for sub_block in block]
69 70
70 71
71 72 def pseudo_input(lines):
72 73 """Return a function that acts like raw_input but feeds the input list."""
73 74 ilines = iter(lines)
74 75 def raw_in(prompt):
75 76 try:
76 77 return next(ilines)
77 78 except StopIteration:
78 79 return ''
79 80 return raw_in
80 81
81 82 #-----------------------------------------------------------------------------
82 83 # Tests
83 84 #-----------------------------------------------------------------------------
84 85 def test_spaces():
85 86 tests = [('', 0),
86 87 (' ', 1),
87 88 ('\n', 0),
88 89 (' \n', 1),
89 90 ('x', 0),
90 91 (' x', 1),
91 92 (' x',2),
92 93 (' x',4),
93 94 # Note: tabs are counted as a single whitespace!
94 95 ('\tx', 1),
95 96 ('\t x', 2),
96 97 ]
97 98 tt.check_pairs(isp.num_ini_spaces, tests)
98 99
99 100
100 101 def test_remove_comments():
101 102 tests = [('text', 'text'),
102 103 ('text # comment', 'text '),
103 104 ('text # comment\n', 'text \n'),
104 105 ('text # comment \n', 'text \n'),
105 106 ('line # c \nline\n','line \nline\n'),
106 107 ('line # c \nline#c2 \nline\nline #c\n\n',
107 108 'line \nline\nline\nline \n\n'),
108 109 ]
109 110 tt.check_pairs(isp.remove_comments, tests)
110 111
111 112 def test_has_comment():
112 113 tests = [('text', False),
113 114 ('text #comment', True),
114 115 ('text #comment\n', True),
115 116 ('#comment', True),
116 117 ('#comment\n', True),
117 118 ('a = "#string"', False),
118 119 ('a = "#string" # comment', True),
119 120 ('a #comment not "string"', True),
120 121 ]
121 122 tt.check_pairs(isp.has_comment, tests)
122 123
123 124
124 125 def test_get_input_encoding():
125 126 encoding = isp.get_input_encoding()
126 127 nt.assert_true(isinstance(encoding, basestring))
127 128 # simple-minded check that at least encoding a simple string works with the
128 129 # encoding we got.
129 130 nt.assert_equal(u'test'.encode(encoding), b'test')
130 131
131 132
132 133 class NoInputEncodingTestCase(unittest.TestCase):
133 134 def setUp(self):
134 135 self.old_stdin = sys.stdin
135 136 class X: pass
136 137 fake_stdin = X()
137 138 sys.stdin = fake_stdin
138 139
139 140 def test(self):
140 141 # Verify that if sys.stdin has no 'encoding' attribute we do the right
141 142 # thing
142 143 enc = isp.get_input_encoding()
143 144 self.assertEqual(enc, 'ascii')
144 145
145 146 def tearDown(self):
146 147 sys.stdin = self.old_stdin
147 148
148 149
149 150 class InputSplitterTestCase(unittest.TestCase):
150 151 def setUp(self):
151 152 self.isp = isp.InputSplitter()
152 153
153 154 def test_reset(self):
154 155 isp = self.isp
155 156 isp.push('x=1')
156 157 isp.reset()
157 158 self.assertEqual(isp._buffer, [])
158 159 self.assertEqual(isp.indent_spaces, 0)
159 160 self.assertEqual(isp.source, '')
160 161 self.assertEqual(isp.code, None)
161 162 self.assertEqual(isp._is_complete, False)
162 163
163 164 def test_source(self):
164 165 self.isp._store('1')
165 166 self.isp._store('2')
166 167 self.assertEqual(self.isp.source, '1\n2\n')
167 168 self.assertTrue(len(self.isp._buffer)>0)
168 169 self.assertEqual(self.isp.source_reset(), '1\n2\n')
169 170 self.assertEqual(self.isp._buffer, [])
170 171 self.assertEqual(self.isp.source, '')
171 172
172 173 def test_indent(self):
173 174 isp = self.isp # shorthand
174 175 isp.push('x=1')
175 176 self.assertEqual(isp.indent_spaces, 0)
176 177 isp.push('if 1:\n x=1')
177 178 self.assertEqual(isp.indent_spaces, 4)
178 179 isp.push('y=2\n')
179 180 self.assertEqual(isp.indent_spaces, 0)
180 181
181 182 def test_indent2(self):
182 183 # In cell mode, inputs must be fed in whole blocks, so skip this test
183 184 if self.isp.input_mode == 'cell': return
184 185
185 186 isp = self.isp
186 187 isp.push('if 1:')
187 188 self.assertEqual(isp.indent_spaces, 4)
188 189 isp.push(' x=1')
189 190 self.assertEqual(isp.indent_spaces, 4)
190 191 # Blank lines shouldn't change the indent level
191 192 isp.push(' '*2)
192 193 self.assertEqual(isp.indent_spaces, 4)
193 194
194 195 def test_indent3(self):
195 196 # In cell mode, inputs must be fed in whole blocks, so skip this test
196 197 if self.isp.input_mode == 'cell': return
197 198
198 199 isp = self.isp
199 200 # When a multiline statement contains parens or multiline strings, we
200 201 # shouldn't get confused.
201 202 isp.push("if 1:")
202 203 isp.push(" x = (1+\n 2)")
203 204 self.assertEqual(isp.indent_spaces, 4)
204 205
205 206 def test_indent4(self):
206 207 # In cell mode, inputs must be fed in whole blocks, so skip this test
207 208 if self.isp.input_mode == 'cell': return
208 209
209 210 isp = self.isp
210 211 # whitespace after ':' should not screw up indent level
211 212 isp.push('if 1: \n x=1')
212 213 self.assertEqual(isp.indent_spaces, 4)
213 214 isp.push('y=2\n')
214 215 self.assertEqual(isp.indent_spaces, 0)
215 216 isp.push('if 1:\t\n x=1')
216 217 self.assertEqual(isp.indent_spaces, 4)
217 218 isp.push('y=2\n')
218 219 self.assertEqual(isp.indent_spaces, 0)
219 220
220 221 def test_dedent_pass(self):
221 222 isp = self.isp # shorthand
222 223 # should NOT cause dedent
223 224 isp.push('if 1:\n passes = 5')
224 225 self.assertEqual(isp.indent_spaces, 4)
225 226 isp.push('if 1:\n pass')
226 227 self.assertEqual(isp.indent_spaces, 0)
227 228 isp.push('if 1:\n pass ')
228 229 self.assertEqual(isp.indent_spaces, 0)
229 230
230 231 def test_dedent_break(self):
231 232 isp = self.isp # shorthand
232 233 # should NOT cause dedent
233 234 isp.push('while 1:\n breaks = 5')
234 235 self.assertEqual(isp.indent_spaces, 4)
235 236 isp.push('while 1:\n break')
236 237 self.assertEqual(isp.indent_spaces, 0)
237 238 isp.push('while 1:\n break ')
238 239 self.assertEqual(isp.indent_spaces, 0)
239 240
240 241 def test_dedent_continue(self):
241 242 isp = self.isp # shorthand
242 243 # should NOT cause dedent
243 244 isp.push('while 1:\n continues = 5')
244 245 self.assertEqual(isp.indent_spaces, 4)
245 246 isp.push('while 1:\n continue')
246 247 self.assertEqual(isp.indent_spaces, 0)
247 248 isp.push('while 1:\n continue ')
248 249 self.assertEqual(isp.indent_spaces, 0)
249 250
250 251 def test_dedent_raise(self):
251 252 isp = self.isp # shorthand
252 253 # should NOT cause dedent
253 254 isp.push('if 1:\n raised = 4')
254 255 self.assertEqual(isp.indent_spaces, 4)
255 256 isp.push('if 1:\n raise TypeError()')
256 257 self.assertEqual(isp.indent_spaces, 0)
257 258 isp.push('if 1:\n raise')
258 259 self.assertEqual(isp.indent_spaces, 0)
259 260 isp.push('if 1:\n raise ')
260 261 self.assertEqual(isp.indent_spaces, 0)
261 262
262 263 def test_dedent_return(self):
263 264 isp = self.isp # shorthand
264 265 # should NOT cause dedent
265 266 isp.push('if 1:\n returning = 4')
266 267 self.assertEqual(isp.indent_spaces, 4)
267 268 isp.push('if 1:\n return 5 + 493')
268 269 self.assertEqual(isp.indent_spaces, 0)
269 270 isp.push('if 1:\n return')
270 271 self.assertEqual(isp.indent_spaces, 0)
271 272 isp.push('if 1:\n return ')
272 273 self.assertEqual(isp.indent_spaces, 0)
273 274 isp.push('if 1:\n return(0)')
274 275 self.assertEqual(isp.indent_spaces, 0)
275 276
276 277 def test_push(self):
277 278 isp = self.isp
278 279 self.assertTrue(isp.push('x=1'))
279 280
280 281 def test_push2(self):
281 282 isp = self.isp
282 283 self.assertFalse(isp.push('if 1:'))
283 284 for line in [' x=1', '# a comment', ' y=2']:
284 285 self.assertTrue(isp.push(line))
285 286
286 287 def test_push3(self):
287 288 isp = self.isp
288 289 isp.push('if True:')
289 290 isp.push(' a = 1')
290 291 self.assertFalse(isp.push('b = [1,'))
291 292
292 293 def test_replace_mode(self):
293 294 isp = self.isp
294 295 isp.input_mode = 'cell'
295 296 isp.push('x=1')
296 297 self.assertEqual(isp.source, 'x=1\n')
297 298 isp.push('x=2')
298 299 self.assertEqual(isp.source, 'x=2\n')
299 300
300 301 def test_push_accepts_more(self):
301 302 isp = self.isp
302 303 isp.push('x=1')
303 304 self.assertFalse(isp.push_accepts_more())
304 305
305 306 def test_push_accepts_more2(self):
306 307 # In cell mode, inputs must be fed in whole blocks, so skip this test
307 308 if self.isp.input_mode == 'cell': return
308 309
309 310 isp = self.isp
310 311 isp.push('if 1:')
311 312 self.assertTrue(isp.push_accepts_more())
312 313 isp.push(' x=1')
313 314 self.assertTrue(isp.push_accepts_more())
314 315 isp.push('')
315 316 self.assertFalse(isp.push_accepts_more())
316 317
317 318 def test_push_accepts_more3(self):
318 319 isp = self.isp
319 320 isp.push("x = (2+\n3)")
320 321 self.assertFalse(isp.push_accepts_more())
321 322
322 323 def test_push_accepts_more4(self):
323 324 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 325 if self.isp.input_mode == 'cell': return
325 326
326 327 isp = self.isp
327 328 # When a multiline statement contains parens or multiline strings, we
328 329 # shouldn't get confused.
329 330 # FIXME: we should be able to better handle de-dents in statements like
330 331 # multiline strings and multiline expressions (continued with \ or
331 332 # parens). Right now we aren't handling the indentation tracking quite
332 333 # correctly with this, though in practice it may not be too much of a
333 334 # problem. We'll need to see.
334 335 isp.push("if 1:")
335 336 isp.push(" x = (2+")
336 337 isp.push(" 3)")
337 338 self.assertTrue(isp.push_accepts_more())
338 339 isp.push(" y = 3")
339 340 self.assertTrue(isp.push_accepts_more())
340 341 isp.push('')
341 342 self.assertFalse(isp.push_accepts_more())
342 343
343 344 def test_push_accepts_more5(self):
344 345 # In cell mode, inputs must be fed in whole blocks, so skip this test
345 346 if self.isp.input_mode == 'cell': return
346 347
347 348 isp = self.isp
348 349 isp.push('try:')
349 350 isp.push(' a = 5')
350 351 isp.push('except:')
351 352 isp.push(' raise')
352 353 self.assertTrue(isp.push_accepts_more())
353 354
354 355 def test_continuation(self):
355 356 isp = self.isp
356 357 isp.push("import os, \\")
357 358 self.assertTrue(isp.push_accepts_more())
358 359 isp.push("sys")
359 360 self.assertFalse(isp.push_accepts_more())
360 361
361 362 def test_syntax_error(self):
362 363 isp = self.isp
363 364 # Syntax errors immediately produce a 'ready' block, so the invalid
364 365 # Python can be sent to the kernel for evaluation with possible ipython
365 366 # special-syntax conversion.
366 367 isp.push('run foo')
367 368 self.assertFalse(isp.push_accepts_more())
368 369
369 370 def test_unicode(self):
370 371 self.isp.push(u"PΓ©rez")
371 372 self.isp.push(u'\xc3\xa9')
372 373 self.isp.push(u"u'\xc3\xa9'")
373 374
374 375 def test_line_continuation(self):
375 376 """ Test issue #2108."""
376 377 isp = self.isp
377 378 # A blank line after a line continuation should not accept more
378 379 isp.push("1 \\\n\n")
379 380 self.assertFalse(isp.push_accepts_more())
380 381 # Whitespace after a \ is a SyntaxError. The only way to test that
381 382 # here is to test that push doesn't accept more (as with
382 383 # test_syntax_error() above).
383 384 isp.push(r"1 \ ")
384 385 self.assertFalse(isp.push_accepts_more())
385 386 # Even if the line is continuable (c.f. the regular Python
386 387 # interpreter)
387 388 isp.push(r"(1 \ ")
388 389 self.assertFalse(isp.push_accepts_more())
389 390
390 391 class InteractiveLoopTestCase(unittest.TestCase):
391 392 """Tests for an interactive loop like a python shell.
392 393 """
393 394 def check_ns(self, lines, ns):
394 395 """Validate that the given input lines produce the resulting namespace.
395 396
396 397 Note: the input lines are given exactly as they would be typed in an
397 398 auto-indenting environment, as mini_interactive_loop above already does
398 399 auto-indenting and prepends spaces to the input.
399 400 """
400 401 src = mini_interactive_loop(pseudo_input(lines))
401 402 test_ns = {}
402 403 exec src in test_ns
403 404 # We can't check that the provided ns is identical to the test_ns,
404 405 # because Python fills test_ns with extra keys (copyright, etc). But
405 406 # we can check that the given dict is *contained* in test_ns
406 407 for k,v in ns.iteritems():
407 408 self.assertEqual(test_ns[k], v)
408 409
409 410 def test_simple(self):
410 411 self.check_ns(['x=1'], dict(x=1))
411 412
412 413 def test_simple2(self):
413 414 self.check_ns(['if 1:', 'x=2'], dict(x=2))
414 415
415 416 def test_xy(self):
416 417 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
417 418
418 419 def test_abc(self):
419 420 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
420 421
421 422 def test_multi(self):
422 423 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
423 424
424 425
425 426 def test_LineInfo():
426 427 """Simple test for LineInfo construction and str()"""
427 428 linfo = isp.LineInfo(' %cd /home')
428 429 nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
429 430
430 # Transformer tests
431 def transform_checker(tests, func):
432 """Utility to loop over test inputs"""
433 for inp, tr in tests:
434 nt.assert_equal(func(inp), tr)
435
436 # Data for all the syntax tests in the form of lists of pairs of
437 # raw/transformed input. We store it here as a global dict so that we can use
438 # it both within single-function tests and also to validate the behavior of the
439 # larger objects
440
441 syntax = \
442 dict(assign_system =
443 [(i,py3compat.u_format(o)) for i,o in \
444 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
445 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
446 ('x=1', 'x=1'), # normal input is unmodified
447 (' ',' '), # blank lines are kept intact
448 ]],
449
450 assign_magic =
451 [(i,py3compat.u_format(o)) for i,o in \
452 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
453 (u'b = %who', "b = get_ipython().magic({u}'who')"),
454 ('x=1', 'x=1'), # normal input is unmodified
455 (' ',' '), # blank lines are kept intact
456 ]],
457
458 classic_prompt =
459 [('>>> x=1', 'x=1'),
460 ('x=1', 'x=1'), # normal input is unmodified
461 (' ', ' '), # blank lines are kept intact
462 ('... ', ''), # continuation prompts
463 ],
464
465 ipy_prompt =
466 [('In [1]: x=1', 'x=1'),
467 ('x=1', 'x=1'), # normal input is unmodified
468 (' ',' '), # blank lines are kept intact
469 (' ....: ', ''), # continuation prompts
470 ],
471
472 # Tests for the escape transformer to leave normal code alone
473 escaped_noesc =
474 [ (' ', ' '),
475 ('x=1', 'x=1'),
476 ],
477
478 # System calls
479 escaped_shell =
480 [(i,py3compat.u_format(o)) for i,o in \
481 [ (u'!ls', "get_ipython().system({u}'ls')"),
482 # Double-escape shell, this means to capture the output of the
483 # subprocess and return it
484 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
485 ]],
486
487 # Help/object info
488 escaped_help =
489 [(i,py3compat.u_format(o)) for i,o in \
490 [ (u'?', 'get_ipython().show_usage()'),
491 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
492 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
493 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
494 (u'?%hist1', "get_ipython().magic({u}'pinfo %hist1')"),
495 (u'?%%hist2', "get_ipython().magic({u}'pinfo %%hist2')"),
496 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
497 ]],
498
499 end_help =
500 [(i,py3compat.u_format(o)) for i,o in \
501 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
502 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
503 (u'%hist1?', "get_ipython().magic({u}'pinfo %hist1')"),
504 (u'%hist2??', "get_ipython().magic({u}'pinfo2 %hist2')"),
505 (u'%%hist3?', "get_ipython().magic({u}'pinfo %%hist3')"),
506 (u'%%hist4??', "get_ipython().magic({u}'pinfo2 %%hist4')"),
507 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
508 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
509 (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
510 "get_ipython().magic({u}'pinfo abc')"),
511 (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
512 "get_ipython().magic({u}'pinfo2 abc.qe')"),
513 (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
514 "get_ipython().magic({u}'psearch *.items')"),
515 (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
516 "get_ipython().magic({u}'pinfo a')"),
517 (u'a*2 #comment?', 'a*2 #comment?'),
518 ]],
519
520 # Explicit magic calls
521 escaped_magic =
522 [(i,py3compat.u_format(o)) for i,o in \
523 [ (u'%cd', "get_ipython().magic({u}'cd')"),
524 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
525 # Backslashes need to be escaped.
526 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
527 (u' %magic', " get_ipython().magic({u}'magic')"),
528 ]],
529
530 # Quoting with separate arguments
531 escaped_quote =
532 [ (',f', 'f("")'),
533 (',f x', 'f("x")'),
534 (' ,f y', ' f("y")'),
535 (',f a b', 'f("a", "b")'),
536 ],
537
538 # Quoting with single argument
539 escaped_quote2 =
540 [ (';f', 'f("")'),
541 (';f x', 'f("x")'),
542 (' ;f y', ' f("y")'),
543 (';f a b', 'f("a b")'),
544 ],
545
546 # Simply apply parens
547 escaped_paren =
548 [ ('/f', 'f()'),
549 ('/f x', 'f(x)'),
550 (' /f y', ' f(y)'),
551 ('/f a b', 'f(a, b)'),
552 ],
553
554 # Check that we transform prompts before other transforms
555 mixed =
556 [(i,py3compat.u_format(o)) for i,o in \
557 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
558 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
559 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
560 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
561 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
562 ]],
563 )
564
565 # multiline syntax examples. Each of these should be a list of lists, with
566 # each entry itself having pairs of raw/transformed input. The union (with
567 # '\n'.join() of the transformed inputs is what the splitter should produce
568 # when fed the raw lines one at a time via push.
569 syntax_ml = \
570 dict(classic_prompt =
571 [ [('>>> for i in range(10):','for i in range(10):'),
572 ('... print i',' print i'),
573 ('... ', ''),
574 ],
575 ],
576
577 ipy_prompt =
578 [ [('In [24]: for i in range(10):','for i in range(10):'),
579 (' ....: print i',' print i'),
580 (' ....: ', ''),
581 ],
582 ],
583
584 multiline_datastructure =
585 [ [('>>> a = [1,','a = [1,'),
586 ('... 2]','2]'),
587 ],
588 ],
589 )
590
591
592 def test_assign_system():
593 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
594
595
596 def test_assign_magic():
597 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
598
599
600 def test_classic_prompt():
601 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
602 for example in syntax_ml['classic_prompt']:
603 transform_checker(example, isp.transform_classic_prompt)
604
605
606 def test_ipy_prompt():
607 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
608 for example in syntax_ml['ipy_prompt']:
609 transform_checker(example, isp.transform_ipy_prompt)
610
611 def test_end_help():
612 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
613
614 def test_escaped_noesc():
615 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
616
617 431
618 def test_escaped_shell():
619 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
620
621
622 def test_escaped_help():
623 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
624
625
626 def test_escaped_magic():
627 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
628
629
630 def test_escaped_quote():
631 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
632
633
634 def test_escaped_quote2():
635 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
636
637
638 def test_escaped_paren():
639 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
640 432
641 433
642 434 class IPythonInputTestCase(InputSplitterTestCase):
643 435 """By just creating a new class whose .isp is a different instance, we
644 436 re-run the same test battery on the new input splitter.
645 437
646 438 In addition, this runs the tests over the syntax and syntax_ml dicts that
647 439 were tested by individual functions, as part of the OO interface.
648 440
649 441 It also makes some checks on the raw buffer storage.
650 442 """
651 443
652 444 def setUp(self):
653 445 self.isp = isp.IPythonInputSplitter(input_mode='line')
654 446
655 447 def test_syntax(self):
656 448 """Call all single-line syntax tests from the main object"""
657 449 isp = self.isp
658 450 for example in syntax.itervalues():
659 451 for raw, out_t in example:
660 452 if raw.startswith(' '):
661 453 continue
662 454
663 455 isp.push(raw+'\n')
664 456 out, out_raw = isp.source_raw_reset()
665 457 self.assertEqual(out.rstrip(), out_t,
666 458 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
667 459 self.assertEqual(out_raw.rstrip(), raw.rstrip())
668 460
669 461 def test_syntax_multiline(self):
670 462 isp = self.isp
671 463 for example in syntax_ml.itervalues():
672 464 out_t_parts = []
673 465 raw_parts = []
674 466 for line_pairs in example:
675 467 for lraw, out_t_part in line_pairs:
676 468 isp.push(lraw)
677 469 out_t_parts.append(out_t_part)
678 470 raw_parts.append(lraw)
679 471
680 472 out, out_raw = isp.source_raw_reset()
681 473 out_t = '\n'.join(out_t_parts).rstrip()
682 474 raw = '\n'.join(raw_parts).rstrip()
683 475 self.assertEqual(out.rstrip(), out_t)
684 476 self.assertEqual(out_raw.rstrip(), raw)
685 477
686 478
687 479 class BlockIPythonInputTestCase(IPythonInputTestCase):
688 480
689 481 # Deactivate tests that don't make sense for the block mode
690 482 test_push3 = test_split = lambda s: None
691 483
692 484 def setUp(self):
693 485 self.isp = isp.IPythonInputSplitter(input_mode='cell')
694 486
695 487 def test_syntax_multiline(self):
696 488 isp = self.isp
697 489 for example in syntax_ml.itervalues():
698 490 raw_parts = []
699 491 out_t_parts = []
700 492 for line_pairs in example:
701 493 for raw, out_t_part in line_pairs:
702 494 raw_parts.append(raw)
703 495 out_t_parts.append(out_t_part)
704 496
705 497 raw = '\n'.join(raw_parts)
706 498 out_t = '\n'.join(out_t_parts)
707 499
708 500 isp.push(raw)
709 501 out, out_raw = isp.source_raw_reset()
710 502 # Match ignoring trailing whitespace
711 503 self.assertEqual(out.rstrip(), out_t.rstrip())
712 504 self.assertEqual(out_raw.rstrip(), raw.rstrip())
713 505
714 506 def test_syntax_multiline_cell(self):
715 507 isp = self.isp
716 508 for example in syntax_ml.itervalues():
717 509
718 510 out_t_parts = []
719 511 for line_pairs in example:
720 512 raw = '\n'.join(r for r, _ in line_pairs)
721 513 out_t = '\n'.join(t for _,t in line_pairs)
722 514 out = isp.transform_cell(raw)
723 515 # Match ignoring trailing whitespace
724 516 self.assertEqual(out.rstrip(), out_t.rstrip())
725 517
726 518 #-----------------------------------------------------------------------------
727 519 # Main - use as a script, mostly for developer experiments
728 520 #-----------------------------------------------------------------------------
729 521
730 522 if __name__ == '__main__':
731 523 # A simple demo for interactive experimentation. This code will not get
732 524 # picked up by any test suite.
733 525 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
734 526
735 527 # configure here the syntax to use, prompt and whether to autoindent
736 528 #isp, start_prompt = InputSplitter(), '>>> '
737 529 isp, start_prompt = IPythonInputSplitter(), 'In> '
738 530
739 531 autoindent = True
740 532 #autoindent = False
741 533
742 534 try:
743 535 while True:
744 536 prompt = start_prompt
745 537 while isp.push_accepts_more():
746 538 indent = ' '*isp.indent_spaces
747 539 if autoindent:
748 540 line = indent + raw_input(prompt+indent)
749 541 else:
750 542 line = raw_input(prompt)
751 543 isp.push(line)
752 544 prompt = '... '
753 545
754 546 # Here we just return input so we can use it in a test suite, but a
755 547 # real interpreter would instead send it for execution somewhere.
756 548 #src = isp.source; raise EOFError # dbg
757 549 src, raw = isp.source_raw_reset()
758 550 print 'Input source was:\n', src
759 551 print 'Raw source was:\n', raw
760 552 except EOFError:
761 553 print 'Bye'
762 554
763 555 # Tests for cell magics support
764 556
765 557 def test_last_blank():
766 558 nt.assert_false(isp.last_blank(''))
767 559 nt.assert_false(isp.last_blank('abc'))
768 560 nt.assert_false(isp.last_blank('abc\n'))
769 561 nt.assert_false(isp.last_blank('abc\na'))
770 562
771 563 nt.assert_true(isp.last_blank('\n'))
772 564 nt.assert_true(isp.last_blank('\n '))
773 565 nt.assert_true(isp.last_blank('abc\n '))
774 566 nt.assert_true(isp.last_blank('abc\n\n'))
775 567 nt.assert_true(isp.last_blank('abc\nd\n\n'))
776 568 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
777 569 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
778 570
779 571
780 572 def test_last_two_blanks():
781 573 nt.assert_false(isp.last_two_blanks(''))
782 574 nt.assert_false(isp.last_two_blanks('abc'))
783 575 nt.assert_false(isp.last_two_blanks('abc\n'))
784 576 nt.assert_false(isp.last_two_blanks('abc\n\na'))
785 577 nt.assert_false(isp.last_two_blanks('abc\n \n'))
786 578 nt.assert_false(isp.last_two_blanks('abc\n\n'))
787 579
788 580 nt.assert_true(isp.last_two_blanks('\n\n'))
789 581 nt.assert_true(isp.last_two_blanks('\n\n '))
790 582 nt.assert_true(isp.last_two_blanks('\n \n'))
791 583 nt.assert_true(isp.last_two_blanks('abc\n\n '))
792 584 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
793 585 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
794 586 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
795 587 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
796 588 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
797 589 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
798 590
799 591
800 592 class CellMagicsCommon(object):
801 593
802 594 def test_whole_cell(self):
803 595 src = "%%cellm line\nbody\n"
804 596 sp = self.sp
805 597 sp.push(src)
806 598 nt.assert_equal(sp.cell_magic_parts, ['body\n'])
807 599 out = sp.source
808 600 ref = u"get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n"
809 601 nt.assert_equal(out, py3compat.u_format(ref))
810 602
811 603 def tearDown(self):
812 604 self.sp.reset()
813 605
814 606
815 607 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
816 608 sp = isp.IPythonInputSplitter(input_mode='cell')
817 609
818 610 def test_incremental(self):
819 611 sp = self.sp
820 612 src = '%%cellm line2\n'
821 613 sp.push(src)
822 614 nt.assert_true(sp.push_accepts_more()) #1
823 615 src += '\n'
824 616 sp.push(src)
825 617 # Note: if we ever change the logic to allow full blank lines (see
826 618 # _handle_cell_magic), then the following test should change to true
827 619 nt.assert_false(sp.push_accepts_more()) #2
828 620 # By now, even with full blanks allowed, a second blank should signal
829 621 # the end. For now this test is only a redundancy safety, but don't
830 622 # delete it in case we change our mind and the previous one goes to
831 623 # true.
832 624 src += '\n'
833 625 sp.push(src)
834 626 nt.assert_false(sp.push_accepts_more()) #3
835 627
836 628
837 629 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
838 630 sp = isp.IPythonInputSplitter(input_mode='line')
839 631
840 632 def test_incremental(self):
841 633 sp = self.sp
842 634 sp.push('%%cellm line2\n')
843 635 nt.assert_true(sp.push_accepts_more()) #1
844 636 sp.push('\n')
845 637 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,84 +1,305 b''
1 1 import unittest
2 2 import nose.tools as nt
3 3
4 4 from IPython.testing import tools as tt
5 5 from IPython.utils import py3compat
6 u_fmt = py3compat.u_format
6 7
7 from IPython.core import inputtransformer
8 from IPython.core.tests.test_inputsplitter import syntax
8 from IPython.core import inputtransformer as ipt
9 9
10 def wrap_transform(transformer):
10 def transform_and_reset(transformer):
11 11 def transform(inp):
12 results = []
13 for line in inp:
14 res = transformer.push(line)
15 if res is not None:
16 results.append(res)
17 transformer.reset()
18 return results
12 try:
13 return transformer.push(inp)
14 finally:
15 transformer.reset()
19 16
20 17 return transform
21 18
22 cellmagic_tests = [
23 (['%%foo a', None], ["get_ipython().run_cell_magic('foo', 'a', '')"]),
24 (['%%bar 123', 'hello', ''], ["get_ipython().run_cell_magic('bar', '123', 'hello')"]),
25 ]
19 # Transformer tests
20 def transform_checker(tests, transformer):
21 """Utility to loop over test inputs"""
22 try:
23 for inp, tr in tests:
24 nt.assert_equal(transformer.push(inp), tr)
25 finally:
26 transformer.reset()
27
28 # Data for all the syntax tests in the form of lists of pairs of
29 # raw/transformed input. We store it here as a global dict so that we can use
30 # it both within single-function tests and also to validate the behavior of the
31 # larger objects
32
33 syntax = \
34 dict(assign_system =
35 [(i,py3compat.u_format(o)) for i,o in \
36 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
37 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
38 ('x=1', 'x=1'), # normal input is unmodified
39 (' ',' '), # blank lines are kept intact
40 ]],
41
42 assign_magic =
43 [(i,py3compat.u_format(o)) for i,o in \
44 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
45 (u'b = %who', "b = get_ipython().magic({u}'who')"),
46 ('x=1', 'x=1'), # normal input is unmodified
47 (' ',' '), # blank lines are kept intact
48 ]],
49
50 classic_prompt =
51 [('>>> x=1', 'x=1'),
52 ('x=1', 'x=1'), # normal input is unmodified
53 (' ', ' '), # blank lines are kept intact
54 ],
55
56 ipy_prompt =
57 [('In [1]: x=1', 'x=1'),
58 ('x=1', 'x=1'), # normal input is unmodified
59 (' ',' '), # blank lines are kept intact
60 ],
61
62 # Tests for the escape transformer to leave normal code alone
63 escaped_noesc =
64 [ (' ', ' '),
65 ('x=1', 'x=1'),
66 ],
67
68 # System calls
69 escaped_shell =
70 [(i,py3compat.u_format(o)) for i,o in \
71 [ (u'!ls', "get_ipython().system({u}'ls')"),
72 # Double-escape shell, this means to capture the output of the
73 # subprocess and return it
74 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
75 ]],
76
77 # Help/object info
78 escaped_help =
79 [(i,py3compat.u_format(o)) for i,o in \
80 [ (u'?', 'get_ipython().show_usage()'),
81 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
82 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
83 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
84 (u'?%hist1', "get_ipython().magic({u}'pinfo %hist1')"),
85 (u'?%%hist2', "get_ipython().magic({u}'pinfo %%hist2')"),
86 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
87 ]],
88
89 end_help =
90 [(i,py3compat.u_format(o)) for i,o in \
91 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
92 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
93 (u'%hist1?', "get_ipython().magic({u}'pinfo %hist1')"),
94 (u'%hist2??', "get_ipython().magic({u}'pinfo2 %hist2')"),
95 (u'%%hist3?', "get_ipython().magic({u}'pinfo %%hist3')"),
96 (u'%%hist4??', "get_ipython().magic({u}'pinfo2 %%hist4')"),
97 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
98 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
99 (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
100 "get_ipython().magic({u}'pinfo abc')"),
101 (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
102 "get_ipython().magic({u}'pinfo2 abc.qe')"),
103 (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
104 "get_ipython().magic({u}'psearch *.items')"),
105 (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
106 "get_ipython().magic({u}'pinfo a')"),
107 (u'a*2 #comment?', 'a*2 #comment?'),
108 ]],
109
110 # Explicit magic calls
111 escaped_magic =
112 [(i,py3compat.u_format(o)) for i,o in \
113 [ (u'%cd', "get_ipython().magic({u}'cd')"),
114 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
115 # Backslashes need to be escaped.
116 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
117 (u' %magic', " get_ipython().magic({u}'magic')"),
118 ]],
119
120 # Quoting with separate arguments
121 escaped_quote =
122 [ (',f', 'f("")'),
123 (',f x', 'f("x")'),
124 (' ,f y', ' f("y")'),
125 (',f a b', 'f("a", "b")'),
126 ],
127
128 # Quoting with single argument
129 escaped_quote2 =
130 [ (';f', 'f("")'),
131 (';f x', 'f("x")'),
132 (' ;f y', ' f("y")'),
133 (';f a b', 'f("a b")'),
134 ],
135
136 # Simply apply parens
137 escaped_paren =
138 [ ('/f', 'f()'),
139 ('/f x', 'f(x)'),
140 (' /f y', ' f(y)'),
141 ('/f a b', 'f(a, b)'),
142 ],
143
144 # Check that we transform prompts before other transforms
145 mixed =
146 [(i,py3compat.u_format(o)) for i,o in \
147 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
148 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
149 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
150 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
151 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
152 ]],
153 )
26 154
27 def test_transform_cellmagic():
28 tt.check_pairs(wrap_transform(inputtransformer.cellmagic), cellmagic_tests)
155 # multiline syntax examples. Each of these should be a list of lists, with
156 # each entry itself having pairs of raw/transformed input. The union (with
157 # '\n'.join() of the transformed inputs is what the splitter should produce
158 # when fed the raw lines one at a time via push.
159 syntax_ml = \
160 dict(classic_prompt =
161 [ [('>>> for i in range(10):','for i in range(10):'),
162 ('... print i',' print i'),
163 ('... ', ''),
164 ],
165 [('>>> a="""','a="""'),
166 ('... 123"""','123"""'),
167 ],
168 [('a="""','a="""'),
169 ('... 123"""','... 123"""'),
170 ],
171 ],
29 172
30 esctransform_tests = [(i, [py3compat.u_format(ol) for ol in o]) for i,o in [
31 (['%pdef zip'], ["get_ipython().magic({u}'pdef zip')"]),
32 (['%abc def \\', 'ghi'], ["get_ipython().magic({u}'abc def ghi')"]),
33 (['%abc def \\', 'ghi\\', None], ["get_ipython().magic({u}'abc def ghi')"]),
34 ]]
173 ipy_prompt =
174 [ [('In [24]: for i in range(10):','for i in range(10):'),
175 (' ....: print i',' print i'),
176 (' ....: ', ''),
177 ],
178 [('In [2]: a="""','a="""'),
179 (' ...: 123"""','123"""'),
180 ],
181 [('a="""','a="""'),
182 (' ...: 123"""',' ...: 123"""'),
183 ],
184 ],
35 185
36 def test_transform_escaped():
37 tt.check_pairs(wrap_transform(inputtransformer.escaped_transformer), esctransform_tests)
186 multiline_datastructure =
187 [ [('>>> a = [1,','a = [1,'),
188 ('... 2]','2]'),
189 ],
190 ],
191
192 leading_indent =
193 [ [(' print "hi"','print "hi"'),
194 (' for a in range(5):','for a in range(5):'),
195 (' a*2',' a*2'),
196 ],
197 [(' a="""','a="""'),
198 (' 123"""','123"""'),
199 ],
200 [('a="""','a="""'),
201 (' 123"""',' 123"""'),
202 ],
203 ],
204
205 cellmagic =
206 [ [('%%foo a', None),
207 (None, "get_ipython().run_cell_magic('foo', 'a', '')"),
208 ],
209 [('%%bar 123', None),
210 ('hello', None),
211 ('', "get_ipython().run_cell_magic('bar', '123', 'hello')"),
212 ],
213 ],
214
215 escaped =
216 [ [('%abc def \\', None),
217 ('ghi', u_fmt("get_ipython().magic({u}'abc def ghi')")),
218 ],
219 [('%abc def \\', None),
220 ('ghi\\', None),
221 (None, u_fmt("get_ipython().magic({u}'abc def ghi')")),
222 ],
223 ],
224
225 assign_magic =
226 [ [('a = %bc de \\', None),
227 ('fg', "a = get_ipython().magic('bc de fg')"),
228 ],
229 [('a = %bc de \\', None),
230 ('fg\\', None),
231 (None, "a = get_ipython().magic('bc de fg')"),
232 ],
233 ],
234
235 assign_system =
236 [ [('a = !bc de \\', None),
237 ('fg', "a = get_ipython().getoutput('bc de fg')"),
238 ],
239 [('a = !bc de \\', None),
240 ('fg\\', None),
241 (None, "a = get_ipython().getoutput('bc de fg')"),
242 ],
243 ],
244 )
38 245
39 def endhelp_test():
40 tt.check_pairs(inputtransformer.help_end.push, syntax['end_help'])
41 246
42 classic_prompt_tests = [
43 (['>>> a=1'], ['a=1']),
44 (['>>> a="""','... 123"""'], ['a="""', '123"""']),
45 (['a="""','... 123"""'], ['a="""', '... 123"""']),
46 ]
247 def test_assign_system():
248 tt.check_pairs(transform_and_reset(ipt.assign_from_system), syntax['assign_system'])
249 for example in syntax_ml['assign_system']:
250 transform_checker(example, ipt.assign_from_system)
251
252 def test_assign_magic():
253 tt.check_pairs(transform_and_reset(ipt.assign_from_magic), syntax['assign_magic'])
254 for example in syntax_ml['assign_magic']:
255 transform_checker(example, ipt.assign_from_magic)
256
47 257
48 258 def test_classic_prompt():
49 tt.check_pairs(wrap_transform(inputtransformer.classic_prompt), classic_prompt_tests)
259 tt.check_pairs(transform_and_reset(ipt.classic_prompt), syntax['classic_prompt'])
260 for example in syntax_ml['classic_prompt']:
261 transform_checker(example, ipt.classic_prompt)
50 262
51 ipy_prompt_tests = [
52 (['In [1]: a=1'], ['a=1']),
53 (['In [2]: a="""',' ...: 123"""'], ['a="""', '123"""']),
54 (['a="""',' ...: 123"""'], ['a="""', ' ...: 123"""']),
55 ]
56 263
57 264 def test_ipy_prompt():
58 tt.check_pairs(wrap_transform(inputtransformer.ipy_prompt), ipy_prompt_tests)
265 tt.check_pairs(transform_and_reset(ipt.ipy_prompt), syntax['ipy_prompt'])
266 for example in syntax_ml['ipy_prompt']:
267 transform_checker(example, ipt.ipy_prompt)
59 268
60 leading_indent_tests = [
61 ([' print "hi"'], ['print "hi"']),
62 ([' for a in range(5):', ' a*2'], ['for a in range(5):', ' a*2']),
63 ([' a="""',' 123"""'], ['a="""', '123"""']),
64 (['a="""',' 123"""'], ['a="""', ' 123"""']),
65 ]
269 def test_help_end():
270 tt.check_pairs(transform_and_reset(ipt.help_end), syntax['end_help'])
66 271
67 def test_leading_indent():
68 tt.check_pairs(wrap_transform(inputtransformer.leading_indent), leading_indent_tests)
272 def test_escaped_noesc():
273 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_noesc'])
69 274
70 assign_magic_tests = [(i, [py3compat.u_format(ol) for ol in o]) for i,o in [
71 (['a = %bc de \\', 'fg'], ["a = get_ipython().magic('bc de fg')"]),
72 (['a = %bc de \\', 'fg\\', None], ["a = get_ipython().magic('bc de fg')"]),
73 ]]
74 275
75 def test_assign_magic():
76 tt.check_pairs(wrap_transform(inputtransformer.assign_from_magic), assign_magic_tests)
276 def test_escaped_shell():
277 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_shell'])
77 278
78 assign_system_tests = [(i, [py3compat.u_format(ol) for ol in o]) for i,o in [
79 (['a = !bc de \\', 'fg'], ["a = get_ipython().getoutput('bc de fg')"]),
80 (['a = !bc de \\', 'fg\\', None], ["a = get_ipython().getoutput('bc de fg')"]),
81 ]]
82 279
83 def test_assign_system():
84 tt.check_pairs(wrap_transform(inputtransformer.assign_from_system), assign_system_tests)
280 def test_escaped_help():
281 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_help'])
282
283
284 def test_escaped_magic():
285 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_magic'])
286
287
288 def test_escaped_quote():
289 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_quote'])
290
291
292 def test_escaped_quote2():
293 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_quote2'])
294
295
296 def test_escaped_paren():
297 tt.check_pairs(transform_and_reset(ipt.escaped_transformer), syntax['escaped_paren'])
298
299 def test_escaped_multiline():
300 for example in syntax_ml['escaped']:
301 transform_checker(example, ipt.escaped_transformer)
302
303 def test_cellmagic():
304 for example in syntax_ml['cellmagic']:
305 transform_checker(example, ipt.cellmagic)
General Comments 0
You need to be logged in to leave comments. Login now