chutney 3.9.0 → 3.11.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/config/chutney_defaults.yml +46 -42
- data/docs/usage/rules.md +2 -0
- data/lib/chutney/linter/avoid_colons_at_start_of_names.rb +17 -0
- data/lib/chutney/linter/same_scenario.rb +52 -0
- data/lib/chutney/version.rb +1 -1
- data/lib/chutney.rb +2 -0
- data/lib/config/locales/en.yml +4 -0
- data/usechutney.com/_data/navigation.yml +6 -0
- data/usechutney.com/docs/rules/avoid-colons-at-start-of-names/index.md +28 -0
- data/usechutney.com/docs/rules/same-scenario/index.md +24 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c008b1c26d32fdc61e5971638623f09d6f34526e0482b31c9e6c98ca7770a5e6
|
4
|
+
data.tar.gz: 4868772b4ffea1157e0c443772d779dc5b693aa7ec693d3e37718d392ab6676b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03c10adcf4fe4c184ef0a867f7b735c1f39e9845ce691c6d6bb2679a3f81917d65e417dd32e80776a5db036afa11de056f35464fdf54db3caf55c82015803cce
|
7
|
+
data.tar.gz: 90fb24d6851765a01e014f1c838c51eed6d0190ce85265ab0344f481fded24ff9b632bdbc847263ddf2b20e80a81f61140cc452409785c52dcc000a105b4c8c4
|
data/config/chutney_defaults.yml
CHANGED
@@ -1,80 +1,84 @@
|
|
1
|
+
AvoidColonsAtStartOfNames:
|
2
|
+
Enabled: true
|
3
|
+
AvoidCommaInTags:
|
4
|
+
Enabled: true
|
1
5
|
AvoidOutlineForSingleExample:
|
2
|
-
|
6
|
+
Enabled: true
|
3
7
|
AvoidFullStop:
|
4
|
-
|
8
|
+
Enabled: true
|
5
9
|
AvoidScripting:
|
6
|
-
|
10
|
+
Enabled: true
|
7
11
|
AvoidSplatStepsInBackground:
|
8
|
-
|
12
|
+
Enabled: true
|
9
13
|
AvoidSplatStepsInScenarios:
|
10
|
-
|
14
|
+
Enabled: true
|
11
15
|
AvoidTypographersQuotes:
|
12
|
-
|
16
|
+
Enabled: true
|
13
17
|
BackgroundDoesMoreThanSetup:
|
14
|
-
|
18
|
+
Enabled: true
|
15
19
|
BackgroundRequiresMultipleScenarios:
|
16
|
-
|
20
|
+
Enabled: true
|
17
21
|
BadScenarioName:
|
18
|
-
|
22
|
+
Enabled: true
|
19
23
|
EmptyFeatureFile:
|
20
|
-
|
24
|
+
Enabled: true
|
21
25
|
FileNameDiffersFeatureName:
|
22
|
-
|
26
|
+
Enabled: true
|
23
27
|
GivensAfterBackground:
|
24
|
-
|
28
|
+
Enabled: true
|
25
29
|
MissingExampleName:
|
26
|
-
|
30
|
+
Enabled: true
|
27
31
|
MissingExampleTable:
|
28
|
-
|
32
|
+
Enabled: true
|
29
33
|
MissingFeatureDescription:
|
30
|
-
|
34
|
+
Enabled: true
|
31
35
|
MissingFeatureName:
|
32
|
-
|
36
|
+
Enabled: true
|
33
37
|
MissingScenarioName:
|
34
|
-
|
38
|
+
Enabled: true
|
35
39
|
MissingScenarioOutline:
|
36
|
-
|
40
|
+
Enabled: true
|
37
41
|
MissingTestAction:
|
38
|
-
|
42
|
+
Enabled: true
|
39
43
|
MissingVerification:
|
40
|
-
|
44
|
+
Enabled: true
|
41
45
|
InconsistentQuoting:
|
42
|
-
|
46
|
+
Enabled: true
|
43
47
|
InvalidFileName:
|
44
|
-
|
48
|
+
Enabled: true
|
45
49
|
InvalidStepFlow:
|
46
|
-
|
50
|
+
Enabled: true
|
47
51
|
RequiredTagsStartsWith:
|
48
|
-
|
52
|
+
Enabled: false
|
49
53
|
SameTagDifferentCase:
|
50
|
-
|
54
|
+
Enabled: true
|
51
55
|
SameTagForAllScenarios:
|
52
|
-
|
56
|
+
Enabled: true
|
53
57
|
ScenarioNamesMatch:
|
54
|
-
|
58
|
+
Enabled: false
|
55
59
|
TagUsedMultipleTimes:
|
56
|
-
|
60
|
+
Enabled: true
|
57
61
|
TooClumsy:
|
58
|
-
|
62
|
+
Enabled: true
|
59
63
|
TooManyDifferentTags:
|
60
|
-
|
61
|
-
|
64
|
+
Enabled: true
|
65
|
+
MaxCount: 3
|
62
66
|
TooManySteps:
|
63
|
-
|
64
|
-
|
67
|
+
Enabled: true
|
68
|
+
MaxCount: 10
|
65
69
|
TooManyTags:
|
66
|
-
|
67
|
-
|
70
|
+
Enabled: true
|
71
|
+
MaxCount: 3
|
68
72
|
TooLongStep:
|
69
|
-
|
70
|
-
|
73
|
+
Enabled: true
|
74
|
+
MaxLength: 80
|
71
75
|
UniqueScenarioNames:
|
72
|
-
|
76
|
+
Enabled: true
|
73
77
|
UnknownVariable:
|
74
|
-
|
78
|
+
Enabled: true
|
75
79
|
UnusedVariable:
|
76
|
-
|
80
|
+
Enabled: true
|
77
81
|
UseBackground:
|
78
|
-
|
82
|
+
Enabled: true
|
79
83
|
UseOutline:
|
80
|
-
|
84
|
+
Enabled: true
|
data/docs/usage/rules.md
CHANGED
@@ -57,6 +57,8 @@ Chutney enforces its rules with the linters. These are:
|
|
57
57
|
|
58
58
|
[RequiredTagsStartWith](https://github.com/BillyRuffian/chutney/blob/master/features/required_tags_starts_with.feature): Chutney can enforce a configurable naming prefix for your tags.
|
59
59
|
|
60
|
+
[SameSecenario](https://github.com/BillyRuffian/chutney/blob/master/features/same_scenario.feature): Makes sure you don't acidentally duplicate the actions of your scenario. *Since v3.11.0*
|
61
|
+
|
60
62
|
[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*
|
61
63
|
|
62
64
|
[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.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chutney
|
4
|
+
# service class to lint for avoiding colons at the start of names
|
5
|
+
class AvoidColonsAtStartOfNames < Linter
|
6
|
+
def lint
|
7
|
+
add_issue(I18n.t('linters.avoid_colons_at_start_of_names'), feature) if feature.name.start_with? ':'
|
8
|
+
|
9
|
+
scenarios do |_feature, scenario|
|
10
|
+
if scenario.name.start_with? ':'
|
11
|
+
add_issue(I18n.t('linters.avoid_colons_at_start_of_names'), feature,
|
12
|
+
scenario)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Chutney
|
2
|
+
|
3
|
+
class SameScenario < Linter
|
4
|
+
def lint
|
5
|
+
dictionary = Hash.new { |hash, key| hash[key] = [] }
|
6
|
+
|
7
|
+
scenarios do |feature, scenario|
|
8
|
+
text = scenario
|
9
|
+
.steps
|
10
|
+
.map { |step| "#{step.text} #{child_text(step)}" }
|
11
|
+
.join("\n") + example_text(scenario)
|
12
|
+
|
13
|
+
digest = Digest::SHA2.hexdigest(text)
|
14
|
+
dictionary[digest] << { scenario:, feature: }
|
15
|
+
end
|
16
|
+
|
17
|
+
dictionary.filter { |k, v| v.size > 1 }
|
18
|
+
.each_value do |v|
|
19
|
+
v[1...].each { |problem|
|
20
|
+
add_issue(I18n.t('linters.same_scenario',
|
21
|
+
feature: problem[:feature].name,
|
22
|
+
scenario: problem[:scenario].name,
|
23
|
+
original_feature: v.first[:feature].name,
|
24
|
+
original_scenario: v.first[:scenario].name),
|
25
|
+
problem[:feature], problem[:scenario], nil) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def child_text(step)
|
30
|
+
step.children.map do |child|
|
31
|
+
if child.is_a?(CukeModeler::Table)
|
32
|
+
child.rows.flat_map(&:cells).map(&:value).join(' | ')
|
33
|
+
elsif child.is_a?(CukeModeler::DocString)
|
34
|
+
child.content
|
35
|
+
else
|
36
|
+
''
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def example_text(scenario)
|
42
|
+
if scenario.is_a?(CukeModeler::Outline)
|
43
|
+
"\n" + scenario.examples
|
44
|
+
.flat_map(&:rows)
|
45
|
+
.flat_map(&:cells)
|
46
|
+
.map(&:value).join(' | ')
|
47
|
+
else
|
48
|
+
''
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/chutney/version.rb
CHANGED
data/lib/chutney.rb
CHANGED
@@ -4,6 +4,7 @@ require 'amatch'
|
|
4
4
|
|
5
5
|
require 'chutney/configuration'
|
6
6
|
require 'chutney/linter'
|
7
|
+
require 'chutney/linter/avoid_colons_at_start_of_names'
|
7
8
|
require 'chutney/linter/avoid_comma_in_tags'
|
8
9
|
require 'chutney/linter/avoid_full_stop'
|
9
10
|
require 'chutney/linter/avoid_outline_for_single_example'
|
@@ -29,6 +30,7 @@ require 'chutney/linter/missing_scenario_outline'
|
|
29
30
|
require 'chutney/linter/missing_test_action'
|
30
31
|
require 'chutney/linter/missing_verification'
|
31
32
|
require 'chutney/linter/required_tags_starts_with'
|
33
|
+
require 'chutney/linter/same_scenario'
|
32
34
|
require 'chutney/linter/same_tag_different_case'
|
33
35
|
require 'chutney/linter/same_tag_for_all_scenarios'
|
34
36
|
require 'chutney/linter/scenario_names_match'
|
data/lib/config/locales/en.yml
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
# God save the Queen, etc. etc.
|
4
4
|
en:
|
5
5
|
linters:
|
6
|
+
avoid_colons_at_start_of_names: >-
|
7
|
+
Avoid using colons at the start of names, it can make them hard to read or find.
|
6
8
|
avoid_comma_in_tags: >-
|
7
9
|
Avoid using commas in tags. Tags should be separated by spaces.
|
8
10
|
avoid_full_stop: >- # https://en.wikipedia.org/wiki/Full_stop
|
@@ -76,6 +78,8 @@ en:
|
|
76
78
|
the assertion being tested.
|
77
79
|
required_tags_starts_with: >-
|
78
80
|
You have tags which do not match the required format. Allowed prefixes are '%{allowed}'.
|
81
|
+
same_scenario: >-
|
82
|
+
Duplicate scenario detected: %{feature} / %{scenario} is a duplicate of %{original_feature} / %{original_scenario}
|
79
83
|
scenario_names_match: >-
|
80
84
|
You have a scenario name which does not match the required format.
|
81
85
|
Allowed patterns are '%{pattern}'.
|
@@ -29,6 +29,10 @@ sidebar:
|
|
29
29
|
|
30
30
|
- title: "Rules"
|
31
31
|
children:
|
32
|
+
- title: "Avoid colons at start of names"
|
33
|
+
url: /docs/rules/avoid-colons-at-start-of-names/
|
34
|
+
- title: "Avoid comma in tags"
|
35
|
+
url: /docs/rules/avoid-comma-in-tags/
|
32
36
|
- title: "Avoid full stops"
|
33
37
|
url: /docs/rules/avoid-full-stops/
|
34
38
|
- title: "Avoid outline for single example"
|
@@ -77,6 +81,8 @@ sidebar:
|
|
77
81
|
url: /docs/rules/missing-test-verification/
|
78
82
|
- title: "Required tags start with"
|
79
83
|
url: /docs/rules/required-tags-start-with/
|
84
|
+
- title: "Same Scenario"
|
85
|
+
url: /docs/rules/same-scenario/
|
80
86
|
- title: "Same tag different case"
|
81
87
|
url: /docs/rules/same-tag-different-case/
|
82
88
|
- title: "Same tag for all scenarios"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
title: "Avoid Colons at Start of Names"
|
3
|
+
layout: single
|
4
|
+
permalink: /docs/rules/avoid-colons-at-start-of-names/
|
5
|
+
---
|
6
|
+
|
7
|
+
Don't have colons at the start of feature or scenario names. It's probably a mistake if you have them from double typing the colon after the `Feature` or `Scenario` keyword.
|
8
|
+
|
9
|
+
|
10
|
+
## Bad
|
11
|
+
|
12
|
+
```gherkin
|
13
|
+
Feature: :My Feature
|
14
|
+
Scenario: :My Scenario
|
15
|
+
Given I have visited the website
|
16
|
+
When I log in
|
17
|
+
Then I will see my account
|
18
|
+
```
|
19
|
+
|
20
|
+
## Good
|
21
|
+
|
22
|
+
```gherkin
|
23
|
+
Feature: My Feature
|
24
|
+
Scenario: My Scenario
|
25
|
+
Given I have visited the website
|
26
|
+
When I log in
|
27
|
+
Then I will see my account
|
28
|
+
```
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
title: "Same Scenario"
|
3
|
+
layout: single
|
4
|
+
permalink: /docs/rules/same-scenario/
|
5
|
+
---
|
6
|
+
|
7
|
+
You have a `Scenario`, or a `Scenario Outline` which appears to be duplicated. This probably means you have a redundant test. You should probably make sure you only have one copy of your steps to be consitent and efficient.
|
8
|
+
|
9
|
+
|
10
|
+
This rule ignores the names of your scenarios but takes into account data tables, examples and doc strings.
|
11
|
+
|
12
|
+
## Examples
|
13
|
+
|
14
|
+
```gherkin
|
15
|
+
Feature: Test
|
16
|
+
Scenario: Scenario A
|
17
|
+
When I do a thing
|
18
|
+
Then A thing happens
|
19
|
+
|
20
|
+
Scenario: Scenario B
|
21
|
+
When I do a thing
|
22
|
+
Then A thing happens
|
23
|
+
```
|
24
|
+
|
metadata
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chutney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nigel Brookes-Thomas
|
8
8
|
- Stefan Rohe
|
9
9
|
- Nishtha Argawal
|
10
10
|
- John Gluck
|
11
|
-
autorequire:
|
12
11
|
bindir: exe
|
13
12
|
cert_chain: []
|
14
|
-
date:
|
13
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: amatch
|
@@ -155,6 +154,7 @@ files:
|
|
155
154
|
- lib/chutney/formatter/rainbow_formatter.rb
|
156
155
|
- lib/chutney/issue.rb
|
157
156
|
- lib/chutney/linter.rb
|
157
|
+
- lib/chutney/linter/avoid_colons_at_start_of_names.rb
|
158
158
|
- lib/chutney/linter/avoid_comma_in_tags.rb
|
159
159
|
- lib/chutney/linter/avoid_full_stop.rb
|
160
160
|
- lib/chutney/linter/avoid_outline_for_single_example.rb
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- lib/chutney/linter/missing_test_action.rb
|
181
181
|
- lib/chutney/linter/missing_verification.rb
|
182
182
|
- lib/chutney/linter/required_tags_starts_with.rb
|
183
|
+
- lib/chutney/linter/same_scenario.rb
|
183
184
|
- lib/chutney/linter/same_tag_different_case.rb
|
184
185
|
- lib/chutney/linter/same_tag_for_all_scenarios.rb
|
185
186
|
- lib/chutney/linter/scenario_names_match.rb
|
@@ -214,6 +215,7 @@ files:
|
|
214
215
|
- usechutney.com/docs/disabling-rules/index.md
|
215
216
|
- usechutney.com/docs/installing/index.md
|
216
217
|
- usechutney.com/docs/language-server/index.md
|
218
|
+
- usechutney.com/docs/rules/avoid-colons-at-start-of-names/index.md
|
217
219
|
- usechutney.com/docs/rules/avoid-comma-in-tags/index.md
|
218
220
|
- usechutney.com/docs/rules/avoid-full-stops/index.md
|
219
221
|
- usechutney.com/docs/rules/avoid-outline-for-single-example/index.md
|
@@ -239,6 +241,7 @@ files:
|
|
239
241
|
- usechutney.com/docs/rules/missing-test-action/index.md
|
240
242
|
- usechutney.com/docs/rules/missing-test-verification/index.md
|
241
243
|
- usechutney.com/docs/rules/required-tag-starts-with/index.md
|
244
|
+
- usechutney.com/docs/rules/same-scenario/index.md
|
242
245
|
- usechutney.com/docs/rules/same-tag-different-case/index.md
|
243
246
|
- usechutney.com/docs/rules/same-tag-for-all-scenarios/index.md
|
244
247
|
- usechutney.com/docs/rules/scenario-names-match/index.md
|
@@ -264,7 +267,6 @@ metadata:
|
|
264
267
|
homepage_uri: https://www.usechutney.com/
|
265
268
|
source_code_uri: https://github.com/BillyRuffian/chutney
|
266
269
|
changelog_uri: https://github.com/BillyRuffian/chutney/releases
|
267
|
-
post_install_message:
|
268
270
|
rdoc_options: []
|
269
271
|
require_paths:
|
270
272
|
- lib
|
@@ -279,8 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
281
|
- !ruby/object:Gem::Version
|
280
282
|
version: '0'
|
281
283
|
requirements: []
|
282
|
-
rubygems_version: 3.
|
283
|
-
signing_key:
|
284
|
+
rubygems_version: 3.6.9
|
284
285
|
specification_version: 4
|
285
286
|
summary: A linter for multi-lingual Gherkin
|
286
287
|
test_files: []
|