rubocop-minitest 0.15.1 → 0.17.1
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 +4 -4
- data/.circleci/config.yml +9 -9
- data/.github/PULL_REQUEST_TEMPLATE.md +3 -4
- data/.github/workflows/spell_checking.yml +33 -0
- data/.rubocop.yml +2 -3
- data/.rubocop_todo.yml +2 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +30 -0
- data/CONTRIBUTING.md +3 -2
- data/Gemfile +4 -1
- data/LICENSE.txt +1 -1
- data/Rakefile +4 -6
- data/codespell.txt +0 -0
- data/config/default.yml +13 -2
- data/docs/antora.yml +1 -1
- data/docs/modules/ROOT/pages/cops_minitest.adoc +99 -4
- data/docs/modules/ROOT/pages/installation.adoc +1 -1
- data/lib/rubocop/cop/minitest/assert_empty.rb +12 -0
- data/lib/rubocop/cop/minitest/assert_empty_literal.rb +1 -1
- data/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +3 -2
- data/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +1 -1
- data/lib/rubocop/cop/minitest/global_expectations.rb +109 -38
- data/lib/rubocop/cop/minitest/multiple_assertions.rb +1 -1
- data/lib/rubocop/cop/minitest/no_assertions.rb +1 -1
- data/lib/rubocop/cop/minitest/refute_empty.rb +12 -0
- data/lib/rubocop/cop/minitest/unreachable_assertion.rb +2 -4
- data/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +9 -21
- data/lib/rubocop/minitest/assert_offense.rb +183 -0
- data/lib/rubocop/minitest/support.rb +10 -0
- data/lib/rubocop/minitest/version.rb +1 -1
- data/mkdocs.yml +1 -1
- data/relnotes/v0.15.2.md +5 -0
- data/relnotes/v0.16.0.md +11 -0
- data/relnotes/v0.17.0.md +5 -0
- data/relnotes/v0.17.1.md +5 -0
- data/rubocop-minitest.gemspec +2 -1
- data/tasks/changelog.rake +34 -0
- data/tasks/changelog.rb +166 -0
- data/tasks/cops_documentation.rake +5 -15
- data/tasks/cut_release.rake +19 -4
- metadata +16 -4
data/tasks/changelog.rb
ADDED
@@ -0,0 +1,166 @@
|
|
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
|
+
ENTRIES_PATH_TEMPLATE = "#{ENTRIES_PATH}%<type>s_%<name>s.md"
|
13
|
+
TYPE_REGEXP = /#{Regexp.escape(ENTRIES_PATH)}([a-z]+)_/.freeze
|
14
|
+
TYPE_TO_HEADER = { new: 'New features', fix: 'Bug fixes', change: 'Changes' }.freeze
|
15
|
+
HEADER = /### (.*)/.freeze
|
16
|
+
PATH = 'CHANGELOG.md'
|
17
|
+
REF_URL = 'https://github.com/rubocop/rubocop-minitest'
|
18
|
+
MAX_LENGTH = 40
|
19
|
+
CONTRIBUTOR = '[@%<user>s]: https://github.com/%<user>s'
|
20
|
+
SIGNATURE = Regexp.new(format(Regexp.escape('[@%<user>s][]'), user: '([\w-]+)'))
|
21
|
+
EOF = "\n"
|
22
|
+
|
23
|
+
# New entry
|
24
|
+
Entry = Struct.new(:type, :body, :ref_type, :ref_id, :user, keyword_init: true) do
|
25
|
+
def initialize(type:, body: last_commit_title, ref_type: nil, ref_id: nil, user: github_user)
|
26
|
+
id, body = extract_id(body)
|
27
|
+
ref_id ||= id || 'x'
|
28
|
+
ref_type ||= id ? :issues : :pull
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def write
|
33
|
+
Dir.mkdir(ENTRIES_PATH) unless Dir.exist?(ENTRIES_PATH)
|
34
|
+
File.write(path, content)
|
35
|
+
path
|
36
|
+
end
|
37
|
+
|
38
|
+
def path
|
39
|
+
format(ENTRIES_PATH_TEMPLATE, type: type, name: str_to_filename(body))
|
40
|
+
end
|
41
|
+
|
42
|
+
def content
|
43
|
+
period = '.' unless body.end_with? '.'
|
44
|
+
"* #{ref}: #{body}#{period} ([@#{user}][])\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
def ref
|
48
|
+
"[##{ref_id}](#{REF_URL}/#{ref_type}/#{ref_id})"
|
49
|
+
end
|
50
|
+
|
51
|
+
def last_commit_title
|
52
|
+
`git log -1 --pretty=%B`.lines.first.chomp
|
53
|
+
end
|
54
|
+
|
55
|
+
def extract_id(body)
|
56
|
+
/^\[Fix(?:es)? #(\d+)\] (.*)/.match(body)&.captures || [nil, body]
|
57
|
+
end
|
58
|
+
|
59
|
+
def str_to_filename(str)
|
60
|
+
str
|
61
|
+
.downcase
|
62
|
+
.split
|
63
|
+
.each { |s| s.gsub!(/\W/, '') }
|
64
|
+
.reject(&:empty?)
|
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
|
+
end
|
80
|
+
attr_reader :header, :rest
|
81
|
+
|
82
|
+
def initialize(content: File.read(PATH), entries: Changelog.read_entries)
|
83
|
+
require 'strscan'
|
84
|
+
|
85
|
+
parse(content)
|
86
|
+
@entries = entries
|
87
|
+
end
|
88
|
+
|
89
|
+
def and_delete!
|
90
|
+
@entries.each_key { |path| File.delete(path) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def merge!
|
94
|
+
File.write(PATH, merge_content)
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def unreleased_content
|
99
|
+
entry_map = parse_entries(@entries)
|
100
|
+
merged_map = merge_entries(entry_map)
|
101
|
+
merged_map.flat_map { |header, things| ["### #{header}\n", *things, ''] }.join("\n")
|
102
|
+
end
|
103
|
+
|
104
|
+
def merge_content
|
105
|
+
merged_content = [@header, unreleased_content, @rest.chomp, *new_contributor_lines].join("\n")
|
106
|
+
|
107
|
+
merged_content << EOF
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.pending?
|
111
|
+
entry_paths.any?
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.entry_paths
|
115
|
+
Dir["#{ENTRIES_PATH}*"]
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.read_entries
|
119
|
+
entry_paths.to_h { |path| [path, File.read(path)] }
|
120
|
+
end
|
121
|
+
|
122
|
+
def new_contributor_lines
|
123
|
+
contributors
|
124
|
+
.map { |user| format(CONTRIBUTOR, user: user) }
|
125
|
+
.reject { |line| @rest.include?(line) }
|
126
|
+
end
|
127
|
+
|
128
|
+
def contributors
|
129
|
+
contributors = @entries.values.flat_map do |entry|
|
130
|
+
entry.match(/\. \((?<contributors>.+)\)\n/)[:contributors].split(',')
|
131
|
+
end
|
132
|
+
|
133
|
+
contributors.join.scan(SIGNATURE).flatten
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def merge_entries(entry_map)
|
139
|
+
all = @unreleased.merge(entry_map) { |_k, v1, v2| v1.concat(v2) }
|
140
|
+
canonical = TYPE_TO_HEADER.values.to_h { |v| [v, nil] }
|
141
|
+
canonical.merge(all).compact
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse(content)
|
145
|
+
ss = StringScanner.new(content)
|
146
|
+
@header = ss.scan_until(FIRST_HEADER)
|
147
|
+
@unreleased = parse_release(ss.scan_until(/\n(?=## )/m))
|
148
|
+
@rest = ss.rest
|
149
|
+
end
|
150
|
+
|
151
|
+
# @return [Hash<type, Array<String>]]
|
152
|
+
def parse_release(unreleased)
|
153
|
+
unreleased.lines.map(&:chomp).reject(&:empty?).slice_before(HEADER).to_h do |header, *entries|
|
154
|
+
[HEADER.match(header)[1], entries]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def parse_entries(path_content_map)
|
159
|
+
changes = Hash.new { |h, k| h[k] = [] }
|
160
|
+
path_content_map.each do |path, content|
|
161
|
+
header = TYPE_TO_HEADER.fetch(TYPE_REGEXP.match(path)[1].to_sym)
|
162
|
+
changes[header].concat(content.lines.map(&:chomp))
|
163
|
+
end
|
164
|
+
changes
|
165
|
+
end
|
166
|
+
end
|
@@ -10,24 +10,14 @@ YARD::Rake::YardocTask.new(:yard_for_generate_documentation) do |task|
|
|
10
10
|
task.options = ['--no-output']
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
task generate_cops_documentation: :yard_for_generate_documentation do
|
13
|
+
task update_cops_documentation: :yard_for_generate_documentation do
|
15
14
|
deps = ['Minitest']
|
16
|
-
CopsDocumentationGenerator.new(departments: deps).call
|
17
|
-
end
|
18
|
-
|
19
|
-
desc 'Verify that documentation is up to date'
|
20
|
-
task verify_cops_documentation: :generate_cops_documentation do
|
21
|
-
# Do not print diff and yield whether exit code was zero
|
22
|
-
sh('git diff --quiet docs') do |outcome, _|
|
23
|
-
exit if outcome
|
24
15
|
|
25
|
-
|
26
|
-
|
16
|
+
# NOTE: Update `<<next>>` version for docs/modules/ROOT/pages/cops_minitest.adoc
|
17
|
+
# when running release tasks.
|
18
|
+
RuboCop::Minitest::Inject.defaults!
|
27
19
|
|
28
|
-
|
29
|
-
exit!
|
30
|
-
end
|
20
|
+
CopsDocumentationGenerator.new(departments: deps).call
|
31
21
|
end
|
32
22
|
|
33
23
|
desc 'Syntax check for the documentation comments'
|
data/tasks/cut_release.rake
CHANGED
@@ -4,9 +4,8 @@ require 'bump'
|
|
4
4
|
|
5
5
|
namespace :cut_release do
|
6
6
|
%w[major minor patch pre].each do |release_type|
|
7
|
-
desc "Cut a new #{release_type} release, create release notes "
|
8
|
-
|
9
|
-
task release_type do
|
7
|
+
desc "Cut a new #{release_type} release, create release notes and update documents."
|
8
|
+
task release_type => 'changelog:check_clean' do
|
10
9
|
run(release_type)
|
11
10
|
end
|
12
11
|
end
|
@@ -40,7 +39,7 @@ namespace :cut_release do
|
|
40
39
|
|
41
40
|
File.open('docs/antora.yml', 'w') do |f|
|
42
41
|
f << antora_metadata.sub(
|
43
|
-
|
42
|
+
"version: 'master'",
|
44
43
|
"version: '#{version_sans_patch(new_version)}'"
|
45
44
|
)
|
46
45
|
end
|
@@ -50,12 +49,25 @@ namespace :cut_release do
|
|
50
49
|
version.split('.').take(2).join('.')
|
51
50
|
end
|
52
51
|
|
52
|
+
# Replace `<<next>>` (and variations) with version being cut.
|
53
|
+
def update_cop_versions(_old_version, new_version)
|
54
|
+
update_file('config/default.yml') do |default|
|
55
|
+
default.gsub(/['"]?<<\s*next\s*>>['"]?/i,
|
56
|
+
"'#{version_sans_patch(new_version)}'")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
53
60
|
def new_version_changes
|
54
61
|
changelog = File.read('CHANGELOG.md')
|
55
62
|
_, _, new_changes, _older_changes = changelog.split(/^## .*$/, 4)
|
56
63
|
new_changes
|
57
64
|
end
|
58
65
|
|
66
|
+
def update_file(path)
|
67
|
+
content = File.read(path)
|
68
|
+
File.write(path, yield(content))
|
69
|
+
end
|
70
|
+
|
59
71
|
def user_links(text)
|
60
72
|
names = text.scan(/\[@(\S+)\]\[\]/).map(&:first).uniq
|
61
73
|
names.map { |name| "[@#{name}]: https://github.com/#{name}" }
|
@@ -67,6 +79,9 @@ namespace :cut_release do
|
|
67
79
|
Bump::Bump.run(release_type, commit: false, bundle: false, tag: false)
|
68
80
|
new_version = Bump::Bump.current
|
69
81
|
|
82
|
+
update_cop_versions(old_version, new_version)
|
83
|
+
Rake::Task['update_cops_documentation'].invoke
|
84
|
+
|
70
85
|
add_header_to_changelog(new_version)
|
71
86
|
create_release_notes(new_version)
|
72
87
|
update_antora_yml(new_version)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-minitest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-01-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -60,9 +60,11 @@ files:
|
|
60
60
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
61
61
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
62
62
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
63
|
+
- ".github/workflows/spell_checking.yml"
|
63
64
|
- ".gitignore"
|
64
65
|
- ".rubocop.yml"
|
65
66
|
- ".rubocop_todo.yml"
|
67
|
+
- ".yardopts"
|
66
68
|
- CHANGELOG.md
|
67
69
|
- CONTRIBUTING.md
|
68
70
|
- Gemfile
|
@@ -71,6 +73,7 @@ files:
|
|
71
73
|
- Rakefile
|
72
74
|
- bin/console
|
73
75
|
- bin/setup
|
76
|
+
- codespell.txt
|
74
77
|
- config/default.yml
|
75
78
|
- docs/antora.yml
|
76
79
|
- docs/modules/ROOT/nav.adoc
|
@@ -127,7 +130,9 @@ files:
|
|
127
130
|
- lib/rubocop/cop/mixin/minitest_exploration_helpers.rb
|
128
131
|
- lib/rubocop/cop/mixin/nil_assertion_handleable.rb
|
129
132
|
- lib/rubocop/minitest.rb
|
133
|
+
- lib/rubocop/minitest/assert_offense.rb
|
130
134
|
- lib/rubocop/minitest/inject.rb
|
135
|
+
- lib/rubocop/minitest/support.rb
|
131
136
|
- lib/rubocop/minitest/version.rb
|
132
137
|
- mkdocs.yml
|
133
138
|
- readthedocs.yml
|
@@ -144,6 +149,10 @@ files:
|
|
144
149
|
- relnotes/v0.14.0.md
|
145
150
|
- relnotes/v0.15.0.md
|
146
151
|
- relnotes/v0.15.1.md
|
152
|
+
- relnotes/v0.15.2.md
|
153
|
+
- relnotes/v0.16.0.md
|
154
|
+
- relnotes/v0.17.0.md
|
155
|
+
- relnotes/v0.17.1.md
|
147
156
|
- relnotes/v0.2.0.md
|
148
157
|
- relnotes/v0.2.1.md
|
149
158
|
- relnotes/v0.3.0.md
|
@@ -159,6 +168,8 @@ files:
|
|
159
168
|
- relnotes/v0.8.1.md
|
160
169
|
- relnotes/v0.9.0.md
|
161
170
|
- rubocop-minitest.gemspec
|
171
|
+
- tasks/changelog.rake
|
172
|
+
- tasks/changelog.rb
|
162
173
|
- tasks/cops_documentation.rake
|
163
174
|
- tasks/cut_release.rake
|
164
175
|
homepage:
|
@@ -168,8 +179,9 @@ metadata:
|
|
168
179
|
homepage_uri: https://docs.rubocop.org/rubocop-minitest/
|
169
180
|
changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
|
170
181
|
source_code_uri: https://github.com/rubocop/rubocop-minitest
|
171
|
-
documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.
|
182
|
+
documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.17
|
172
183
|
bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
|
184
|
+
rubygems_mfa_required: 'true'
|
173
185
|
post_install_message:
|
174
186
|
rdoc_options: []
|
175
187
|
require_paths:
|
@@ -185,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
197
|
- !ruby/object:Gem::Version
|
186
198
|
version: '0'
|
187
199
|
requirements: []
|
188
|
-
rubygems_version: 3.3.
|
200
|
+
rubygems_version: 3.3.3
|
189
201
|
signing_key:
|
190
202
|
specification_version: 4
|
191
203
|
summary: Automatic Minitest code style checking tool.
|