chutney 3.12.4 → 3.14.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8bef0309c872b30a632afd0d944493cc0ecba7e5eb5348e470ede52b44cad857
4
- data.tar.gz: 30c86c817bc8167157bcbb1679ee619908d5d505e52e856e12d294fa0b7c9ed6
3
+ metadata.gz: 3c21346027cfc0954890e1e287dbf282e76567e58267f9da730d2132d0ae83e1
4
+ data.tar.gz: d0a823dcd25b1bccc00bc873444f079e1be6421aad287c624a26fd3b6e11dac2
5
5
  SHA512:
6
- metadata.gz: e97e7afee0915e9fcd16f2af9f713a0fa31832cdf01dab3a57c351d09592c54f27a57c0f053667d82e707f1a94be41ca1fc1e12deb3640c687b25f752a704a28
7
- data.tar.gz: c62aacc66844003019511c285a7ab2bf5728383dcaf2c19b2e3f2859e1a2395a4d7b8690e8b619f1967a0ed677727a928f8177c8023b20d03aec94ed613c8cd0
6
+ metadata.gz: 77880b9602738619b732d6eeee96a05cab06177c159fce4b0a150af9684d166e65314408548edaf42cc735cb93eef88164338ec32561210c19a9cabe3a22ab38
7
+ data.tar.gz: 3e650442d104bd17c8cdffbc5956291e9cb288a4b0fbca34cbdb0dc6c6b7413e8ed40bff9d4272e48aebc6062bb459c89f627f08fa29660fbc1e279f967bf5dd
data/chutney.gemspec CHANGED
@@ -48,7 +48,7 @@ Gem::Specification.new do |spec|
48
48
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
49
49
  spec.require_paths = ['lib']
50
50
 
51
- spec.add_dependency 'amatch', '>= 0.4', '< 0.7'
51
+ spec.add_dependency 'amatch', '>= 0.4', '< 0.8'
52
52
  spec.add_dependency 'cuke_modeler', '~> 3.26'
53
53
  spec.add_dependency 'i18n', '>= 1.8.2', '< 1.15.0'
54
54
  spec.add_dependency 'fast-mcp', '~> 1.5'
@@ -12,6 +12,8 @@ AvoidSplatStepsInBackground:
12
12
  Enabled: true
13
13
  AvoidSplatStepsInScenarios:
14
14
  Enabled: true
15
+ AvoidTags:
16
+ Enabled: false
15
17
  AvoidTypographersQuotes:
16
18
  Enabled: true
17
19
  BackgroundDoesMoreThanSetup:
@@ -74,6 +76,9 @@ TooManyTags:
74
76
  TooLongStep:
75
77
  Enabled: true
76
78
  MaxLength: 80
79
+ TooShortTag:
80
+ Enabled: true
81
+ MinLength: 2
77
82
  UniqueScenarioNames:
78
83
  Enabled: true
79
84
  UnknownVariable:
data/docs/usage/rules.md CHANGED
@@ -19,6 +19,8 @@ Chutney enforces its rules with the linters. These are:
19
19
 
20
20
  [AvoidSplatStepsInScenarios](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_splat_steps_in_scenarios.feature): The Scenario contains a splat step. It should only contain named steps.
21
21
 
22
+ [AvoidTags](https://github.com/BillyRuffian/chutney/blob/master/features/avoid_tags.feature): The Feature file contains tags to avoid.
23
+
22
24
  [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
25
 
24
26
  [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.
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chutney
4
+ # service class to lint for avoiding tags
5
+ class AvoidTags < Linter
6
+ def lint
7
+ return if feature.nil?
8
+
9
+ feature_tags = tags_for(feature)
10
+ feature_tags_to_avoid_found = feature_tags & tags_to_avoid
11
+
12
+ unless feature_tags_to_avoid_found.empty?
13
+ feature_tags_to_avoid_found = feature_tags_to_avoid_found.map { |tag| tag.prepend('@') }
14
+ add_issue(I18n.t('linters.avoid_tags', tags: feature_tags_to_avoid_found.join(', ')), feature)
15
+ end
16
+
17
+ scenarios do |_feature, scenario|
18
+ scenario_tags = tags_for(scenario)
19
+ scenario_tags_to_avoid_found = scenario_tags & tags_to_avoid
20
+
21
+ unless scenario_tags_to_avoid_found.empty?
22
+ scenario_tags_to_avoid_found = scenario_tags_to_avoid_found.map { |tag| tag.prepend('@') }
23
+ add_issue(I18n.t('linters.avoid_tags', tags: scenario_tags_to_avoid_found.join(', ')), feature, scenario)
24
+ end
25
+ end
26
+ end
27
+
28
+ def tags_to_avoid
29
+ tags_to_avoid = configuration['Tags'] || []
30
+
31
+ return [] unless tags_to_avoid.is_a?(Array)
32
+
33
+ tags_to_avoid
34
+ end
35
+ end
36
+ end
@@ -13,7 +13,7 @@ module Chutney
13
13
 
14
14
  def lint # rubocop:disable Metrics/MethodLength
15
15
  scenarios do |feature, scenario|
16
- text = background ? background.steps.map(&:to_s).join("\n").concat("\n") : ''
16
+ text = background ? background.steps.join("\n").concat("\n") : ''
17
17
  text += scenario
18
18
  .steps
19
19
  .map { |step| "#{step.text} #{child_text(step)}" }
@@ -23,16 +23,16 @@ module Chutney
23
23
  end
24
24
 
25
25
  SameScenario.dictionary.filter { |_k, v| v.size > 1 }
26
- .each_value do |v|
27
- v[1...].each_with_index do |problem, index|
28
- add_issue(I18n.t('linters.same_scenario',
29
- feature: problem[:feature].name,
30
- scenario: problem[:scenario].name,
31
- original_feature: v.first[:feature].name,
32
- original_scenario: v.first[:scenario].name),
33
- problem[:feature], problem[:scenario], nil)
34
- v.delete_at(index + 1)
35
- end
26
+ .each_value do |v|
27
+ v[1...].each_with_index do |problem, index|
28
+ add_issue(I18n.t('linters.same_scenario',
29
+ feature: problem[:feature].name,
30
+ scenario: problem[:scenario].name,
31
+ original_feature: v.first[:feature].name,
32
+ original_scenario: v.first[:scenario].name),
33
+ problem[:feature], problem[:scenario], nil)
34
+ v.delete_at(index + 1)
35
+ end
36
36
  end
37
37
  end
38
38
 
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chutney
4
+ # service class to lint for tags that are too short, such as @t
5
+ class TooShortTag < Linter
6
+ def lint
7
+ scenarios do |feature, scenario|
8
+ tags = tags_for(feature) + tags_for(scenario)
9
+ next unless tags.any? { |tag| tag.length < min_length }
10
+
11
+ add_issue(
12
+ I18n.t('linters.too_short_tag', min_length:, tags:),
13
+ feature
14
+ )
15
+ end
16
+ end
17
+
18
+ def min_length
19
+ configuration['MinLength']&.to_i || 2
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chutney
4
- VERSION = '3.12.4'
4
+ VERSION = '3.14.0'
5
5
  end
data/lib/chutney.rb CHANGED
@@ -11,6 +11,7 @@ require 'chutney/linter/avoid_outline_for_single_example'
11
11
  require 'chutney/linter/avoid_scripting'
12
12
  require 'chutney/linter/avoid_splat_steps_in_background'
13
13
  require 'chutney/linter/avoid_splat_steps_in_scenarios'
14
+ require 'chutney/linter/avoid_tags'
14
15
  require 'chutney/linter/avoid_typographers_quotes'
15
16
  require 'chutney/linter/background_does_more_than_setup'
16
17
  require 'chutney/linter/background_requires_multiple_scenarios'
@@ -40,6 +41,7 @@ require 'chutney/linter/too_long_step'
40
41
  require 'chutney/linter/too_many_different_tags'
41
42
  require 'chutney/linter/too_many_steps'
42
43
  require 'chutney/linter/too_many_tags'
44
+ require 'chutney/linter/too_short_tag'
43
45
  require 'chutney/linter/unique_scenario_names'
44
46
  require 'chutney/linter/unknown_variable'
45
47
  require 'chutney/linter/unused_variable'
@@ -19,6 +19,8 @@ en:
19
19
  The Background contains a splat step. It should only contain named steps.
20
20
  avoid_splat_steps_in_scenarios: >-
21
21
  The Scenario contains a splat step. It should only contain named steps.
22
+ avoid_tags: >-
23
+ The following tags are not allowed: %{tags}.
22
24
  avoid_typographers_quotes: >-
23
25
  You are using typographers quotation marks (curly quotes).
24
26
  Make sure you intend to use this character and not a neutral quote
@@ -108,6 +110,8 @@ en:
108
110
  There are too many steps in this feature. There are %{count} and the maximum is %{max}.
109
111
  too_many_tags: >-
110
112
  There are too many tags in this feature. There are %{count} and the maximum is %{max}.
113
+ too_short_tag: >-
114
+ Your tag is too short: %{tags}. The minimum length of a tag is %{min_length}. Tags should have meaning.
111
115
  unique_scenario_names: >-
112
116
  The scenario name '%{name}' is duplicated, first used at line %{line}, column %{column}.
113
117
  unknown_variable: >-
@@ -0,0 +1,38 @@
1
+ # Avoid Tags
2
+
3
+ Sometimes you just need a tag for you... maybe to filter your scenarios for focused testing?... or maybe you've got some fancy after hook to help with debugging?
4
+ Whatever the reason, you probably didn't mean to commit that to source.
5
+
6
+ AvoidTags helps prevent the accidental commit of tags by warning you if you have any tags in your feature file which match a configurable list of tags to avoid.
7
+
8
+ ## Configuration
9
+
10
+ ```yaml
11
+ AvoidTags:
12
+ Enabled: true
13
+ Tags:
14
+ - MyFancyDebugTag
15
+ ```
16
+
17
+ ## Bad
18
+
19
+ ```gherkin
20
+ @MyFancyDebugTag
21
+ Scenario: Log in with valid credentials
22
+ Given I have visited the website
23
+ And I have logged in
24
+ And I have viewed sale items
25
+ When I view special offers
26
+ Then I will see my discount code
27
+ ```
28
+
29
+ ## Good
30
+
31
+ ```gherkin
32
+ Scenario: Log in with valid credentials
33
+ Given I have visited the website
34
+ And I have logged in
35
+ And I have viewed sale items
36
+ When I view special offers
37
+ Then I will see my discount code
38
+ ```
@@ -36,6 +36,7 @@
36
36
  * [Too Many Different Tags](/docs/rules/too-many-different-tags)
37
37
  * [Too Many Steps](/docs/rules/too-many-steps)
38
38
  * [Too Many Tags](/docs/rules/too-many-tags)
39
+ * [Too Short Tag](/docs/rules/too_short_tag)
39
40
  * [Unique Scenario Names](/docs/rules/unique-scenario-names)
40
41
  * [Unknown Variable](/docs/rules/unknown-variable)
41
42
  * [Unused Variable](/docs/rules/unused-variable)
@@ -0,0 +1,25 @@
1
+ # Too Short Tag
2
+
3
+ If you have used a tag that is too short, you have probably done it while locally testing. This is a bad practice because it makes your tests harder to read and maintain.
4
+
5
+ It is much better to use tags that relate to the test, such as a ticket number to connect the development work you are testing
6
+
7
+ ## Bad
8
+
9
+ ```gherkin
10
+ @t
11
+ Scenario: Log in with valid credentials
12
+ Given I have visited the website
13
+ When I log in with "user1" and "pass1"
14
+ Then I will see my account
15
+ ```
16
+
17
+ ## Good
18
+
19
+ ```gherkin
20
+ @QE-0001
21
+ Scenario: Log in with valid credentials
22
+ Given I have visited the website
23
+ When I log in with "user1" and "pass1"
24
+ Then I will see my account
25
+ ```
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.12.4
4
+ version: 3.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nigel Brookes-Thomas
@@ -10,7 +10,7 @@ authors:
10
10
  - John Gluck
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 1980-01-02 00:00:00.000000000 Z
13
+ date: 2026-06-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: amatch
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0.4'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '0.7'
24
+ version: '0.8'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: '0.4'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '0.7'
34
+ version: '0.8'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: cuke_modeler
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +183,7 @@ files:
183
183
  - lib/chutney/linter/avoid_scripting.rb
184
184
  - lib/chutney/linter/avoid_splat_steps_in_background.rb
185
185
  - lib/chutney/linter/avoid_splat_steps_in_scenarios.rb
186
+ - lib/chutney/linter/avoid_tags.rb
186
187
  - lib/chutney/linter/avoid_typographers_quotes.rb
187
188
  - lib/chutney/linter/background_does_more_than_setup.rb
188
189
  - lib/chutney/linter/background_requires_multiple_scenarios.rb
@@ -212,6 +213,7 @@ files:
212
213
  - lib/chutney/linter/too_many_different_tags.rb
213
214
  - lib/chutney/linter/too_many_steps.rb
214
215
  - lib/chutney/linter/too_many_tags.rb
216
+ - lib/chutney/linter/too_short_tag.rb
215
217
  - lib/chutney/linter/unique_scenario_names.rb
216
218
  - lib/chutney/linter/unknown_variable.rb
217
219
  - lib/chutney/linter/unused_variable.rb
@@ -250,6 +252,7 @@ files:
250
252
  - usechutney.com.site/site/src/docs/rules/avoid-scripting.page.md
251
253
  - usechutney.com.site/site/src/docs/rules/avoid-splat-steps-in-background.page.md
252
254
  - usechutney.com.site/site/src/docs/rules/avoid-splat-steps-in-scenarios.page.md
255
+ - usechutney.com.site/site/src/docs/rules/avoid-tags.md
253
256
  - usechutney.com.site/site/src/docs/rules/avoid-typographers-quotes.page.md
254
257
  - usechutney.com.site/site/src/docs/rules/background-does-more-than-setup.page.md
255
258
  - usechutney.com.site/site/src/docs/rules/background-requires-multiple-scenarios.page.md
@@ -280,6 +283,7 @@ files:
280
283
  - usechutney.com.site/site/src/docs/rules/too-many-different-tags.page.md
281
284
  - usechutney.com.site/site/src/docs/rules/too-many-steps.page.md
282
285
  - usechutney.com.site/site/src/docs/rules/too-many-tags.page.md
286
+ - usechutney.com.site/site/src/docs/rules/too_short_tag.page.md
283
287
  - usechutney.com.site/site/src/docs/rules/unique-scenario-names.page.md
284
288
  - usechutney.com.site/site/src/docs/rules/unknown-variable.page.md
285
289
  - usechutney.com.site/site/src/docs/rules/unused-variable.page.md
@@ -311,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
311
315
  - !ruby/object:Gem::Version
312
316
  version: '0'
313
317
  requirements: []
314
- rubygems_version: 4.0.3
318
+ rubygems_version: 4.0.10
315
319
  specification_version: 4
316
320
  summary: A linter for multi-lingual Gherkin
317
321
  test_files: []