tailor 1.0.0.alpha2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.gitignore +1 -0
  2. data/.tailor +10 -2
  3. data/Gemfile.lock +2 -2
  4. data/History.rdoc +20 -0
  5. data/README.rdoc +176 -26
  6. data/features/configurable.feature +19 -39
  7. data/features/horizontal_spacing.feature +3 -2
  8. data/features/indentation.feature +2 -2
  9. data/features/indentation/bad_files_with_no_trailing_newline.feature +9 -8
  10. data/features/indentation/good_files_with_no_trailing_newline.feature +19 -6
  11. data/features/name_detection.feature +2 -2
  12. data/features/support/env.rb +0 -2
  13. data/features/support/file_cases/horizontal_spacing_cases.rb +5 -4
  14. data/features/support/file_cases/indentation_cases.rb +105 -54
  15. data/features/support/file_cases/naming_cases.rb +0 -1
  16. data/features/support/file_cases/vertical_spacing_cases.rb +0 -1
  17. data/features/support/legacy/bad_ternary_colon_spacing.rb +1 -1
  18. data/features/valid_ruby.feature +17 -0
  19. data/features/vertical_spacing.feature +40 -19
  20. data/lib/ext/string_ext.rb +12 -0
  21. data/lib/tailor/cli.rb +7 -5
  22. data/lib/tailor/cli/options.rb +13 -3
  23. data/lib/tailor/composite_observable.rb +17 -2
  24. data/lib/tailor/configuration.rb +83 -72
  25. data/lib/tailor/configuration/style.rb +85 -0
  26. data/lib/tailor/critic.rb +67 -117
  27. data/lib/tailor/formatter.rb +38 -0
  28. data/lib/tailor/formatters/text.rb +35 -10
  29. data/lib/tailor/lexed_line.rb +38 -5
  30. data/lib/tailor/lexer.rb +150 -14
  31. data/lib/tailor/{lexer_constants.rb → lexer/lexer_constants.rb} +9 -7
  32. data/lib/tailor/lexer/token.rb +6 -2
  33. data/lib/tailor/logger.rb +4 -0
  34. data/lib/tailor/problem.rb +8 -73
  35. data/lib/tailor/reporter.rb +1 -1
  36. data/lib/tailor/ruler.rb +67 -6
  37. data/lib/tailor/rulers/allow_camel_case_methods_ruler.rb +9 -1
  38. data/lib/tailor/rulers/allow_hard_tabs_ruler.rb +9 -1
  39. data/lib/tailor/rulers/allow_invalid_ruby_ruler.rb +38 -0
  40. data/lib/tailor/rulers/allow_screaming_snake_case_classes_ruler.rb +9 -2
  41. data/lib/tailor/rulers/allow_trailing_line_spaces_ruler.rb +10 -5
  42. data/lib/tailor/rulers/indentation_spaces_ruler.rb +93 -26
  43. data/lib/tailor/rulers/indentation_spaces_ruler/indentation_manager.rb +128 -84
  44. data/lib/tailor/rulers/max_code_lines_in_class_ruler.rb +9 -5
  45. data/lib/tailor/rulers/max_code_lines_in_method_ruler.rb +9 -5
  46. data/lib/tailor/rulers/max_line_length_ruler.rb +10 -5
  47. data/lib/tailor/rulers/spaces_after_comma_ruler.rb +13 -4
  48. data/lib/tailor/rulers/spaces_after_lbrace_ruler.rb +8 -4
  49. data/lib/tailor/rulers/spaces_after_lbracket_ruler.rb +8 -4
  50. data/lib/tailor/rulers/spaces_after_lparen_ruler.rb +8 -4
  51. data/lib/tailor/rulers/spaces_before_comma_ruler.rb +8 -4
  52. data/lib/tailor/rulers/spaces_before_lbrace_ruler.rb +13 -6
  53. data/lib/tailor/rulers/spaces_before_rbrace_ruler.rb +12 -8
  54. data/lib/tailor/rulers/spaces_before_rbracket_ruler.rb +12 -5
  55. data/lib/tailor/rulers/spaces_before_rparen_ruler.rb +13 -6
  56. data/lib/tailor/rulers/spaces_in_empty_braces_ruler.rb +13 -9
  57. data/lib/tailor/rulers/trailing_newlines_ruler.rb +10 -5
  58. data/lib/tailor/tailorrc.erb +3 -3
  59. data/lib/tailor/version.rb +1 -1
  60. data/m.rb +15 -0
  61. data/spec/spec_helper.rb +0 -1
  62. data/spec/tailor/cli_spec.rb +8 -9
  63. data/spec/tailor/composite_observable_spec.rb +41 -0
  64. data/spec/tailor/configuration/style_spec.rb +197 -0
  65. data/spec/tailor/configuration_spec.rb +52 -33
  66. data/spec/tailor/critic_spec.rb +7 -8
  67. data/spec/tailor/formatter_spec.rb +52 -0
  68. data/spec/tailor/lexed_line_spec.rb +236 -88
  69. data/spec/tailor/lexer_spec.rb +8 -63
  70. data/spec/tailor/problem_spec.rb +14 -46
  71. data/spec/tailor/reporter_spec.rb +8 -8
  72. data/spec/tailor/ruler_spec.rb +1 -1
  73. data/spec/tailor/rulers/indentation_spaces_ruler/indentation_manager_spec.rb +132 -176
  74. data/spec/tailor/rulers/indentation_spaces_ruler_spec.rb +41 -33
  75. data/spec/tailor/rulers/{spaces_after_comma_spec.rb → spaces_after_comma_ruler_spec.rb} +5 -5
  76. data/spec/tailor/rulers/spaces_after_lbrace_ruler_spec.rb +14 -14
  77. data/spec/tailor/rulers/spaces_before_lbrace_ruler_spec.rb +1 -1
  78. data/spec/tailor/rulers/spaces_before_rbrace_ruler_spec.rb +1 -1
  79. data/spec/tailor/version_spec.rb +1 -1
  80. data/spec/tailor_spec.rb +3 -1
  81. data/tailor.gemspec +11 -3
  82. data/uest.rb +9 -0
  83. metadata +66 -41
  84. data/features/step_definitions/spacing/commas_steps.rb +0 -14
@@ -16,7 +16,8 @@ describe Tailor::Lexer do
16
16
  end
17
17
 
18
18
  before do
19
- Tailor::Lexer.any_instance.stub(:ensure_trailing_newline).and_return(file_text)
19
+ Tailor::Lexer.any_instance.stub(:ensure_trailing_newline).
20
+ and_return(file_text)
20
21
  end
21
22
 
22
23
  describe "#initialize" do
@@ -45,67 +46,11 @@ describe Tailor::Lexer do
45
46
  end
46
47
  end
47
48
 
48
- describe "#on_ignored_nl" do
49
- it "calls #current_line_lex" do
50
- pending
51
- subject.stub(:only_spaces?).and_return true
52
- subject.should_receive(:current_line_lex)
53
- subject.on_ignored_nl("\n")
54
- end
55
-
56
- context "#only_spaces? is true" do
57
- pending
58
- before { subject.stub(:only_spaces?).and_return true }
59
-
60
- it "does not call #update_actual_indentation" do
61
- pending
62
- end
63
- end
64
- end
65
-
66
49
  describe "#on_sp" do
67
- context "@config says to disallow hard tabs" do
68
- before do
69
- config = { horizontal_spacing: { allow_hard_tabs: false } }
70
- subject.instance_variable_set(:@config, config)
71
- end
72
-
73
- context "token contains a hard tab" do
74
- it "adds a new problem to @problems" do
75
- pending "This behavior moved to indent_sp_ruler--move there."
76
-
77
- subject.instance_variable_set(:@problems, [])
78
-
79
- expect { subject.on_sp("\t") }.
80
- to change{subject.instance_variable_get(:@problems).size}.
81
- from(0).to 1
82
- end
83
- end
84
-
85
- context "token does not contain a hard tab" do
86
- it "does not add a new problem to @problems" do
87
- pending "This behavior moved to indent_sp_ruler--move there."
88
-
89
- subject.instance_variable_set(:@problems, [])
90
-
91
- expect { subject.on_sp("\x20") }.
92
- to_not change{subject.instance_variable_get(:@problems).size}.
93
- from(0).to 1
94
- end
95
- end
96
- end
97
-
98
- context "@config says to allow hard tabs" do
99
- before do
100
- config = { horizontal_spacing: { allow_hard_tabs: true } }
101
- subject.instance_variable_set(:@config, config)
102
- end
103
-
104
- it "does not check the token" do
105
- token = double "token"
106
- token.stub(:size)
107
- token.should_not_receive(:=~)
108
- subject.on_sp(token)
50
+ context "token is a backslash then newline" do
51
+ it "calls #notify_ignored_nl_observers" do
52
+ subject.should_receive(:notify_ignored_nl_observers)
53
+ subject.on_sp("\\\n")
109
54
  end
110
55
  end
111
56
  end
@@ -157,10 +102,10 @@ describe Tailor::Lexer do
157
102
  before do
158
103
  Tailor::Lexer.any_instance.unstub(:ensure_trailing_newline)
159
104
  end
160
-
105
+
161
106
  context "text contains a trailing newline already" do
162
107
  let!(:text) { "text\n" }
163
-
108
+
164
109
  before do
165
110
  subject.stub(:count_trailing_newlines).and_return 1
166
111
  end
@@ -5,7 +5,7 @@ describe Tailor::Problem do
5
5
  before do
6
6
  Tailor::Problem.any_instance.stub(:log)
7
7
  end
8
-
8
+
9
9
  let(:lineno) { 10 }
10
10
  let(:column) { 11 }
11
11
 
@@ -15,60 +15,28 @@ describe Tailor::Problem do
15
15
  end
16
16
 
17
17
  it "sets self[:type] to the type param" do
18
- Tailor::Problem.new(:test, lineno, column).should include(type: :test)
18
+ Tailor::Problem.new(:test, lineno, column, "", :b).
19
+ should include(type: :test)
19
20
  end
20
21
 
21
22
  it "sets self[:line] to the lineno param" do
22
- Tailor::Problem.new(:test, lineno, column).should include(line: lineno)
23
- end
24
-
25
- it "sets self[:column] to 'column' from the binding" do
26
- Tailor::Problem.new(:test, lineno, column).should include(column: column)
27
- end
28
-
29
- it "sets self[:message] to what's returned from #message for @type" do
30
- Tailor::Problem.any_instance.should_receive(:message).with(:test).
31
- and_return("test message")
32
-
33
- problem = Tailor::Problem.new(:test, lineno, column)
34
- problem.should include(message: "test message")
35
- end
36
- end
37
-
38
- describe "#message" do
39
- before do
40
- Tailor::Problem.any_instance.stub(:set_values)
41
- end
42
-
43
- context "type is :indentation" do
44
- it "builds a successful message" do
45
- options = { actual_indentation: 10, should_be_at: 97 }
46
- problem = Tailor::Problem.new(:test, lineno, column, options)
47
- problem.message(:indentation).should match /10.*97/
48
- end
23
+ Tailor::Problem.new(:test, lineno, column, "", :c).
24
+ should include(line: lineno)
49
25
  end
50
26
 
51
- context "type is :trailing_newlines" do
52
- it "builds a successful message" do
53
- options = { actual_trailing_newlines: 123, should_have: 777 }
54
- problem = Tailor::Problem.new(:test, lineno, column, options)
55
- problem.message(:trailing_newlines).should match /123.*777/
56
- end
27
+ it "sets self[:column] to the column param" do
28
+ Tailor::Problem.new(:test, lineno, column, "", :d).
29
+ should include(column: column)
57
30
  end
58
31
 
59
- context "type is :hard_tab" do
60
- it "builds a successful message" do
61
- problem = Tailor::Problem.new(:test, lineno, column)
62
- problem.message(:hard_tab).should match /Hard tab found./
63
- end
32
+ it "sets self[:message] to the message param" do
33
+ Tailor::Problem.new(:test, lineno, column, "test", :d).
34
+ should include(message: "test")
64
35
  end
65
36
 
66
- context "type is :line_length" do
67
- it "builds a successful message" do
68
- options = { actual_length: 88, should_be_at: 77 }
69
- problem = Tailor::Problem.new(:test, lineno, column, options)
70
- problem.message(:line_length).should match /88.*77/
71
- end
37
+ it "sets self[:level] to the level param" do
38
+ Tailor::Problem.new(:test, lineno, column, "test", :d).
39
+ should include(level: :d)
72
40
  end
73
41
  end
74
42
  end
@@ -8,22 +8,22 @@ describe Tailor::Reporter do
8
8
 
9
9
  it "creates a new Formatter object of the type passed in" do
10
10
  reporter = Tailor::Reporter.new(formats)
11
- reporter.formatters.first.should be_a Tailor::Formatter::Text
11
+ reporter.formatters.first.should be_a Tailor::Formatters::Text
12
12
  end
13
13
  end
14
14
  end
15
-
15
+
16
16
  describe "#file_report" do
17
17
  let(:file_problems) { double "file problems" }
18
- let(:formatter) { double "Tailor::Formatter::SomeFormatter" }
19
-
18
+ let(:formatter) { double "Tailor::Formatters::SomeFormatter" }
19
+
20
20
  subject do
21
21
  t = Tailor::Reporter.new
22
22
  t.instance_variable_set(:@formatters, [formatter])
23
-
23
+
24
24
  t
25
- end
26
-
25
+ end
26
+
27
27
  it "calls #file_report on each @formatters" do
28
28
  label = :some_label
29
29
  formatter.should_receive(:file_report).with(file_problems, label)
@@ -34,7 +34,7 @@ describe Tailor::Reporter do
34
34
 
35
35
  describe "#summary_report" do
36
36
  let(:all_problems) { double "all problems" }
37
- let(:formatter) { double "Tailor::Formatter::SomeFormatter" }
37
+ let(:formatter) { double "Tailor::Formatters::SomeFormatter" }
38
38
 
39
39
  subject do
40
40
  t = Tailor::Reporter.new
@@ -2,7 +2,7 @@ require_relative '../spec_helper'
2
2
  require 'tailor/ruler'
3
3
 
4
4
  describe Tailor::Ruler do
5
- before { subject.stub(:log) }
5
+ before { Tailor::Logger.stub(:log) }
6
6
 
7
7
  describe "#add_child_ruler" do
8
8
  it "adds new rulers to @child_rulers" do
@@ -8,7 +8,7 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
8
8
  let!(:lexed_line) { double "LexedLine" }
9
9
 
10
10
  before do
11
- #Tailor::Logger.stub(:log)
11
+ Tailor::Logger.stub(:log)
12
12
  subject.instance_variable_set(:@spaces, spaces)
13
13
  end
14
14
 
@@ -23,13 +23,6 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
23
23
  end
24
24
  end
25
25
 
26
- describe "#next_should_be_at" do
27
- it "returns @proper[:next_line]" do
28
- subject.instance_variable_set(:@proper, { next_line: 123 })
29
- subject.next_should_be_at.should == 123
30
- end
31
- end
32
-
33
26
  describe "#decrease_this_line" do
34
27
  let!(:spaces) { 27 }
35
28
 
@@ -76,67 +69,7 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
76
69
  end
77
70
  end
78
71
 
79
- describe "#increase_next_line" do
80
- context "#started? is true" do
81
- before { subject.stub(:started?).and_return true }
82
-
83
- it "increases @proper[:next_line] by @spaces" do
84
- expect { subject.increase_next_line }.to change{subject.next_should_be_at}.
85
- by(spaces)
86
- end
87
- end
88
-
89
- context "#started? is false" do
90
- before { subject.stub(:started?).and_return false }
91
-
92
- it "does not increases @proper[:next_line]" do
93
- expect { subject.increase_next_line }.to_not change{subject.next_should_be_at}.
94
- by(spaces)
95
- end
96
- end
97
- end
98
-
99
- describe "#decrease_next_line" do
100
- let!(:spaces) { 27 }
101
-
102
- context "#started? is true" do
103
- before { subject.stub(:started?).and_return true }
104
-
105
- it "decrements @proper[:next_line] by @spaces" do
106
- expect { subject.decrease_next_line }.to change{subject.next_should_be_at}.
107
- by(-spaces)
108
- end
109
- end
110
-
111
- context "#started? is false" do
112
- before { subject.stub(:started?).and_return false }
113
-
114
- it "decrements @proper[:next_line] by @spaces" do
115
- expect { subject.decrease_next_line }.to_not change{subject.next_should_be_at}.
116
- by(-spaces)
117
- end
118
- end
119
- end
120
-
121
72
  describe "#set_up_line_transition" do
122
- context "@amount_to_change_next > 0" do
123
- before { subject.instance_variable_set(:@amount_to_change_next, 1) }
124
-
125
- it "should call #increase_next_line" do
126
- subject.should_receive(:increase_next_line)
127
- subject.set_up_line_transition
128
- end
129
- end
130
-
131
- context "@amount_to_change_next < 0" do
132
- before { subject.instance_variable_set(:@amount_to_change_next, -1) }
133
-
134
- it "should call #increase_next_line" do
135
- subject.should_receive(:decrease_next_line)
136
- subject.set_up_line_transition
137
- end
138
- end
139
-
140
73
  context "@amount_to_change_this < 0" do
141
74
  before { subject.instance_variable_set(:@amount_to_change_this, -1) }
142
75
 
@@ -155,18 +88,16 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
155
88
  subject.instance_variable_set(:@proper, { next_line: 33 })
156
89
 
157
90
  expect { subject.transition_lines }.to change{subject.should_be_at}.
158
- from(subject.should_be_at).to(subject.next_should_be_at)
91
+ from(subject.should_be_at).to(33)
159
92
  end
160
93
  end
161
94
 
162
- context "#started? is true" do
95
+ context "#started? is false" do
163
96
  before { subject.stub(:started?).and_return false }
164
97
 
165
98
  it "sets @proper[:this_line] to @proper[:next_line]" do
166
99
  subject.instance_variable_set(:@proper, { next_line: 33 })
167
-
168
- expect { subject.transition_lines }.to_not change{subject.should_be_at}.
169
- from(subject.should_be_at).to(subject.next_should_be_at)
100
+ expect { subject.transition_lines }.to_not change{subject.should_be_at}
170
101
  end
171
102
  end
172
103
  end
@@ -243,14 +174,19 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
243
174
  end
244
175
 
245
176
  describe "#line_ends_with_single_token_indenter?" do
246
- context "lexed_line doesn't end with an op, comma, or period" do
177
+ context "lexed_line doesn't end with an op, comma, period, label, or kw" do
247
178
  before do
248
179
  lexed_line.stub(ends_with_op?: false)
249
180
  lexed_line.stub(ends_with_comma?: false)
250
181
  lexed_line.stub(ends_with_period?: false)
182
+ lexed_line.stub(ends_with_label?: false)
183
+ lexed_line.stub(ends_with_modifier_kw?: false)
251
184
  end
252
185
 
253
- specify { subject.line_ends_with_single_token_indenter?(lexed_line).should be_false }
186
+ specify do
187
+ subject.line_ends_with_single_token_indenter?(lexed_line).
188
+ should be_false
189
+ end
254
190
  end
255
191
 
256
192
  context "lexed_line ends with an op" do
@@ -258,9 +194,13 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
258
194
  lexed_line.stub(ends_with_op?: true)
259
195
  lexed_line.stub(ends_with_comma?: false)
260
196
  lexed_line.stub(ends_with_period?: false)
197
+ lexed_line.stub(ends_with_label?: false)
198
+ lexed_line.stub(ends_with_modifier_kw?: false)
261
199
  end
262
200
 
263
- specify { subject.line_ends_with_single_token_indenter?(lexed_line).should be_true }
201
+ specify do
202
+ subject.line_ends_with_single_token_indenter?(lexed_line).should be_true
203
+ end
264
204
  end
265
205
 
266
206
  context "lexed_line ends with a comma" do
@@ -268,9 +208,13 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
268
208
  lexed_line.stub(ends_with_op?: false)
269
209
  lexed_line.stub(ends_with_comma?: true)
270
210
  lexed_line.stub(ends_with_period?: false)
211
+ lexed_line.stub(ends_with_label?: false)
212
+ lexed_line.stub(ends_with_modifier_kw?: false)
271
213
  end
272
214
 
273
- specify { subject.line_ends_with_single_token_indenter?(lexed_line).should be_true }
215
+ specify do
216
+ subject.line_ends_with_single_token_indenter?(lexed_line).should be_true
217
+ end
274
218
  end
275
219
 
276
220
  context "lexed_line ends with a period" do
@@ -278,16 +222,48 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
278
222
  lexed_line.stub(ends_with_op?: false)
279
223
  lexed_line.stub(ends_with_comma?: false)
280
224
  lexed_line.stub(ends_with_period?: true)
225
+ lexed_line.stub(ends_with_label?: false)
226
+ lexed_line.stub(ends_with_modifier_kw?: false)
227
+ end
228
+
229
+ specify do
230
+ subject.line_ends_with_single_token_indenter?(lexed_line).should be_true
231
+ end
232
+ end
233
+
234
+ context "lexed_line ends with a label" do
235
+ before do
236
+ lexed_line.stub(ends_with_op?: false)
237
+ lexed_line.stub(ends_with_comma?: false)
238
+ lexed_line.stub(ends_with_period?: false)
239
+ lexed_line.stub(ends_with_label?: true)
240
+ lexed_line.stub(ends_with_modifier_kw?: false)
281
241
  end
282
242
 
283
- specify { subject.line_ends_with_single_token_indenter?(lexed_line).should be_true }
243
+ specify do
244
+ subject.line_ends_with_single_token_indenter?(lexed_line).should be_true
245
+ end
246
+ end
247
+
248
+ context "lexed_line ends with a modified kw" do
249
+ before do
250
+ lexed_line.stub(ends_with_op?: false)
251
+ lexed_line.stub(ends_with_comma?: false)
252
+ lexed_line.stub(ends_with_period?: false)
253
+ lexed_line.stub(ends_with_label?: false)
254
+ lexed_line.stub(ends_with_modifier_kw?: true)
255
+ end
256
+
257
+ specify do
258
+ subject.line_ends_with_single_token_indenter?(lexed_line).should be_true
259
+ end
284
260
  end
285
261
  end
286
262
 
287
263
  describe "#line_ends_with_same_as_last" do
288
- context "@single_tokens is empty" do
264
+ context "@indent_reasons is empty" do
289
265
  before do
290
- subject.instance_variable_set(:@single_tokens, [])
266
+ subject.instance_variable_set(:@indent_reasons, [])
291
267
  end
292
268
 
293
269
  it "returns false" do
@@ -295,11 +271,12 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
295
271
  end
296
272
  end
297
273
 
298
- context "@single_tokens.last[:token] != token_event.last" do
274
+ context "@indent_reasons.last[:token] != token_event.last" do
299
275
  let(:last_single_token) { [[1, 2], :on_comma, ','] }
300
276
 
301
277
  before do
302
- subject.instance_variable_set(:@single_tokens, [{ event: :on_op }])
278
+ subject.instance_variable_set(:@indent_reasons,
279
+ [{ event_type: :on_op }])
303
280
  end
304
281
 
305
282
  it "returns false" do
@@ -307,148 +284,127 @@ describe Tailor::Rulers::IndentationSpacesRuler::IndentationManager do
307
284
  end
308
285
  end
309
286
 
310
- context "@single_tokens.last[:token] == token_event.last" do
287
+ context "@indent_reasons.last[:token] == token_event.last" do
311
288
  let(:last_single_token) { [[1, 2], :on_comma, ','] }
312
289
 
313
290
  before do
314
- subject.instance_variable_set(:@single_tokens, [{ event: :on_comma }])
291
+ subject.instance_variable_set(:@indent_reasons,
292
+ [{ event_type: :on_comma }])
315
293
  end
316
294
 
317
- it "returns false" do
295
+ it "returns true" do
318
296
  subject.line_ends_with_same_as_last(last_single_token).should be_true
319
297
  end
320
298
  end
321
299
  end
322
300
 
323
- describe "#comma_is_part_of_enclosed_statement?" do
324
- context "lexed_line does not end with a comma" do
325
- before { lexed_line.stub(ends_with_comma?: false) }
326
-
327
- it "returns false" do
328
- subject.comma_is_part_of_enclosed_statement?(lexed_line, 1).
329
- should be_false
330
- end
331
- end
332
-
333
- context "lexed_line ends with a comma" do
334
- before { lexed_line.stub(ends_with_comma?: true) }
335
-
336
- context "continuing_enclosed_statement? is true" do
337
- before { subject.stub(continuing_enclosed_statement?: true) }
301
+ describe "#multi_line_parens?" do
302
+ context "an unclosed ( exists on the previous line" do
303
+ context "an unclosed ( does not exist on the current line" do
304
+ before do
305
+ d_tokens = [{ token: '(', lineno: 1 }]
306
+ subject.instance_variable_set(:@indent_reasons, d_tokens)
307
+ end
338
308
 
339
309
  it "returns true" do
340
- subject.comma_is_part_of_enclosed_statement?(lexed_line, 1).
341
- should be_true
310
+ subject.multi_line_parens?(2).should be_true
342
311
  end
343
312
  end
344
313
 
345
- context "continuing_enclosed_statement? is true" do
346
- before { subject.stub(continuing_enclosed_statement?: false) }
314
+ context "an unclosed ( exists on the current line" do
315
+ before do
316
+ d_tokens = [{ token: '(', lineno: 1 }, { token: '(', lineno: 2 }]
317
+ subject.instance_variable_set(:@indent_reasons, d_tokens)
318
+ end
347
319
 
348
- it "returns false" do
349
- subject.comma_is_part_of_enclosed_statement?(lexed_line, 1).
350
- should be_false
320
+ it "returns true" do
321
+ subject.multi_line_parens?(2).should be_false
351
322
  end
352
323
  end
353
324
  end
354
- end
355
325
 
356
- describe "#keyword_and_single_token_line?" do
357
- context "no @double_tokens on this line" do
326
+ context "an unclosed ( does not exist on the previous line" do
358
327
  before do
359
- d_tokens = [{ lineno: 12345 }]
360
- subject.instance_variable_set(:@double_tokens, d_tokens)
328
+ d_tokens = [{ token: '(', lineno: 1 }]
329
+ subject.instance_variable_set(:@indent_reasons, d_tokens)
361
330
  end
362
331
 
363
- it "returns false" do
364
- subject.keyword_and_single_token_line?(1).should be_false
332
+ it "returns true" do
333
+ subject.multi_line_parens?(1).should be_false
365
334
  end
366
335
  end
336
+ end
367
337
 
368
- context "@double_tokens exist on this line" do
369
- context "no kw tokens on this line" do
370
- before do
371
- d_tokens = [{ token: '{', lineno: 1 }]
372
- subject.instance_variable_set(:@double_tokens, d_tokens)
373
- end
338
+ describe "#last_opening_event" do
339
+ context "@indent_reasons is empty" do
340
+ before { subject.instance_variable_set(:@indent_reasons, []) }
341
+ specify { subject.last_opening_event(nil).should be_nil }
342
+ end
374
343
 
375
- it "returns false" do
376
- subject.keyword_and_single_token_line?(1).should be_false
377
- end
344
+ context "@indent_reasons contains the corresponding opening event" do
345
+ let(:indent_reasons) do
346
+ [{ event_type: :on_lparen }, { event_type: :on_lbrace }]
378
347
  end
379
348
 
380
- context "kw tokens on this line" do
381
- before do
382
- d_tokens = [{ token: 'class', lineno: 1 }]
383
- subject.instance_variable_set(:@double_tokens, d_tokens)
384
- end
349
+ before { subject.instance_variable_set(:@indent_reasons, indent_reasons) }
385
350
 
386
- context "no @single_tokens on this line" do
387
- it "returns false" do
388
- subject.keyword_and_single_token_line?(1).should be_false
389
- end
351
+ context "the corresponding opening event is last" do
352
+ it "returns the matching opening event" do
353
+ subject.last_opening_event(:on_rbrace).should == indent_reasons.last
390
354
  end
355
+ end
391
356
 
392
- context "@single_tokens exist on this line" do
393
- before do
394
- s_tokens = [{ token: '[', lineno: 1 }]
395
- subject.instance_variable_set(:@single_tokens, s_tokens)
396
- end
397
-
398
- it "returns true" do
399
- subject.keyword_and_single_token_line?(1).should be_true
400
- end
357
+ context "the corresponding opening event is not last" do
358
+ it "returns the matching opening event" do
359
+ subject.last_opening_event(:on_rparen).should == indent_reasons.first
401
360
  end
402
361
  end
403
362
  end
404
363
  end
405
364
 
406
- describe "#multi_line_braces?" do
407
- pending
408
- end
365
+ describe "#remove_continuation_keywords" do
366
+ before do
367
+ subject.instance_variable_set(:@indent_reasons, indent_reasons)
368
+ end
409
369
 
410
- describe "#multi_line_brackets?" do
411
- pending
412
- end
370
+ context "@indent_reasons is empty" do
371
+ let(:indent_reasons) do
372
+ i = double "@indent_reasons"
373
+ i.stub_chain(:last, :[]).and_return []
374
+ i.stub(:empty?).and_return true
413
375
 
414
- describe "#multi_line_parens?" do
415
- context "an unclosed ( exists on the previous line" do
416
- context "an unclosed ( does not exist on the current line" do
417
- before do
418
- d_tokens = [{ token: '(', lineno: 1 }]
419
- subject.instance_variable_set(:@double_tokens, d_tokens)
420
- end
421
-
422
- it "returns true" do
423
- subject.multi_line_parens?(2).should be_true
424
- end
376
+ i
425
377
  end
426
378
 
427
- context "an unclosed ( exists on the current line" do
428
- before do
429
- d_tokens = [{ token: '(', lineno: 1 }, { token: '(', lineno: 2 }]
430
- subject.instance_variable_set(:@double_tokens, d_tokens)
431
- end
379
+ specify { subject.remove_continuation_keywords.should be_nil }
380
+ end
432
381
 
433
- it "returns true" do
434
- subject.multi_line_parens?(2).should be_false
435
- end
382
+ context "@indent_reasons does not contain CONTINUATION_KEYWORDS" do
383
+ let(:indent_reasons) do
384
+ i = double "@indent_reasons"
385
+ i.stub_chain(:last, :[]).and_return [{ token: 'if' }]
386
+ i.stub(:empty?).and_return false
387
+
388
+ i
389
+ end
390
+
391
+ it "should not call #pop on @indent_reasons" do
392
+ indent_reasons.should_not_receive(:pop)
393
+ subject.remove_continuation_keywords
436
394
  end
437
395
  end
438
396
 
439
- context "an unclosed ( does not exist on the previous line" do
440
- before do
441
- d_tokens = [{ token: '(', lineno: 1 }]
442
- subject.instance_variable_set(:@double_tokens, d_tokens)
397
+ context "@indent_reasons contains CONTINUATION_KEYWORDS" do
398
+ let(:indent_reasons) do
399
+ [{ token: 'if' }, { token: 'elsif' }]
443
400
  end
444
401
 
445
- it "returns true" do
446
- subject.multi_line_parens?(1).should be_false
402
+ it "should call #pop on @indent_reasons one time" do
403
+ subject.instance_variable_set(:@indent_reasons, indent_reasons)
404
+ subject.remove_continuation_keywords
405
+ subject.instance_variable_get(:@indent_reasons).should ==
406
+ [{ token: 'if' }]
447
407
  end
448
408
  end
449
409
  end
450
-
451
- describe "#in_tstring?" do
452
- pending
453
- end
454
410
  end