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

prevent ':' from indenting inside unfinished string
[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>return 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 an 'if' is followed by" do
220      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
221      it "an elif, it lines up with the 'if'" do
222         vim.feedkeys 'elif y:'
223         indent.should == shiftwidth * 2
224      end
225
226      it "an 'else', it lines up with the 'if'" do
227         vim.feedkeys 'else:'
228         indent.should == shiftwidth * 2
229      end
230   end
231
232   describe "when a 'for' is followed by" do
233      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
234      it "an 'else', it lines up with the 'for'" do
235         vim.feedkeys 'else:'
236         indent.should == shiftwidth * 2
237      end
238   end
239
240   describe "when an 'else' is followed by" do
241      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
242      it "a 'finally', it lines up with the 'else'" do
243         vim.feedkeys 'finally:'
244         indent.should == shiftwidth * 2
245      end
246   end
247
248
249   describe "when a 'try' is followed by" do
250      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
251      it "an 'except', it lines up with the 'try'" do
252         vim.feedkeys 'except:'
253         indent.should == shiftwidth * 2
254      end
255
256      it "an 'else', it lines up with the 'try'" do
257         vim.feedkeys 'else:'
258         indent.should == shiftwidth * 2
259      end
260
261      it "a 'finally', it lines up with the 'try'" do
262         vim.feedkeys 'finally:'
263         indent.should == shiftwidth * 2
264      end
265   end
266
267   describe "when an 'except' is followed by" do
268      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
269      it "an 'else', it lines up with the 'except'" do
270         vim.feedkeys 'else:'
271         indent.should == shiftwidth * 2
272      end
273
274      it "another 'except', it lines up with the previous 'except'" do
275         vim.feedkeys 'except:'
276         indent.should == shiftwidth * 2
277      end
278
279      it "a 'finally', it lines up with the 'except'" do
280         vim.feedkeys 'finally:'
281         indent.should == shiftwidth * 2
282      end
283   end
284
285   def shiftwidth
286     @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
287   end
288   def tabstop
289     @tabstop ||= vim.echo("&tabstop").to_i
290   end
291   def indent
292     vim.echo("indent('.')").to_i
293   end
294   def previous_indent
295     pline = vim.echo("line('.')").to_i - 1
296     vim.echo("indent('#{pline}')").to_i
297   end
298   def proposed_indent
299     line = vim.echo("line('.')")
300     col = vim.echo("col('.')")
301     indent_value = vim.echo("GetPythonPEPIndent(line('.'))").to_i
302     vim.command("call cursor(#{line}, #{col})")
303     return indent_value
304   end
305 end
306
307 describe "vim when using width of 4" do
308   before {
309     vim.command("set sw=4 ts=4 sts=4 et")
310   }
311
312   it_behaves_like "vim"
313 end
314
315 describe "vim when using width of 8" do
316   before {
317     vim.command("set sw=8 ts=8 sts=8 et")
318   }
319
320   it_behaves_like "vim"
321 end