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