5
5
from unittest import TestCase
6
6
from unittest .mock import patch
7
7
8
- from .support import FakeConsole , handle_all_events , handle_events_narrow_console
9
- from .support import more_lines , multiline_input , code_to_events
8
+ from .support import (
9
+ FakeConsole ,
10
+ handle_all_events ,
11
+ handle_events_narrow_console ,
12
+ more_lines ,
13
+ multiline_input ,
14
+ code_to_events ,
15
+ )
10
16
from _pyrepl .console import Event
11
17
from _pyrepl .readline import ReadlineAlikeReader , ReadlineConfig
12
18
from _pyrepl .readline import multiline_input as readline_multiline_input
13
19
14
20
15
21
class TestCursorPosition (TestCase ):
22
+ def prepare_reader (self , events ):
23
+ console = FakeConsole (events )
24
+ config = ReadlineConfig (readline_completer = None )
25
+ reader = ReadlineAlikeReader (console = console , config = config )
26
+ return reader
27
+
16
28
def test_up_arrow_simple (self ):
17
29
# fmt: off
18
30
code = (
19
- ' def f():\n '
20
- ' ...\n '
31
+ " def f():\n "
32
+ " ...\n "
21
33
)
22
34
# fmt: on
23
35
events = itertools .chain (
@@ -34,8 +46,8 @@ def test_up_arrow_simple(self):
34
46
def test_down_arrow_end_of_input (self ):
35
47
# fmt: off
36
48
code = (
37
- ' def f():\n '
38
- ' ...\n '
49
+ " def f():\n "
50
+ " ...\n "
39
51
)
40
52
# fmt: on
41
53
events = itertools .chain (
@@ -300,6 +312,79 @@ def test_cursor_position_after_wrap_and_move_up(self):
300
312
self .assertEqual (reader .pos , 10 )
301
313
self .assertEqual (reader .cxy , (1 , 1 ))
302
314
315
+ def test_auto_indent_default (self ):
316
+ # fmt: off
317
+ input_code = (
318
+ "def f():\n "
319
+ "pass\n \n "
320
+ )
321
+
322
+ output_code = (
323
+ "def f():\n "
324
+ " pass\n "
325
+ " "
326
+ )
327
+ # fmt: on
328
+
329
+ def test_auto_indent_continuation (self ):
330
+ # auto indenting according to previous user indentation
331
+ # fmt: off
332
+ events = itertools .chain (
333
+ code_to_events ("def f():\n " ),
334
+ # add backspace to delete default auto-indent
335
+ [
336
+ Event (evt = "key" , data = "backspace" , raw = bytearray (b"\x7f " )),
337
+ ],
338
+ code_to_events (
339
+ " pass\n "
340
+ "pass\n \n "
341
+ ),
342
+ )
343
+
344
+ output_code = (
345
+ "def f():\n "
346
+ " pass\n "
347
+ " pass\n "
348
+ " "
349
+ )
350
+ # fmt: on
351
+
352
+ reader = self .prepare_reader (events )
353
+ output = multiline_input (reader )
354
+ self .assertEqual (output , output_code )
355
+
356
+ def test_auto_indent_prev_block (self ):
357
+ # auto indenting according to indentation in different block
358
+ # fmt: off
359
+ events = itertools .chain (
360
+ code_to_events ("def f():\n " ),
361
+ # add backspace to delete default auto-indent
362
+ [
363
+ Event (evt = "key" , data = "backspace" , raw = bytearray (b"\x7f " )),
364
+ ],
365
+ code_to_events (
366
+ " pass\n "
367
+ "pass\n \n "
368
+ ),
369
+ code_to_events (
370
+ "def g():\n "
371
+ "pass\n \n "
372
+ ),
373
+ )
374
+
375
+
376
+ output_code = (
377
+ "def g():\n "
378
+ " pass\n "
379
+ " "
380
+ )
381
+ # fmt: on
382
+
383
+ reader = self .prepare_reader (events )
384
+ output1 = multiline_input (reader )
385
+ output2 = multiline_input (reader )
386
+ self .assertEqual (output2 , output_code )
387
+
303
388
304
389
class TestPyReplOutput (TestCase ):
305
390
def prepare_reader (self , events ):
@@ -316,14 +401,12 @@ def test_basic(self):
316
401
317
402
def test_multiline_edit (self ):
318
403
events = itertools .chain (
319
- code_to_events ("def f():\n ...\n \n " ),
404
+ code_to_events ("def f():\n ...\n \n " ),
320
405
[
321
406
Event (evt = "key" , data = "up" , raw = bytearray (b"\x1b OA" )),
322
407
Event (evt = "key" , data = "up" , raw = bytearray (b"\x1b OA" )),
323
408
Event (evt = "key" , data = "up" , raw = bytearray (b"\x1b OA" )),
324
409
Event (evt = "key" , data = "right" , raw = bytearray (b"\x1b OC" )),
325
- Event (evt = "key" , data = "right" , raw = bytearray (b"\x1b OC" )),
326
- Event (evt = "key" , data = "right" , raw = bytearray (b"\x1b OC" )),
327
410
Event (evt = "key" , data = "backspace" , raw = bytearray (b"\x7f " )),
328
411
Event (evt = "key" , data = "g" , raw = bytearray (b"g" )),
329
412
Event (evt = "key" , data = "down" , raw = bytearray (b"\x1b OB" )),
@@ -334,9 +417,9 @@ def test_multiline_edit(self):
334
417
reader = self .prepare_reader (events )
335
418
336
419
output = multiline_input (reader )
337
- self .assertEqual (output , "def f():\n ...\n " )
420
+ self .assertEqual (output , "def f():\n ...\n " )
338
421
output = multiline_input (reader )
339
- self .assertEqual (output , "def g():\n ...\n " )
422
+ self .assertEqual (output , "def g():\n ...\n " )
340
423
341
424
def test_history_navigation_with_up_arrow (self ):
342
425
events = itertools .chain (
@@ -485,6 +568,7 @@ class Dummy:
485
568
@property
486
569
def test_func (self ):
487
570
import warnings
571
+
488
572
warnings .warn ("warnings\n " )
489
573
return None
490
574
@@ -508,12 +592,12 @@ def prepare_reader(self, events):
508
592
def test_paste (self ):
509
593
# fmt: off
510
594
code = (
511
- ' def a():\n '
512
- ' for x in range(10):\n '
513
- ' if x%2:\n '
514
- ' print(x)\n '
515
- ' else:\n '
516
- ' pass\n '
595
+ " def a():\n "
596
+ " for x in range(10):\n "
597
+ " if x%2:\n "
598
+ " print(x)\n "
599
+ " else:\n "
600
+ " pass\n "
517
601
)
518
602
# fmt: on
519
603
@@ -534,10 +618,10 @@ def test_paste(self):
534
618
def test_paste_mid_newlines (self ):
535
619
# fmt: off
536
620
code = (
537
- ' def f():\n '
538
- ' x = y\n '
539
- ' \n '
540
- ' y = z\n '
621
+ " def f():\n "
622
+ " x = y\n "
623
+ " \n "
624
+ " y = z\n "
541
625
)
542
626
# fmt: on
543
627
@@ -558,16 +642,16 @@ def test_paste_mid_newlines(self):
558
642
def test_paste_mid_newlines_not_in_paste_mode (self ):
559
643
# fmt: off
560
644
code = (
561
- ' def f():\n '
562
- ' x = y\n '
563
- ' \n '
564
- ' y = z\n \n '
645
+ " def f():\n "
646
+ " x = y\n "
647
+ " \n "
648
+ " y = z\n \n "
565
649
)
566
650
567
651
expected = (
568
- ' def f():\n '
569
- ' x = y\n '
570
- ' '
652
+ " def f():\n "
653
+ " x = y\n "
654
+ " "
571
655
)
572
656
# fmt: on
573
657
@@ -579,20 +663,20 @@ def test_paste_mid_newlines_not_in_paste_mode(self):
579
663
def test_paste_not_in_paste_mode (self ):
580
664
# fmt: off
581
665
input_code = (
582
- ' def a():\n '
583
- ' for x in range(10):\n '
584
- ' if x%2:\n '
585
- ' print(x)\n '
586
- ' else:\n '
587
- ' pass\n \n '
666
+ " def a():\n "
667
+ " for x in range(10):\n "
668
+ " if x%2:\n "
669
+ " print(x)\n "
670
+ " else:\n "
671
+ " pass\n \n "
588
672
)
589
673
590
674
output_code = (
591
- ' def a():\n '
592
- ' for x in range(10):\n '
593
- ' if x%2:\n '
594
- ' print(x)\n '
595
- ' else:'
675
+ " def a():\n "
676
+ " for x in range(10):\n "
677
+ " if x%2:\n "
678
+ " print(x)\n "
679
+ " else:"
596
680
)
597
681
# fmt: on
598
682
@@ -605,25 +689,25 @@ def test_bracketed_paste(self):
605
689
"""Test that bracketed paste using \x1b [200~ and \x1b [201~ works."""
606
690
# fmt: off
607
691
input_code = (
608
- ' def a():\n '
609
- ' for x in range(10):\n '
610
- ' \n '
611
- ' if x%2:\n '
612
- ' print(x)\n '
613
- ' \n '
614
- ' else:\n '
615
- ' pass\n '
692
+ " def a():\n "
693
+ " for x in range(10):\n "
694
+ " \n "
695
+ " if x%2:\n "
696
+ " print(x)\n "
697
+ " \n "
698
+ " else:\n "
699
+ " pass\n "
616
700
)
617
701
618
702
output_code = (
619
- ' def a():\n '
620
- ' for x in range(10):\n '
621
- ' \n '
622
- ' if x%2:\n '
623
- ' print(x)\n '
624
- ' \n '
625
- ' else:\n '
626
- ' pass\n '
703
+ " def a():\n "
704
+ " for x in range(10):\n "
705
+ " \n "
706
+ " if x%2:\n "
707
+ " print(x)\n "
708
+ " \n "
709
+ " else:\n "
710
+ " pass\n "
627
711
)
628
712
# fmt: on
629
713
0 commit comments