+
+ describe "when an 'if' contains a try-except" do
+ before {
+ vim.feedkeys 'iif x:\<CR>try:\<CR>pass\<CR>except:\<CR>pass\<CR>'
+ indent.should == shiftwidth
+ }
+ it "an 'else' should be indented to the try" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth
+ proposed_indent.should == shiftwidth
+ end
+ it "an 'else' should keep the indent of the 'if'" do
+ vim.feedkeys 'else:\<ESC><<'
+ indent.should == 0
+ proposed_indent.should == 0
+ end
+ end
+
+ describe "when a 'for' is followed by" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
+ it "an 'else', it lines up with the 'for'" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth * 2
+ end
+ end
+
+ describe "when an 'else' is followed by" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
+ it "a 'finally', it lines up with the 'else'" do
+ vim.feedkeys 'finally:'
+ indent.should == shiftwidth * 2
+ end
+ end
+
+
+ describe "when a 'try' is followed by" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
+ it "an 'except', it lines up with the 'try'" do
+ vim.feedkeys 'except:'
+ indent.should == shiftwidth * 2
+ end
+
+ it "an 'else', it lines up with the 'try'" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth * 2
+ end
+
+ it "a 'finally', it lines up with the 'try'" do
+ vim.feedkeys 'finally:'
+ indent.should == shiftwidth * 2
+ end
+ end
+
+ describe "when an 'except' is followed by" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
+ it "an 'else', it lines up with the 'except'" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth * 2
+ end
+
+ it "another 'except', it lines up with the previous 'except'" do
+ vim.feedkeys 'except:'
+ indent.should == shiftwidth * 2
+ end
+
+ it "a 'finally', it lines up with the 'except'" do
+ vim.feedkeys 'finally:'
+ indent.should == shiftwidth * 2
+ end
+ end
+
+ describe "when an else is used inside of a nested if" do
+ before { vim.feedkeys 'iif foo:\<CR>if bar:\<CR>pass\<CR>' }
+ it "indents the else to the inner if" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth
+ end
+ end
+
+ describe "when an else is used outside of a nested if" do
+ before { vim.feedkeys 'iif True:\<CR>if True:\<CR>pass\<CR>\<Esc>0' }
+ it "indents the else to the outer if" do
+ indent.should == 0
+ proposed_indent.should == shiftwidth
+
+ vim.feedkeys 'ielse:'
+ indent.should == 0
+ proposed_indent.should == 0
+ end
+ end
+
+ describe "when jedi-vim call signatures are used" do
+ before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
+
+ it "ignores the call signature after a colon" do
+ vim.feedkeys 'iif True: JEDI_CALL_SIGNATURE\<CR>'
+ indent.should == shiftwidth
+ end
+
+ it "ignores the call signature after a function" do
+ vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\<CR>'
+ indent.should == shiftwidth * 2
+ end
+ end
+end
+
+shared_examples_for "multiline strings" do
+ before(:each) {
+ # clear buffer
+ vim.normal 'gg"_dG'
+
+ # Insert two blank lines.
+ # The first line is a corner case in this plugin that would shadow the
+ # correct behaviour of other tests. Thus we explicitly jump to the first
+ # line when we require so.
+ vim.feedkeys 'i\<CR>\<CR>\<ESC>'
+ }
+
+ describe "when after an '(' that is followed by an unfinished string" do
+ before { vim.feedkeys 'itest("""' }
+
+ it "it indents the next line" do
+ vim.feedkeys '\<CR>'
+ expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
+ proposed_indent.should == expected_proposed
+ indent.should == expected_indent
+ end
+
+ it "with contents it indents the second line to the parenthesis" do
+ vim.feedkeys 'second line\<CR>'
+ expected_proposed, expected_indent = multiline_indent(0, 5)
+ proposed_indent.should == expected_proposed
+ indent.should == expected_indent
+ end
+ end
+
+ describe "when after assigning an unfinished string" do
+ before { vim.feedkeys 'itest = """' }
+
+ it "it indents the next line" do
+ vim.feedkeys '\<CR>'
+ expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
+ proposed_indent.should == expected_proposed
+ indent.should == expected_indent
+ end
+ end
+
+ describe "when after assigning an indented unfinished string" do
+ before { vim.feedkeys 'i test = """' }
+
+ it "it indents the next line" do
+ vim.feedkeys '\<CR>'
+ expected_proposed, expected_indent = multiline_indent(4, shiftwidth + 4)
+ proposed_indent.should == expected_proposed
+ indent.should == expected_indent
+ end
+ end
+
+ describe "when after assigning an indented finished string" do
+ before { vim.feedkeys 'i test = ""' }
+
+ it "it does indent the next line" do
+ vim.feedkeys '\<CR>'
+ indent.should == 4
+ end
+
+ it "and writing a new string, it does indent the next line" do
+ vim.feedkeys '\<CR>""'
+ indent.should == 4
+ end
+ end
+
+ describe "when after a docstring" do
+ it "it does indent the next line to the docstring" do
+ vim.feedkeys 'i """\<CR>'
+ indent.should == 4
+ proposed_indent.should == 4
+ end
+
+ it "indents the closing docstring quotes" do
+ vim.feedkeys 'i """\<CR>\<CR>"""'
+ indent.should == 4
+ proposed_indent.should == 4
+ vim.echo('getline(3)').should == ' """'
+ end
+
+ it "indents non-matching docstring quotes" do
+ vim.feedkeys 'i """\<CR>\<Esc>'
+ vim.feedkeys "0C'''"
+ vim.echo('line(".")').should == "4"
+ vim.echo('getline(".")').should == "'''"
+ indent.should == 0
+ proposed_indent.should == -1
+ end
+ end
+
+ describe "when after a docstring with contents" do
+ before { vim.feedkeys 'i """First line' }
+ it "it does indent the next line to the docstring" do
+ vim.feedkeys '\<CR>'
+ indent.should == 4
+ proposed_indent.should == 4
+ end
+ end
+
+ describe "when breaking a string after opening parenthesis" do
+ before { vim.feedkeys 'i foo("""bar\<Left>\<Left>\<Left>' }
+ it "it does indent the next line as after an opening multistring" do
+ vim.feedkeys '\<CR>'
+ _, expected_indent = multiline_indent(4, 4 + shiftwidth)
+ indent.should == expected_indent
+ proposed_indent.should == -1
+
+ # it keeps the indent after an empty line
+ vim.feedkeys '\<CR>'
+ proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
+ indent.should == expected_indent
+ proposed_indent.should == proposed_indent
+
+ # it keeps the indent of nonblank above
+ vim.feedkeys '\<End>\<CR>'
+ proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
+ indent.should == expected_indent
+ proposed_indent.should == proposed_indent
+
+ # it keeps the indent of nonblank above before an empty line
+ vim.feedkeys '\<CR>'
+ proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
+ indent.should == expected_indent
+ proposed_indent.should == proposed_indent
+ end
+ end
+end
+
+SUITE_SHIFTWIDTHS = [4, 3]
+SUITE_HANG_CLOSINGS = [false, true]
+
+SUITE_SHIFTWIDTHS.each do |sw|
+ describe "vim when using width of #{sw}" do
+ before {
+ vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et")
+ }
+ it "sets shiftwidth to #{sw}" do
+ shiftwidth.should == sw
+ end
+
+ SUITE_HANG_CLOSINGS.each do |hc|
+ describe "vim when hang_closing is set to #{hc}" do
+ before {
+ set_hang_closing hc
+ }
+ it "sets hang_closing to #{hc}" do
+ hang_closing.should == !!hc
+ end
+
+ it_behaves_like "vim"
+ end
+ end
+ end
+end
+
+describe "vim when not using python_pep8_indent_multiline_string" do
+ before {
+ vim.command("set sw=4 ts=4 sts=4 et")
+ vim.command("unlet! g:python_pep8_indent_multiline_string")
+ }
+ it_behaves_like "multiline strings"
+end
+
+describe "vim when using python_pep8_indent_multiline_first=0" do
+ before {
+ vim.command("set sw=4 ts=4 sts=4 et")
+ vim.command("let g:python_pep8_indent_multiline_string=0")
+ }
+ it_behaves_like "multiline strings"
+end
+
+describe "vim when using python_pep8_indent_multiline_string=-1" do
+ before {
+ vim.command("set sw=4 ts=4 sts=4 et")
+ vim.command("let g:python_pep8_indent_multiline_string=-1")
+ }
+ it_behaves_like "multiline strings"
+end
+
+describe "vim when using python_pep8_indent_multiline_string=-2" do
+ before {
+ vim.command("set sw=4 ts=4 sts=4 et")
+ vim.command("let g:python_pep8_indent_multiline_string=-2")
+ }
+ it_behaves_like "multiline strings"
+end
+
+describe "Handles far away opening parens" do
+ before { vim.feedkeys '\<ESC>ggdGifrom foo import (' }
+
+ it "indents by one level" do
+ vim.feedkeys '\<CR>'
+ proposed_indent.should == shiftwidth
+ end
+
+ it "indents by one level for 10 lines" do
+ vim.command('set paste | exe "norm 9o" | set nopaste')
+ vim.feedkeys '\<Esc>o'
+ indent.should == shiftwidth
+ end
+
+ it "indents by one level for 50 lines" do
+ vim.command('set paste | exe "norm 49o" | set nopaste')
+ vim.feedkeys '\<Esc>o'
+ indent.should == shiftwidth