require "spec_helper"
-describe "vim" do
+shared_examples_for "vim" do
- before(:each) { vim.normal 'gg"_dG' } # clear buffer
+ 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 using the indent plugin" do
it "sets the indentexpr and indentkeys options" do
end
describe "when entering the first line" do
- before { vim.feedkeys 'ipass' }
+ before { vim.feedkeys '0ggipass' }
it "does not indent" do
proposed_indent.should == 0
end
end
- # describe "when after a '(' that is at the end of its line" do
- # before { vim.feedkeys 'itest(\<CR>' }
+ describe "when after a '(' that is at the end of its line" do
+ before { vim.feedkeys 'itest(\<CR>' }
- # it "indents by one level" do
- # proposed_indent.should == shiftwidth
- # vim.feedkeys 'something'
- # indent.should == shiftwidth
- # vim.normal '=='
- # indent.should == shiftwidth
- # end
+ it "indents by one level" do
+ proposed_indent.should == shiftwidth
+ vim.feedkeys 'something'
+ indent.should == shiftwidth
+ vim.normal '=='
+ indent.should == shiftwidth
+ end
- # it "puts the closing parenthesis at the same level" do
- # vim.feedkeys ')'
- # indent.should == 0
- # end
- # end
+ it "puts the closing parenthesis at the same level" do
+ vim.feedkeys ')'
+ indent.should == 0
+ end
+ end
describe "when after an '(' that is followed by something" do
before { vim.feedkeys 'itest(something,\<CR>' }
end
end
+ describe "when after multiple parens of different types" do
+ it "indents by one level" do
+ vim.feedkeys 'if({\<CR>'
+ indent.should == shiftwidth
+ end
+
+ it "lines up with the last paren" do
+ vim.feedkeys 'ifff({123: 456,\<CR>'
+ indent.should == 5
+ end
+ end
+
+ describe "when '#' is contained in a string that is followed by a colon" do
+ it "indents by one level" do
+ vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
+ indent.should == shiftwidth
+ end
+ end
+
+ describe "when '#' is not contained in a string and is followed by a colon" do
+ it "does not indent" do
+ vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
+ indent.should == 0
+ end
+ end
+
+ describe "when inside an unfinished string" do
+ it "does not indent" do
+ vim.feedkeys 'i"test:\<ESC>'
+ vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
+ ).downcase.should include 'string'
+ vim.feedkeys 'a\<CR>'
+ proposed_indent.should == 0
+ indent.should == 0
+ end
+
+ it "does not dedent" do
+ vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
+ vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
+ ).downcase.should include 'string'
+ proposed_indent.should == shiftwidth
+ indent.should == shiftwidth
+ end
+ end
+
describe "when using simple control structures" do
it "indents shiftwidth spaces" do
vim.feedkeys 'iwhile True:\<CR>pass'
end
end
+ describe "when writing an 'else' block" do
+ it "aligns to the preceeding 'for' block" do
+ vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
+ indent.should == 0
+ end
+
+ it "aligns to the preceeding 'if' block" do
+ vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
+ indent.should == shiftwidth
+ end
+ end
+
+ describe "when using parens and control statements" do
+ it "avoids ambiguity by using extra indentation" do
+ vim.feedkeys 'iif (111 and\<CR>'
+ if shiftwidth == 4
+ indent.should == shiftwidth * 2
+ else
+ indent.should == 4
+ end
+ vim.feedkeys '222):\<CR>'
+ indent.should == shiftwidth
+ vim.feedkeys 'pass\<CR>'
+ indent.should == 0
+ end
+
+ it "still aligns parens properly if not ambiguous" do
+ vim.feedkeys 'iwhile (111 and\<CR>'
+ indent.should == 7
+ vim.feedkeys '222):\<CR>'
+ indent.should == shiftwidth
+ vim.feedkeys 'pass\<CR>'
+ indent.should == 0
+ end
+
+ it "still handles multiple parens correctly" do
+ vim.feedkeys 'iif (111 and (222 and 333\<CR>'
+ indent.should == 13
+ vim.feedkeys 'and 444\<CR>'
+ indent.should == 13
+ vim.feedkeys ')\<CR>'
+ if shiftwidth == 4
+ indent.should == shiftwidth * 2
+ else
+ indent.should == 4
+ end
+ vim.feedkeys 'and 555):\<CR>'
+ indent.should == shiftwidth
+ vim.feedkeys 'pass\<CR>'
+ indent.should == 0
+ end
+ end
+
describe "when a line breaks with a manual '\\'" do
it "indents shiftwidth spaces on normal line" do
vim.feedkeys 'ivalue = test + \\\\\<CR>'
end
it "indents relative to line above" do
- vim.feedkeys 'i\tvalue = test + \\\\\<CR>'
+ vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
indent.should == shiftwidth * 2
end
end
+ describe "when current line is dedented compared to previous line" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
+ it "and current line has a valid indentation (Part 1)" do
+ vim.feedkeys '0i\<TAB>if y:'
+ proposed_indent.should == -1
+ end
+
+ it "and current line has a valid indentation (Part 2)" do
+ vim.feedkeys '0i\<TAB>\<TAB>if y:'
+ proposed_indent.should == -1
+ end
+
+ it "and current line has an invalid indentation" do
+ vim.feedkeys 'i while True:\<CR>'
+ indent.should == previous_indent + shiftwidth
+ end
+ end
+
+ describe "when current line is dedented compared to the last non-empty line" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>\<ESC>' }
+ it "and current line has a valid indentation (Part 1)" do
+ vim.feedkeys '0i\<TAB>if y:'
+ proposed_indent.should == -1
+ end
+ end
+
+ describe "when an 'if' is followed by" do
+ before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
+ it "an elif, it lines up with the 'if'" do
+ vim.feedkeys 'elif y:'
+ indent.should == shiftwidth * 2
+ end
+
+ it "an 'else', it lines up with the 'if'" do
+ vim.feedkeys 'else:'
+ indent.should == shiftwidth * 2
+ 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
+
def shiftwidth
@shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
end
def indent
vim.echo("indent('.')").to_i
end
+ def previous_indent
+ pline = vim.echo("line('.')").to_i - 1
+ vim.echo("indent('#{pline}')").to_i
+ end
def proposed_indent
- vim.echo("GetPythonPEPIndent(line('.'))").to_i
+ line = vim.echo("line('.')")
+ col = vim.echo("col('.')")
+ indent_value = vim.echo("GetPythonPEPIndent(line('.'))").to_i
+ vim.command("call cursor(#{line}, #{col})")
+ return indent_value
end
end
+describe "vim when using width of 4" do
+ before {
+ vim.command("set sw=4 ts=4 sts=4 et")
+ }
+
+ it_behaves_like "vim"
+end
+
+describe "vim when using width of 8" do
+ before {
+ vim.command("set sw=8 ts=8 sts=8 et")
+ }
+
+ it_behaves_like "vim"
+end