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.
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: []