chutney 3.0.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +16 -0
- data/.rubocop.yml +2 -1
- data/LICENSE.txt +1 -1
- data/README.md +3 -1
- data/Rakefile +7 -9
- data/chutney.gemspec +3 -3
- data/config/chutney_defaults.yml +2 -0
- data/config/cucumber.yml +1 -1
- data/docs/index.md +1 -1
- data/docs/usage/rules.md +34 -64
- data/lib/chutney/formatter/pie_formatter.rb +0 -4
- data/lib/chutney/linter/same_tag_different_case.rb +37 -0
- data/lib/chutney/linter.rb +26 -19
- data/lib/chutney/locator.rb +46 -0
- data/lib/chutney/version.rb +1 -1
- data/lib/chutney.rb +4 -0
- data/lib/config/locales/en.yml +3 -0
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 364df4d2dc550c7ee5dbd99b93301c2a83a281b1bf83cc9a00ed201635a919f6
|
4
|
+
data.tar.gz: 97e765ad65d122ed5771cbf87e30a774a200b6a03bdc6b7c22c5b515562f8377
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6821d88c15aa693efff3a4bcde58357a6a066791b39c0354667fc4f6a66d58c607a502e7c97c47df8e286fedf5d5a2d2c8447eab25e2335a75521fca837c9990
|
7
|
+
data.tar.gz: 16700a464d8c6700e8d88e83ae387d05502eba187fd281cb0f391fd306155c1cdf118d76eaf0f9f32bfb03a48caf39d79b76031c7ff5a43e0789fe7167f3625a
|
@@ -0,0 +1,16 @@
|
|
1
|
+
version: 2
|
2
|
+
updates:
|
3
|
+
- package-ecosystem: bundler
|
4
|
+
directory: "/"
|
5
|
+
schedule:
|
6
|
+
interval: daily
|
7
|
+
open-pull-requests-limit: 10
|
8
|
+
ignore:
|
9
|
+
- dependency-name: rubocop
|
10
|
+
versions:
|
11
|
+
- 1.10.0
|
12
|
+
- 1.11.0
|
13
|
+
- 1.12.0
|
14
|
+
- 1.12.1
|
15
|
+
- 1.9.0
|
16
|
+
- 1.9.1
|
data/.rubocop.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -21,6 +21,8 @@
|
|
21
21
|
|
22
22
|
Read the documentation [here](https://billyruffian.github.io/chutney/) or try [Chutney Online](https://chutney.billy-ruffian.co.uk).
|
23
23
|
|
24
|
+
See [this page](https://billyruffian.github.io/chutney/usage/rules.html) for a full list of the rules chutney encourages.
|
25
|
+
|
24
26
|
## Notes
|
25
27
|
|
26
|
-
Chutney 3+
|
28
|
+
Chutney 3+ has replaced its direct dependency on Cucumber and instead uses the excellent [cuke_modeller](https://github.com/enkessler/cuke_modeler) to parse your feature files.
|
data/Rakefile
CHANGED
@@ -18,18 +18,16 @@ end
|
|
18
18
|
|
19
19
|
desc 'Checks ruby style'
|
20
20
|
task :rubocop do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
puts 'Rubocop failed'
|
28
|
-
end
|
21
|
+
sh 'rubocop -a'
|
22
|
+
rescue RuntimeError => e
|
23
|
+
# Rubocop failing due to style violations is fine. Other errors should bubble up to our attention.
|
24
|
+
raise e unless e.message =~ /status \(1\).*rubocop/
|
25
|
+
|
26
|
+
puts 'Rubocop failed'
|
29
27
|
end
|
30
28
|
|
31
29
|
task :spec do
|
32
|
-
sh 'rspec'
|
30
|
+
sh 'bundle exec rspec'
|
33
31
|
end
|
34
32
|
|
35
33
|
task :cucumber do
|
data/chutney.gemspec
CHANGED
@@ -56,13 +56,13 @@ Gem::Specification.new do |spec|
|
|
56
56
|
|
57
57
|
|
58
58
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
59
|
-
spec.add_development_dependency 'cucumber', '~>
|
59
|
+
spec.add_development_dependency 'cucumber', '~> 7.0'
|
60
60
|
spec.add_development_dependency 'pry-byebug', '~> 3.0'
|
61
61
|
spec.add_development_dependency 'rake', '~> 13.0'
|
62
62
|
spec.add_development_dependency 'rerun', '~> 0.13'
|
63
63
|
spec.add_development_dependency 'rspec-expectations', '~> 3.0'
|
64
|
-
spec.add_development_dependency 'rubocop', '~>
|
64
|
+
spec.add_development_dependency 'rubocop', '~> 1.14.0'
|
65
65
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
66
66
|
|
67
|
-
spec.required_ruby_version = '
|
67
|
+
spec.required_ruby_version = '>= 2.6'
|
68
68
|
end
|
data/config/chutney_defaults.yml
CHANGED
data/config/cucumber.yml
CHANGED
@@ -1 +1 @@
|
|
1
|
-
default: --publish-quiet
|
1
|
+
default: --publish-quiet
|
data/docs/index.md
CHANGED
@@ -18,4 +18,4 @@ You're trying to follow TDD or ATDD principles, you're writing executable specif
|
|
18
18
|
|
19
19
|
Cucumber itself is an awesome tool which bridges with gap between business language, software development language and the language of testers. With all these folks interested, it's easy to write problematic and hard to maintain features. Chutney tries to help with that by having a common set of quality rules for your feature files.
|
20
20
|
|
21
|
-
Chutney is able to lint feature files in any spoken language supported by Cucumber
|
21
|
+
Chutney is able to lint feature files in any spoken language supported by Cucumber.
|
data/docs/usage/rules.md
CHANGED
@@ -9,98 +9,68 @@ nav_order: 2
|
|
9
9
|
|
10
10
|
Chutney enforces its rules with the linters. These are:
|
11
11
|
|
12
|
-
[AvoidFullStop](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_full_stop.feature)
|
13
|
-
: Don't have a full stop (period) at the end of step because it makes step reuse really hard.
|
12
|
+
[AvoidFullStop](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_full_stop.feature): Don't have a full stop (period) at the end of step because it makes step reuse really hard.
|
14
13
|
|
15
|
-
[AvoidOutlineForSingleExample](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_outline_for_single_example.feature)
|
16
|
-
: If you only have a single example in your example table, use a plain-old scenario instead.
|
14
|
+
[AvoidOutlineForSingleExample](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_outline_for_single_example.feature): If you only have a single example in your example table, use a plain-old scenario instead.
|
17
15
|
|
18
|
-
[AvoidScripting](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_scripting.feature)
|
19
|
-
: You have a lot of steps, are you sure you're not scripting the scenario when you should be specifying the behaviour of the system?
|
16
|
+
[AvoidScripting](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_scripting.feature): You have a lot of steps, are you sure you're not scripting the scenario when you should be specifying the behaviour of the system?
|
20
17
|
|
21
|
-
[AvoidTypographersQuotes](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_typographers_quotes.feature)
|
22
|
-
: Cutting and pasting from Word documents? Is that pasting in curly-quotes instead of neutral ones you would type on a keyboard? Are you sure that's what you want?
|
18
|
+
[AvoidTypographersQuotes](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_typographers_quotes.feature): Cutting and pasting from Word documents? Is that pasting in curly-quotes instead of neutral ones you would type on a keyboard? Are you sure that's what you want?
|
23
19
|
|
24
|
-
[BackgroundDoesMoreThanSetup](https://github.com/BillyRuffian/chutney/blob/master/features/background_does_more_than_setup.feature)
|
25
|
-
: Background in feature files should only do setup activity and so they should only contain `Given` steps.
|
20
|
+
[BackgroundDoesMoreThanSetup](https://github.com/BillyRuffian/chutney/blob/master/features/background_does_more_than_setup.feature): Background in feature files should only do setup activity and so they should only contain `Given` steps.
|
26
21
|
|
27
|
-
[BackgroundRequiresMultipleScenarios](https://github.com/BillyRuffian/chutney/blob/master/features/background_requires_multiple_scenarios.feature)
|
28
|
-
: If you only have one scenario, don't bother having a Background section.
|
22
|
+
[BackgroundRequiresMultipleScenarios](https://github.com/BillyRuffian/chutney/blob/master/features/background_requires_multiple_scenarios.feature): If you only have one scenario, don't bother having a Background section.
|
29
23
|
|
30
|
-
[BadScenarioName](https://github.com/BillyRuffian/chutney/blob/master/features/bad_scenario_name.feature)
|
31
|
-
: You should avoid using words like 'test' or 'check' in your scenario names, instead you should define the behaviour of your system.
|
24
|
+
[BadScenarioName](https://github.com/BillyRuffian/chutney/blob/master/features/bad_scenario_name.feature): You should avoid using words like 'test' or 'check' in your scenario names, instead you should define the behaviour of your system.
|
32
25
|
|
33
|
-
[EmptyFeatureFile](https://github.com/BillyRuffian/chutney/blob/master/features/empty_feature_file.feature)
|
34
|
-
: The feature should have content and should avoid committing empty features to repositories.
|
26
|
+
[EmptyFeatureFile](https://github.com/BillyRuffian/chutney/blob/master/features/empty_feature_file.feature): The feature should have content and should avoid committing empty features to repositories.
|
35
27
|
|
36
|
-
[FileNameDiffersFeatureName](https://github.com/BillyRuffian/chutney/blob/master/features/file_name_differs_feature_name.feature)
|
37
|
-
: The feature should have a name that follows the file name.
|
28
|
+
[FileNameDiffersFeatureName](https://github.com/BillyRuffian/chutney/blob/master/features/file_name_differs_feature_name.feature): The feature should have a name that follows the file name.
|
38
29
|
|
39
|
-
[GivensAfterBackground](https://github.com/BillyRuffian/chutney/blob/master/features/givens_after_background.feature)
|
40
|
-
: If you have a Background section and your scenario needs more preconditions then it should start immediately with an `And` step and not another `Given`.
|
30
|
+
[GivensAfterBackground](https://github.com/BillyRuffian/chutney/blob/master/features/givens_after_background.feature): If you have a Background section and your scenario needs more preconditions then it should start immediately with an `And` step and not another `Given`.
|
41
31
|
|
42
|
-
[InvalidFileName](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_file_name.feature)
|
43
|
-
: Make sure your file name is in snake case, not mixed case or with spaces.
|
32
|
+
[InvalidFileName](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_file_name.feature): Make sure your file name is in snake case, not mixed case or with spaces.
|
44
33
|
|
45
|
-
[InvalidStepFlow](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_step_flow.feature)
|
46
|
-
: Your scenarios should follow Given → When → Then, in that order.
|
34
|
+
[InvalidStepFlow](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_step_flow.feature): Your scenarios should follow Given → When → Then, in that order.
|
47
35
|
|
48
|
-
[MissingExampleName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_example_name.feature)
|
49
|
-
: If you have more than one example table in your scenario, they should each be given unique names.
|
36
|
+
[MissingExampleName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_example_name.feature): If you have more than one example table in your scenario, they should each be given unique names.
|
50
37
|
|
51
|
-
[MissingFeatureDescription](https://github.com/BillyRuffian/chutney/blob/master/features/missing_feature_description.feature)
|
52
|
-
: Your feature should have a value statement. These are usually in the form 'As a... I want.. So that...'.
|
38
|
+
[MissingFeatureDescription](https://github.com/BillyRuffian/chutney/blob/master/features/missing_feature_description.feature): Your feature should have a value statement. These are usually in the form 'As a... I want.. So that...'.
|
53
39
|
|
54
|
-
[MissingFeatureName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_feature_name.feature)
|
55
|
-
: You should give your features a descriptive name.
|
40
|
+
[MissingFeatureName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_feature_name.feature): You should give your features a descriptive name.
|
56
41
|
|
57
|
-
[MissingScenarioName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_scenario_name.feature)
|
58
|
-
: You should name your scenarios and scenario outlines.
|
42
|
+
[MissingScenarioName](https://github.com/BillyRuffian/chutney/blob/master/features/missing_scenario_name.feature): You should name your scenarios and scenario outlines.
|
59
43
|
|
60
|
-
[MissingTestAction](https://github.com/BillyRuffian/chutney/blob/master/features/missing_test_action.feature)
|
61
|
-
: You don't have an action (a `When` step) in your scenario.
|
44
|
+
[MissingTestAction](https://github.com/BillyRuffian/chutney/blob/master/features/missing_test_action.feature): You don't have an action (a `When` step) in your scenario.
|
62
45
|
|
63
|
-
[MissingVerification](https://github.com/BillyRuffian/chutney/blob/master/features/missing_verification.feature)
|
64
|
-
: You don't have a verification step (a `Then` step) in your scenario.
|
46
|
+
[MissingVerification](https://github.com/BillyRuffian/chutney/blob/master/features/missing_verification.feature): You don't have a verification step (a `Then` step) in your scenario.
|
65
47
|
|
66
|
-
[RequiredTagsStartWith](https://github.com/BillyRuffian/chutney/blob/master/features/required_tags_starts_with.feature)
|
67
|
-
: Chutney can enforce a configurable naming prefix for your tags.
|
48
|
+
[RequiredTagsStartWith](https://github.com/BillyRuffian/chutney/blob/master/features/required_tags_starts_with.feature): Chutney can enforce a configurable naming prefix for your tags.
|
68
49
|
|
69
|
-
[
|
70
|
-
: You have the same tag for all you scenarios; move the tag to the feature level instead.
|
50
|
+
[SameTagForDifferentCase](https://github.com/BillyRuffian/chutney/blob/master/features/same_tag_different_case.feature): Don't mix the case of tags which have already appeared. Cucumber tags are case sensitive. *Since 3.1.0*
|
71
51
|
|
72
|
-
[
|
73
|
-
: Chutney can enforce a naming convention for your scenario names.
|
52
|
+
[SameTagForAllScenarios](https://github.com/BillyRuffian/chutney/blob/master/features/same_tag_for_all_scenarios.feature): You have the same tag for all you scenarios; move the tag to the feature level instead.
|
74
53
|
|
75
|
-
[
|
76
|
-
: Chutney can warn if you have used a tag a lot with a feature.
|
54
|
+
[ScenarioNamesMatch](https://github.com/BillyRuffian/chutney/blob/master/features/scenario_names_match.feature): Chutney can enforce a naming convention for your scenario names.
|
77
55
|
|
78
|
-
[
|
79
|
-
: This is a very long scenario. Consider writing it more concisely.
|
56
|
+
[TagUsedMultipleTimes](https://github.com/BillyRuffian/chutney/blob/master/features/tag_used_multiple_times.feature): Chutney can warn if you have used a tag a lot with a feature.
|
80
57
|
|
81
|
-
[
|
82
|
-
: This is a very long step. Consider writing it more concisely.
|
58
|
+
[TooClumsy](https://github.com/BillyRuffian/chutney/blob/master/features/too_clumsy.feature): This is a very long scenario. Consider writing it more concisely.
|
83
59
|
|
84
|
-
[
|
85
|
-
: This feature has a lot of different tags.
|
60
|
+
[TooLongStep](https://github.com/BillyRuffian/chutney/blob/master/features/too_long_step.feature): This is a very long step. Consider writing it more concisely.
|
86
61
|
|
87
|
-
[
|
88
|
-
: This feature has a lot of steps. Consider writing it more concisely.
|
62
|
+
[TooManyDifferentTags](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_different_tags.feature): This feature has a lot of different tags.
|
89
63
|
|
90
|
-
[
|
91
|
-
: There are a lot of tags in this feature.
|
64
|
+
[TooManySteps](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_steps.feature): This feature has a lot of steps. Consider writing it more concisely.
|
92
65
|
|
93
|
-
[
|
94
|
-
: You have duplicated a scenario name when they should be unique.
|
66
|
+
[TooManyTags](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_tags.feature): There are a lot of tags in this feature.
|
95
67
|
|
96
|
-
[
|
97
|
-
: You are referencing a variable which doesn't appear to be defined. This is a source of subtle errors.
|
68
|
+
[UniqueScenarioNames](https://github.com/BillyRuffian/chutney/blob/master/features/unique_scenario_names.feature): You have duplicated a scenario name when they should be unique.
|
98
69
|
|
99
|
-
[
|
100
|
-
: You have a variable which you are not using.
|
70
|
+
[UnknownVariable](https://github.com/BillyRuffian/chutney/blob/master/features/unknown_variable.feature): You are referencing a variable which doesn't appear to be defined. This is a source of subtle errors.
|
101
71
|
|
102
|
-
[
|
103
|
-
: You have a setup setup used in all of your scenarios. Move it to a Background section.
|
72
|
+
[UnusedVariable](https://github.com/BillyRuffian/chutney/blob/master/features/unused_variable.feature): You have a variable which you are not using.
|
104
73
|
|
105
|
-
[
|
106
|
-
|
74
|
+
[UseBackground](https://github.com/BillyRuffian/chutney/blob/master/features/use_background.feature): You have a setup setup used in all of your scenarios. Move it to a Background section.
|
75
|
+
|
76
|
+
[UseOutline](https://github.com/BillyRuffian/chutney/blob/master/features/use_outline.feature): You have very similar scenarios. You should consider if they should be combined into a Scenario Outline.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chutney/linter'
|
4
|
+
|
5
|
+
module Chutney
|
6
|
+
# service class to lint for missing verifications
|
7
|
+
class SameTagDifferentCase < Linter
|
8
|
+
def all_known_tags
|
9
|
+
# rubocop:disable Style/ClassVars
|
10
|
+
@@all_known_tags ||= []
|
11
|
+
# rubocop:enable Style/ClassVars
|
12
|
+
end
|
13
|
+
|
14
|
+
def lint
|
15
|
+
scenarios do |feature, scenario|
|
16
|
+
total_tags = tags_for(feature) + tags_for(scenario)
|
17
|
+
|
18
|
+
total_tags.each do |tag|
|
19
|
+
collision_with = case_collision(tag)
|
20
|
+
if collision_with
|
21
|
+
add_issue(I18n.t('linters.same_tag_different_case',
|
22
|
+
existing_tag: collision_with, tag: tag),
|
23
|
+
feature, scenario)
|
24
|
+
else
|
25
|
+
@@all_known_tags << tag
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def case_collision(tag)
|
32
|
+
return nil if all_known_tags.include?(tag)
|
33
|
+
|
34
|
+
all_known_tags.select { |t| t.casecmp(tag).zero? }.first
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/chutney/linter.rb
CHANGED
@@ -19,8 +19,6 @@ module Chutney
|
|
19
19
|
@filename = filename
|
20
20
|
@issues = []
|
21
21
|
@configuration = configuration
|
22
|
-
# language = @content.dig(:feature, :language) || 'en'
|
23
|
-
# @dialect = Gherkin::Dialect.for(language)
|
24
22
|
end
|
25
23
|
|
26
24
|
def lint
|
@@ -68,11 +66,18 @@ module Chutney
|
|
68
66
|
end
|
69
67
|
|
70
68
|
def dialect
|
71
|
-
@content.feature&.parsing_data
|
69
|
+
parsing_data = @content.feature&.parsing_data
|
70
|
+
if !parsing_data.nil? && parsing_data.respond_to?(:language)
|
71
|
+
parsing_data.language
|
72
|
+
elsif parsing_data
|
73
|
+
parsing_data[:language]
|
74
|
+
else
|
75
|
+
raise UnsupportedCucumberError, 'This version of cucumber is unsupported (langauge detection)'
|
76
|
+
end
|
72
77
|
end
|
73
78
|
|
74
79
|
def tags_for(element)
|
75
|
-
element.tags.map { |tag| tag.name[1
|
80
|
+
element.tags.map { |tag| tag.name[1..] }
|
76
81
|
end
|
77
82
|
|
78
83
|
def add_issue(message, feature = nil, scenario = nil, item = nil)
|
@@ -81,19 +86,12 @@ module Chutney
|
|
81
86
|
gherkin_type: type(feature, scenario, item),
|
82
87
|
location: location(feature, scenario, item),
|
83
88
|
feature: feature&.name,
|
84
|
-
scenario: scenario&.name
|
85
|
-
step: item&.parsing_data&.dig(:name)
|
89
|
+
scenario: scenario&.name
|
86
90
|
).to_h
|
87
91
|
end
|
88
92
|
|
89
93
|
def location(feature, scenario, step)
|
90
|
-
|
91
|
-
step.parsing_data[:location]
|
92
|
-
elsif scenario
|
93
|
-
scenario.parsing_data.dig(:scenario, :location) || scenario.parsing_data.dig(:background, :location)
|
94
|
-
else
|
95
|
-
feature ? feature.parsing_data[:location] : { line: 0, column: 0 }
|
96
|
-
end
|
94
|
+
Locator.locate(feature, scenario, step)
|
97
95
|
end
|
98
96
|
|
99
97
|
def type(_feature, scenario, step)
|
@@ -128,9 +126,9 @@ module Chutney
|
|
128
126
|
|
129
127
|
def off_switch?(element = feature)
|
130
128
|
off_switch = element.tags
|
129
|
+
.map(&:name)
|
131
130
|
.then { |tags| tags || [] }
|
132
|
-
.filter { |
|
133
|
-
.filter { |tag| tag[:name] == "@disable#{linter_name}" }
|
131
|
+
.filter { |tag_name| tag_name == "@disable#{linter_name}" }
|
134
132
|
.count
|
135
133
|
.positive?
|
136
134
|
off_switch ||= off_switch?(feature) unless element == feature
|
@@ -138,16 +136,21 @@ module Chutney
|
|
138
136
|
end
|
139
137
|
|
140
138
|
def background
|
139
|
+
return unless feature&.background
|
140
|
+
return if off_switch?(feature)
|
141
|
+
|
141
142
|
if block_given?
|
142
|
-
yield(feature, feature
|
143
|
+
yield(feature, feature.background)
|
143
144
|
else
|
144
|
-
feature
|
145
|
+
feature.background
|
145
146
|
end
|
146
147
|
end
|
147
148
|
|
148
149
|
def scenarios
|
149
150
|
if block_given?
|
150
151
|
feature&.tests&.each do |test|
|
152
|
+
next if off_switch?(test)
|
153
|
+
|
151
154
|
yield(feature, test)
|
152
155
|
end
|
153
156
|
|
@@ -169,8 +172,12 @@ module Chutney
|
|
169
172
|
end
|
170
173
|
|
171
174
|
def steps
|
172
|
-
feature&.tests&.each do |
|
173
|
-
|
175
|
+
feature&.tests&.each do |test|
|
176
|
+
next if off_switch?(test)
|
177
|
+
|
178
|
+
test.steps.each do |step|
|
179
|
+
yield(feature, test, step)
|
180
|
+
end
|
174
181
|
end
|
175
182
|
end
|
176
183
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chutney
|
4
|
+
# Utility module to assist in locating the source of parts of a gherkin specification
|
5
|
+
module Locator
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def locate(feature, scenario, step)
|
9
|
+
if step
|
10
|
+
locate_step(step)
|
11
|
+
elsif scenario
|
12
|
+
locate_scenario(scenario)
|
13
|
+
elsif feature
|
14
|
+
locate_feature(feature)
|
15
|
+
else
|
16
|
+
feature
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def locate_step(step)
|
21
|
+
return step.parsing_data.location.to_h if step.parsing_data.respond_to?(:location)
|
22
|
+
return step.parsing_data[:location] if step.parsing_data.is_a?(Hash)
|
23
|
+
|
24
|
+
raise UnsupportedCucumberError, 'This version of cucumber is unsupported (step location)'
|
25
|
+
end
|
26
|
+
|
27
|
+
def locate_scenario(scenario)
|
28
|
+
parsing_data = scenario.parsing_data
|
29
|
+
|
30
|
+
if parsing_data.is_a?(Hash)
|
31
|
+
parsing_data.dig(:scenario, :location) || parsing_data.dig(:background, :location)
|
32
|
+
elsif parsing_data.respond_to?(:scenario)
|
33
|
+
(parsing_data.scenario || parsing_data.background).location.to_h
|
34
|
+
else
|
35
|
+
raise UnsupportedCucumberError, 'This version of cucumber is unsupported (scenario location)'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def locate_feature(feature)
|
40
|
+
return feature.parsing_data.location.to_h if feature.parsing_data.respond_to?(:location)
|
41
|
+
return feature.parsing_data[:location] if feature.parsing_data.is_a?(Hash)
|
42
|
+
|
43
|
+
raise UnsupportedCucumberError, 'This version of cucumber is unsupported (feature location)'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/chutney/version.rb
CHANGED
data/lib/chutney.rb
CHANGED
@@ -23,6 +23,7 @@ require 'chutney/linter/missing_scenario_name'
|
|
23
23
|
require 'chutney/linter/missing_test_action'
|
24
24
|
require 'chutney/linter/missing_verification'
|
25
25
|
require 'chutney/linter/required_tags_starts_with'
|
26
|
+
require 'chutney/linter/same_tag_different_case'
|
26
27
|
require 'chutney/linter/same_tag_for_all_scenarios'
|
27
28
|
require 'chutney/linter/scenario_names_match'
|
28
29
|
require 'chutney/linter/tag_used_multiple_times'
|
@@ -36,6 +37,7 @@ require 'chutney/linter/unknown_variable'
|
|
36
37
|
require 'chutney/linter/unused_variable'
|
37
38
|
require 'chutney/linter/use_background'
|
38
39
|
require 'chutney/linter/use_outline'
|
40
|
+
require 'chutney/locator'
|
39
41
|
require 'chutney/version'
|
40
42
|
|
41
43
|
require 'cuke_modeler'
|
@@ -47,6 +49,8 @@ require 'set'
|
|
47
49
|
require 'yaml'
|
48
50
|
|
49
51
|
module Chutney
|
52
|
+
class UnsupportedCucumberError < StandardError; end
|
53
|
+
|
50
54
|
# gherkin linter
|
51
55
|
class ChutneyLint
|
52
56
|
extend Forwardable
|
data/lib/config/locales/en.yml
CHANGED
@@ -63,6 +63,9 @@ en:
|
|
63
63
|
scenario_names_match: >-
|
64
64
|
You have a scenario name which does not match the required format.
|
65
65
|
Allowed patterns are '%{pattern}'.
|
66
|
+
same_tag_different_case: >-
|
67
|
+
You have a tag which has already appeared as '@%{existing_tag}' which is a different case
|
68
|
+
to '@%{tag}'. Cucumber tags are case-sensitive: use a consistent case for your tag names.
|
66
69
|
same_tag_for_all_scenarios:
|
67
70
|
feature_level: >-
|
68
71
|
You are using the same tag (%{tag}) for all scenarios.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chutney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nigel Brookes-Thomas
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-09-24 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: amatch
|
@@ -103,14 +103,14 @@ dependencies:
|
|
103
103
|
requirements:
|
104
104
|
- - "~>"
|
105
105
|
- !ruby/object:Gem::Version
|
106
|
-
version: '
|
106
|
+
version: '7.0'
|
107
107
|
type: :development
|
108
108
|
prerelease: false
|
109
109
|
version_requirements: !ruby/object:Gem::Requirement
|
110
110
|
requirements:
|
111
111
|
- - "~>"
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version: '
|
113
|
+
version: '7.0'
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: pry-byebug
|
116
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,14 +173,14 @@ dependencies:
|
|
173
173
|
requirements:
|
174
174
|
- - "~>"
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version:
|
176
|
+
version: 1.14.0
|
177
177
|
type: :development
|
178
178
|
prerelease: false
|
179
179
|
version_requirements: !ruby/object:Gem::Requirement
|
180
180
|
requirements:
|
181
181
|
- - "~>"
|
182
182
|
- !ruby/object:Gem::Version
|
183
|
-
version:
|
183
|
+
version: 1.14.0
|
184
184
|
- !ruby/object:Gem::Dependency
|
185
185
|
name: rspec
|
186
186
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,6 +208,7 @@ extra_rdoc_files: []
|
|
208
208
|
files:
|
209
209
|
- ".circleci/config.yml"
|
210
210
|
- ".coveralls.yml"
|
211
|
+
- ".github/dependabot.yml"
|
211
212
|
- ".gitignore"
|
212
213
|
- ".rspec"
|
213
214
|
- ".rubocop.yml"
|
@@ -262,6 +263,7 @@ files:
|
|
262
263
|
- lib/chutney/linter/missing_test_action.rb
|
263
264
|
- lib/chutney/linter/missing_verification.rb
|
264
265
|
- lib/chutney/linter/required_tags_starts_with.rb
|
266
|
+
- lib/chutney/linter/same_tag_different_case.rb
|
265
267
|
- lib/chutney/linter/same_tag_for_all_scenarios.rb
|
266
268
|
- lib/chutney/linter/scenario_names_match.rb
|
267
269
|
- lib/chutney/linter/tag_used_multiple_times.rb
|
@@ -275,6 +277,7 @@ files:
|
|
275
277
|
- lib/chutney/linter/unused_variable.rb
|
276
278
|
- lib/chutney/linter/use_background.rb
|
277
279
|
- lib/chutney/linter/use_outline.rb
|
280
|
+
- lib/chutney/locator.rb
|
278
281
|
- lib/chutney/version.rb
|
279
282
|
- lib/config/locales/en.yml
|
280
283
|
- spec/chutney_spec.rb
|
@@ -292,7 +295,7 @@ require_paths:
|
|
292
295
|
- lib
|
293
296
|
required_ruby_version: !ruby/object:Gem::Requirement
|
294
297
|
requirements:
|
295
|
-
- - "
|
298
|
+
- - ">="
|
296
299
|
- !ruby/object:Gem::Version
|
297
300
|
version: '2.6'
|
298
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -301,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
304
|
- !ruby/object:Gem::Version
|
302
305
|
version: '0'
|
303
306
|
requirements: []
|
304
|
-
rubygems_version: 3.
|
307
|
+
rubygems_version: 3.2.22
|
305
308
|
signing_key:
|
306
309
|
specification_version: 4
|
307
310
|
summary: A linter for multi-lingual Gherkin
|