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