]> 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 #39 from blueyed/fix-indent
[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 using gq to reindent a '(' that is" do
80     before { vim.feedkeys 'itest(' }
81     it "something and has a string without spaces at the end" do
82       vim.feedkeys 'something_very_long_blaaaaaaaaa, "some_very_long_string_blaaaaaaaaaaaaaaaaaaaa"\<esc>gqq'
83       indent.should == 5
84     end
85   end
86
87   describe "when after multiple parens of different types" do
88     it "indents by one level" do
89       vim.feedkeys 'if({\<CR>'
90       indent.should == shiftwidth
91     end
92
93     it "lines up with the last paren" do
94       vim.feedkeys 'ifff({123: 456,\<CR>'
95       indent.should == 5
96     end
97   end
98
99   describe "when '#' is contained in a string that is followed by a colon" do
100     it "indents by one level" do
101         vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
102         indent.should == shiftwidth
103     end
104   end
105
106   describe "when '#' is not contained in a string and is followed by a colon" do
107     it "does not indent" do
108         vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
109         indent.should == 0
110     end
111   end
112
113   describe "when inside an unfinished string" do
114     it "does not indent" do
115       vim.feedkeys 'i"test:\<ESC>'
116       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
117               ).downcase.should include 'string'
118       vim.feedkeys 'a\<CR>'
119       proposed_indent.should == 0
120       indent.should == 0
121     end
122
123     it "does not dedent" do
124       vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
125       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
126               ).downcase.should include 'string'
127       proposed_indent.should == shiftwidth
128       indent.should == shiftwidth
129     end
130   end
131
132   describe "when using simple control structures" do
133       it "indents shiftwidth spaces" do
134           vim.feedkeys 'iwhile True:\<CR>pass'
135           indent.should == shiftwidth
136       end
137   end
138
139   describe "when writing an 'else' block" do
140     it "aligns to the preceeding 'for' block" do
141       vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
142       indent.should == 0
143     end
144
145     it "aligns to the preceeding 'if' block" do
146       vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
147       indent.should == shiftwidth
148     end
149   end
150
151   describe "when using parens and control statements" do
152     it "avoids ambiguity by using extra indentation" do
153       vim.feedkeys 'iif (111 and\<CR>'
154       if shiftwidth == 4
155         indent.should == shiftwidth * 2
156       else
157         indent.should == 4
158       end
159       vim.feedkeys '222):\<CR>'
160       indent.should == shiftwidth
161       vim.feedkeys 'pass\<CR>'
162       indent.should == 0
163     end
164
165     it "still aligns parens properly if not ambiguous" do
166       vim.feedkeys 'iwhile (111 and\<CR>'
167       indent.should == 7
168       vim.feedkeys '222):\<CR>'
169       indent.should == shiftwidth
170       vim.feedkeys 'pass\<CR>'
171       indent.should == 0
172     end
173
174     it "still handles multiple parens correctly" do
175       vim.feedkeys 'iif (111 and (222 and 333\<CR>'
176       indent.should == 13
177       vim.feedkeys 'and 444\<CR>'
178       indent.should == 13
179       vim.feedkeys ')\<CR>'
180       if shiftwidth == 4
181         indent.should == shiftwidth * 2
182       else
183         indent.should == 4
184       end
185       vim.feedkeys 'and 555):\<CR>'
186       indent.should == shiftwidth
187       vim.feedkeys 'pass\<CR>'
188       indent.should == 0
189     end
190   end
191
192   describe "when a line breaks with a manual '\\'" do
193     it "indents shiftwidth spaces on normal line" do
194         vim.feedkeys 'ivalue = test + \\\\\<CR>'
195         indent.should == shiftwidth
196     end
197
198     it "indents 2x shiftwidth spaces for control structures" do
199         vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
200         indent.should == shiftwidth * 2
201     end
202
203     it "indents relative to line above" do
204         vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
205         indent.should == shiftwidth * 2
206     end
207   end
208
209   describe "when current line is dedented compared to previous line" do
210      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
211      it "and current line has a valid indentation (Part 1)" do
212         vim.feedkeys '0i\<TAB>if y:'
213         proposed_indent.should == -1
214      end
215
216      it "and current line has a valid indentation (Part 2)" do
217         vim.feedkeys '0i\<TAB>\<TAB>if y:'
218         proposed_indent.should == -1
219      end
220
221      it "and current line has an invalid indentation" do
222         vim.feedkeys 'i    while True:\<CR>'
223         indent.should == previous_indent + shiftwidth
224      end
225   end
226
227   describe "when current line is dedented compared to the last non-empty line" do
228      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
229      it "and current line has a valid indentation" do
230         vim.feedkeys '0i\<TAB>if y:'
231         proposed_indent.should == -1
232      end
233   end
234
235   describe "when an 'if' is followed by" do
236      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
237      it "an elif, it lines up with the 'if'" do
238         vim.feedkeys 'elif y:'
239         indent.should == shiftwidth * 2
240      end
241
242      it "an 'else', it lines up with the 'if'" do
243         vim.feedkeys 'else:'
244         indent.should == shiftwidth * 2
245      end
246   end
247
248   describe "when a 'for' is followed by" do
249      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
250      it "an 'else', it lines up with the 'for'" do
251         vim.feedkeys 'else:'
252         indent.should == shiftwidth * 2
253      end
254   end
255
256   describe "when an 'else' is followed by" do
257      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
258      it "a 'finally', it lines up with the 'else'" do
259         vim.feedkeys 'finally:'
260         indent.should == shiftwidth * 2
261      end
262   end
263
264
265   describe "when a 'try' is followed by" do
266      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
267      it "an 'except', it lines up with the 'try'" do
268         vim.feedkeys 'except:'
269         indent.should == shiftwidth * 2
270      end
271
272      it "an 'else', it lines up with the 'try'" do
273         vim.feedkeys 'else:'
274         indent.should == shiftwidth * 2
275      end
276
277      it "a 'finally', it lines up with the 'try'" do
278         vim.feedkeys 'finally:'
279         indent.should == shiftwidth * 2
280      end
281   end
282
283   describe "when an 'except' is followed by" do
284      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
285      it "an 'else', it lines up with the 'except'" do
286         vim.feedkeys 'else:'
287         indent.should == shiftwidth * 2
288      end
289
290      it "another 'except', it lines up with the previous 'except'" do
291         vim.feedkeys 'except:'
292         indent.should == shiftwidth * 2
293      end
294
295      it "a 'finally', it lines up with the 'except'" do
296         vim.feedkeys 'finally:'
297         indent.should == shiftwidth * 2
298      end
299   end
300
301   def shiftwidth
302     @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
303   end
304   def tabstop
305     @tabstop ||= vim.echo("&tabstop").to_i
306   end
307   def indent
308     vim.echo("indent('.')").to_i
309   end
310   def previous_indent
311     pline = vim.echo("line('.')").to_i - 1
312     vim.echo("indent('#{pline}')").to_i
313   end
314   def proposed_indent
315     line = vim.echo("line('.')")
316     col = vim.echo("col('.')")
317     indent_value = vim.echo("GetPythonPEPIndent(line('.'))").to_i
318     vim.command("call cursor(#{line}, #{col})")
319     return indent_value
320   end
321 end
322
323 describe "vim when using width of 4" do
324   before {
325     vim.command("set sw=4 ts=4 sts=4 et")
326   }
327
328   it_behaves_like "vim"
329 end
330
331 describe "vim when using width of 8" do
332   before {
333     vim.command("set sw=8 ts=8 sts=8 et")
334   }
335
336   it_behaves_like "vim"
337 end