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