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