cuke_linter 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/cuke_linter.gemspec +1 -0
- data/lib/cuke_linter.rb +24 -3
- data/lib/cuke_linter/linters/element_with_too_many_tags_linter.rb +41 -0
- data/lib/cuke_linter/linters/feature_without_name_linter.rb +20 -0
- data/lib/cuke_linter/linters/test_with_no_action_step_linter.rb +23 -0
- data/lib/cuke_linter/linters/test_with_no_name_linter.rb +20 -0
- data/lib/cuke_linter/linters/test_with_no_verification_step_linter.rb +23 -0
- data/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb +1 -1
- data/lib/cuke_linter/version.rb +1 -1
- data/testing/cucumber/features/command_line.feature +6 -4
- data/testing/cucumber/features/configuration/configuring_linters.feature +36 -0
- data/testing/cucumber/features/linters/{background_does_more_than_setup_linter.feature → background_does_more_than_setup.feature} +2 -2
- data/testing/cucumber/features/linters/custom_linters.feature +3 -3
- data/testing/cucumber/features/linters/default_linters.feature +5 -1
- data/testing/cucumber/features/linters/element_with_too_many_tags.feature +70 -0
- data/testing/cucumber/features/linters/example_without_name.feature +6 -1
- data/testing/cucumber/features/linters/feature_without_description.feature +1 -1
- data/testing/cucumber/features/linters/feature_without_name.feature +18 -0
- data/testing/cucumber/features/linters/feature_without_scenarios.feature +1 -1
- data/testing/cucumber/features/linters/outline_with_single_example_row.feature +1 -1
- data/testing/cucumber/features/linters/{single_test_background_linter.feature → single_test_background.feature} +1 -1
- data/testing/cucumber/features/linters/step_too_long.feature +3 -3
- data/testing/cucumber/features/linters/step_with_end_period.feature +1 -1
- data/testing/cucumber/features/linters/test_with_no_action_step.feature +30 -0
- data/testing/cucumber/features/linters/test_with_no_name.feature +23 -0
- data/testing/cucumber/features/linters/test_with_no_verification_step.feature +31 -0
- data/testing/cucumber/features/linters/test_with_too_many_steps.feature +6 -6
- data/testing/cucumber/step_definitions/setup_steps.rb +24 -0
- data/testing/cucumber/step_definitions/verification_steps.rb +5 -1
- data/testing/model_factory.rb +1 -0
- data/testing/rspec/spec/integration/cli_integration_spec.rb +16 -11
- data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +37 -0
- data/testing/rspec/spec/integration/linters/element_with_too_many_tags_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/feature_without_name_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_no_action_step_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_no_name_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_no_verification_step_integration_spec.rb +8 -0
- data/testing/rspec/spec/unit/linters/element_with_too_many_tags_linter_unit_spec.rb +333 -0
- data/testing/rspec/spec/unit/linters/feature_without_name_linter_unit_spec.rb +112 -0
- data/testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb +53 -52
- data/testing/rspec/spec/unit/linters/test_with_no_action_step_linter_unit_spec.rb +217 -0
- data/testing/rspec/spec/unit/linters/test_with_no_name_linter_unit_spec.rb +115 -0
- data/testing/rspec/spec/unit/linters/test_with_no_verification_step_linter_unit_spec.rb +217 -0
- data/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +2 -2
- metadata +24 -4
@@ -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
|