cuke_linter 0.9.0 → 0.10.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 +17 -1
- data/CONTRIBUTING.md +26 -0
- data/README.md +2 -15
- data/lib/cuke_linter.rb +36 -18
- data/lib/cuke_linter/linters/example_without_name_linter.rb +1 -1
- data/lib/cuke_linter/linters/feature_with_too_many_different_tags_linter.rb +38 -0
- data/lib/cuke_linter/linters/test_should_use_background_linter.rb +28 -0
- data/lib/cuke_linter/linters/test_with_action_step_as_final_step_linter.rb +23 -0
- data/lib/cuke_linter/linters/test_with_setup_step_after_action_step_linter.rb +31 -0
- data/lib/cuke_linter/linters/test_with_setup_step_after_verification_step_linter.rb +31 -0
- data/lib/cuke_linter/linters/test_with_setup_step_as_final_step_linter.rb +23 -0
- data/lib/cuke_linter/version.rb +1 -1
- data/testing/cucumber/features/default_linters.feature +20 -14
- data/testing/cucumber/features/linters/example_without_name.feature +8 -6
- data/testing/cucumber/features/linters/feature_with_too_many_different_tags.feature +56 -0
- data/testing/cucumber/features/linters/step_with_end_period.feature +1 -1
- data/testing/cucumber/features/linters/test_should_use_background.feature +29 -0
- data/testing/cucumber/features/linters/test_with_action_as_final_step.feature +28 -0
- data/testing/cucumber/features/linters/test_with_setup_step_after_action_step.feature +30 -0
- data/testing/cucumber/features/linters/test_with_setup_step_after_verification_step.feature +30 -0
- data/testing/cucumber/features/linters/test_with_setup_step_as_final_step.feature +28 -0
- data/testing/cucumber/features/linters/test_with_too_many_steps.feature +5 -0
- data/testing/cucumber/step_definitions/setup_steps.rb +28 -0
- data/testing/model_factory.rb +1 -1
- data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +12 -0
- data/testing/rspec/spec/integration/linters/feature_with_too_many_different_tags_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_should_use_background_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_action_step_as_final_step_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_setup_step_after_action_step_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_setup_step_after_verification_step_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/integration/linters/test_with_setup_step_as_final_step_linter_integration_spec.rb +8 -0
- data/testing/rspec/spec/unit/linters/background_does_more_than_setup_linter_unit_spec.rb +20 -57
- data/testing/rspec/spec/unit/linters/element_with_too_many_tags_linter_unit_spec.rb +18 -52
- data/testing/rspec/spec/unit/linters/example_without_name_linter_unit_spec.rb +41 -43
- data/testing/rspec/spec/unit/linters/feature_with_too_many_different_tags_linter_unit_spec.rb +293 -0
- data/testing/rspec/spec/unit/linters/feature_without_description_linter_unit_spec.rb +25 -42
- data/testing/rspec/spec/unit/linters/feature_without_name_linter_unit_spec.rb +10 -38
- data/testing/rspec/spec/unit/linters/feature_without_scenarios_linter_unit_spec.rb +32 -52
- data/testing/rspec/spec/unit/linters/linter_unit_spec.rb +27 -10
- data/testing/rspec/spec/unit/linters/linter_unit_specs.rb +26 -12
- data/testing/rspec/spec/unit/linters/outline_with_single_example_row_linter_unit_spec.rb +19 -66
- data/testing/rspec/spec/unit/linters/single_test_background_linter_unit_spec.rb +12 -39
- data/testing/rspec/spec/unit/linters/step_with_end_period_linter_unit_spec.rb +9 -28
- data/testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb +19 -45
- data/testing/rspec/spec/unit/linters/test_should_use_background_linter_unit_spec.rb +226 -0
- data/testing/rspec/spec/unit/linters/test_with_action_step_as_final_step_linter_unit_spec.rb +98 -0
- data/testing/rspec/spec/unit/linters/test_with_no_action_step_linter_unit_spec.rb +10 -51
- data/testing/rspec/spec/unit/linters/test_with_no_name_linter_unit_spec.rb +11 -38
- data/testing/rspec/spec/unit/linters/test_with_no_verification_step_linter_unit_spec.rb +16 -54
- data/testing/rspec/spec/unit/linters/test_with_setup_step_after_action_step_linter_unit_spec.rb +124 -0
- data/testing/rspec/spec/unit/linters/test_with_setup_step_after_verification_step_linter_unit_spec.rb +125 -0
- data/testing/rspec/spec/unit/linters/test_with_setup_step_as_final_step_linter_unit_spec.rb +98 -0
- data/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +9 -49
- metadata +27 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bc16cc61de218e7a1790a86b16d614e9b831e24fb31b46dafa7fe60fbc6768a
|
4
|
+
data.tar.gz: d4bc88c2c166feef1057e89d2430889cb3baa4522a7bf03e2cc2a05586069707
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2504c5d82a51883f883976bc427b9894a8af138a92bd4d714d8cac8c0dbfca9bff9467811002cfd748ad9f9f8d47ce3584d30443927cbce029ceb2549d8c12bb
|
7
|
+
data.tar.gz: 557843507486823449ff2cfed0e8e69f1b5500f3996a42df170e83286ef61d247bc586f3cf04b2393ad5b4b619080a9a95264620631dd82b8f0490cb411241dc
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
8
8
|
|
9
9
|
Nothing yet...
|
10
10
|
|
11
|
+
|
12
|
+
## [0.10.0] - 2019-10-04
|
13
|
+
|
14
|
+
### Added
|
15
|
+
- New linters
|
16
|
+
- FeatureWithTooManyDifferentTagsLinter
|
17
|
+
- TestShouldUseBackgroundLinter
|
18
|
+
- TestWithActionStepAsFinalStepLinter
|
19
|
+
- TestWithSetupStepAfterActionStepLinter
|
20
|
+
- TestWithSetupStepAfterVerificationStepLinter
|
21
|
+
- TestWithSetupStepAsFinalStepLinter
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Improved some of the documentation and linting messages so that it is more clear what the problem is.
|
25
|
+
|
11
26
|
## [0.9.0] - 2019-09-11
|
12
27
|
|
13
28
|
### Added
|
@@ -90,7 +105,8 @@ Nothing yet...
|
|
90
105
|
- Custom linters, formatters, and command line usability
|
91
106
|
|
92
107
|
|
93
|
-
[Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.
|
108
|
+
[Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.10.0...HEAD
|
109
|
+
[0.10.0]: https://github.com/enkessler/cuke_linter/compare/v0.9.0...v0.10.0
|
94
110
|
[0.9.0]: https://github.com/enkessler/cuke_linter/compare/v0.8.0...v0.9.0
|
95
111
|
[0.8.0]: https://github.com/enkessler/cuke_linter/compare/v0.7.0...v0.8.0
|
96
112
|
[0.7.0]: https://github.com/enkessler/cuke_linter/compare/v0.6.0...v0.7.0
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Development
|
2
|
+
|
3
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake cuke_linter:test_everything` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
4
|
+
|
5
|
+
|
6
|
+
## Contributing
|
7
|
+
|
8
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/enkessler/cuke_linter.
|
9
|
+
|
10
|
+
1. Fork it
|
11
|
+
2. Create your feature branch **(off of the development branch)**
|
12
|
+
`git checkout -b my-new-feature dev`
|
13
|
+
3. Commit your changes
|
14
|
+
`git commit -am 'Add some feature'`
|
15
|
+
4. Push to the branch
|
16
|
+
`git push origin my-new-feature`
|
17
|
+
5. Create new Pull Request
|
18
|
+
|
19
|
+
|
20
|
+
### Adding a new linter
|
21
|
+
|
22
|
+
Some guidelines when adding a new linter
|
23
|
+
* Inherit from the base linter class. It will handle almost all of the functional requirements of a linter.
|
24
|
+
* Existing linters should provide decent examples of how to create new linters and how to test them. A copy/paste/tweak approach is perfectly valid.
|
25
|
+
* Keep linters simple. Rather than have one linter that has different behaviors depending on context, create a different linter class for each context.
|
26
|
+
* Keep things alphabetical. There are going to be lots of linters and things will be easier to find if lists of them in the code base (e.g. `require` statments, documentation, etc.) are in an intuitive order.
|
data/README.md
CHANGED
@@ -147,23 +147,10 @@ Rather than using the default linters or providing a custom set of of modified l
|
|
147
147
|
|
148
148
|
For more detailed examples of usage, see the documentation [here](https://app.cucumber.pro/projects/cuke_linter).
|
149
149
|
|
150
|
+
## Development and Contributing
|
150
151
|
|
151
|
-
|
152
|
+
See [CONTRIBUTING.md](https://github.com/enkessler/cuke_linter/blob/master/CONTRIBUTING.md)
|
152
153
|
|
153
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake cuke_linter:test_everything` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
154
|
-
|
155
|
-
## Contributing
|
156
|
-
|
157
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/enkessler/cuke_linter.
|
158
|
-
|
159
|
-
1. Fork it
|
160
|
-
2. Create your feature branch **(off of the development branch)**
|
161
|
-
`git checkout -b my-new-feature`
|
162
|
-
3. Commit your changes
|
163
|
-
`git commit -am 'Add some feature'`
|
164
|
-
4. Push to the branch
|
165
|
-
`git push origin my-new-feature`
|
166
|
-
5. Create new Pull Request
|
167
154
|
|
168
155
|
## License
|
169
156
|
|
data/lib/cuke_linter.rb
CHANGED
@@ -7,6 +7,7 @@ require 'cuke_linter/linters/linter'
|
|
7
7
|
require 'cuke_linter/linters/background_does_more_than_setup_linter'
|
8
8
|
require 'cuke_linter/linters/element_with_too_many_tags_linter'
|
9
9
|
require 'cuke_linter/linters/example_without_name_linter'
|
10
|
+
require 'cuke_linter/linters/feature_with_too_many_different_tags_linter'
|
10
11
|
require 'cuke_linter/linters/feature_without_name_linter'
|
11
12
|
require 'cuke_linter/linters/feature_without_description_linter'
|
12
13
|
require 'cuke_linter/linters/feature_without_scenarios_linter'
|
@@ -14,9 +15,14 @@ require 'cuke_linter/linters/outline_with_single_example_row_linter'
|
|
14
15
|
require 'cuke_linter/linters/single_test_background_linter'
|
15
16
|
require 'cuke_linter/linters/step_with_end_period_linter'
|
16
17
|
require 'cuke_linter/linters/step_with_too_many_characters_linter'
|
18
|
+
require 'cuke_linter/linters/test_should_use_background_linter'
|
19
|
+
require 'cuke_linter/linters/test_with_action_step_as_final_step_linter'
|
17
20
|
require 'cuke_linter/linters/test_with_no_action_step_linter'
|
18
21
|
require 'cuke_linter/linters/test_with_no_name_linter'
|
19
22
|
require 'cuke_linter/linters/test_with_no_verification_step_linter'
|
23
|
+
require 'cuke_linter/linters/test_with_setup_step_after_action_step_linter'
|
24
|
+
require 'cuke_linter/linters/test_with_setup_step_after_verification_step_linter'
|
25
|
+
require 'cuke_linter/linters/test_with_setup_step_as_final_step_linter'
|
20
26
|
require 'cuke_linter/linters/test_with_too_many_steps_linter'
|
21
27
|
|
22
28
|
|
@@ -24,20 +30,26 @@ require 'cuke_linter/linters/test_with_too_many_steps_linter'
|
|
24
30
|
|
25
31
|
module CukeLinter
|
26
32
|
|
27
|
-
@original_linters = { 'BackgroundDoesMoreThanSetupLinter'
|
28
|
-
'ElementWithTooManyTagsLinter'
|
29
|
-
'ExampleWithoutNameLinter'
|
30
|
-
'
|
31
|
-
'
|
32
|
-
'
|
33
|
-
'
|
34
|
-
'
|
35
|
-
'
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
'
|
33
|
+
@original_linters = { 'BackgroundDoesMoreThanSetupLinter' => BackgroundDoesMoreThanSetupLinter.new,
|
34
|
+
'ElementWithTooManyTagsLinter' => ElementWithTooManyTagsLinter.new,
|
35
|
+
'ExampleWithoutNameLinter' => ExampleWithoutNameLinter.new,
|
36
|
+
'FeatureWithTooManyDifferentTagsLinter' => FeatureWithTooManyDifferentTagsLinter.new,
|
37
|
+
'FeatureWithoutDescriptionLinter' => FeatureWithoutDescriptionLinter.new,
|
38
|
+
'FeatureWithoutNameLinter' => FeatureWithoutNameLinter.new,
|
39
|
+
'FeatureWithoutScenariosLinter' => FeatureWithoutScenariosLinter.new,
|
40
|
+
'OutlineWithSingleExampleRowLinter' => OutlineWithSingleExampleRowLinter.new,
|
41
|
+
'SingleTestBackgroundLinter' => SingleTestBackgroundLinter.new,
|
42
|
+
'StepWithEndPeriodLinter' => StepWithEndPeriodLinter.new,
|
43
|
+
'StepWithTooManyCharactersLinter' => StepWithTooManyCharactersLinter.new,
|
44
|
+
'TestShouldUseBackgroundLinter' => TestShouldUseBackgroundLinter.new,
|
45
|
+
'TestWithActionStepAsFinalStepLinter' => TestWithActionStepAsFinalStepLinter.new,
|
46
|
+
'TestWithNoActionStepLinter' => TestWithNoActionStepLinter.new,
|
47
|
+
'TestWithNoNameLinter' => TestWithNoNameLinter.new,
|
48
|
+
'TestWithNoVerificationStepLinter' => TestWithNoVerificationStepLinter.new,
|
49
|
+
'TestWithSetupStepAfterActionStepLinter' => TestWithSetupStepAfterActionStepLinter.new,
|
50
|
+
'TestWithSetupStepAfterVerificationStepLinter' => TestWithSetupStepAfterVerificationStepLinter.new,
|
51
|
+
'TestWithSetupStepAsFinalStepLinter' => TestWithSetupStepAsFinalStepLinter.new,
|
52
|
+
'TestWithTooManyStepsLinter' => TestWithTooManyStepsLinter.new }
|
41
53
|
|
42
54
|
|
43
55
|
# Configures linters based on the given options
|
@@ -97,8 +109,15 @@ module CukeLinter
|
|
97
109
|
# Lints the given model trees and file paths using the given linting objects and formatting the results with the given formatters and their respective output locations
|
98
110
|
def self.lint(file_paths: [], model_trees: [], linters: self.registered_linters.values, formatters: [[CukeLinter::PrettyFormatter.new]])
|
99
111
|
|
100
|
-
|
101
|
-
|
112
|
+
# TODO: Test this?
|
113
|
+
# Because directive memoization is based on a model's `#object_id` and Ruby reuses object IDs over the life
|
114
|
+
# life of a program as objects are garbage collected, it is not safe to remember the IDs forever. However,
|
115
|
+
# models shouldn't get GC'd in the middle of the linting process and so the start of the linting process is
|
116
|
+
# a good time to reset things
|
117
|
+
@directives_for_feature_file = {}
|
118
|
+
|
119
|
+
model_trees = [CukeModeler::Directory.new(Dir.pwd)] if model_trees.empty? && file_paths.empty?
|
120
|
+
file_path_models = file_paths.collect do |file_path|
|
102
121
|
# TODO: raise exception unless path exists
|
103
122
|
case
|
104
123
|
when File.directory?(file_path)
|
@@ -178,8 +197,7 @@ module CukeLinter
|
|
178
197
|
|
179
198
|
|
180
199
|
def self.linter_directives_for_feature_file(feature_file_model)
|
181
|
-
# IMPORTANT ASSUMPTION: Models never change during the life of
|
182
|
-
@directives_for_feature_file ||= {}
|
200
|
+
# IMPORTANT ASSUMPTION: Models never change during the life of a linting, so data only has to be gathered once
|
183
201
|
return @directives_for_feature_file[feature_file_model.object_id] if @directives_for_feature_file[feature_file_model.object_id]
|
184
202
|
|
185
203
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects features that contain too many different tags
|
4
|
+
|
5
|
+
class FeatureWithTooManyDifferentTagsLinter < Linter
|
6
|
+
|
7
|
+
# Changes the linting settings on the linter using the provided configuration
|
8
|
+
def configure(options)
|
9
|
+
@tag_threshold = options['TagCountThreshold']
|
10
|
+
end
|
11
|
+
|
12
|
+
# The rule used to determine if a model has a problem
|
13
|
+
def rule(model)
|
14
|
+
return false unless model.is_a?(CukeModeler::Feature)
|
15
|
+
|
16
|
+
tags = model.tags
|
17
|
+
|
18
|
+
model.each_descendant do |descendant_model|
|
19
|
+
if descendant_model.respond_to?(:tags)
|
20
|
+
tags.concat(descendant_model.tags)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
tags = tags.collect(&:name).uniq
|
25
|
+
|
26
|
+
@linted_tag_threshold = @tag_threshold || 10
|
27
|
+
@linted_tag_count = tags.count
|
28
|
+
|
29
|
+
@linted_tag_count > @linted_tag_threshold
|
30
|
+
end
|
31
|
+
|
32
|
+
# The message used to describe the problem that has been found
|
33
|
+
def message
|
34
|
+
"Feature contains too many different tags. #{@linted_tag_count} tags found (max #{@linted_tag_threshold})."
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects scenarios and outlines within a feature that all share common beginning steps
|
4
|
+
|
5
|
+
class TestShouldUseBackgroundLinter < Linter
|
6
|
+
|
7
|
+
# The rule used to determine if a model has a problem
|
8
|
+
def rule(model)
|
9
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
10
|
+
|
11
|
+
model_steps = model.steps || []
|
12
|
+
parent_feature_model = model.get_ancestor(:feature)
|
13
|
+
|
14
|
+
return false unless parent_feature_model.tests.count > 1
|
15
|
+
|
16
|
+
parent_feature_model.tests.all? do |test|
|
17
|
+
test_steps = test.steps || []
|
18
|
+
test_steps.first == model_steps.first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# The message used to describe the problem that has been found
|
23
|
+
def message
|
24
|
+
'Test shares steps with all other tests in feature. Use a background.'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects scenarios and outlines that have an action step as their final step
|
4
|
+
|
5
|
+
class TestWithActionStepAsFinalStepLinter < Linter
|
6
|
+
|
7
|
+
# The rule used to determine if a model has a problem
|
8
|
+
def rule(model)
|
9
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
10
|
+
|
11
|
+
model_steps = model.steps || []
|
12
|
+
return false unless model_steps.last
|
13
|
+
|
14
|
+
model_steps.last.keyword == 'When'
|
15
|
+
end
|
16
|
+
|
17
|
+
# The message used to describe the problem that has been found
|
18
|
+
def message
|
19
|
+
"Test has 'When' as the final step."
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects scenarios and outlines that have a setup step that comes after an action step
|
4
|
+
|
5
|
+
class TestWithSetupStepAfterActionStepLinter < Linter
|
6
|
+
|
7
|
+
# The rule used to determine if a model has a problem
|
8
|
+
def rule(model)
|
9
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
10
|
+
|
11
|
+
model_steps = model.steps || []
|
12
|
+
action_step_found = false
|
13
|
+
|
14
|
+
model_steps.each do |step|
|
15
|
+
if action_step_found
|
16
|
+
return true if step.keyword == 'Given'
|
17
|
+
else
|
18
|
+
action_step_found = step.keyword == 'When'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
# The message used to describe the problem that has been found
|
26
|
+
def message
|
27
|
+
"Test has 'Given' step after 'When' step."
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects scenarios and outlines that have a setup step that comes after a verification step
|
4
|
+
|
5
|
+
class TestWithSetupStepAfterVerificationStepLinter < Linter
|
6
|
+
|
7
|
+
# The rule used to determine if a model has a problem
|
8
|
+
def rule(model)
|
9
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
10
|
+
|
11
|
+
model_steps = model.steps || []
|
12
|
+
verification_step_found = false
|
13
|
+
|
14
|
+
model_steps.each do |step|
|
15
|
+
if verification_step_found
|
16
|
+
return true if step.keyword == 'Given'
|
17
|
+
else
|
18
|
+
verification_step_found = step.keyword == 'Then'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
# The message used to describe the problem that has been found
|
26
|
+
def message
|
27
|
+
"Test has 'Given' step after 'Then' step."
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CukeLinter
|
2
|
+
|
3
|
+
# A linter that detects scenarios and outlines that have a setup step as their final step
|
4
|
+
|
5
|
+
class TestWithSetupStepAsFinalStepLinter < Linter
|
6
|
+
|
7
|
+
# The rule used to determine if a model has a problem
|
8
|
+
def rule(model)
|
9
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
10
|
+
|
11
|
+
model_steps = model.steps || []
|
12
|
+
return false unless model_steps.last
|
13
|
+
|
14
|
+
model_steps.last.keyword == 'Given'
|
15
|
+
end
|
16
|
+
|
17
|
+
# The message used to describe the problem that has been found
|
18
|
+
def message
|
19
|
+
"Test has 'Given' as the final step."
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/cuke_linter/version.rb
CHANGED
@@ -8,20 +8,26 @@ Feature: Default Linters
|
|
8
8
|
Scenario: Using the default linters
|
9
9
|
Given no other linters have been registered or unregistered
|
10
10
|
Then the following linters are registered by default
|
11
|
-
| BackgroundDoesMoreThanSetupLinter
|
12
|
-
| ElementWithTooManyTagsLinter
|
13
|
-
| ExampleWithoutNameLinter
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
| BackgroundDoesMoreThanSetupLinter |
|
12
|
+
| ElementWithTooManyTagsLinter |
|
13
|
+
| ExampleWithoutNameLinter |
|
14
|
+
| FeatureWithTooManyDifferentTagsLinter |
|
15
|
+
| FeatureWithoutDescriptionLinter |
|
16
|
+
| FeatureWithoutNameLinter |
|
17
|
+
| FeatureWithoutScenariosLinter |
|
18
|
+
| OutlineWithSingleExampleRowLinter |
|
19
|
+
| SingleTestBackgroundLinter |
|
20
|
+
| StepWithEndPeriodLinter |
|
21
|
+
| StepWithTooManyCharactersLinter |
|
22
|
+
| TestShouldUseBackgroundLinter |
|
23
|
+
| TestWithActionStepAsFinalStepLinter |
|
24
|
+
| TestWithNoActionStepLinter |
|
25
|
+
| TestWithNoNameLinter |
|
26
|
+
| TestWithNoVerificationStepLinter |
|
27
|
+
| TestWithSetupStepAfterActionStepLinter |
|
28
|
+
| TestWithSetupStepAfterVerificationStepLinter |
|
29
|
+
| TestWithSetupStepAsFinalStepLinter |
|
30
|
+
| TestWithTooManyStepsLinter |
|
25
31
|
|
26
32
|
|
27
33
|
Scenario: Registering new linters
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Feature: Example without name linter
|
2
2
|
|
3
3
|
As a reader of documentation
|
4
|
-
I want every example to have a name
|
5
|
-
So that I can understand the significance of the example
|
4
|
+
I want every example grouping to have a name
|
5
|
+
So that I can understand the significance of the example data
|
6
6
|
|
7
7
|
|
8
8
|
Scenario: Linting
|
@@ -13,18 +13,20 @@ Feature: Example without name linter
|
|
13
13
|
|
14
14
|
Scenario Outline:
|
15
15
|
* a step
|
16
|
-
|
16
|
+
|
17
|
+
Examples: Happy paths!
|
17
18
|
| param |
|
18
19
|
| value |
|
20
|
+
|
21
|
+
# Unknown paths :(
|
19
22
|
Examples:
|
20
23
|
| param |
|
21
24
|
| value |
|
22
25
|
"""
|
23
26
|
When it is linted
|
24
27
|
Then an error is reported:
|
25
|
-
| linter | problem
|
26
|
-
| ExampleWithoutNameLinter | Example has no name | <path_to_file>:
|
27
|
-
| ExampleWithoutNameLinter | Example has no name | <path_to_file>:8 |
|
28
|
+
| linter | problem | location |
|
29
|
+
| ExampleWithoutNameLinter | Example grouping has no name | <path_to_file>:11 |
|
28
30
|
|
29
31
|
@wip
|
30
32
|
Scenario: Configuration
|