rubocop-minitest 0.16.0 → 0.17.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: ae51cf25ec8713911a7b48130c68450d8cb983cbf280757d65fbad039deb9005
4
- data.tar.gz: 15ade21076b9c6f31ae2336b1d0dabd7f626aa334a3f36d4fb007021121d73fa
3
+ metadata.gz: f04d27399103835be508a28975344afe09018c9f480217824f65c0c43be34b3d
4
+ data.tar.gz: 3021b9fa8b826d056b69d2c91b6d447dc66a3acecc82bf439a2931e6f25ea9f6
5
5
  SHA512:
6
- metadata.gz: 8e2735ab5ec9466052e86755ab05eb739039a4eaf4c3aa25cf22beed6f292251f845561ed7cdb5596094b15835ff67d2f66acb18c5c99ddd66c6ebd23ce83291
7
- data.tar.gz: 9c352bf7cbd8dc650a57591c9add7d3b11f1cd0f87ec5c3e629befa1149e05987640d50e5f0301b957c308e1bbf43524785e6ed4993c3caf25bdd0b78279958e
6
+ metadata.gz: 61ae0ab74e4a736221044989b3ef08e5c743b6cd43024c6ed236e276a4fefb0ec6c3fd23232f401ef205d0db5e8575c8cb1b85b31186a8e26c7be031e65f9772
7
+ data.tar.gz: a574a9d994741b69bf4280b91ef7321498aeeaec391cdfee7784230baf55a0d45bf4013a8395418b96b442a39fb13b5a33fa23b8bb03d2cce92bb77c040317c9
data/.circleci/config.yml CHANGED
@@ -30,9 +30,6 @@ jobs:
30
30
  - run:
31
31
  name: Check documentation syntax
32
32
  command: bundle exec rake documentation_syntax_check
33
- - run:
34
- name: Build documentation and verify that doc files are in sync
35
- command: bundle exec rake verify_cops_documentation
36
33
 
37
34
  workflows:
38
35
  build:
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 0.17.0 (2021-11-23)
6
+
7
+ ### New features
8
+
9
+ * [#155](https://github.com/rubocop/rubocop-minitest/issues/155): Provide `assert_offense`, `assert_correction`, and `assert_no_offenses` testing APIs for custom Minitest cop development. ([@koic][])
10
+
5
11
  ## 0.16.0 (2021-11-14)
6
12
 
7
13
  ### New features
data/Rakefile CHANGED
@@ -30,7 +30,6 @@ RuboCop::RakeTask.new(:internal_investigation)
30
30
 
31
31
  task default: %i[
32
32
  documentation_syntax_check
33
- generate_cops_documentation
34
33
  test
35
34
  internal_investigation
36
35
  ]
data/docs/antora.yml CHANGED
@@ -2,6 +2,6 @@ name: rubocop-minitest
2
2
  title: RuboCop Minitest
3
3
  # We always provide version without patch here (e.g. 1.1),
4
4
  # as patch versions should not appear in the docs.
5
- version: '0.16'
5
+ version: '0.17'
6
6
  nav:
7
7
  - modules/ROOT/nav.adoc
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Laziness copied from rubocop source code
4
+ require 'rubocop/rspec/expect_offense'
5
+ require 'rubocop/cop/legacy/corrector'
6
+
7
+ module RuboCop
8
+ module Minitest
9
+ # Mixin for `assert_offense` and `assert_no_offenses`
10
+ #
11
+ # This mixin makes it easier to specify strict offense assertions
12
+ # in a declarative and visual fashion. Just type out the code that
13
+ # should generate a offense, annotate code by writing '^'s
14
+ # underneath each character that should be highlighted, and follow
15
+ # the carets with a string (separated by a space) that is the
16
+ # message of the offense. You can include multiple offenses in
17
+ # one code snippet.
18
+ #
19
+ # @example Usage
20
+ #
21
+ # assert_offense(<<~RUBY)
22
+ # class FooTest < Minitest::Test
23
+ # def test_do_something
24
+ # assert_equal(nil, somestuff)
25
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `assert_nil(somestuff)` over `assert_equal(nil, somestuff)`.
26
+ # end
27
+ # end
28
+ # RUBY
29
+ #
30
+ # Auto-correction can be tested using `assert_correction` after
31
+ # `assert_offense`.
32
+ #
33
+ # @example `assert_offense` and `assert_correction`
34
+ #
35
+ # assert_offense(<<~RUBY)
36
+ # class FooTest < Minitest::Test
37
+ # def test_do_something
38
+ # assert_equal(nil, somestuff)
39
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `assert_nil(somestuff)` over `assert_equal(nil, somestuff)`.
40
+ # end
41
+ # end
42
+ # RUBY
43
+ #
44
+ # assert_correction(<<~RUBY)
45
+ # class FooTest < Minitest::Test
46
+ # def test_do_something
47
+ # assert_nil(somestuff)
48
+ # end
49
+ # end
50
+ # RUBY
51
+ #
52
+ # If you do not want to specify an offense then use the
53
+ # companion method `assert_no_offenses`. This method is a much
54
+ # simpler assertion since it just inspects the source and checks
55
+ # that there were no offenses. The `assert_offense` method has
56
+ # to do more work by parsing out lines that contain carets.
57
+ #
58
+ # If the code produces an offense that could not be auto-corrected, you can
59
+ # use `assert_no_corrections` after `assert_offense`.
60
+ #
61
+ # @example `assert_offense` and `assert_no_corrections`
62
+ #
63
+ # assert_offense(<<~RUBY)
64
+ # class FooTest < Minitest::Test
65
+ # def test_do_something
66
+ # assert_equal(nil, somestuff)
67
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `assert_nil(somestuff)` over `assert_equal(nil, somestuff)`.
68
+ # end
69
+ # end
70
+ # RUBY
71
+ #
72
+ # assert_no_corrections
73
+ module AssertOffense
74
+ private
75
+
76
+ def setup
77
+ cop_name = self.class.to_s.delete_suffix('Test')
78
+
79
+ @cop = RuboCop::Cop::Minitest.const_get(cop_name).new
80
+ end
81
+
82
+ def assert_no_offenses(source, file = nil)
83
+ setup_assertion
84
+
85
+ offenses = inspect_source(source, @cop, file)
86
+
87
+ expected_annotations = RuboCop::RSpec::ExpectOffense::AnnotatedSource.parse(source)
88
+ actual_annotations = expected_annotations.with_offense_annotations(offenses)
89
+
90
+ assert_equal(source, actual_annotations.to_s)
91
+ end
92
+
93
+ def assert_offense(source, file = nil)
94
+ setup_assertion
95
+
96
+ @cop.instance_variable_get(:@options)[:auto_correct] = true
97
+
98
+ expected_annotations = RuboCop::RSpec::ExpectOffense::AnnotatedSource.parse(source)
99
+ if expected_annotations.plain_source == source
100
+ raise 'Use `assert_no_offenses` to assert that no offenses are found'
101
+ end
102
+
103
+ @processed_source = parse_source!(expected_annotations.plain_source, file)
104
+
105
+ offenses = _investigate(@cop, @processed_source)
106
+
107
+ actual_annotations = expected_annotations.with_offense_annotations(offenses)
108
+
109
+ assert_equal(expected_annotations.to_s, actual_annotations.to_s)
110
+ end
111
+
112
+ def _investigate(cop, processed_source)
113
+ team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
114
+ report = team.investigate(processed_source)
115
+ @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
116
+ report.offenses
117
+ end
118
+
119
+ def assert_correction(correction, loop: true)
120
+ raise '`assert_correction` must follow `assert_offense`' unless @processed_source
121
+
122
+ iteration = 0
123
+ new_source = loop do
124
+ iteration += 1
125
+
126
+ corrected_source = @last_corrector.rewrite
127
+
128
+ break corrected_source unless loop
129
+ break corrected_source if @last_corrector.empty? || corrected_source == @processed_source.buffer.source
130
+
131
+ if iteration > RuboCop::Runner::MAX_ITERATIONS
132
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [])
133
+ end
134
+
135
+ # Prepare for next loop
136
+ @processed_source = parse_source!(corrected_source, @processed_source.path)
137
+
138
+ _investigate(@cop, @processed_source)
139
+ end
140
+
141
+ assert_equal(correction, new_source)
142
+ end
143
+
144
+ def setup_assertion
145
+ RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
146
+ RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
147
+ end
148
+
149
+ def inspect_source(source, cop, file = nil)
150
+ processed_source = parse_source!(source, file)
151
+ raise 'Error parsing example code' unless processed_source.valid_syntax?
152
+
153
+ _investigate(cop, processed_source)
154
+ end
155
+
156
+ def investigate(cop, processed_source)
157
+ needed = Hash.new { |h, k| h[k] = [] }
158
+ Array(cop.class.joining_forces).each { |force| needed[force] << cop }
159
+ forces = needed.map do |force_class, joining_cops|
160
+ force_class.new(joining_cops)
161
+ end
162
+
163
+ commissioner = RuboCop::Cop::Commissioner.new([cop], forces, raise_error: true)
164
+ commissioner.investigate(processed_source)
165
+ commissioner
166
+ end
167
+
168
+ def parse_source!(source, file = nil)
169
+ if file.respond_to?(:write)
170
+ file.write(source)
171
+ file.rewind
172
+ file = file.path
173
+ end
174
+
175
+ RuboCop::ProcessedSource.new(source, ruby_version, file)
176
+ end
177
+
178
+ def ruby_version
179
+ 2.5
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Require this file to load code that supports testing using Minitest.
4
+
5
+ require 'rubocop'
6
+ require 'minitest/autorun'
7
+ require 'minitest/pride'
8
+ require_relative 'assert_offense'
9
+
10
+ Minitest::Test.include RuboCop::Minitest::AssertOffense
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Minitest
5
5
  # This module holds the RuboCop Minitest version information.
6
6
  module Version
7
- STRING = '0.16.0'
7
+ STRING = '0.17.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
@@ -0,0 +1,5 @@
1
+ ### New features
2
+
3
+ * [#155](https://github.com/rubocop/rubocop-minitest/issues/155): Provide `assert_offense`, `assert_correction`, and `assert_no_offenses` testing APIs for custom Minitest cop development. ([@koic][])
4
+
5
+ [@koic]: https://github.com/koic
@@ -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
15
  CopsDocumentationGenerator.new(departments: deps).call
17
16
  end
18
17
 
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
-
25
- # Output diff before raising error
26
- sh('GIT_PAGER=cat git diff docs')
27
-
28
- warn 'The docs directory is out of sync. Run `rake generate_cops_documentation` and commit the results.'
29
- exit!
30
- end
18
+ desc 'Generate docs of all cops departments (obsolete)'
19
+ task :generate_cops_documentation do
20
+ puts 'Updating the documentation is now done automatically!'
31
21
  end
32
22
 
33
23
  desc 'Syntax check for the documentation comments'
@@ -49,12 +49,25 @@ namespace :cut_release do
49
49
  version.split('.').take(2).join('.')
50
50
  end
51
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
+
52
60
  def new_version_changes
53
61
  changelog = File.read('CHANGELOG.md')
54
62
  _, _, new_changes, _older_changes = changelog.split(/^## .*$/, 4)
55
63
  new_changes
56
64
  end
57
65
 
66
+ def update_file(path)
67
+ content = File.read(path)
68
+ File.write(path, yield(content))
69
+ end
70
+
58
71
  def user_links(text)
59
72
  names = text.scan(/\[@(\S+)\]\[\]/).map(&:first).uniq
60
73
  names.map { |name| "[@#{name}]: https://github.com/#{name}" }
@@ -66,6 +79,9 @@ namespace :cut_release do
66
79
  Bump::Bump.run(release_type, commit: false, bundle: false, tag: false)
67
80
  new_version = Bump::Bump.current
68
81
 
82
+ update_cop_versions(old_version, new_version)
83
+ Rake::Task['update_cops_documentation'].invoke
84
+
69
85
  add_header_to_changelog(new_version)
70
86
  create_release_notes(new_version)
71
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.16.0
4
+ version: 0.17.0
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-11-14 00:00:00.000000000 Z
13
+ date: 2021-11-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -130,7 +130,9 @@ files:
130
130
  - lib/rubocop/cop/mixin/minitest_exploration_helpers.rb
131
131
  - lib/rubocop/cop/mixin/nil_assertion_handleable.rb
132
132
  - lib/rubocop/minitest.rb
133
+ - lib/rubocop/minitest/assert_offense.rb
133
134
  - lib/rubocop/minitest/inject.rb
135
+ - lib/rubocop/minitest/support.rb
134
136
  - lib/rubocop/minitest/version.rb
135
137
  - mkdocs.yml
136
138
  - readthedocs.yml
@@ -149,6 +151,7 @@ files:
149
151
  - relnotes/v0.15.1.md
150
152
  - relnotes/v0.15.2.md
151
153
  - relnotes/v0.16.0.md
154
+ - relnotes/v0.17.0.md
152
155
  - relnotes/v0.2.0.md
153
156
  - relnotes/v0.2.1.md
154
157
  - relnotes/v0.3.0.md
@@ -175,7 +178,7 @@ metadata:
175
178
  homepage_uri: https://docs.rubocop.org/rubocop-minitest/
176
179
  changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
177
180
  source_code_uri: https://github.com/rubocop/rubocop-minitest
178
- documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.16
181
+ documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.17
179
182
  bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
180
183
  rubygems_mfa_required: 'true'
181
184
  post_install_message: