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

Fix indenting of strings, especially after opening paren
[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 after an '(' that is followed by an unfinished string" do
133     before { vim.feedkeys 'itest("""' }
134
135     it "it does not indent the next line" do
136       vim.feedkeys '\<CR>'
137       proposed_indent.should == 0
138       indent.should == 0
139     end
140
141     it "with contents it does not indent the next line" do
142       vim.feedkeys 'string_contents\<CR>'
143       proposed_indent.should == 0
144       indent.should == 0
145     end
146   end
147
148   describe "when after assigning an unfinished string" do
149     before { vim.feedkeys 'itest = """' }
150
151     it "it does not indent the next line" do
152       vim.feedkeys '\<CR>'
153       proposed_indent.should == 0
154       indent.should == 0
155     end
156   end
157
158   describe "when after assigning an unfinished string" do
159     before { vim.feedkeys 'i    test = """' }
160
161     it "it does not indent the next line" do
162       vim.feedkeys '\<CR>'
163       proposed_indent.should == 0
164       indent.should == 0
165     end
166   end
167
168   describe "when after assigning a finished string" do
169     before { vim.feedkeys 'i    test = ""' }
170
171     it "it does indent the next line" do
172       vim.feedkeys '\<CR>'
173       proposed_indent.should == 4
174       indent.should == 4
175     end
176
177     it "and writing a new string, it does indent the next line" do
178       vim.feedkeys '\<CR>""'
179       proposed_indent.should == 4
180       indent.should == 4
181     end
182   end
183
184   describe "when after a docstring" do
185     before { vim.feedkeys 'i    """' }
186
187     it "it does indent the next line" do
188       vim.feedkeys '\<CR>'
189       proposed_indent.should == 4
190       indent.should == 4
191     end
192   end
193
194   describe "when using simple control structures" do
195       it "indents shiftwidth spaces" do
196           vim.feedkeys 'iwhile True:\<CR>pass'
197           indent.should == shiftwidth
198       end
199   end
200
201   describe "when writing an 'else' block" do
202     it "aligns to the preceeding 'for' block" do
203       vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
204       indent.should == 0
205     end
206
207     it "aligns to the preceeding 'if' block" do
208       vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
209       indent.should == shiftwidth
210     end
211   end
212
213   describe "when using parens and control statements" do
214     it "avoids ambiguity by using extra indentation" do
215       vim.feedkeys 'iif (111 and\<CR>'
216       if shiftwidth == 4
217         indent.should == shiftwidth * 2
218       else
219         indent.should == 4
220       end
221       vim.feedkeys '222):\<CR>'
222       indent.should == shiftwidth
223       vim.feedkeys 'pass\<CR>'
224       indent.should == 0
225     end
226
227     it "still aligns parens properly if not ambiguous" do
228       vim.feedkeys 'iwhile (111 and\<CR>'
229       indent.should == 7
230       vim.feedkeys '222):\<CR>'
231       indent.should == shiftwidth
232       vim.feedkeys 'pass\<CR>'
233       indent.should == 0
234     end
235
236     it "still handles multiple parens correctly" do
237       vim.feedkeys 'iif (111 and (222 and 333\<CR>'
238       indent.should == 13
239       vim.feedkeys 'and 444\<CR>'
240       indent.should == 13
241       vim.feedkeys ')\<CR>'
242       if shiftwidth == 4
243         indent.should == shiftwidth * 2
244       else
245         indent.should == 4
246       end
247       vim.feedkeys 'and 555):\<CR>'
248       indent.should == shiftwidth
249       vim.feedkeys 'pass\<CR>'
250       indent.should == 0
251     end
252   end
253
254   describe "when a line breaks with a manual '\\'" do
255     it "indents shiftwidth spaces on normal line" do
256         vim.feedkeys 'ivalue = test + \\\\\<CR>'
257         indent.should == shiftwidth
258     end
259
260     it "indents 2x shiftwidth spaces for control structures" do
261         vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
262         indent.should == shiftwidth * 2
263     end
264
265     it "indents relative to line above" do
266         vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
267         indent.should == shiftwidth * 2
268     end
269   end
270
271   describe "when current line is dedented compared to previous line" do
272      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
273      it "and current line has a valid indentation (Part 1)" do
274         vim.feedkeys '0i\<TAB>if y:'
275         proposed_indent.should == -1
276      end
277
278      it "and current line has a valid indentation (Part 2)" do
279         vim.feedkeys '0i\<TAB>\<TAB>if y:'
280         proposed_indent.should == -1
281      end
282
283      it "and current line has an invalid indentation" do
284         vim.feedkeys 'i    while True:\<CR>'
285         indent.should == previous_indent + shiftwidth
286      end
287   end
288
289   describe "when current line is dedented compared to the last non-empty line" do
290      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
291      it "and current line has a valid indentation" do
292         vim.feedkeys '0i\<TAB>if y:'
293         proposed_indent.should == -1
294      end
295   end
296
297   describe "when an 'if' is followed by" do
298      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
299      it "an elif, it lines up with the 'if'" do
300         vim.feedkeys 'elif y:'
301         indent.should == shiftwidth * 2
302      end
303
304      it "an 'else', it lines up with the 'if'" do
305         vim.feedkeys 'else:'
306         indent.should == shiftwidth * 2
307      end
308   end
309
310   describe "when a 'for' is followed by" do
311      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
312      it "an 'else', it lines up with the 'for'" do
313         vim.feedkeys 'else:'
314         indent.should == shiftwidth * 2
315      end
316   end
317
318   describe "when an 'else' is followed by" do
319      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
320      it "a 'finally', it lines up with the 'else'" do
321         vim.feedkeys 'finally:'
322         indent.should == shiftwidth * 2
323      end
324   end
325
326
327   describe "when a 'try' is followed by" do
328      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
329      it "an 'except', it lines up with the 'try'" do
330         vim.feedkeys 'except:'
331         indent.should == shiftwidth * 2
332      end
333
334      it "an 'else', it lines up with the 'try'" do
335         vim.feedkeys 'else:'
336         indent.should == shiftwidth * 2
337      end
338
339      it "a 'finally', it lines up with the 'try'" do
340         vim.feedkeys 'finally:'
341         indent.should == shiftwidth * 2
342      end
343   end
344
345   describe "when an 'except' is followed by" do
346      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
347      it "an 'else', it lines up with the 'except'" do
348         vim.feedkeys 'else:'
349         indent.should == shiftwidth * 2
350      end
351
352      it "another 'except', it lines up with the previous 'except'" do
353         vim.feedkeys 'except:'
354         indent.should == shiftwidth * 2
355      end
356
357      it "a 'finally', it lines up with the 'except'" do
358         vim.feedkeys 'finally:'
359         indent.should == shiftwidth * 2
360      end
361   end
362
363   def shiftwidth
364     @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
365   end
366   def tabstop
367     @tabstop ||= vim.echo("&tabstop").to_i
368   end
369   def indent
370     vim.echo("indent('.')").to_i
371   end
372   def previous_indent
373     pline = vim.echo("line('.')").to_i - 1
374     vim.echo("indent('#{pline}')").to_i
375   end
376   def proposed_indent
377     line = vim.echo("line('.')")
378     col = vim.echo("col('.')")
379     indent_value = vim.echo("GetPythonPEPIndent(line('.'))").to_i
380     vim.command("call cursor(#{line}, #{col})")
381     return indent_value
382   end
383 end
384
385 describe "vim when using width of 4" do
386   before {
387     vim.command("set sw=4 ts=4 sts=4 et")
388   }
389
390   it_behaves_like "vim"
391 end
392
393 describe "vim when using width of 8" do
394   before {
395     vim.command("set sw=8 ts=8 sts=8 et")
396   }
397
398   it_behaves_like "vim"
399 end