chutney 3.5.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
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