cuke_linter 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/cuke_linter.gemspec +1 -0
  4. data/lib/cuke_linter.rb +24 -3
  5. data/lib/cuke_linter/linters/element_with_too_many_tags_linter.rb +41 -0
  6. data/lib/cuke_linter/linters/feature_without_name_linter.rb +20 -0
  7. data/lib/cuke_linter/linters/test_with_no_action_step_linter.rb +23 -0
  8. data/lib/cuke_linter/linters/test_with_no_name_linter.rb +20 -0
  9. data/lib/cuke_linter/linters/test_with_no_verification_step_linter.rb +23 -0
  10. data/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb +1 -1
  11. data/lib/cuke_linter/version.rb +1 -1
  12. data/testing/cucumber/features/command_line.feature +6 -4
  13. data/testing/cucumber/features/configuration/configuring_linters.feature +36 -0
  14. data/testing/cucumber/features/linters/{background_does_more_than_setup_linter.feature → background_does_more_than_setup.feature} +2 -2
  15. data/testing/cucumber/features/linters/custom_linters.feature +3 -3
  16. data/testing/cucumber/features/linters/default_linters.feature +5 -1
  17. data/testing/cucumber/features/linters/element_with_too_many_tags.feature +70 -0
  18. data/testing/cucumber/features/linters/example_without_name.feature +6 -1
  19. data/testing/cucumber/features/linters/feature_without_description.feature +1 -1
  20. data/testing/cucumber/features/linters/feature_without_name.feature +18 -0
  21. data/testing/cucumber/features/linters/feature_without_scenarios.feature +1 -1
  22. data/testing/cucumber/features/linters/outline_with_single_example_row.feature +1 -1
  23. data/testing/cucumber/features/linters/{single_test_background_linter.feature → single_test_background.feature} +1 -1
  24. data/testing/cucumber/features/linters/step_too_long.feature +3 -3
  25. data/testing/cucumber/features/linters/step_with_end_period.feature +1 -1
  26. data/testing/cucumber/features/linters/test_with_no_action_step.feature +30 -0
  27. data/testing/cucumber/features/linters/test_with_no_name.feature +23 -0
  28. data/testing/cucumber/features/linters/test_with_no_verification_step.feature +31 -0
  29. data/testing/cucumber/features/linters/test_with_too_many_steps.feature +6 -6
  30. data/testing/cucumber/step_definitions/setup_steps.rb +24 -0
  31. data/testing/cucumber/step_definitions/verification_steps.rb +5 -1
  32. data/testing/model_factory.rb +1 -0
  33. data/testing/rspec/spec/integration/cli_integration_spec.rb +16 -11
  34. data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +37 -0
  35. data/testing/rspec/spec/integration/linters/element_with_too_many_tags_linter_integration_spec.rb +8 -0
  36. data/testing/rspec/spec/integration/linters/feature_without_name_linter_integration_spec.rb +8 -0
  37. data/testing/rspec/spec/integration/linters/test_with_no_action_step_integration_spec.rb +8 -0
  38. data/testing/rspec/spec/integration/linters/test_with_no_name_integration_spec.rb +8 -0
  39. data/testing/rspec/spec/integration/linters/test_with_no_verification_step_integration_spec.rb +8 -0
  40. data/testing/rspec/spec/unit/linters/element_with_too_many_tags_linter_unit_spec.rb +333 -0
  41. data/testing/rspec/spec/unit/linters/feature_without_name_linter_unit_spec.rb +112 -0
  42. data/testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb +53 -52
  43. data/testing/rspec/spec/unit/linters/test_with_no_action_step_linter_unit_spec.rb +217 -0
  44. data/testing/rspec/spec/unit/linters/test_with_no_name_linter_unit_spec.rb +115 -0
  45. data/testing/rspec/spec/unit/linters/test_with_no_verification_step_linter_unit_spec.rb +217 -0
  46. data/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +2 -2
  47. metadata +24 -4
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::TestWithNoNameLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::TestWithNoVerificationStepLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,333 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::ElementWithTooManyTagsLinter do
5
+
6
+ let(:good_data) do
7
+ model = CukeLinter::ModelFactory.generate_scenario_model
8
+ model.tags = [:tag_1]
9
+
10
+ model
11
+ end
12
+
13
+ let(:bad_data) do
14
+ model = CukeLinter::ModelFactory.generate_scenario_model
15
+ model.tags = [:tag_1,
16
+ :tag_2,
17
+ :tag_3,
18
+ :tag_4,
19
+ :tag_5,
20
+ :tag_6]
21
+
22
+ model
23
+ end
24
+
25
+
26
+ it_should_behave_like 'a linter at the unit level'
27
+ it_should_behave_like 'a configurable linter at the unit level'
28
+
29
+
30
+ it 'has a name' do
31
+ expect(subject.name).to eq('ElementWithTooManyTagsLinter')
32
+ end
33
+
34
+ describe 'linting' do
35
+
36
+ ['feature', 'scenario', 'outline', 'example'].each do |model_type|
37
+
38
+ context "with a #{model_type} that has too many tags" do
39
+
40
+ let(:test_model) do
41
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
42
+ model.tags = [:tag_1,
43
+ :tag_2,
44
+ :tag_3,
45
+ :tag_4,
46
+ :tag_5,
47
+ :tag_6]
48
+
49
+ model
50
+ end
51
+
52
+ it 'records a problem' do
53
+ result = subject.lint(test_model)
54
+
55
+ expect(result[:problem]).to match(/^#{model_type.capitalize} has too many tags. \d+ tags found \(max 5\)\.$/)
56
+ end
57
+
58
+ it 'records the location of the problem' do
59
+ test_model.source_line = 1
60
+ result = subject.lint(test_model)
61
+ expect(result[:location]).to eq('path_to_file:1')
62
+
63
+ test_model.source_line = 3
64
+ result = subject.lint(test_model)
65
+ expect(result[:location]).to eq('path_to_file:3')
66
+ end
67
+
68
+ it 'includes the number of tags found in the problem record' do
69
+ tag_count = test_model.tags.count
70
+ result = subject.lint(test_model)
71
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{tag_count} tags found (max 5).")
72
+
73
+ test_model.tags << :another_tag
74
+ result = subject.lint(test_model)
75
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{tag_count + 1} tags found (max 5).")
76
+ end
77
+
78
+ end
79
+
80
+ context "with a #{model_type} that does not have too many tags" do
81
+
82
+ context 'because it has 5 tags' do
83
+
84
+ let(:test_model) do
85
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
86
+ model.tags = [:tag_1,
87
+ :tag_2,
88
+ :tag_3,
89
+ :tag_4,
90
+ :tag_5]
91
+
92
+ model
93
+ end
94
+
95
+ it 'does not record a problem' do
96
+ expect(subject.lint(test_model)).to eq(nil)
97
+ end
98
+
99
+ end
100
+
101
+ context 'because it has fewer than 5 tags' do
102
+
103
+ let(:test_model) do
104
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
105
+ model.tags = [:tag_1]
106
+
107
+ model
108
+ end
109
+
110
+ it 'does not record a problem' do
111
+ expect(subject.lint(test_model)).to eq(nil)
112
+ end
113
+
114
+ end
115
+
116
+ context 'because it has no tags' do
117
+
118
+ context 'because its tags are empty' do
119
+
120
+ let(:test_model) do
121
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
122
+ model.tags = []
123
+
124
+ model
125
+ end
126
+
127
+ it 'does not record a problem' do
128
+ expect(subject.lint(test_model)).to eq(nil)
129
+ end
130
+
131
+ end
132
+
133
+ context 'because its tags are nil' do
134
+
135
+ let(:test_model) do
136
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
137
+ model.tags = nil
138
+
139
+ model
140
+ end
141
+
142
+ it 'does not record a problem' do
143
+ expect(subject.lint(test_model)).to eq(nil)
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
152
+
153
+ describe 'configuration' do
154
+
155
+ let(:default_tag_threshold) { 5 }
156
+
157
+
158
+ describe 'tag threshold configuration' do
159
+
160
+ context 'with no configuration' do
161
+
162
+ context 'because configuration never happened' do
163
+
164
+ let(:unconfigured_test_model) do
165
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
166
+ model.tags = []
167
+ (default_tag_threshold + 1).times { model.tags << :a_tag }
168
+
169
+ model
170
+ end
171
+
172
+ it 'defaults to a tag threshold of 5 tags' do
173
+ result = subject.lint(unconfigured_test_model)
174
+
175
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{unconfigured_test_model.tags.count} tags found (max 5).")
176
+ end
177
+
178
+ end
179
+
180
+ context 'because configuration did not set a tag threshold' do
181
+
182
+ let(:configuration) { {} }
183
+ let(:test_model) do
184
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
185
+ model.tags = []
186
+ (default_tag_threshold + 1).times { model.tags << :a_tag }
187
+
188
+ model
189
+ end
190
+
191
+ before(:each) do
192
+ subject.configure(configuration)
193
+ end
194
+
195
+ it 'defaults to a tag threshold of 5 tags' do
196
+ result = subject.lint(test_model)
197
+
198
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{test_model.tags.count} tags found (max 5).")
199
+ end
200
+
201
+ end
202
+
203
+ end
204
+
205
+ context 'with configuration' do
206
+
207
+ let(:tag_threshold) { 3 }
208
+ let(:configuration) { { 'TagCountThreshold' => tag_threshold } }
209
+
210
+ before(:each) do
211
+ subject.configure(configuration)
212
+ end
213
+
214
+ let(:test_model) do
215
+ model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
216
+ model.tags = []
217
+ (tag_threshold + 1).times { model.tags << :a_tag }
218
+
219
+ model
220
+ end
221
+
222
+ it 'the tag threshold used is the configured value' do
223
+ result = subject.lint(test_model)
224
+
225
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{test_model.tags.count} tags found (max #{tag_threshold}).")
226
+ end
227
+
228
+ end
229
+
230
+ end
231
+
232
+
233
+ describe 'tag inheritance configuration' do
234
+
235
+ let(:test_model_with_inherited_tags) do
236
+ test_model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
237
+ test_model.tags = []
238
+ (default_tag_threshold).times { test_model.tags << :a_tag }
239
+
240
+ ancestor_model = CukeLinter::ModelFactory.generate_lintable_model
241
+ ancestor_model.tags = [:an_extra_tag]
242
+
243
+ test_model.parent_model = ancestor_model
244
+
245
+ test_model
246
+ end
247
+
248
+
249
+ context 'with no configuration' do
250
+
251
+ context 'because configuration never happened' do
252
+
253
+ it 'does not include inherited tags' do
254
+ result = subject.lint(test_model_with_inherited_tags)
255
+
256
+ expect(result).to eq(nil)
257
+ end
258
+
259
+ end
260
+
261
+ context 'because configuration did not set tag inheritance' do
262
+
263
+ let(:configuration) { {} }
264
+
265
+ before(:each) do
266
+ subject.configure(configuration)
267
+ end
268
+
269
+ it 'does not include inherited tags' do
270
+ result = subject.lint(test_model_with_inherited_tags)
271
+
272
+ expect(result).to eq(nil)
273
+ end
274
+
275
+ end
276
+
277
+ end
278
+
279
+ context 'with configuration' do
280
+
281
+ before(:each) do
282
+ subject.configure(configuration)
283
+ end
284
+
285
+ context 'enabling tag inheritance' do
286
+
287
+ let(:configuration) { { 'CountInheritedTags' => true } }
288
+
289
+ it 'does include inherited tags' do
290
+ result = subject.lint(test_model_with_inherited_tags)
291
+
292
+ expect(result).to_not be_nil
293
+ expect(result[:problem]).to eq("#{model_type.capitalize} has too many tags. #{test_model_with_inherited_tags.all_tags.count} tags found (max #{default_tag_threshold}).")
294
+ end
295
+
296
+ end
297
+
298
+ context 'disabling tag inheritance' do
299
+
300
+ let(:configuration) { { 'CountInheritedTags' => false } }
301
+
302
+ it 'does not include inherited tags' do
303
+ result = subject.lint(test_model_with_inherited_tags)
304
+
305
+ expect(result).to eq(nil)
306
+ end
307
+
308
+ end
309
+
310
+ end
311
+
312
+ end
313
+
314
+ end
315
+
316
+ end
317
+
318
+
319
+ context 'a non-taggable model' do
320
+
321
+ let(:test_model) { CukeModeler::Model.new }
322
+
323
+ it 'returns no result' do
324
+ result = subject.lint(test_model)
325
+
326
+ expect(result).to eq(nil)
327
+ end
328
+
329
+ end
330
+
331
+ end
332
+
333
+ end
@@ -0,0 +1,112 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::FeatureWithoutNameLinter do
5
+
6
+ let(:good_data) do
7
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature: some name')
8
+ end
9
+
10
+ let(:bad_data) do
11
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:')
12
+ end
13
+
14
+
15
+ it_should_behave_like 'a linter at the unit level'
16
+
17
+
18
+ it 'has a name' do
19
+ expect(subject.name).to eq('FeatureWithoutNameLinter')
20
+ end
21
+
22
+ describe 'linting' do
23
+
24
+ context 'with a feature that has no name' do
25
+
26
+ context 'because its name is empty' do
27
+
28
+ let(:test_model) do
29
+ model = CukeLinter::ModelFactory.generate_feature_model(parent_file_path: 'path_to_file')
30
+ model.name = ''
31
+
32
+ model
33
+ end
34
+
35
+ it 'records a problem' do
36
+ result = subject.lint(test_model)
37
+
38
+ expect(result[:problem]).to eq('Feature does not have a name.')
39
+ end
40
+
41
+ it 'records the location of the problem' do
42
+ test_model.source_line = 1
43
+ result = subject.lint(test_model)
44
+ expect(result[:location]).to eq('path_to_file:1')
45
+
46
+ test_model.source_line = 3
47
+ result = subject.lint(test_model)
48
+ expect(result[:location]).to eq('path_to_file:3')
49
+ end
50
+
51
+ end
52
+
53
+ context 'because its name is nil' do
54
+
55
+ let(:test_model) do
56
+ model = CukeLinter::ModelFactory.generate_feature_model(parent_file_path: 'path_to_file')
57
+ model.name = nil
58
+
59
+ model
60
+ end
61
+
62
+ it 'records a problem' do
63
+ result = subject.lint(test_model)
64
+
65
+ expect(result[:problem]).to eq('Feature does not have a name.')
66
+ end
67
+
68
+ it 'records the location of the problem' do
69
+ test_model.source_line = 1
70
+ result = subject.lint(test_model)
71
+ expect(result[:location]).to eq('path_to_file:1')
72
+
73
+ test_model.source_line = 3
74
+ result = subject.lint(test_model)
75
+ expect(result[:location]).to eq('path_to_file:3')
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+
82
+ context 'with a feature that does have a name' do
83
+
84
+ let(:test_model) do
85
+ model = CukeLinter::ModelFactory.generate_feature_model
86
+ model.name = 'foo'
87
+
88
+ model
89
+ end
90
+
91
+ it 'does not record a problem' do
92
+ expect(subject.lint(test_model)).to eq(nil)
93
+ end
94
+
95
+ end
96
+
97
+
98
+ context 'a non-feature model' do
99
+
100
+ let(:test_model) { CukeModeler::Model.new }
101
+
102
+ it 'returns no result' do
103
+ result = subject.lint(test_model)
104
+
105
+ expect(result).to eq(nil)
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+
112
+ end