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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a489eb526fae6a79ff386986463cf473aa4f5bc353448e99338781556f7fd194
4
- data.tar.gz: 5cd7a3264aba055c8fe738147edfa661f57e2c0e258d5991b42adbfb2af45f05
3
+ metadata.gz: 364df4d2dc550c7ee5dbd99b93301c2a83a281b1bf83cc9a00ed201635a919f6
4
+ data.tar.gz: 97e765ad65d122ed5771cbf87e30a774a200b6a03bdc6b7c22c5b515562f8377
5
5
  SHA512:
6
- metadata.gz: 9fb8325c116764fadd900b0b98961eca7cf95f49ac171ef64e77e29f1806d6ff78bcca90ea9e2119320d33d81b13e67749fb3bf8e916df13e154871b54602b35
7
- data.tar.gz: 8290dd430b9b55c900179717c3b3fcd83ea805e9142751dec8c69ae4c1e2233a3d5392d8951705a3fed0678b3a9fd768941889b5e9086465fa54ced8c43b1811
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
@@ -25,7 +25,8 @@ Layout/LineLength:
25
25
  # Offense count: 1
26
26
  # Configuration parameters: CountComments.
27
27
  Metrics/MethodLength:
28
- Max: 11
28
+ Max: 20
29
+
29
30
 
30
31
  # Offense count: 1
31
32
  # Cop supports --auto-correct.
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Funkwerk AG
3
+ Copyright (c) 2020, 2021 Nigel Brookes-Thomas
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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+ (in beta) 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.
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
- begin
22
- sh 'rubocop -a'
23
- rescue RuntimeError => e
24
- # Rubocop failing due to style violations is fine. Other errors should bubble up to our attention.
25
- raise e unless e.message =~ /status \(1\).*rubocop/
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', '~> 5.1'
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', '~> 0.90.0'
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 = '~> 2.6'
67
+ spec.required_ruby_version = '>= 2.6'
68
68
  end
@@ -36,6 +36,8 @@ InvalidStepFlow:
36
36
  Enabled: true
37
37
  RequiredTagsStartsWith:
38
38
  Enabled: false
39
+ SameTagDifferentCase:
40
+ Enabled: true
39
41
  SameTagForAllScenarios:
40
42
  Enabled: true
41
43
  ScenarioNamesMatch:
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 3.
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
- [SameTagForAllScenarios](https://github.com/BillyRuffian/chutney/blob/master/features/same_tag_for_all_scenarios.feature)
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
- [ScenarioNamesMatch](https://github.com/BillyRuffian/chutney/blob/master/features/scenario_names_match.feature)
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
- [TagUsedMultipleTimes](https://github.com/BillyRuffian/chutney/blob/master/features/tag_used_multiple_times.feature)
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
- [TooClumsy](https://github.com/BillyRuffian/chutney/blob/master/features/too_clumsy.feature)
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
- [TooLongStep](https://github.com/BillyRuffian/chutney/blob/master/features/too_long_step.feature)
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
- [TooManyDifferentTags](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_different_tags.feature)
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
- [TooManySteps](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_steps.feature)
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
- [TooManyTags](https://github.com/BillyRuffian/chutney/blob/master/features/too_many_tags.feature)
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
- [UniqueScenarioNames](https://github.com/BillyRuffian/chutney/blob/master/features/unique_scenario_names.feature)
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
- [UnknownVariable](https://github.com/BillyRuffian/chutney/blob/master/features/unknown_variable.feature)
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
- [UnusedVariable](https://github.com/BillyRuffian/chutney/blob/master/features/unused_variable.feature)
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
- [UseBackground](https://github.com/BillyRuffian/chutney/blob/master/features/use_background.feature)
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
- [UseOutline](https://github.com/BillyRuffian/chutney/blob/master/features/use_outline.feature)
106
- : You have very similar scenarios. You should consider if they should be combined into a Scenario Outline.
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.
@@ -6,10 +6,6 @@ require 'tty/pie'
6
6
  module Chutney
7
7
  # format results as pie charts
8
8
  class PieFormatter < Formatter
9
- def initialize
10
- super
11
- end
12
-
13
9
  def format
14
10
  data = top_offences.map do |offence|
15
11
  {
@@ -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
@@ -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&.dig(:language) || 'en'
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..-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
- if step
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 { |tag| tag[:type] == :Tag }
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&.background)
143
+ yield(feature, feature.background)
143
144
  else
144
- feature&.background
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 |t|
173
- t.steps.each { |s| yield(feature, t, s) }
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chutney
4
- VERSION = '3.0.0'
4
+ VERSION = '3.2.0'
5
5
  end
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
@@ -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.0.0
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: 2020-09-23 00:00:00.000000000 Z
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: '5.1'
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: '5.1'
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: 0.90.0
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: 0.90.0
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.1.2
307
+ rubygems_version: 3.2.22
305
308
  signing_key:
306
309
  specification_version: 4
307
310
  summary: A linter for multi-lingual Gherkin