rubocop-rspec-extra 0.1.0 → 0.2.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: b6d37e0a9b8e12b308c8f45612176fd83edd6a6ce1852746dc0140efba3efb6b
4
- data.tar.gz: ef9b88f0c670940a7f79b8c4ae6e73f1f8b492b630cceb540dab1c6a85ec003e
3
+ metadata.gz: 15b0c1d5b0b7c30874b0c8f567006e6ae733d4ad096eaa885b9397feed61de69
4
+ data.tar.gz: 47e774fa8976ee7a0d8f3b348224d2ccb95bc529334880aa1bd6a71f02e941a2
5
5
  SHA512:
6
- metadata.gz: 6ba9025e60e671873a082672d0677fc2eacd07c60f1d1fca1d9ac6068fdd9d1894faf6336e37d63f86bfbc9bcb482477bd246176e23967cd9f36df316107a323
7
- data.tar.gz: e6b5eda765dd616f7ba4d9e24c93462b0440986b00098f11c21993c45e93e8391723e6301db74f2a53beae6745caf7e51cee045f4696a03b8f44d1808669aa37
6
+ metadata.gz: 53973d3db669c54dcdcee88596381906a407d33d63eec4c1536c361f118b59de9a3f8bc90a4984462cd6507af0c9bb080cfd59de20724341c6e3fff7969a2609
7
+ data.tar.gz: ed2a3474c9676133f943bab5170cc0f0b20a1f5b5f06e8d6f6ba60e8aea78b721838e8df9ff2e8a4d85bc06902489e543e50d2a46d886421727d347fff2bb04a
data/.rubocop.yml CHANGED
@@ -9,7 +9,7 @@ require:
9
9
 
10
10
  AllCops:
11
11
  NewCops: enable
12
- TargetRubyVersion: 2.6
12
+ TargetRubyVersion: 2.7
13
13
  SuggestExtensions: false
14
14
 
15
15
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
- ## Unreleased
1
+ # Changelog
2
2
 
3
- ## 0.1.0 - 2023-04-18
3
+ ## Master (Unreleased)
4
+
5
+ ## 0.2.0 (2024-03-01)
6
+
7
+ - Fix an error for `RSpec/Extra/RestrictBlockTag`. ([@ydah])
8
+ - Fix an error for `RSpec/Extra/RestrictBlockTagValue`. ([@ydah])
9
+ - Drop Ruby 2.6 support. ([@ydah])
10
+
11
+ ## 0.1.0 (2023-04-18)
4
12
 
5
13
  - Initial release
14
+
15
+ <!-- Contributors (alphabetically) -->
16
+
17
+ [@ydah]: https://github.com/ydah
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rubocop::Rspec::Extra
2
2
 
3
- ![GitHub top language](https://img.shields.io/github/languages/top/ydah/rubocop-rspec-extra) ![GitHub](https://img.shields.io/github/license/ydah/rubocop-rspec-extra) ![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg) [![CI](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/6b1f27edd867a4b64661/maintainability)](https://codeclimate.com/github/ydah/rubocop-rspec-extra/maintainability)
3
+ ![GitHub top language](https://img.shields.io/github/languages/top/ydah/rubocop-rspec-extra) ![GitHub](https://img.shields.io/github/license/ydah/rubocop-rspec-extra) [![Gem Version](https://badge.fury.io/rb/rubocop-rspec-extra.svg)](https://badge.fury.io/rb/rubocop-rspec-extra) ![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg) [![CI](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/6b1f27edd867a4b64661/maintainability)](https://codeclimate.com/github/ydah/rubocop-rspec-extra/maintainability)
4
4
 
5
5
  A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing RSpec. A place where no one is officially employed, but where useful cops can gather.
6
6
 
data/config/default.yml CHANGED
@@ -5,17 +5,17 @@ RSpec/Extra:
5
5
  RSpec/Extra/BeEmpty:
6
6
  Description: Prefer using `be_empty` when checking for an empty array.
7
7
  Enabled: pending
8
- VersionAdded: '<<next>>'
8
+ VersionAdded: '0.1'
9
9
  Reference: https://www.rubydoc.info/gems/rubocop-rspec-extra/RuboCop/Cop/RSpec/Extra/BeEmpty
10
10
 
11
11
  RSpec/Extra/RestrictBlockTag:
12
12
  Description: 'Restrict to only allowed block tags.'
13
13
  Enabled: false
14
- VersionAdded: '<<next>>'
14
+ VersionAdded: '0.1'
15
15
  AllowTags: []
16
16
 
17
17
  RSpec/Extra/RestrictBlockTagValue:
18
18
  Description: 'Restrict to only allowed block tag value.'
19
19
  Enabled: pending
20
- VersionAdded: '<<next>>'
20
+ VersionAdded: '0.1'
21
21
  AllowTagValues: {}
data/docs/antora.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: rubocop-rspec-extra
2
2
  title: RuboCop RSpec Extra
3
- version: ~
3
+ version: '0.2'
4
4
  nav:
5
5
  - modules/ROOT/nav.adoc
@@ -1,3 +1,9 @@
1
+ ////
2
+ Do NOT edit this file by hand directly, as it is automatically generated.
3
+
4
+ Please make any necessary changes to the cop documentation within the source files themselves.
5
+ ////
6
+
1
7
  = RSpec/Extra
2
8
 
3
9
  == RSpec/Extra/BeEmpty
@@ -7,8 +13,8 @@
7
13
 
8
14
  | Pending
9
15
  | Yes
10
- | Yes
11
- | <<next>>
16
+ | Always
17
+ | 0.2
12
18
  | -
13
19
  |===
14
20
 
@@ -44,7 +50,7 @@ expect(array).to be_empty
44
50
  | Disabled
45
51
  | Yes
46
52
  | No
47
- | <<next>>
53
+ | 0.2
48
54
  | -
49
55
  |===
50
56
 
@@ -95,7 +101,7 @@ end
95
101
  | Pending
96
102
  | Yes
97
103
  | No
98
- | <<next>>
104
+ | 0.2
99
105
  | -
100
106
  |===
101
107
 
@@ -30,8 +30,9 @@ module RuboCop
30
30
  class RestrictBlockTag < Base
31
31
  include Metadata
32
32
 
33
- def on_metadata(symbols, pairs)
34
- offenses = (symbols + pairs.map(&:key)).filter do |symbol|
33
+ def on_metadata(symbols, hash)
34
+ symbols += hash.pairs.map(&:key) unless hash.nil?
35
+ offenses = symbols.filter do |symbol|
35
36
  !allow_tags.include?(symbol.value.to_s)
36
37
  end
37
38
 
@@ -19,8 +19,10 @@ module RuboCop
19
19
  include Metadata
20
20
  MSG = "This value is not allowed in this tag. Allowed tag value: %<allow_tag_value>s."
21
21
 
22
- def on_metadata(_symbols, pairs)
23
- offenses = pairs.filter do |pair|
22
+ def on_metadata(_symbols, hash)
23
+ return if hash.nil?
24
+
25
+ offenses = hash.pairs.filter do |pair|
24
26
  allow_tag_values.any? do |k, v|
25
27
  pair.key.value.to_s == k &&
26
28
  pair.value.value.to_s != v
@@ -3,7 +3,7 @@
3
3
  module Rubocop
4
4
  module Rspec
5
5
  module Extra
6
- VERSION = "0.1.0"
6
+ VERSION = "0.2.0"
7
7
  end
8
8
  end
9
9
  end
@@ -5,7 +5,7 @@ require "bump"
5
5
  namespace :cut_release do
6
6
  %w[major minor patch pre].each do |release_type|
7
7
  desc "Cut a new #{release_type} release and create release notes."
8
- task release_type => "changelog:check_clean" do
8
+ task release_type do
9
9
  run(release_type)
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec-extra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ydah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-17 00:00:00.000000000 Z
11
+ date: 2024-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -25,7 +25,6 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: |
28
- Automatic committee code style checking tool.
29
28
  A RuboCop extension focused on enforcing RSpec.
30
29
  A place where no one is officially employed, but where useful cops can gather.
31
30
  email:
@@ -60,8 +59,6 @@ files:
60
59
  - lib/rubocop/cop/rspec/extra/restrict_block_tag_value.rb
61
60
  - lib/rubocop/rspec/extra/inject.rb
62
61
  - lib/rubocop/rspec/extra/version.rb
63
- - tasks/changelog.rake
64
- - tasks/changelog.rb
65
62
  - tasks/cops_documentation.rake
66
63
  - tasks/cut_release.rake
67
64
  - tasks/new_cop.rake
@@ -81,15 +78,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
78
  requirements:
82
79
  - - ">="
83
80
  - !ruby/object:Gem::Version
84
- version: 2.6.0
81
+ version: 2.7.0
85
82
  required_rubygems_version: !ruby/object:Gem::Requirement
86
83
  requirements:
87
84
  - - ">="
88
85
  - !ruby/object:Gem::Version
89
86
  version: '0'
90
87
  requirements: []
91
- rubygems_version: 3.4.5
88
+ rubygems_version: 3.5.3
92
89
  signing_key:
93
90
  specification_version: 4
94
- summary: Automatic committee code style checking tool.
91
+ summary: A RuboCop extension focused on enforcing RSpec.
95
92
  test_files: []
data/tasks/changelog.rake DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- autoload :Changelog, "#{__dir__}/changelog"
4
-
5
- namespace :changelog do
6
- %i[new fix change].each do |type|
7
- desc "Create a Changelog entry (#{type})"
8
- task type, [:id] do |_task, args|
9
- ref_type = :pull if args[:id]
10
- path = Changelog::Entry.new(type: type, ref_id: args[:id], ref_type: ref_type).write
11
- cmd = "git add #{path}"
12
- system cmd
13
- puts "Entry '#{path}' created and added to git index"
14
- end
15
- end
16
-
17
- desc "Merge entries and delete them"
18
- task :merge do
19
- raise "No entries!" unless Changelog.pending?
20
-
21
- Changelog.new.merge!.and_delete!
22
- cmd = "git commit -a -m 'Update Changelog'"
23
- puts cmd
24
- system cmd
25
- end
26
-
27
- desc "Check to see if there are any entries left"
28
- task :check_clean do
29
- next unless Changelog.pending?
30
-
31
- puts "*** Pending changelog entries!"
32
- puts "Do `bundle exec rake changelog:merge`"
33
- exit(1)
34
- end
35
- end
data/tasks/changelog.rb DELETED
@@ -1,193 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if RUBY_VERSION < "2.6"
4
- puts "Changelog utilities available only for Ruby 2.6+"
5
- exit(1)
6
- end
7
-
8
- # Changelog utility
9
- class Changelog
10
- ENTRIES_PATH = "changelog/"
11
- FIRST_HEADER = /#{Regexp.escape("## Master (Unreleased)\n")}/m.freeze
12
- CONTRIBUTORS_HEADER = /#{Regexp.escape("<!-- Contributors (alphabetically) -->\n\n")}/m.freeze
13
- ENTRIES_PATH_TEMPLATE = "#{ENTRIES_PATH}%<type>s_%<name>s.md"
14
- TYPE_REGEXP = /#{Regexp.escape(ENTRIES_PATH)}([a-z]+)_/.freeze
15
- TYPE_TO_HEADER = { new: "New features", fix: "Bug fixes", change: "Changes" }.freeze
16
- HEADER = /### (.*)/.freeze
17
- PATH = "CHANGELOG.md"
18
- REF_URL = "https://github.com/rubocop/rubocop-rspec-extra"
19
- MAX_LENGTH = 40
20
- CONTRIBUTOR = "[@%<link>s]: https://github.com/%<user>s"
21
- SIGNATURE = Regexp.new(format(Regexp.escape("[@%<user>s]"), user: '([\w-]+)'))
22
- EOF = "\n"
23
-
24
- # New entry
25
- Entry = Struct.new(:type, :body, :ref_type, :ref_id, :user, keyword_init: true) do
26
- def initialize(type:, body: last_commit_title, ref_type: nil, ref_id: nil, user: github_user)
27
- id, body = extract_id(body)
28
- ref_id ||= id || "x"
29
- ref_type ||= id ? :issues : :pull
30
- super
31
- end
32
-
33
- def write
34
- FileUtils.mkdir_p(ENTRIES_PATH)
35
- File.write(path, content)
36
- path
37
- end
38
-
39
- def path
40
- format(ENTRIES_PATH_TEMPLATE, type: type, name: str_to_filename(body))
41
- end
42
-
43
- def content
44
- period = "." unless body.end_with? "."
45
- "- #{ref}: #{body}#{period} ([@#{user}])\n"
46
- end
47
-
48
- def ref
49
- "[##{ref_id}](#{REF_URL}/#{ref_type}/#{ref_id})"
50
- end
51
-
52
- def last_commit_title
53
- `git log -1 --pretty=%B`.lines.first.chomp
54
- end
55
-
56
- def extract_id(body)
57
- /^\[Fix(?:es)? #(\d+)\] (.*)/.match(body)&.captures || [nil, body]
58
- end
59
-
60
- def str_to_filename(str)
61
- str
62
- .split
63
- .reject(&:empty?)
64
- .map { |s| prettify(s) }
65
- .inject do |result, word|
66
- s = "#{result}_#{word}"
67
- return result if s.length > MAX_LENGTH
68
-
69
- s
70
- end
71
- end
72
-
73
- def github_user
74
- user = `git config --global credential.username`.chomp
75
- warn 'Set your username with `git config --global credential.username "myusernamehere"`' if user.empty?
76
-
77
- user
78
- end
79
-
80
- private
81
-
82
- def prettify(str)
83
- str.gsub!(/\W/, "_")
84
-
85
- # Separate word boundaries by `_`.
86
- str.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
87
- (Regexp.last_match(1) || Regexp.last_match(2)) << "_"
88
- end
89
-
90
- str.gsub!(/\A_+|_+\z/, "")
91
- str.downcase!
92
- str
93
- end
94
- end
95
-
96
- def self.pending?
97
- entry_paths.any?
98
- end
99
-
100
- def self.entry_paths
101
- Dir["#{ENTRIES_PATH}*"]
102
- end
103
-
104
- def self.read_entries
105
- entry_paths.to_h { |path| [path, File.read(path)] }
106
- end
107
-
108
- attr_reader :header, :rest
109
-
110
- def initialize(content: File.read(PATH), entries: Changelog.read_entries)
111
- require "strscan"
112
-
113
- parse(content)
114
- @entries = entries
115
- end
116
-
117
- def and_delete!
118
- @entries.each_key { |path| File.delete(path) }
119
- end
120
-
121
- def merge!
122
- File.write(PATH, merge_content)
123
- self
124
- end
125
-
126
- def unreleased_content
127
- entry_map = parse_entries(@entries)
128
- merged_map = merge_entries(entry_map)
129
- merged_map.flat_map do |header, things|
130
- ["### #{header}\n", *things, ""]
131
- end.join("\n")
132
- end
133
-
134
- def merge_content
135
- merged_content = [@header, unreleased_content, @changes.chomp, *all_contributors].join("\n")
136
-
137
- merged_content << EOF
138
- end
139
-
140
- def all_contributors
141
- (@contributors.split(/\R/) + new_contributors).uniq.sort
142
- end
143
-
144
- def new_contributors
145
- contributors
146
- .map { |user| format(CONTRIBUTOR, link: user.downcase, user: user) }
147
- end
148
-
149
- def contributors
150
- contributors = @entries.values.flat_map do |entry|
151
- entry.match(/\. \((?<contributors>.+)\)\n/)[:contributors].split(",")
152
- end
153
-
154
- contributors.join.scan(SIGNATURE).flatten
155
- end
156
-
157
- private
158
-
159
- def merge_entries(entry_map)
160
- all = @unreleased.merge(entry_map) { |_k, v1, v2| v1.concat(v2) }
161
- canonical = TYPE_TO_HEADER.values.to_h { |v| [v, nil] }
162
- canonical.merge(all).compact
163
- end
164
-
165
- def parse(content)
166
- ss = StringScanner.new(content)
167
- @header = ss.scan_until(FIRST_HEADER)
168
- @unreleased = parse_release(ss.scan_until(/\n(?=## )/m))
169
- @changes = ss.scan_until(CONTRIBUTORS_HEADER)
170
- @contributors = ss.rest
171
- end
172
-
173
- # @return [Hash<type, Array<String>]]
174
- def parse_release(unreleased)
175
- unreleased
176
- .lines
177
- .map(&:chomp)
178
- .reject(&:empty?)
179
- .slice_before(HEADER)
180
- .to_h do |header, *entries|
181
- [HEADER.match(header)[1], entries]
182
- end
183
- end
184
-
185
- def parse_entries(path_content_map)
186
- changes = Hash.new { |h, k| h[k] = [] }
187
- path_content_map.each do |path, content|
188
- header = TYPE_TO_HEADER.fetch(TYPE_REGEXP.match(path)[1].to_sym)
189
- changes[header].concat(content.lines.map(&:chomp))
190
- end
191
- changes
192
- end
193
- end