]> git.madduck.net Git - etc/vim.git/blob - spec/indent/indent_spec.rb

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

db66b8f0a877bdc20847f1b2f642b08238a371d8
[etc/vim.git] / spec / indent / indent_spec.rb
1 require "spec_helper"
2
3 shared_examples_for "vim" do
4   before(:each) {
5     # clear buffer
6     vim.normal 'gg"_dG'
7
8     # Insert two blank lines.
9     # The first line is a corner case in this plugin that would shadow the
10     # correct behaviour of other tests. Thus we explicitly jump to the first
11     # line when we require so.
12     vim.feedkeys 'i\<CR>\<CR>\<ESC>'
13   }
14
15   describe "when using the indent plugin" do
16     it "sets the indentexpr and indentkeys options" do
17       vim.command("set indentexpr?").should include "GetPythonPEPIndent("
18       vim.command("set indentkeys?").should include "=elif"
19     end
20
21     it "sets autoindent and expandtab" do
22       vim.command("set autoindent?").should match(/\s*autoindent/)
23       vim.command("set expandtab?").should match(/\s*expandtab/)
24     end
25   end
26
27   describe "when entering the first line" do
28     before { vim.feedkeys '0ggipass' }
29
30     it "does not indent" do
31       indent.should == 0
32       proposed_indent.should == 0
33     end
34
35     it "does not indent when using '=='" do
36       vim.normal "=="
37       indent.should == 0
38     end
39   end
40
41   describe "when after a '(' that is at the end of its line" do
42     before { vim.feedkeys 'itest(\<CR>' }
43
44     it "indents by one level" do
45       proposed_indent.should == shiftwidth
46       vim.feedkeys 'something'
47       indent.should == shiftwidth
48       vim.normal '=='
49       indent.should == shiftwidth
50     end
51
52     it "puts the closing parenthesis at the same level" do
53       vim.feedkeys ')'
54       indent.should == (hang_closing ? shiftwidth : 0)
55     end
56   end
57
58   describe "when after an '(' that is followed by something" do
59     before { vim.feedkeys 'itest(something,\<CR>' }
60
61     it "lines up on following lines" do
62       indent.should == 5
63       vim.feedkeys 'more,\<CR>'
64       indent.should == 5
65     end
66
67     it "lines up the closing parenthesis" do
68       vim.feedkeys ')'
69       indent.should == 5
70     end
71
72     it "does not touch the closing parenthesis if it is already indented further" do
73       vim.feedkeys '  )'
74       indent.should == 7
75     end
76   end
77
78   describe "when after an '{' that is followed by a comment" do
79     before { vim.feedkeys 'imydict = {  # comment\<CR>' }
80
81     it "indent by one level" do
82       indent.should == shiftwidth
83       vim.feedkeys '1: 1,\<CR>'
84       indent.should == shiftwidth
85     end
86
87     it "lines up the closing parenthesis" do
88       vim.feedkeys '}'
89       indent.should == (hang_closing ? shiftwidth : 0)
90     end
91   end
92
93   describe "when using gq to reindent a '(' that is" do
94     before { vim.feedkeys 'itest(' }
95     it "something and has a string without spaces at the end" do
96       vim.feedkeys 'something_very_long_blaaaaaaaaa, "some_very_long_string_blaaaaaaaaaaaaaaaaaaaa"\<esc>gqq'
97       indent.should == 5
98     end
99   end
100
101   describe "when after multiple parens of different types" do
102     it "indents by one level" do
103       vim.feedkeys 'if({\<CR>'
104       indent.should == shiftwidth
105     end
106
107     it "lines up with the last paren" do
108       vim.feedkeys 'ifff({123: 456,\<CR>'
109       indent.should == 5
110     end
111   end
112
113   describe "when '#' is contained in a string that is followed by a colon" do
114     it "indents by one level" do
115         vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
116         indent.should == shiftwidth
117     end
118   end
119
120   describe "when '#' is not contained in a string and is followed by a colon" do
121     it "does not indent" do
122         vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
123         indent.should == 0
124     end
125   end
126
127   describe "when inside an unfinished string" do
128     it "does not indent" do
129       vim.feedkeys 'i"test:\<ESC>'
130       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
131               ).downcase.should include 'string'
132       vim.feedkeys 'a\<CR>'
133       proposed_indent.should == -1
134       indent.should == 0
135     end
136
137     it "does not dedent" do
138       vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
139       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
140               ).downcase.should include 'string'
141       proposed_indent.should == shiftwidth
142       indent.should == shiftwidth
143     end
144   end
145
146   describe "when the previous line has a colon in a string" do
147     before { vim.feedkeys 'itest(":".join(["1","2"]))\<CR>' }
148     it "does not indent" do
149       vim.feedkeys 'if True:'
150       indent.should == 0
151       proposed_indent.should == 0
152     end
153   end
154
155   describe "when the previous line has a list slice" do
156     it "does not indent" do
157       vim.feedkeys 'ib = a[2:]\<CR>'
158       indent.should == 0
159       proposed_indent.should == 0
160     end
161   end
162
163   describe "when line is empty inside a block" do
164     it "is indented like the previous line" do
165       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>2\<ESC>kcc'
166       indent.should == shiftwidth
167     end
168   end
169
170   describe "when an empty line is after empty line / before non-empty" do
171     it "is indented like the next line" do
172       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>2\<ESC><<kcc'
173       indent.should == 0
174     end
175   end
176
177   describe "when an empty line is after empty line / before non-empty (nested)" do
178     it "is indented like the next line" do
179       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>\<ESC>0i\<TAB>2\<ESC>kcc'
180       indent.should == shiftwidth
181     end
182   end
183
184   describe "when line is empty inside a block following multi-line statement" do
185     it "is indented like the previous line" do
186       vim.feedkeys 'idef a():\<CR>x = (1 +\<CR>2)\<CR>\<CR>y\<ESC>kcc'
187       indent.should == shiftwidth
188     end
189   end
190
191   describe "when line is empty inside a block following stop statement" do
192     it "is indented like the previous line minus shiftwidth" do
193       vim.feedkeys 'iif x:\<CR>if y:\<CR>pass\<CR>\<CR>z\<ESC>kcc'
194       indent.should == shiftwidth
195     end
196   end
197
198   describe "when using simple control structures" do
199       it "indents shiftwidth spaces" do
200           vim.feedkeys 'iwhile True:\<CR>pass'
201           indent.should == shiftwidth
202       end
203   end
204
205   describe "when using a function definition" do
206       it "indents shiftwidth spaces" do
207           vim.feedkeys 'idef long_function_name(\<CR>arg'
208           indent.should == shiftwidth * 2
209       end
210   end
211
212   describe "when using a class definition" do
213       it "indents shiftwidth spaces" do
214           vim.feedkeys 'iclass Foo(\<CR>'
215           indent.should == shiftwidth * 2
216       end
217   end
218
219   describe "when writing an 'else' block" do
220     it "aligns to the preceeding 'for' block" do
221       vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
222       indent.should == 0
223     end
224
225     it "aligns to the preceeding 'if' block" do
226       vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
227       indent.should == shiftwidth
228     end
229   end
230
231   describe "when using parens and control statements" do
232     it "avoids ambiguity by using extra indentation" do
233       vim.feedkeys 'iif (111 and\<CR>'
234       if shiftwidth == 4
235         indent.should == shiftwidth * 2
236       else
237         indent.should == 4
238       end
239       vim.feedkeys '222):\<CR>'
240       indent.should == shiftwidth
241       vim.feedkeys 'pass\<CR>'
242       indent.should == 0
243     end
244
245     it "still aligns parens properly if not ambiguous" do
246       vim.feedkeys 'iwhile (111 and\<CR>'
247       indent.should == 7
248       vim.feedkeys '222):\<CR>'
249       indent.should == shiftwidth
250       vim.feedkeys 'pass\<CR>'
251       indent.should == 0
252     end
253
254     it "handles nested expressions (Flake8's E127)" do
255       vim.feedkeys 'i[\<CR>x for x in foo\<CR>if (\<CR>'
256       indent.should == shiftwidth * 2
257     end
258
259     it "still handles multiple parens correctly" do
260       vim.feedkeys 'iif (111 and (222 and 333\<CR>'
261       indent.should == 13
262       vim.feedkeys 'and 444\<CR>'
263       indent.should == 13
264       vim.feedkeys ')\<CR>'
265       if shiftwidth == 4
266         indent.should == shiftwidth * 2
267       else
268         indent.should == 4
269       end
270       vim.feedkeys 'and 555):\<CR>'
271       indent.should == shiftwidth
272       vim.feedkeys 'pass\<CR>'
273       indent.should == 0
274     end
275   end
276
277   describe "when a line breaks with a manual '\\'" do
278     it "indents shiftwidth spaces on normal line" do
279         vim.feedkeys 'ivalue = test + \\\\\<CR>'
280         indent.should == shiftwidth
281     end
282
283     it "indents 2x shiftwidth spaces for control structures" do
284         vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
285         indent.should == shiftwidth * 2
286     end
287
288     it "indents relative to line above" do
289         vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
290         indent.should == shiftwidth * 2
291     end
292   end
293
294   describe "when current line is dedented compared to previous line" do
295      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
296      it "and current line has a valid indentation (Part 1)" do
297         vim.feedkeys '0i\<TAB>if y:'
298         proposed_indent.should == -1
299      end
300
301      it "and current line has a valid indentation (Part 2)" do
302         vim.feedkeys '0i\<TAB>\<TAB>if y:'
303         proposed_indent.should == -1
304      end
305
306      it "and current line has an invalid indentation" do
307         vim.feedkeys 'i    while True:\<CR>'
308         indent.should == previous_indent + shiftwidth
309      end
310   end
311
312   describe "when current line is dedented compared to the last non-empty line" do
313      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
314      it "and current line has a valid indentation" do
315         vim.feedkeys '0i\<TAB>if y:'
316         proposed_indent.should == -1
317      end
318   end
319
320   describe "when an 'if' is followed by" do
321      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
322      it "an elif, it lines up with the 'if'" do
323         vim.feedkeys 'elif y:'
324         indent.should == shiftwidth * 2
325      end
326
327      it "an 'else', it lines up with the 'if'" do
328         vim.feedkeys 'else:'
329         indent.should == shiftwidth * 2
330      end
331   end
332
333   describe "when an 'if' contains a try-except" do
334      before {
335        vim.feedkeys 'iif x:\<CR>try:\<CR>pass\<CR>except:\<CR>pass\<CR>'
336        indent.should == shiftwidth
337      }
338      it "an 'else' should be indented to the try" do
339        vim.feedkeys 'else:'
340        indent.should == shiftwidth
341        proposed_indent.should == shiftwidth
342      end
343      it "an 'else' should keep the indent of the 'if'" do
344        vim.feedkeys 'else:\<ESC><<'
345        indent.should == 0
346        proposed_indent.should == 0
347      end
348   end
349
350   describe "when a 'for' is followed by" do
351      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
352      it "an 'else', it lines up with the 'for'" do
353         vim.feedkeys 'else:'
354         indent.should == shiftwidth * 2
355      end
356   end
357
358   describe "when an 'else' is followed by" do
359      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
360      it "a 'finally', it lines up with the 'else'" do
361         vim.feedkeys 'finally:'
362         indent.should == shiftwidth * 2
363      end
364   end
365
366
367   describe "when a 'try' is followed by" do
368      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
369      it "an 'except', it lines up with the 'try'" do
370         vim.feedkeys 'except:'
371         indent.should == shiftwidth * 2
372      end
373
374      it "an 'else', it lines up with the 'try'" do
375         vim.feedkeys 'else:'
376         indent.should == shiftwidth * 2
377      end
378
379      it "a 'finally', it lines up with the 'try'" do
380         vim.feedkeys 'finally:'
381         indent.should == shiftwidth * 2
382      end
383   end
384
385   describe "when an 'except' is followed by" do
386      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
387      it "an 'else', it lines up with the 'except'" do
388         vim.feedkeys 'else:'
389         indent.should == shiftwidth * 2
390      end
391
392      it "another 'except', it lines up with the previous 'except'" do
393         vim.feedkeys 'except:'
394         indent.should == shiftwidth * 2
395      end
396
397      it "a 'finally', it lines up with the 'except'" do
398         vim.feedkeys 'finally:'
399         indent.should == shiftwidth * 2
400      end
401   end
402
403   describe "when an else is used inside of a nested if" do
404     before { vim.feedkeys 'iif foo:\<CR>if bar:\<CR>pass\<CR>' }
405     it "indents the else to the inner if" do
406       vim.feedkeys 'else:'
407       indent.should == shiftwidth
408     end
409   end
410
411   describe "when an else is used outside of a nested if" do
412     before { vim.feedkeys 'iif True:\<CR>if True:\<CR>pass\<CR>\<Esc>0' }
413     it "indents the else to the outer if" do
414       indent.should == 0
415       proposed_indent.should == shiftwidth
416
417       vim.feedkeys 'ielse:'
418       indent.should == 0
419       proposed_indent.should == 0
420     end
421   end
422
423   describe "when jedi-vim call signatures are used" do
424     before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
425
426     it "ignores the call signature after a colon" do
427       vim.feedkeys 'iif True:  JEDI_CALL_SIGNATURE\<CR>'
428       indent.should == shiftwidth
429     end
430
431     it "ignores the call signature after a function" do
432       vim.feedkeys 'idef f(  JEDI_CALL_SIGNATURE\<CR>'
433       indent.should == shiftwidth * 2
434     end
435   end
436 end
437
438 shared_examples_for "multiline strings" do
439   before(:each) {
440     # clear buffer
441     vim.normal 'gg"_dG'
442
443     # Insert two blank lines.
444     # The first line is a corner case in this plugin that would shadow the
445     # correct behaviour of other tests. Thus we explicitly jump to the first
446     # line when we require so.
447     vim.feedkeys 'i\<CR>\<CR>\<ESC>'
448   }
449
450   describe "when after an '(' that is followed by an unfinished string" do
451     before { vim.feedkeys 'itest("""' }
452
453     it "it indents the next line" do
454       vim.feedkeys '\<CR>'
455       expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
456       proposed_indent.should == expected_proposed
457       indent.should == expected_indent
458     end
459
460     it "with contents it indents the second line to the parenthesis" do
461       vim.feedkeys 'second line\<CR>'
462       expected_proposed, expected_indent = multiline_indent(0, 5)
463       proposed_indent.should == expected_proposed
464       indent.should == expected_indent
465     end
466   end
467
468   describe "when after assigning an unfinished string" do
469     before { vim.feedkeys 'itest = """' }
470
471     it "it indents the next line" do
472       vim.feedkeys '\<CR>'
473       expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
474       proposed_indent.should == expected_proposed
475       indent.should == expected_indent
476     end
477   end
478
479   describe "when after assigning an indented unfinished string" do
480     before { vim.feedkeys 'i    test = """' }
481
482     it "it indents the next line" do
483       vim.feedkeys '\<CR>'
484       expected_proposed, expected_indent = multiline_indent(4, shiftwidth + 4)
485       proposed_indent.should == expected_proposed
486       indent.should == expected_indent
487     end
488   end
489
490   describe "when after assigning an indented finished string" do
491     before { vim.feedkeys 'i    test = ""' }
492
493     it "it does indent the next line" do
494       vim.feedkeys '\<CR>'
495       indent.should == 4
496     end
497
498     it "and writing a new string, it does indent the next line" do
499       vim.feedkeys '\<CR>""'
500       indent.should == 4
501     end
502   end
503
504   describe "when after a docstring" do
505     it "it does indent the next line to the docstring" do
506       vim.feedkeys 'i    """\<CR>'
507       indent.should == 4
508       proposed_indent.should == 4
509     end
510
511     it "indents the closing docstring quotes" do
512       vim.feedkeys 'i    """\<CR>\<CR>"""'
513       indent.should == 4
514       proposed_indent.should == 4
515       vim.echo('getline(3)').should == '    """'
516     end
517
518     it "indents non-matching docstring quotes" do
519       vim.feedkeys 'i    """\<CR>\<Esc>'
520       vim.feedkeys "0C'''"
521       vim.echo('line(".")').should == "4"
522       vim.echo('getline(".")').should == "'''"
523       indent.should == 0
524       proposed_indent.should == -1
525     end
526   end
527
528   describe "when after a docstring with contents" do
529     before { vim.feedkeys 'i    """First line' }
530     it "it does indent the next line to the docstring" do
531       vim.feedkeys '\<CR>'
532       indent.should == 4
533       proposed_indent.should == 4
534     end
535   end
536
537   describe "when breaking a string after opening parenthesis" do
538     before { vim.feedkeys 'i    foo("""bar\<Left>\<Left>\<Left>' }
539     it "it does indent the next line as after an opening multistring" do
540       vim.feedkeys '\<CR>'
541       _, expected_indent = multiline_indent(4, 4 + shiftwidth)
542       indent.should == expected_indent
543       proposed_indent.should == -1
544
545       # it keeps the indent after an empty line
546       vim.feedkeys '\<CR>'
547       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
548       indent.should == expected_indent
549       proposed_indent.should == proposed_indent
550
551       # it keeps the indent of nonblank above
552       vim.feedkeys '\<End>\<CR>'
553       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
554       indent.should == expected_indent
555       proposed_indent.should == proposed_indent
556
557       # it keeps the indent of nonblank above before an empty line
558       vim.feedkeys '\<CR>'
559       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
560       indent.should == expected_indent
561       proposed_indent.should == proposed_indent
562     end
563   end
564 end
565
566 SUITE_SHIFTWIDTHS = [4, 3]
567 SUITE_HANG_CLOSINGS = [false, true]
568
569 SUITE_SHIFTWIDTHS.each do |sw|
570   describe "vim when using width of #{sw}" do
571     before {
572       vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et")
573     }
574     it "sets shiftwidth to #{sw}" do
575       shiftwidth.should == sw
576     end
577
578     SUITE_HANG_CLOSINGS.each do |hc|
579       describe "vim when hang_closing is set to #{hc}" do
580         before {
581           set_hang_closing hc
582         }
583         it "sets hang_closing to #{hc}" do
584           hang_closing.should == !!hc
585         end
586
587         it_behaves_like "vim"
588       end
589     end
590   end
591 end
592
593 describe "vim when not using python_pep8_indent_multiline_string" do
594   before {
595     vim.command("set sw=4 ts=4 sts=4 et")
596     vim.command("unlet! g:python_pep8_indent_multiline_string")
597   }
598   it_behaves_like "multiline strings"
599 end
600
601 describe "vim when using python_pep8_indent_multiline_first=0" do
602   before {
603     vim.command("set sw=4 ts=4 sts=4 et")
604     vim.command("let g:python_pep8_indent_multiline_string=0")
605   }
606   it_behaves_like "multiline strings"
607 end
608
609 describe "vim when using python_pep8_indent_multiline_string=-1" do
610   before {
611     vim.command("set sw=4 ts=4 sts=4 et")
612     vim.command("let g:python_pep8_indent_multiline_string=-1")
613   }
614   it_behaves_like "multiline strings"
615 end
616
617 describe "vim when using python_pep8_indent_multiline_string=-2" do
618   before {
619     vim.command("set sw=4 ts=4 sts=4 et")
620     vim.command("let g:python_pep8_indent_multiline_string=-2")
621   }
622   it_behaves_like "multiline strings"
623 end
624
625 describe "Handles far away opening parens" do
626   before { vim.feedkeys '\<ESC>ggdGifrom foo import (' }
627
628   it "indents by one level" do
629     vim.feedkeys '\<CR>'
630     proposed_indent.should == shiftwidth
631   end
632
633   it "indents by one level for 10 lines" do
634     vim.command('set paste | exe "norm 9o" | set nopaste')
635     vim.feedkeys '\<Esc>o'
636     indent.should == shiftwidth
637   end
638
639   it "indents by one level for 50 lines" do
640     vim.command('set paste | exe "norm 49o" | set nopaste')
641     vim.feedkeys '\<Esc>o'
642     indent.should == shiftwidth
643   end
644 end
645
646 describe "Handles far away opening square brackets" do
647   before { vim.feedkeys '\<ESC>ggdGibar = [' }
648
649   it "indents by one level" do
650     vim.feedkeys '\<CR>'
651     proposed_indent.should == shiftwidth
652   end
653
654   it "indents by one level for 10 lines" do
655     vim.command('set paste | exe "norm 9o" | set nopaste')
656     vim.feedkeys '\<Esc>o'
657     indent.should == shiftwidth
658   end
659
660   it "indents by one level for 100 lines" do
661     vim.command('set paste | exe "norm 99o" | set nopaste')
662     vim.feedkeys '\<Esc>o'
663     indent.should == shiftwidth
664   end
665 end
666
667 describe "Handles far away opening curly brackets" do
668   before { vim.feedkeys '\<ESC>ggdGijson = {' }
669
670   it "indents by one level" do
671     vim.feedkeys '\<CR>'
672     vim.feedkeys '\<Esc>o'
673     proposed_indent.should == shiftwidth
674   end
675
676   it "indents by one level for 10 lines" do
677     vim.command('set paste | exe "norm 9o" | set nopaste')
678     vim.feedkeys '\<Esc>o'
679     indent.should == shiftwidth
680   end
681
682   it "indents by one level for 1000 lines" do
683     vim.command('set paste | exe "norm 999o" | set nopaste')
684     vim.feedkeys '\<Esc>o'
685     indent.should == shiftwidth
686   end
687 end
688
689 describe "Compact multiline dict" do
690   before { vim.feedkeys '\<ESC>ggdGid = {"one": 1,' }
691
692   it "gets indented correctly" do
693     vim.feedkeys '\<CR>'
694     proposed_indent.should == 5
695
696     vim.feedkeys '"two": 2}'
697     proposed_indent.should == 5
698
699     vim.feedkeys '\<CR>'
700     proposed_indent.should == 0
701   end
702 end
703
704 describe "Using O" do
705   before {
706     vim.feedkeys '\<ESC>ggdG'
707     vim.feedkeys 'iif foo:\<CR>'
708   }
709
710   it "respects autoindent" do
711     vim.feedkeys '1\<CR>\<CR>'
712     indent.should == shiftwidth
713     vim.feedkeys '\<Esc>ko'
714     indent.should == shiftwidth
715     vim.feedkeys '\<Esc>kO'
716     indent.should == shiftwidth
717     # Uses/keeps indent from line above
718     vim.feedkeys '\<Esc>i2\<Esc>O'
719     indent.should == shiftwidth
720     # Uses/keeps indent from line above
721     vim.feedkeys '\<Esc>j\<Esc>O'
722     indent.should == 0
723   end
724 end
725
726 describe "searchpairpos" do
727   before { vim.feedkeys '\<ESC>ggdG' }
728   it "handles nested parenthesis" do
729     vim.feedkeys 'iif foo.startswith("("):\<CR>'
730     indent.should == shiftwidth
731   end
732 end
733
734 describe "o within TODO" do
735   before {
736     vim.feedkeys '\<ESC>ggdG'
737     vim.feedkeys 'iif 1:  # TODO\<Esc>'
738     # Assertion that we have a pythonTodo here.
739     vim.echo('synIDattr(synID(line("."), col("."), 0), "name")').should match 'pythonTodo'
740   }
741
742   it "respects autoindent" do
743     vim.feedkeys 'o'
744     indent.should == shiftwidth
745   end
746 end