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
@@ -25,7 +25,7 @@ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
describe 'linting' do
|
28
|
-
|
28
|
+
|
29
29
|
let(:default_character_threshold) { 80 }
|
30
30
|
|
31
31
|
context 'when the step is too long' do
|
@@ -34,16 +34,16 @@ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
|
|
34
34
|
step = 'x' * (default_character_threshold + 1)
|
35
35
|
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it 'reports a problem' do
|
39
39
|
result = subject.lint(step_too_long_model)
|
40
40
|
|
41
41
|
expect(result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it 'records the location of the problem' do
|
45
45
|
result = subject.lint(step_too_long_model)
|
46
|
-
|
46
|
+
|
47
47
|
expect(result[:location]).to eq('path_to_file:4')
|
48
48
|
end
|
49
49
|
|
@@ -58,19 +58,19 @@ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
context 'when the step is the maximum length' do
|
63
|
-
|
63
|
+
|
64
64
|
let(:step_mex_length_model) do
|
65
65
|
step = 'x' * default_character_threshold
|
66
66
|
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it 'does not record a problem' do
|
70
70
|
result = subject.lint(step_mex_length_model)
|
71
71
|
expect(result).to eq(nil)
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
end
|
75
75
|
|
76
76
|
context 'when the step is below the maximum length' do
|
@@ -103,50 +103,62 @@ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
|
|
103
103
|
|
104
104
|
end
|
105
105
|
|
106
|
+
context 'a non-step model' do
|
107
|
+
|
108
|
+
let(:test_model) { CukeModeler::Model.new }
|
109
|
+
|
110
|
+
it 'returns no result' do
|
111
|
+
result = subject.lint(test_model)
|
112
|
+
|
113
|
+
expect(result).to eq(nil)
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
106
118
|
end
|
107
119
|
|
108
120
|
describe 'configuration' do
|
109
121
|
|
110
122
|
context 'with no configuration' do
|
111
123
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'because configuration did not set a step threshold' do
|
130
|
-
let(:configuration) { {} }
|
131
|
-
let(:configured_model) do
|
132
|
-
subject.configure(configuration)
|
133
|
-
step = 'x' * (default_character_threshold + 1)
|
134
|
-
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
135
|
-
end
|
124
|
+
let(:default_character_threshold) { 80 }
|
125
|
+
|
126
|
+
context 'because configuration never happened' do
|
127
|
+
|
128
|
+
let(:default_model) do
|
129
|
+
step = 'x' * (default_character_threshold + 1)
|
130
|
+
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'defaults to a maximum of 80 characters' do
|
134
|
+
result = subject.lint(default_model)
|
135
|
+
|
136
|
+
expect(result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
|
137
|
+
end
|
136
138
|
|
137
|
-
it 'defaults to a maximum of 80 characters' do
|
138
|
-
result = subject.lint(configured_model)
|
139
|
-
|
140
|
-
expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
|
141
139
|
end
|
142
140
|
|
143
|
-
|
141
|
+
context 'because configuration did not set a step threshold' do
|
142
|
+
let(:configuration) { {} }
|
143
|
+
let(:configured_model) do
|
144
|
+
subject.configure(configuration)
|
145
|
+
step = 'x' * (default_character_threshold + 1)
|
146
|
+
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'defaults to a maximum of 80 characters' do
|
150
|
+
result = subject.lint(configured_model)
|
151
|
+
|
152
|
+
expect(result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
144
156
|
|
145
157
|
end
|
146
158
|
|
147
159
|
context 'when configured' do
|
148
160
|
let(:character_threshold) { 10 }
|
149
|
-
let(:configuration) { {'StepLengthThreshold' => character_threshold} }
|
161
|
+
let(:configuration) { { 'StepLengthThreshold' => character_threshold } }
|
150
162
|
|
151
163
|
subject { linter = CukeLinter::StepWithTooManyCharactersLinter.new
|
152
164
|
linter.configure(configuration)
|
@@ -156,25 +168,14 @@ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
|
|
156
168
|
step = 'x' * (character_threshold + 1)
|
157
169
|
CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
|
158
170
|
end
|
159
|
-
|
160
|
-
it 'uses the maximum character length provided by configuration' do
|
161
|
-
result = subject.lint(test_model)
|
162
|
-
|
163
|
-
expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 10\)/)
|
164
|
-
end
|
165
|
-
|
166
|
-
end
|
167
|
-
|
168
|
-
context 'a non-step model' do
|
169
171
|
|
170
|
-
|
171
|
-
|
172
|
-
it 'returns no result' do
|
172
|
+
it 'uses the maximum character length provided by configuration' do
|
173
173
|
result = subject.lint(test_model)
|
174
174
|
|
175
|
-
expect(result).to
|
175
|
+
expect(result[:problem]).to match(/^Step is too long. \d+ characters found \(max 10\)/)
|
176
176
|
end
|
177
177
|
|
178
178
|
end
|
179
|
+
|
179
180
|
end
|
180
181
|
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require_relative '../../../../../environments/rspec_env'
|
2
|
+
|
3
|
+
|
4
|
+
RSpec.describe CukeLinter::TestWithNoActionStepLinter do
|
5
|
+
|
6
|
+
let(:good_data) do
|
7
|
+
CukeLinter::ModelFactory.generate_scenario_model(source_text: 'Scenario:
|
8
|
+
When an action step')
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:bad_data) do
|
12
|
+
CukeLinter::ModelFactory.generate_scenario_model(source_text: 'Scenario:
|
13
|
+
* no action step')
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
it_should_behave_like 'a linter at the unit level'
|
18
|
+
|
19
|
+
|
20
|
+
it 'has a name' do
|
21
|
+
expect(subject.name).to eq('TestWithNoActionStepLinter')
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'linting' do
|
25
|
+
|
26
|
+
['scenario', 'outline'].each do |model_type|
|
27
|
+
|
28
|
+
context "with a #{model_type} that has no action step" do
|
29
|
+
|
30
|
+
context 'because it has no steps' do
|
31
|
+
|
32
|
+
context 'because its steps are empty' do
|
33
|
+
|
34
|
+
let(:test_model) do
|
35
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
|
36
|
+
model.steps = []
|
37
|
+
|
38
|
+
model
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'records a problem' do
|
42
|
+
result = subject.lint(test_model)
|
43
|
+
|
44
|
+
expect(result[:problem]).to eq("Test does not have a 'When' step.")
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'records the location of the problem' do
|
48
|
+
test_model.source_line = 1
|
49
|
+
result = subject.lint(test_model)
|
50
|
+
expect(result[:location]).to eq('path_to_file:1')
|
51
|
+
|
52
|
+
test_model.source_line = 3
|
53
|
+
result = subject.lint(test_model)
|
54
|
+
expect(result[:location]).to eq('path_to_file:3')
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'because its steps are nil' do
|
60
|
+
|
61
|
+
let(:test_model) do
|
62
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
|
63
|
+
model.steps = nil
|
64
|
+
|
65
|
+
model
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'records a problem' do
|
69
|
+
result = subject.lint(test_model)
|
70
|
+
|
71
|
+
expect(result[:problem]).to eq("Test does not have a 'When' step.")
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'records the location of the problem' do
|
75
|
+
test_model.source_line = 1
|
76
|
+
result = subject.lint(test_model)
|
77
|
+
expect(result[:location]).to eq('path_to_file:1')
|
78
|
+
|
79
|
+
test_model.source_line = 3
|
80
|
+
result = subject.lint(test_model)
|
81
|
+
expect(result[:location]).to eq('path_to_file:3')
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'because none of its steps is an action step' do
|
89
|
+
|
90
|
+
let(:test_model) do
|
91
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
|
92
|
+
model.steps = [CukeModeler::Step.new('* not an action step')]
|
93
|
+
|
94
|
+
model
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'records a problem' do
|
98
|
+
result = subject.lint(test_model)
|
99
|
+
|
100
|
+
expect(result[:problem]).to eq("Test does not have a 'When' step.")
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'records the location of the problem' do
|
104
|
+
test_model.source_line = 1
|
105
|
+
result = subject.lint(test_model)
|
106
|
+
expect(result[:location]).to eq('path_to_file:1')
|
107
|
+
|
108
|
+
test_model.source_line = 3
|
109
|
+
result = subject.lint(test_model)
|
110
|
+
expect(result[:location]).to eq('path_to_file:3')
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with a #{model_type} that does have an action step" do
|
118
|
+
|
119
|
+
context 'that comes from its background' do
|
120
|
+
|
121
|
+
let(:test_model) do
|
122
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
|
123
|
+
model.steps = []
|
124
|
+
background_model = CukeModeler::Background.new
|
125
|
+
background_model.steps = [CukeModeler::Step.new('When an action step')]
|
126
|
+
model.parent_model.background = background_model
|
127
|
+
|
128
|
+
model
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'does not record a problem' do
|
132
|
+
expect(subject.lint(test_model)).to eq(nil)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'that is part of itself' do
|
138
|
+
|
139
|
+
let(:test_model) do
|
140
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
|
141
|
+
model.steps = [CukeModeler::Step.new('When an action step')]
|
142
|
+
|
143
|
+
model
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'does not record a problem' do
|
147
|
+
expect(subject.lint(test_model)).to eq(nil)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
['scenario', 'outline'].each do |model_type|
|
157
|
+
|
158
|
+
context "with a #{model_type} that has a related background" do
|
159
|
+
|
160
|
+
let(:test_model) do
|
161
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
|
162
|
+
model.parent_model.background = background_model
|
163
|
+
|
164
|
+
model
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'that has no background steps' do
|
168
|
+
context 'because its steps are empty' do
|
169
|
+
|
170
|
+
let(:background_model) do
|
171
|
+
model = CukeModeler::Background.new
|
172
|
+
model.steps = []
|
173
|
+
|
174
|
+
model
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'can handle it' do
|
178
|
+
expect { subject.lint(test_model) }.to_not raise_error
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'because its steps are nil' do
|
184
|
+
|
185
|
+
let(:background_model) do
|
186
|
+
model = CukeModeler::Background.new
|
187
|
+
model.steps = nil
|
188
|
+
|
189
|
+
model
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'can handle it' do
|
193
|
+
expect { subject.lint(test_model) }.to_not raise_error
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
context 'a non-test model' do
|
206
|
+
|
207
|
+
let(:test_model) { CukeModeler::Model.new }
|
208
|
+
|
209
|
+
it 'returns no result' do
|
210
|
+
result = subject.lint(test_model)
|
211
|
+
|
212
|
+
expect(result).to eq(nil)
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require_relative '../../../../../environments/rspec_env'
|
2
|
+
|
3
|
+
|
4
|
+
RSpec.describe CukeLinter::TestWithNoNameLinter do
|
5
|
+
|
6
|
+
let(:good_data) do
|
7
|
+
CukeLinter::ModelFactory.generate_scenario_model(source_text: 'Scenario: some name')
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:bad_data) do
|
11
|
+
CukeLinter::ModelFactory.generate_scenario_model(source_text: 'Scenario:')
|
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('TestWithNoNameLinter')
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'linting' do
|
23
|
+
|
24
|
+
['scenario', 'outline'].each do |model_type|
|
25
|
+
|
26
|
+
context "with a #{model_type} that has no name" do
|
27
|
+
|
28
|
+
context 'because its name is empty' do
|
29
|
+
|
30
|
+
let(:test_model) do
|
31
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
|
32
|
+
model.name = ''
|
33
|
+
|
34
|
+
model
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'records a problem' do
|
38
|
+
result = subject.lint(test_model)
|
39
|
+
|
40
|
+
expect(result[:problem]).to eq('Test does not have a name.')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'records the location of the problem' do
|
44
|
+
test_model.source_line = 1
|
45
|
+
result = subject.lint(test_model)
|
46
|
+
expect(result[:location]).to eq('path_to_file:1')
|
47
|
+
|
48
|
+
test_model.source_line = 3
|
49
|
+
result = subject.lint(test_model)
|
50
|
+
expect(result[:location]).to eq('path_to_file:3')
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'because its name is nil' do
|
56
|
+
|
57
|
+
let(:test_model) do
|
58
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model", parent_file_path: 'path_to_file')
|
59
|
+
model.name = nil
|
60
|
+
|
61
|
+
model
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'records a problem' do
|
65
|
+
result = subject.lint(test_model)
|
66
|
+
|
67
|
+
expect(result[:problem]).to eq('Test does not have a name.')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'records the location of the problem' do
|
71
|
+
test_model.source_line = 1
|
72
|
+
result = subject.lint(test_model)
|
73
|
+
expect(result[:location]).to eq('path_to_file:1')
|
74
|
+
|
75
|
+
test_model.source_line = 3
|
76
|
+
result = subject.lint(test_model)
|
77
|
+
expect(result[:location]).to eq('path_to_file:3')
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with a #{model_type} that does have a name" do
|
85
|
+
|
86
|
+
let(:test_model) do
|
87
|
+
model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
|
88
|
+
model.name = 'foo'
|
89
|
+
|
90
|
+
model
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does not record a problem' do
|
94
|
+
expect(subject.lint(test_model)).to eq(nil)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'a non-test model' do
|
102
|
+
|
103
|
+
let(:test_model) { CukeModeler::Model.new }
|
104
|
+
|
105
|
+
it 'returns no result' do
|
106
|
+
result = subject.lint(test_model)
|
107
|
+
|
108
|
+
expect(result).to eq(nil)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|