chutney 3.5.0 → 3.7.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: 72a8913c71a8e2291fa14ef87b527e11481dfe45519370455fbddf2df8856836
4
- data.tar.gz: cd4fded7ea629dd5ae5e5b74ac204c8b5d3dfee96e21f65db3c3355449dbb0c1
3
+ metadata.gz: 07c1a6a4a0afe29926cdb6c12fd189f6d30fe10e2a5d728478144ff3707ddee2
4
+ data.tar.gz: b6e39a2d58ed3a4f8a67c04e3f55522d068192b7d4d8975f9f03ad8d8385a1da
5
5
  SHA512:
6
- metadata.gz: 2387b637bdb751865c8f6fbc97f61e90e25f7d6dc52f6da7dae598f5d156c06226f985df609b3a58597213f7e9b6e5a87be2fd5c67c78b57ae60c16603cde040
7
- data.tar.gz: b7d67216485f10777e91250582facc4143e0f463360463f87aa8bf219e16b91e8e000a4e8ae94f442130f5246d0adf61e4df0b50b22bea1a05743145ea77e346
6
+ metadata.gz: 04d16c6f3be6ce96f57df7db2c6a2e7c3bc1cd3946f676400df989c0fb6afb07b02519248b2b22c873705d362b05af2cd214f849e234252116e215427ac067be
7
+ data.tar.gz: c00827961589bd8ca1b47a4c7b0c229ba5fa7505830fc061891c461ceb28c4af9cfb98b660bbef47d30eac725c86b9ebc61f1eb7bf7ed6f7d4d7a024c478df84
data/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
  </div>
21
21
 
22
- Read the documentation [here](https://billyruffian.github.io/chutney/) or try [Chutney Online](https://chutney.billy-ruffian.co.uk).
22
+ Read the documentation [here](https://billyruffian.github.io/chutney/).
23
23
 
24
24
  See [this page](https://billyruffian.github.io/chutney/usage/rules.html) for a full list of the rules chutney encourages.
25
25
 
data/chutney.gemspec CHANGED
@@ -50,7 +50,7 @@ Gem::Specification.new do |spec|
50
50
 
51
51
  spec.add_runtime_dependency 'amatch', '~> 0.4.0'
52
52
  spec.add_runtime_dependency 'cuke_modeler', '~> 3.3'
53
- spec.add_runtime_dependency 'i18n', '>= 1.8.2', '< 1.13.0'
53
+ spec.add_runtime_dependency 'i18n', '>= 1.8.2', '< 1.15.0'
54
54
  spec.add_runtime_dependency 'pastel', '~> 0.7'
55
55
  spec.add_runtime_dependency 'tty-pie', '~> 0.3'
56
56
 
@@ -61,7 +61,7 @@ Gem::Specification.new do |spec|
61
61
  spec.add_development_dependency 'rake', '~> 13.0'
62
62
  spec.add_development_dependency 'rerun', '~> 0.13'
63
63
  spec.add_development_dependency 'rspec-expectations', '~> 3.0'
64
- spec.add_development_dependency 'rubocop', '~> 1.45.1'
64
+ spec.add_development_dependency 'rubocop', '~> 1.50.2'
65
65
  spec.add_development_dependency 'rspec', '~> 3.8'
66
66
 
67
67
  spec.required_ruby_version = '>= 2.6'
@@ -38,6 +38,8 @@ MissingTestAction:
38
38
  Enabled: true
39
39
  MissingVerification:
40
40
  Enabled: true
41
+ InconsistentQuoting:
42
+ Enabled: true
41
43
  InvalidFileName:
42
44
  Enabled: true
43
45
  InvalidStepFlow:
data/docs/usage/rules.md CHANGED
@@ -33,6 +33,8 @@ Chutney enforces its rules with the linters. These are:
33
33
 
34
34
  [GivensAfterBackground](https://github.com/BillyRuffian/chutney/blob/master/features/givens_after_background.feature): If you have a Background section and your scenario needs more preconditions then it should start immediately with an `And` step and not another `Given`.
35
35
 
36
+ [InconsistentQuoting](https://github.com/BillyRuffian/chutney/blob/master/features/inconsistent_quoting.feature): Use either single quotation marks *or* double quotation marks around parameters but don't use a mix of the two styles.
37
+
36
38
  [InvalidFileName](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_file_name.feature): Make sure your file name is in snake case, not mixed case or with spaces.
37
39
 
38
40
  [InvalidStepFlow](https://github.com/BillyRuffian/chutney/blob/master/features/invalid_step_flow.feature): Your scenarios should follow Given → When → Then, in that order.
data/exe/chutney CHANGED
@@ -9,6 +9,7 @@ require 'chutney/formatter/rainbow_formatter'
9
9
  require 'optparse'
10
10
 
11
11
  formatters = Set.new
12
+ quiet = false
12
13
 
13
14
  # rubocop:disable Metrics/BlockLength
14
15
  OptionParser.new do |opts|
@@ -21,6 +22,12 @@ OptionParser.new do |opts|
21
22
  formatters << formatter
22
23
  end
23
24
 
25
+ opts.on('-q',
26
+ '--quiet',
27
+ 'Disable chutney usage warnings. Does not affect the output of the formatters.') do
28
+ quiet = true
29
+ end
30
+
24
31
  opts.on('-v', '--version', 'Display the version.') do
25
32
  puts Chutney::VERSION
26
33
  exit
@@ -28,7 +35,7 @@ OptionParser.new do |opts|
28
35
 
29
36
  opts.on('-l',
30
37
  '--linters',
31
- 'List the linter status by this configuration and exit') do
38
+ 'List the linter status by this configuration and exit.') do
32
39
  pastel = Pastel.new
33
40
  chutney_config = Chutney::ChutneyLint.new.configuration
34
41
  max_name_length = chutney_config.keys.map(&:length).max + 1
@@ -43,6 +50,24 @@ OptionParser.new do |opts|
43
50
  end
44
51
  exit
45
52
  end
53
+
54
+ opts.on('--init',
55
+ 'Install a `chutney.yml` configuration file.') do
56
+ config_dest = if File.exist?('config') && File.directory?('config')
57
+ 'config'
58
+ else
59
+ '.'
60
+ end
61
+ config_path = File.join(config_dest, 'chutney.yml')
62
+ default_path = Chutney::ChutneyLint.new.configuration.default_configuration_path
63
+ if File.exist?(config_path)
64
+ puts "#{config_path} already exists - remove it first if you want to overwrite."
65
+ else
66
+ FileUtils.cp(default_path, config_path)
67
+ puts "#{config_path} created."
68
+ end
69
+ exit
70
+ end
46
71
  end.parse!
47
72
  # rubocop:enable Metrics/BlockLength
48
73
 
@@ -52,6 +77,7 @@ files = ARGV.map { |pattern| Dir.glob(pattern) }.flatten
52
77
  files = Dir.glob('features/**/*.feature') if ARGV.empty?
53
78
 
54
79
  linter = Chutney::ChutneyLint.new(*files)
80
+ linter.configuration.quiet! if quiet
55
81
  report = linter.analyse
56
82
 
57
83
  formatters.each do |formatter|
@@ -5,19 +5,17 @@ require 'delegate'
5
5
  module Chutney
6
6
  # gherkin_lint configuration object
7
7
  class Configuration < SimpleDelegator
8
+ attr_accessor :default_configuration_path, :user_configuration_path
9
+
8
10
  def initialize(path)
9
- @path = path
11
+ @default_configuration_path = path
10
12
  @config = load_configuration || {}
11
13
  load_user_configuration
12
14
  super(@config)
13
15
  end
14
16
 
15
- def configuration_path
16
- @path
17
- end
18
-
19
17
  def load_configuration
20
- YAML.load_file configuration_path || '' if configuration_path
18
+ YAML.load_file default_configuration_path || '' if default_configuration_path
21
19
  end
22
20
 
23
21
  def load_user_configuration
@@ -25,8 +23,29 @@ module Chutney
25
23
  Dir.glob(File.join(Dir.pwd, '**', fname))
26
24
  end.flatten
27
25
 
28
- config_file = config_files.first
29
- merge_config(config_file) if !config_file.nil? && File.exist?(config_file)
26
+ self.user_configuration_path = config_files.first
27
+ return unless !user_configuration_path.nil? && File.exist?(user_configuration_path)
28
+
29
+ begin
30
+ merge_config(user_configuration_path)
31
+ rescue TypeError
32
+ unless quiet?
33
+ warn("Chutney: configuration file `#{user_configuration_path}` is not correctly formatted YAML, " \
34
+ 'falling back to gem defaults.')
35
+ end
36
+ end
37
+ end
38
+
39
+ def using_user_configuration?
40
+ !user_configuration_path.nil?
41
+ end
42
+
43
+ def quiet?
44
+ @config.fetch('quiet', false)
45
+ end
46
+
47
+ def quiet!
48
+ @config['quiet'] = true
30
49
  end
31
50
 
32
51
  private
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chutney
4
+ # service class to lint for avoiding periods
5
+ class InconsistentQuoting < Linter
6
+ # regular expression to extract quoted string
7
+ # matching group 1: opening quote; 2: quoted text; 3: closing quote
8
+ # opening and closing quote must match (via backrefs)
9
+ # apostrophes, both singular and plural posessives, are accounted for
10
+ QUOTED_STRING = /(?!\b\b)(['"])(.*(?:\b'\b[^\1]*)*(?!\b[\1]\b))(\1)/.freeze
11
+ Parameter = Struct.new('Parameter', :quotation_mark, :name)
12
+
13
+ def lint
14
+ quoted_params = parameters.group_by(&:quotation_mark)
15
+ single_quoted = quoted_params[%(')] || []
16
+ double_quoted = quoted_params[%(")] || []
17
+ return unless single_quoted.count.positive? && double_quoted.count.positive?
18
+
19
+ add_issue(
20
+ I18n.t('linters.inconsistent_quoting',
21
+ count_single: single_quoted.count, count_double: double_quoted.count,
22
+ example_single: %('#{single_quoted.first.name}'), example_double: %("#{double_quoted.first.name}")),
23
+ feature
24
+ )
25
+ end
26
+
27
+ def parameters
28
+ parameters = []
29
+
30
+ steps do |_feature, _child, step|
31
+ step_parameters = step
32
+ .text
33
+ .scan(QUOTED_STRING)
34
+ .map { |p| p.take(2) } # close quote will match open quote: drop it
35
+ .map { |p| Parameter.new(*p) }
36
+ parameters.concat(step_parameters)
37
+ end
38
+
39
+ parameters
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chutney
4
- VERSION = '3.5.0'
4
+ VERSION = '3.7.0'
5
5
  end
data/lib/chutney.rb CHANGED
@@ -16,6 +16,7 @@ require 'chutney/linter/bad_scenario_name'
16
16
  require 'chutney/linter/empty_feature_file'
17
17
  require 'chutney/linter/file_name_differs_feature_name'
18
18
  require 'chutney/linter/givens_after_background'
19
+ require 'chutney/linter/inconsistent_quoting'
19
20
  require 'chutney/linter/invalid_file_name'
20
21
  require 'chutney/linter/invalid_step_flow'
21
22
  require 'chutney/linter/missing_example_name'
@@ -46,8 +47,6 @@ require 'chutney/version'
46
47
 
47
48
  require 'cuke_modeler'
48
49
  require 'forwardable'
49
- # require 'gherkin/dialect'
50
- # require 'gherkin/parser'
51
50
  require 'i18n'
52
51
  require 'set'
53
52
  require 'yaml'
@@ -90,6 +89,14 @@ module Chutney
90
89
  end
91
90
 
92
91
  def analyse
92
+ if configuration.respond_to?(:using_user_configuration?) &&
93
+ !configuration.quiet? &&
94
+ !configuration.using_user_configuration?
95
+ warn('Chutney: no local configuration found, using gem defaults. Run `chutney -l` to list enabled ' \
96
+ 'enabled linters, `chutney --init` to install a local configuration file or `chutney --quiet` ' \
97
+ 'to disable this message.')
98
+ end
99
+
93
100
  files.each do |f|
94
101
  lint(f)
95
102
  end
@@ -33,6 +33,12 @@ en:
33
33
  givens_after_background: >-
34
34
  Avoid using the 'Given' keyword in scenarios if you have a background.
35
35
  Instead, setup steps begin your scenario and should start with an 'And' or 'But' keyword.
36
+ inconsistent_quoting: >-
37
+ Avoid using inconsistent quoting for your parameters.
38
+ You have %{count_single} single-quoted parameters (e.g. %{example_single})
39
+ and %{count_double} double-quoted parameters (e.g. %{example_double}).
40
+ You should adopt a single style to avoid confusion about the meaning and purpose
41
+ of the parameters.
36
42
  invalid_file_name: >-
37
43
  Filenames of feature files should be in snake case.
38
44
  You should name this file '%{recommended_name}'.
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.5.0
4
+ version: 3.7.0
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: 2023-02-22 00:00:00.000000000 Z
14
+ date: 2023-12-07 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: amatch
@@ -50,7 +50,7 @@ dependencies:
50
50
  version: 1.8.2
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: 1.13.0
53
+ version: 1.15.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -60,7 +60,7 @@ dependencies:
60
60
  version: 1.8.2
61
61
  - - "<"
62
62
  - !ruby/object:Gem::Version
63
- version: 1.13.0
63
+ version: 1.15.0
64
64
  - !ruby/object:Gem::Dependency
65
65
  name: pastel
66
66
  requirement: !ruby/object:Gem::Requirement
@@ -179,14 +179,14 @@ dependencies:
179
179
  requirements:
180
180
  - - "~>"
181
181
  - !ruby/object:Gem::Version
182
- version: 1.45.1
182
+ version: 1.50.2
183
183
  type: :development
184
184
  prerelease: false
185
185
  version_requirements: !ruby/object:Gem::Requirement
186
186
  requirements:
187
187
  - - "~>"
188
188
  - !ruby/object:Gem::Version
189
- version: 1.45.1
189
+ version: 1.50.2
190
190
  - !ruby/object:Gem::Dependency
191
191
  name: rspec
192
192
  requirement: !ruby/object:Gem::Requirement
@@ -262,6 +262,7 @@ files:
262
262
  - lib/chutney/linter/empty_feature_file.rb
263
263
  - lib/chutney/linter/file_name_differs_feature_name.rb
264
264
  - lib/chutney/linter/givens_after_background.rb
265
+ - lib/chutney/linter/inconsistent_quoting.rb
265
266
  - lib/chutney/linter/invalid_file_name.rb
266
267
  - lib/chutney/linter/invalid_step_flow.rb
267
268
  - lib/chutney/linter/missing_example_name.rb
@@ -314,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
315
  - !ruby/object:Gem::Version
315
316
  version: '0'
316
317
  requirements: []
317
- rubygems_version: 3.4.1
318
+ rubygems_version: 3.4.10
318
319
  signing_key:
319
320
  specification_version: 4
320
321
  summary: A linter for multi-lingual Gherkin