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
@@ -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
- let(:default_character_threshold) { 80 }
113
-
114
- context 'because configuration never happened' do
115
-
116
- let(:default_model) do
117
- step = 'x' * (default_character_threshold + 1)
118
- CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
119
- end
120
-
121
- it 'defaults to a maximum of 80 characters' do
122
- result = subject.lint(default_model)
123
-
124
- expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
125
- end
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
- end
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
- let(:test_model) { CukeModeler::Model.new }
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 eq(nil)
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