rubocop-rspec-extra 0.1.0 → 0.2.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: 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