chutney 2.2.1 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -1
- data/Gemfile +2 -0
- data/Rakefile +2 -0
- data/chutney.gemspec +8 -4
- data/config/cucumber.yml +1 -0
- data/exe/chutney +2 -0
- data/lib/chutney.rb +9 -11
- data/lib/chutney/configuration.rb +2 -0
- data/lib/chutney/formatter.rb +2 -0
- data/lib/chutney/formatter/json_formatter.rb +2 -0
- data/lib/chutney/formatter/pie_formatter.rb +2 -0
- data/lib/chutney/formatter/rainbow_formatter.rb +2 -0
- data/lib/chutney/issue.rb +2 -0
- data/lib/chutney/linter.rb +58 -59
- data/lib/chutney/linter/avoid_full_stop.rb +3 -1
- data/lib/chutney/linter/avoid_outline_for_single_example.rb +8 -6
- data/lib/chutney/linter/avoid_scripting.rb +6 -4
- data/lib/chutney/linter/avoid_typographers_quotes.rb +16 -14
- data/lib/chutney/linter/background_does_more_than_setup.rb +8 -6
- data/lib/chutney/linter/background_requires_multiple_scenarios.rb +6 -3
- data/lib/chutney/linter/bad_scenario_name.rb +4 -2
- data/lib/chutney/linter/empty_feature_file.rb +2 -0
- data/lib/chutney/linter/file_name_differs_feature_name.rb +4 -2
- data/lib/chutney/linter/givens_after_background.rb +5 -6
- data/lib/chutney/linter/invalid_file_name.rb +2 -0
- data/lib/chutney/linter/invalid_step_flow.rb +7 -7
- data/lib/chutney/linter/missing_example_name.rb +7 -5
- data/lib/chutney/linter/missing_feature_description.rb +4 -3
- data/lib/chutney/linter/missing_feature_name.rb +3 -2
- data/lib/chutney/linter/missing_scenario_name.rb +3 -4
- data/lib/chutney/linter/missing_test_action.rb +3 -1
- data/lib/chutney/linter/missing_verification.rb +3 -1
- data/lib/chutney/linter/required_tags_starts_with.rb +2 -0
- data/lib/chutney/linter/same_tag_for_all_scenarios.rb +11 -10
- data/lib/chutney/linter/scenario_names_match.rb +4 -3
- data/lib/chutney/linter/tag_used_multiple_times.rb +2 -0
- data/lib/chutney/linter/too_clumsy.rb +3 -1
- data/lib/chutney/linter/too_long_step.rb +4 -2
- data/lib/chutney/linter/too_many_different_tags.rb +4 -2
- data/lib/chutney/linter/too_many_steps.rb +4 -2
- data/lib/chutney/linter/too_many_tags.rb +2 -0
- data/lib/chutney/linter/unique_scenario_names.rb +3 -3
- data/lib/chutney/linter/unknown_variable.rb +13 -13
- data/lib/chutney/linter/unused_variable.rb +13 -13
- data/lib/chutney/linter/use_background.rb +17 -16
- data/lib/chutney/linter/use_outline.rb +8 -7
- data/lib/chutney/version.rb +3 -1
- data/spec/chutney_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- metadata +33 -12
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for too long steps
|
3
5
|
class TooLongStep < Linter
|
4
6
|
def lint
|
5
7
|
steps do |feature, scenario, step|
|
6
|
-
next if step
|
8
|
+
next if step.text.length <= maxlength
|
7
9
|
|
8
10
|
add_issue(
|
9
|
-
I18n.t('linters.too_long_step', length: step
|
11
|
+
I18n.t('linters.too_long_step', length: step.text.length, max: maxlength),
|
10
12
|
feature, scenario
|
11
13
|
)
|
12
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for too many different tags
|
3
5
|
class TooManyDifferentTags < Linter
|
@@ -16,9 +18,9 @@ module Chutney
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def all_tags
|
19
|
-
return [] unless feature&.
|
21
|
+
return [] unless feature&.scenarios
|
20
22
|
|
21
|
-
tags_for(feature) + feature
|
23
|
+
tags_for(feature) + feature.scenarios.map { |scenario| tags_for(scenario) }.flatten
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for too many steps
|
3
5
|
class TooManySteps < Linter
|
4
6
|
def lint
|
5
7
|
filled_scenarios do |feature, scenario|
|
6
|
-
next if scenario
|
8
|
+
next if scenario.steps.length <= maxcount
|
7
9
|
|
8
10
|
add_issue(
|
9
|
-
I18n.t('linters.too_many_steps', count: scenario
|
11
|
+
I18n.t('linters.too_many_steps', count: scenario.steps.length, max: maxcount),
|
10
12
|
feature
|
11
13
|
)
|
12
14
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for unique scenario names
|
3
5
|
class UniqueScenarioNames < Linter
|
4
6
|
def lint
|
5
7
|
references_by_name = {}
|
6
8
|
scenarios do |feature, scenario|
|
7
|
-
|
8
|
-
|
9
|
-
name = scenario[:name]
|
9
|
+
name = scenario.name
|
10
10
|
if references_by_name[name]
|
11
11
|
issue(name, references_by_name[name], scenario)
|
12
12
|
else
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for unknown variables
|
3
5
|
class UnknownVariable < Linter
|
4
6
|
def lint
|
5
7
|
filled_scenarios do |feature, scenario|
|
6
8
|
known_vars = Set.new(known_variables(scenario))
|
7
|
-
scenario
|
9
|
+
scenario.steps.each do |step|
|
8
10
|
step_vars(step).each do |used_var|
|
9
11
|
next if known_vars.include? used_var
|
10
12
|
|
@@ -17,17 +19,17 @@ module Chutney
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def step_vars(step)
|
20
|
-
vars = gather_vars step
|
21
|
-
return vars unless step.
|
22
|
+
vars = gather_vars step.text
|
23
|
+
return vars unless step.block
|
22
24
|
|
23
|
-
vars + gather_vars_from_argument(step
|
25
|
+
vars + gather_vars_from_argument(step.block)
|
24
26
|
end
|
25
27
|
|
26
28
|
def gather_vars_from_argument(argument)
|
27
|
-
return gather_vars argument
|
28
|
-
|
29
|
-
|
30
|
-
row
|
29
|
+
return gather_vars argument.content if argument.is_a? CukeModeler::DocString
|
30
|
+
|
31
|
+
argument.rows.map do |row|
|
32
|
+
row.cells.map { |cell| gather_vars cell.value }.flatten
|
31
33
|
end.flatten
|
32
34
|
end
|
33
35
|
|
@@ -36,11 +38,9 @@ module Chutney
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def known_variables(scenario)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
example[:tableHeader][:cells].map { |cell| cell[:value].strip }
|
43
|
-
end.flatten
|
41
|
+
return [] unless scenario.is_a? CukeModeler::Outline
|
42
|
+
|
43
|
+
scenario.examples.map { |ex| ex.rows.first.cells.map(&:value) }.flatten
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for unused variables
|
3
5
|
class UnusedVariable < Linter
|
4
6
|
def lint
|
5
7
|
scenarios do |feature, scenario|
|
6
|
-
next unless scenario.
|
7
|
-
|
8
|
-
scenario
|
9
|
-
next unless example.key?(:tableHeader)
|
8
|
+
next unless scenario.is_a? CukeModeler::Outline
|
9
|
+
|
10
|
+
scenario.examples.each do |example|
|
10
11
|
|
11
|
-
example
|
12
|
+
example.rows.first.cells.map(&:value).each do |variable|
|
12
13
|
next if used?(variable, scenario)
|
13
14
|
|
14
15
|
add_issue(I18n.t('linters.unused_variable', variable: variable), feature, scenario, example)
|
@@ -19,11 +20,10 @@ module Chutney
|
|
19
20
|
|
20
21
|
def used?(variable, scenario)
|
21
22
|
variable = "<#{variable}>"
|
22
|
-
return false unless scenario.key? :steps
|
23
23
|
|
24
|
-
scenario
|
25
|
-
return true if step
|
26
|
-
next unless step.
|
24
|
+
scenario.steps.each do |step|
|
25
|
+
return true if step.text.include? variable
|
26
|
+
next unless step.block
|
27
27
|
return true if used_in_docstring?(variable, step)
|
28
28
|
return true if used_in_table?(variable, step)
|
29
29
|
end
|
@@ -31,14 +31,14 @@ module Chutney
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def used_in_docstring?(variable, step)
|
34
|
-
step
|
34
|
+
step.block.is_a?(CukeModeler::DocString) && step.block.content.include?(variable)
|
35
35
|
end
|
36
36
|
|
37
37
|
def used_in_table?(variable, step)
|
38
|
-
return false unless step
|
38
|
+
return false unless step.block.is_a?(CukeModeler::Table)
|
39
39
|
|
40
|
-
step
|
41
|
-
row
|
40
|
+
step.block.rows.each do |row|
|
41
|
+
row.cells.each { |cell| return true if cell.value.include?(variable) }
|
42
42
|
end
|
43
43
|
false
|
44
44
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for using background
|
3
5
|
class UseBackground < Linter
|
@@ -13,14 +15,13 @@ module Chutney
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def gather_givens
|
16
|
-
return unless feature.
|
18
|
+
return unless feature.children
|
17
19
|
|
18
20
|
has_non_given_step = false
|
19
|
-
|
20
|
-
next unless scenario.
|
21
|
-
next if scenario[:steps].empty?
|
21
|
+
scenarios do |_feature, scenario|
|
22
|
+
next unless scenario.steps
|
22
23
|
|
23
|
-
has_non_given_step = true unless given_word?(scenario
|
24
|
+
has_non_given_step = true unless given_word?(scenario.steps.first.keyword)
|
24
25
|
end
|
25
26
|
return if has_non_given_step
|
26
27
|
|
@@ -29,15 +30,13 @@ module Chutney
|
|
29
30
|
result
|
30
31
|
end
|
31
32
|
|
32
|
-
def expanded_steps
|
33
|
-
|
34
|
-
next unless scenario
|
35
|
-
next unless scenario.include? :steps
|
36
|
-
next if scenario[:steps].empty?
|
33
|
+
def expanded_steps(&block)
|
34
|
+
scenarios do |_feature, scenario|
|
35
|
+
next unless scenario.steps
|
37
36
|
|
38
|
-
prototypes = [render_step(scenario
|
39
|
-
prototypes = expand_examples(scenario
|
40
|
-
prototypes.each
|
37
|
+
prototypes = [render_step(scenario.steps.first)]
|
38
|
+
prototypes = expand_examples(scenario.examples, prototypes) if scenario.is_a? CukeModeler::Outline
|
39
|
+
prototypes.each(&block)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
@@ -50,10 +49,12 @@ module Chutney
|
|
50
49
|
|
51
50
|
def expand_outlines(sentence, example)
|
52
51
|
result = []
|
53
|
-
headers = example
|
54
|
-
example
|
52
|
+
headers = example.rows.first.cells.map(&:value)
|
53
|
+
example.rows.each_with_index do |row, idx|
|
54
|
+
next if idx.zero? # skip the header
|
55
|
+
|
55
56
|
modified_sentence = sentence.dup
|
56
|
-
headers.zip(row
|
57
|
+
headers.zip(row.cells.map(&:value)).map do |key, value|
|
57
58
|
modified_sentence.gsub!("<#{key}>", value)
|
58
59
|
end
|
59
60
|
result.push modified_sentence
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Chutney
|
2
4
|
# service class to lint for using outline
|
3
5
|
class UseOutline < Linter
|
@@ -36,12 +38,11 @@ module Chutney
|
|
36
38
|
|
37
39
|
def gather_scenarios(feature)
|
38
40
|
scenarios = []
|
39
|
-
return scenarios if feature.nil? || !feature.
|
41
|
+
return scenarios if feature.nil? || !feature.tests
|
40
42
|
|
41
|
-
|
42
|
-
next unless scenario
|
43
|
-
next
|
44
|
-
next if scenario[:steps].empty?
|
43
|
+
scenarios do |_feature, scenario|
|
44
|
+
next unless scenario.steps
|
45
|
+
next if scenario.steps.empty?
|
45
46
|
|
46
47
|
scenarios.push generate_reference(feature, scenario)
|
47
48
|
end
|
@@ -51,8 +52,8 @@ module Chutney
|
|
51
52
|
def generate_reference(feature, scenario)
|
52
53
|
reference = {}
|
53
54
|
reference[:reference] = location(feature, scenario, nil)
|
54
|
-
reference[:name] = "#{scenario
|
55
|
-
reference[:text] = scenario
|
55
|
+
reference[:name] = "#{scenario.keyword}: #{scenario.name}"
|
56
|
+
reference[:text] = scenario.steps.map { |step| render_step(step) }.join ' '
|
56
57
|
reference
|
57
58
|
end
|
58
59
|
end
|
data/lib/chutney/version.rb
CHANGED
data/spec/chutney_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
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:
|
4
|
+
version: 3.0.0.beta.1
|
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-
|
14
|
+
date: 2020-09-02 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: amatch
|
@@ -28,19 +28,39 @@ dependencies:
|
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.4.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: cuke_modeler
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
34
|
- - "~>"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
36
|
+
version: '3.3'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '3.3'
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: gherkin
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
42
49
|
- !ruby/object:Gem::Version
|
43
50
|
version: 5.1.0
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '9.1'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 5.1.0
|
61
|
+
- - "<"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '9.1'
|
44
64
|
- !ruby/object:Gem::Dependency
|
45
65
|
name: i18n
|
46
66
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,14 +123,14 @@ dependencies:
|
|
103
123
|
requirements:
|
104
124
|
- - "~>"
|
105
125
|
- !ruby/object:Gem::Version
|
106
|
-
version: '
|
126
|
+
version: '5.1'
|
107
127
|
type: :development
|
108
128
|
prerelease: false
|
109
129
|
version_requirements: !ruby/object:Gem::Requirement
|
110
130
|
requirements:
|
111
131
|
- - "~>"
|
112
132
|
- !ruby/object:Gem::Version
|
113
|
-
version: '
|
133
|
+
version: '5.1'
|
114
134
|
- !ruby/object:Gem::Dependency
|
115
135
|
name: pry-byebug
|
116
136
|
requirement: !ruby/object:Gem::Requirement
|
@@ -196,7 +216,7 @@ dependencies:
|
|
196
216
|
- !ruby/object:Gem::Version
|
197
217
|
version: '3.8'
|
198
218
|
description: A linter for your Cucumber features. It supports any spoken language
|
199
|
-
Cucumber
|
219
|
+
Cucumber supports.
|
200
220
|
email:
|
201
221
|
- nigel@brookes-thomas.co.uk
|
202
222
|
executables:
|
@@ -216,6 +236,7 @@ files:
|
|
216
236
|
- Rakefile
|
217
237
|
- chutney.gemspec
|
218
238
|
- config/chutney.yml
|
239
|
+
- config/cucumber.yml
|
219
240
|
- docs/.keep
|
220
241
|
- docs/_config.yml
|
221
242
|
- docs/credits.md
|
@@ -289,17 +310,17 @@ require_paths:
|
|
289
310
|
- lib
|
290
311
|
required_ruby_version: !ruby/object:Gem::Requirement
|
291
312
|
requirements:
|
292
|
-
- - "
|
313
|
+
- - "~>"
|
293
314
|
- !ruby/object:Gem::Version
|
294
|
-
version: '
|
315
|
+
version: '2.6'
|
295
316
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
296
317
|
requirements:
|
297
|
-
- - "
|
318
|
+
- - ">"
|
298
319
|
- !ruby/object:Gem::Version
|
299
|
-
version:
|
320
|
+
version: 1.3.1
|
300
321
|
requirements: []
|
301
322
|
rubygems_version: 3.1.2
|
302
323
|
signing_key:
|
303
324
|
specification_version: 4
|
304
|
-
summary: A linter for
|
325
|
+
summary: A linter for multi-lingual Gherkin
|
305
326
|
test_files: []
|