]> 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:

Merge pull request #24 from has2k1/fix-indent-eagerness
[etc/vim.git] / spec / indent / indent_spec.rb
1 require "spec_helper"
2
3 shared_examples_for "vim" do
4
5   before(:each) {
6     # clear buffer
7     vim.normal 'gg"_dG'
8
9     # Insert two blank lines.
10     # The first line is a corner case in this plugin that would shadow the
11     # correct behaviour of other tests. Thus we explicitly jump to the first
12     # line when we require so.
13     vim.feedkeys 'i\<CR>\<CR>\<ESC>'
14   }
15
16   describe "when using the indent plugin" do
17     it "sets the indentexpr and indentkeys options" do
18       vim.command("set indentexpr?").should include "GetPythonPEPIndent("
19       vim.command("set indentkeys?").should include "=elif"
20     end
21
22     it "sets autoindent and expandtab" do
23       vim.command("set autoindent?").should match(/\s*autoindent/)
24       vim.command("set expandtab?").should match(/\s*expandtab/)
25     end
26   end
27
28   describe "when entering the first line" do
29     before { vim.feedkeys '0ggipass' }
30
31     it "does not indent" do
32       proposed_indent.should == 0
33       indent.should == 0
34     end
35
36     it "does not indent when using '=='" do
37       vim.normal "=="
38       indent.should == 0
39     end
40   end
41
42   describe "when after a '(' that is at the end of its line" do
43     before { vim.feedkeys 'itest(\<CR>' }
44
45     it "indents by one level" do
46       proposed_indent.should == shiftwidth
47       vim.feedkeys 'something'
48       indent.should == shiftwidth
49       vim.normal '=='
50       indent.should == shiftwidth
51     end
52
53     it "puts the closing parenthesis at the same level" do
54       vim.feedkeys ')'
55       indent.should == 0
56     end
57   end
58
59   describe "when after an '(' that is followed by something" do
60     before { vim.feedkeys 'itest(something,\<CR>' }
61
62     it "lines up on following lines" do
63       indent.should == 5
64       vim.feedkeys 'more,\<CR>'
65       indent.should == 5
66     end
67
68     it "lines up the closing parenthesis" do
69       vim.feedkeys ')'
70       indent.should == 5
71     end
72
73     it "does not touch the closing parenthesis if it is already indented further" do
74       vim.feedkeys '  )'
75       indent.should == 7
76     end
77   end
78
79   describe "when after multiple parens of different types" do
80     it "indents by one level" do
81       vim.feedkeys 'if({\<CR>'
82       indent.should == shiftwidth
83     end
84
85     it "lines up with the last paren" do
86       vim.feedkeys 'ifff({123: 456,\<CR>'
87       indent.should == 5
88     end
89   end
90
91   describe "when '#' is contained in a string that is followed by a colon" do
92     it "indents by one level" do
93         vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
94         indent.should == shiftwidth
95     end
96   end
97
98   describe "when '#' is not contained in a string and is followed by a colon" do
99     it "does not indent" do
100         vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
101         indent.should == 0
102     end
103   end
104
105   describe "when inside an unfinished string" do
106     it "does not indent" do
107       vim.feedkeys 'i"test:\<ESC>'
108       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
109               ).downcase.should include 'string'
110       vim.feedkeys 'a\<CR>'
111       proposed_indent.should == 0
112       indent.should == 0
113     end
114
115     it "does not dedent" do
116       vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
117       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
118               ).downcase.should include 'string'
119       proposed_indent.should == shiftwidth
120       indent.should == shiftwidth
121     end
122   end
123
124   describe "when using simple control structures" do
125       it "indents shiftwidth spaces" do
126           vim.feedkeys 'iwhile True:\<CR>pass'
127           indent.should == shiftwidth
128       end
129   end
130
131   describe "when writing an 'else' block" do
132     it "aligns to the preceeding 'for' block" do
133       vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
134       indent.should == 0
135     end
136
137     it "aligns to the preceeding 'if' block" do
138       vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
139       indent.should == shiftwidth
140     end
141   end
142
143   describe "when using parens and control statements" do
144     it "avoids ambiguity by using extra indentation" do
145       vim.feedkeys 'iif (111 and\<CR>'
146       if shiftwidth == 4
147         indent.should == shiftwidth * 2
148       else
149         indent.should == 4
150       end
151       vim.feedkeys '222):\<CR>'
152       indent.should == shiftwidth
153       vim.feedkeys 'pass\<CR>'
154       indent.should == 0
155     end
156
157     it "still aligns parens properly if not ambiguous" do
158       vim.feedkeys 'iwhile (111 and\<CR>'
159       indent.should == 7
160       vim.feedkeys '222):\<CR>'
161       indent.should == shiftwidth
162       vim.feedkeys 'pass\<CR>'
163       indent.should == 0
164     end
165
166     it "still handles multiple parens correctly" do
167       vim.feedkeys 'iif (111 and (222 and 333\<CR>'
168       indent.should == 13
169       vim.feedkeys 'and 444\<CR>'
170       indent.should == 13
171       vim.feedkeys ')\<CR>'
172       if shiftwidth == 4
173         indent.should == shiftwidth * 2
174       else
175         indent.should == 4
176       end
177       vim.feedkeys 'and 555):\<CR>'
178       indent.should == shiftwidth
179       vim.feedkeys 'pass\<CR>'
180       indent.should == 0
181     end
182   end
183
184   describe "when a line breaks with a manual '\\'" do
185     it "indents shiftwidth spaces on normal line" do
186         vim.feedkeys 'ivalue = test + \\\\\<CR>'
187         indent.should == shiftwidth
188     end
189
190     it "indents 2x shiftwidth spaces for control structures" do
191         vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
192         indent.should == shiftwidth * 2
193     end
194
195     it "indents relative to line above" do
196         vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
197         indent.should == shiftwidth * 2
198     end
199   end
200
201   describe "when current line is dedented compared to previous line" do
202      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
203      it "and current line has a valid indentation (Part 1)" do
204         vim.feedkeys '0i\<TAB>if y:'
205         proposed_indent.should == -1
206      end
207
208      it "and current line has a valid indentation (Part 2)" do
209         vim.feedkeys '0i\<TAB>\<TAB>if y:'
210         proposed_indent.should == -1
211      end
212
213      it "and current line has an invalid indentation" do
214         vim.feedkeys 'i    while True:\<CR>'
215         indent.should == previous_indent + shiftwidth
216      end
217   end
218
219   describe "when current line is dedented compared to the last non-empty line" do
220      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
221      it "and current line has a valid indentation" do
222         vim.feedkeys '0i\<TAB>if y:'
223         proposed_indent.should == -1
224      end
225   end
226
227   describe "when an 'if' is followed by" do
228      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
229      it "an elif, it lines up with the 'if'" do
230         vim.feedkeys 'elif y:'
231         indent.should == shiftwidth * 2
232      end
233
234      it "an 'else', it lines up with the 'if'" do
235         vim.feedkeys 'else:'
236         indent.should == shiftwidth * 2
237      end
238   end
239
240   describe "when a 'for' is followed by" do
241      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
242      it "an 'else', it lines up with the 'for'" do
243         vim.feedkeys 'else:'
244         indent.should == shiftwidth * 2
245      end
246   end
247
248   describe "when an 'else' is followed by" do
249      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
250      it "a 'finally', it lines up with the 'else'" do
251         vim.feedkeys 'finally:'
252         indent.should == shiftwidth * 2
253      end
254   end
255
256
257   describe "when a 'try' is followed by" do
258      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
259      it "an 'except', it lines up with the 'try'" do
260         vim.feedkeys 'except:'
261         indent.should == shiftwidth * 2
262      end
263
264      it "an 'else', it lines up with the 'try'" do
265         vim.feedkeys 'else:'
266         indent.should == shiftwidth * 2
267      end
268
269      it "a 'finally', it lines up with the 'try'" do
270         vim.feedkeys 'finally:'
271         indent.should == shiftwidth * 2
272      end
273   end
274
275   describe "when an 'except' is followed by" do
276      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
277      it "an 'else', it lines up with the 'except'" do
278         vim.feedkeys 'else:'
279         indent.should == shiftwidth * 2
280      end
281
282      it "another 'except', it lines up with the previous 'except'" do
283         vim.feedkeys 'except:'
284         indent.should == shiftwidth * 2
285      end
286
287      it "a 'finally', it lines up with the 'except'" do
288         vim.feedkeys 'finally:'
289         indent.should == shiftwidth * 2
290      end
291   end
292
293   def shiftwidth
294     @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
295   end
296   def tabstop
297     @tabstop ||= vim.echo("&tabstop").to_i
298   end
299   def indent
300     vim.echo("indent('.')").to_i
301   end
302   def previous_indent
303     pline = vim.echo("line('.')").to_i - 1
304     vim.echo("indent('#{pline}')").to_i
305   end
306   def proposed_indent
307     line = vim.echo("line('.')")
308     col = vim.echo("col('.')")
309     indent_value = vim.echo("GetPythonPEPIndent(line('.'))").to_i
310     vim.command("call cursor(#{line}, #{col})")
311     return indent_value
312   end
313 end
314
315 describe "vim when using width of 4" do
316   before {
317     vim.command("set sw=4 ts=4 sts=4 et")
318   }
319
320   it_behaves_like "vim"
321 end
322
323 describe "vim when using width of 8" do
324   before {
325     vim.command("set sw=8 ts=8 sts=8 et")
326   }
327
328   it_behaves_like "vim"
329 end