chutney 2.2.1 → 3.0.0.beta.1

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -1
  3. data/Gemfile +2 -0
  4. data/Rakefile +2 -0
  5. data/chutney.gemspec +8 -4
  6. data/config/cucumber.yml +1 -0
  7. data/exe/chutney +2 -0
  8. data/lib/chutney.rb +9 -11
  9. data/lib/chutney/configuration.rb +2 -0
  10. data/lib/chutney/formatter.rb +2 -0
  11. data/lib/chutney/formatter/json_formatter.rb +2 -0
  12. data/lib/chutney/formatter/pie_formatter.rb +2 -0
  13. data/lib/chutney/formatter/rainbow_formatter.rb +2 -0
  14. data/lib/chutney/issue.rb +2 -0
  15. data/lib/chutney/linter.rb +58 -59
  16. data/lib/chutney/linter/avoid_full_stop.rb +3 -1
  17. data/lib/chutney/linter/avoid_outline_for_single_example.rb +8 -6
  18. data/lib/chutney/linter/avoid_scripting.rb +6 -4
  19. data/lib/chutney/linter/avoid_typographers_quotes.rb +16 -14
  20. data/lib/chutney/linter/background_does_more_than_setup.rb +8 -6
  21. data/lib/chutney/linter/background_requires_multiple_scenarios.rb +6 -3
  22. data/lib/chutney/linter/bad_scenario_name.rb +4 -2
  23. data/lib/chutney/linter/empty_feature_file.rb +2 -0
  24. data/lib/chutney/linter/file_name_differs_feature_name.rb +4 -2
  25. data/lib/chutney/linter/givens_after_background.rb +5 -6
  26. data/lib/chutney/linter/invalid_file_name.rb +2 -0
  27. data/lib/chutney/linter/invalid_step_flow.rb +7 -7
  28. data/lib/chutney/linter/missing_example_name.rb +7 -5
  29. data/lib/chutney/linter/missing_feature_description.rb +4 -3
  30. data/lib/chutney/linter/missing_feature_name.rb +3 -2
  31. data/lib/chutney/linter/missing_scenario_name.rb +3 -4
  32. data/lib/chutney/linter/missing_test_action.rb +3 -1
  33. data/lib/chutney/linter/missing_verification.rb +3 -1
  34. data/lib/chutney/linter/required_tags_starts_with.rb +2 -0
  35. data/lib/chutney/linter/same_tag_for_all_scenarios.rb +11 -10
  36. data/lib/chutney/linter/scenario_names_match.rb +4 -3
  37. data/lib/chutney/linter/tag_used_multiple_times.rb +2 -0
  38. data/lib/chutney/linter/too_clumsy.rb +3 -1
  39. data/lib/chutney/linter/too_long_step.rb +4 -2
  40. data/lib/chutney/linter/too_many_different_tags.rb +4 -2
  41. data/lib/chutney/linter/too_many_steps.rb +4 -2
  42. data/lib/chutney/linter/too_many_tags.rb +2 -0
  43. data/lib/chutney/linter/unique_scenario_names.rb +3 -3
  44. data/lib/chutney/linter/unknown_variable.rb +13 -13
  45. data/lib/chutney/linter/unused_variable.rb +13 -13
  46. data/lib/chutney/linter/use_background.rb +17 -16
  47. data/lib/chutney/linter/use_outline.rb +8 -7
  48. data/lib/chutney/version.rb +3 -1
  49. data/spec/chutney_spec.rb +2 -0
  50. data/spec/spec_helper.rb +2 -0
  51. 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[:text].length <= maxlength
8
+ next if step.text.length <= maxlength
7
9
 
8
10
  add_issue(
9
- I18n.t('linters.too_long_step', length: step[:text].length, max: maxlength),
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&.include?(:children)
21
+ return [] unless feature&.scenarios
20
22
 
21
- tags_for(feature) + feature[:children].map { |scenario| tags_for(scenario) }.flatten
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[:steps].length <= maxcount
8
+ next if scenario.steps.length <= maxcount
7
9
 
8
10
  add_issue(
9
- I18n.t('linters.too_many_steps', count: scenario[:steps].length, max: maxcount),
11
+ I18n.t('linters.too_many_steps', count: scenario.steps.length, max: maxcount),
10
12
  feature
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 tags
3
5
  class TooManyTags < Linter
@@ -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
- next unless scenario.key? :name
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[:steps].each do |step|
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[:text]
21
- return vars unless step.include? :argument
22
+ vars = gather_vars step.text
23
+ return vars unless step.block
22
24
 
23
- vars + gather_vars_from_argument(step[:argument])
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[:content] if argument[:type] == :DocString
28
-
29
- (argument[:rows] || []).map do |row|
30
- row[:cells].map { |value| gather_vars value[:value] }.flatten
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
- (scenario[:examples] || []).map do |example|
40
- next unless example.key? :tableHeader
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.key?(:examples)
7
-
8
- scenario[:examples].each do |example|
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[:tableHeader][:cells].map { |cell| cell[:value] }.each do |variable|
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[:steps].each do |step|
25
- return true if step[:text].include? variable
26
- next unless step.include? :argument
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[:argument][:type] == :DocString && step[:argument][:content].include?(variable)
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[:argument][:type] == :DataTable
38
+ return false unless step.block.is_a?(CukeModeler::Table)
39
39
 
40
- step[:argument][:rows].each do |row|
41
- row[:cells].each { |value| return true if value[:value].include?(variable) }
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.include? :children
18
+ return unless feature.children
17
19
 
18
20
  has_non_given_step = false
19
- feature[:children].each do |scenario|
20
- next unless scenario.include? :steps
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[:steps].first[:keyword])
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
- feature[:children].each do |scenario|
34
- next unless scenario[:type] != :Background
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[:steps].first)]
39
- prototypes = expand_examples(scenario[:examples], prototypes) if scenario.key? :examples
40
- prototypes.each { |prototype| yield prototype }
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[:tableHeader][:cells].map { |cell| cell[:value] }
54
- example[:tableBody].each do |row| # .slice(1, example[:tableBody].length).each do |row|
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[:cells].map { |cell| cell[:value] }).map do |key, value|
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.include?(:children)
41
+ return scenarios if feature.nil? || !feature.tests
40
42
 
41
- feature[:children].each do |scenario|
42
- next unless scenario[:type] == :Scenario
43
- next unless scenario.include? :steps
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[:keyword]}: #{scenario[:name]}"
55
- reference[:text] = scenario[:steps].map { |step| render_step(step) }.join ' '
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Chutney
2
- VERSION = '2.2.1'.freeze
4
+ VERSION = '3.0.0.beta.1'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'chutney'
2
4
 
3
5
  describe Chutney::ChutneyLint do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simplecov'
2
4
  require 'coveralls'
3
5
  # Coveralls.wear!
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: 2.2.1
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-08-25 00:00:00.000000000 Z
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: gherkin
31
+ name: cuke_modeler
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: 5.1.0
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: '3.0'
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: '3.0'
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 v3 supports.
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: '0'
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: '0'
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 English language Gherkin
325
+ summary: A linter for multi-lingual Gherkin
305
326
  test_files: []