rubocop-minitest 0.15.1 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +9 -9
  3. data/.github/PULL_REQUEST_TEMPLATE.md +3 -4
  4. data/.github/workflows/spell_checking.yml +33 -0
  5. data/.rubocop.yml +2 -3
  6. data/.rubocop_todo.yml +2 -0
  7. data/.yardopts +3 -0
  8. data/CHANGELOG.md +30 -0
  9. data/CONTRIBUTING.md +3 -2
  10. data/Gemfile +4 -1
  11. data/LICENSE.txt +1 -1
  12. data/Rakefile +4 -6
  13. data/codespell.txt +0 -0
  14. data/config/default.yml +13 -2
  15. data/docs/antora.yml +1 -1
  16. data/docs/modules/ROOT/pages/cops_minitest.adoc +99 -4
  17. data/docs/modules/ROOT/pages/installation.adoc +1 -1
  18. data/lib/rubocop/cop/minitest/assert_empty.rb +12 -0
  19. data/lib/rubocop/cop/minitest/assert_empty_literal.rb +1 -1
  20. data/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +3 -2
  21. data/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +1 -1
  22. data/lib/rubocop/cop/minitest/global_expectations.rb +109 -38
  23. data/lib/rubocop/cop/minitest/multiple_assertions.rb +1 -1
  24. data/lib/rubocop/cop/minitest/no_assertions.rb +1 -1
  25. data/lib/rubocop/cop/minitest/refute_empty.rb +12 -0
  26. data/lib/rubocop/cop/minitest/unreachable_assertion.rb +2 -4
  27. data/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +9 -21
  28. data/lib/rubocop/minitest/assert_offense.rb +183 -0
  29. data/lib/rubocop/minitest/support.rb +10 -0
  30. data/lib/rubocop/minitest/version.rb +1 -1
  31. data/mkdocs.yml +1 -1
  32. data/relnotes/v0.15.2.md +5 -0
  33. data/relnotes/v0.16.0.md +11 -0
  34. data/relnotes/v0.17.0.md +5 -0
  35. data/relnotes/v0.17.1.md +5 -0
  36. data/rubocop-minitest.gemspec +2 -1
  37. data/tasks/changelog.rake +34 -0
  38. data/tasks/changelog.rb +166 -0
  39. data/tasks/cops_documentation.rake +5 -15
  40. data/tasks/cut_release.rake +19 -4
  41. metadata +16 -4
@@ -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
- desc 'Generate docs of all cops departments'
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
- # Output diff before raising error
26
- sh('GIT_PAGER=cat git diff docs')
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
- warn 'The docs directory is out of sync. Run `rake generate_cops_documentation` and commit the results.'
29
- exit!
30
- end
20
+ CopsDocumentationGenerator.new(departments: deps).call
31
21
  end
32
22
 
33
23
  desc 'Syntax check for the documentation comments'
@@ -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
- 'and update documents.'
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
- 'version: master',
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.15.1
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: 2021-09-26 00:00:00.000000000 Z
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.15
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.0.dev
200
+ rubygems_version: 3.3.3
189
201
  signing_key:
190
202
  specification_version: 4
191
203
  summary: Automatic Minitest code style checking tool.