rubocop-minitest 0.0.1 → 0.1.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: 4c7ce50a5646f2bad96ee8d2b6c5e038493e7690d75c040f97598f4ea36c7617
4
- data.tar.gz: e0de4fc4ec8b0bb2edcd30a9fd79dc47ffb0bbec832fd8f6b567657c080911a5
3
+ metadata.gz: ee9ffa711b1d8af3e0efded458b42333d3c297e9b2f65ec9dc311e5577398552
4
+ data.tar.gz: 801b3f7a5100a60528f8643ece061ad2dab145f0d52335a9cd7070190a03f2ff
5
5
  SHA512:
6
- metadata.gz: fef612ef3f6893b6c1fb54a4f71a643dfc7cde7c8b980594b41635511fe7e2f83fa0775466006acab09f45f435024a8f6c001ebecb4c1f67d67357b0d3388fbf
7
- data.tar.gz: 0725f8782b018823060f2b6192de3e2365b87dbb97997960410f2bb61d1c9a71a916fd5d2b0d537892f41114c2e2b38a217c71e686c87b1421abf300ce55edcb
6
+ metadata.gz: c9568032ba4258bd449864b1cc982d5e1f85b44e862e360b3ad9dcaa3b96ec9c497c51901632015d45b184611cbe4c376fe7786b77ded3197baa0b44e26c4a28
7
+ data.tar.gz: 810285b00445e4c90e576f5875d01f151a8d031ac6da3595087e1e6df958464e7d8add79a230a9dd2086c5fd030f5e99153b9011b868eadd4a9fd19c0ed87993
@@ -0,0 +1,43 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ rake_default:
5
+ parameters:
6
+ image:
7
+ description: "Name of the Docker image."
8
+ type: string
9
+ default: "circleci/ruby"
10
+ docker:
11
+ - image: << parameters.image >>
12
+ environment:
13
+ # CircleCI container has two cores, but Ruby can see 32 cores. So we
14
+ # configure test-queue.
15
+ # See https://github.com/tmm1/test-queue#environment-variables
16
+ TEST_QUEUE_WORKERS: 2
17
+ JRUBY_OPTS: "--dev -J-Xmx1000M"
18
+ steps:
19
+ - checkout
20
+ - run: bundle install
21
+ - run: bundle exec rake
22
+
23
+ workflows:
24
+ build:
25
+ jobs:
26
+ - rake_default:
27
+ name: Ruby 2.3
28
+ image: circleci/ruby:2.3
29
+ - rake_default:
30
+ name: Ruby 2.4
31
+ image: circleci/ruby:2.4
32
+ - rake_default:
33
+ name: Ruby 2.5
34
+ image: circleci/ruby:2.5
35
+ - rake_default:
36
+ name: Ruby 2.6
37
+ image: circleci/ruby:2.6
38
+ - rake_default:
39
+ name: Ruby HEAD
40
+ image: rubocophq/circleci-ruby-snapshot:latest # Nightly snapshot build
41
+ - rake_default:
42
+ name: JRuby 9.2
43
+ image: circleci/jruby:9.2
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: Bug Report
3
+ about: Report an issue with RuboCop Minitest you've discovered.
4
+ ---
5
+
6
+ *Be clear, concise and precise in your description of the problem.
7
+ Open an issue with a descriptive title and a summary in grammatically correct,
8
+ complete sentences.*
9
+
10
+ *Use the template below when reporting bugs. Please, make sure that
11
+ you're running the latest stable RuboCop and that the problem you're reporting
12
+ hasn't been reported (and potentially fixed) already.*
13
+
14
+ *Before filing the ticket you should replace all text above the horizontal
15
+ rule with your own words.*
16
+
17
+ --------
18
+
19
+ ## Expected behavior
20
+
21
+ Describe here how you expected RuboCop Minitest to behave in this particular situation.
22
+
23
+ ## Actual behavior
24
+
25
+ Describe here what actually happened.
26
+
27
+ ## Steps to reproduce the problem
28
+
29
+ This is extremely important! Providing us with a reliable way to reproduce
30
+ a problem will expedite its solution.
31
+
32
+ ## RuboCop version
33
+
34
+ Include the output of `rubocop -V` or `bundle exec rubocop -V` if using Bundler. Here's an example:
35
+
36
+ ```
37
+ $ [bundle exec] rubocop -V
38
+ 0.74.0 (using Parser 2.6.4.0, running on ruby 2.6.4 x86_64-darwin17)
39
+ ```
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest new RuboCop Rails features or improvements to existing features.
4
+ ---
5
+
6
+ ## Is your feature request related to a problem? Please describe.
7
+
8
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9
+
10
+ ## Describe the solution you'd like
11
+
12
+ A clear and concise description of what you want to happen.
13
+
14
+ ## Describe alternatives you've considered
15
+
16
+ A clear and concise description of any alternative solutions or features you've considered.
17
+
18
+ ## Additional context
19
+
20
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,18 @@
1
+ **Replace this text with a summary of the changes in your PR.
2
+ The more detailed you are, the better.**
3
+
4
+ -----------------
5
+
6
+ Before submitting the PR make sure the following are checked:
7
+
8
+ * [ ] Wrote [good commit messages][1].
9
+ * [ ] Commit message starts with `[Fix #issue-number]` (if the related issue exists).
10
+ * [ ] Feature branch is up-to-date with `master` (if not - rebase it).
11
+ * [ ] Squashed related commits together.
12
+ * [ ] Added tests.
13
+ * [ ] Added an entry to the [Changelog](https://github.com/rubocop-hq/rubocop-minitest/blob/master/CHANGELOG.md) if the new code introduces user-observable changes. See [changelog entry format](https://github.com/rubocop-hq/rubocop-minitest/blob/master/CONTRIBUTING.md#changelog-entry-format).
14
+ * [ ] The PR relates to *only* one subject with a clear title
15
+ and description in grammatically correct, complete sentences.
16
+ * [ ] Run `bundle exec rake default`. It executes all tests and RuboCop for itself, and generates the documentation.
17
+
18
+ [1]: https://chris.beams.io/posts/git-commit/
data/.gitignore CHANGED
@@ -1,11 +1,61 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
1
+ # rcov generated
2
+ coverage
3
+ coverage.data
4
+
5
+ # rdoc generated
6
+ rdoc
7
+
8
+ # yard generated
9
+ doc
10
+ .yardoc
11
+
12
+ # bundler
13
+ .bundle
14
+ Gemfile.lock
15
+ Gemfile.local
16
+
17
+ # rbenv
18
+ .ruby-version
19
+
20
+ # rspec
21
+ /spec/examples.txt
22
+ /.test_queue_stats
23
+
24
+ # jeweler generated
25
+ pkg
26
+
27
+ # etags
28
+ TAGS
29
+
30
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
31
+ #
32
+ # * Create a file at ~/.gitignore
33
+ # * Include files you want ignored
34
+ # * Run: git config --global core.excludesfile ~/.gitignore
35
+ #
36
+ # After doing this, these files will be ignored in all your git projects,
37
+ # saving you from having to 'pollute' every project you touch with them
38
+ #
39
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
40
+ #
41
+ # For MacOS:
42
+ #
43
+ #.DS_Store
44
+
45
+ # For TextMate
46
+ #*.tmproj
47
+ #tmtags
48
+
49
+ # For emacs:
50
+ #*~
51
+ #\#*
52
+ #.\#*
53
+
54
+ # For vim:
55
+ *.swp
56
+
57
+ # For redcar:
58
+ #.redcar
59
+
60
+ # For rubinius:
61
+ #*.rbc
@@ -0,0 +1,85 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ # This is the configuration used to check the rubocop source code.
4
+
5
+ require:
6
+ - rubocop/cop/internal_affairs
7
+ - rubocop-performance
8
+ - rubocop-minitest
9
+
10
+ AllCops:
11
+ TargetRubyVersion: 2.3
12
+
13
+ Naming/PredicateName:
14
+ # Method define macros for dynamically generated method.
15
+ MethodDefinitionMacros:
16
+ - define_method
17
+ - define_singleton_method
18
+ - def_node_matcher
19
+ - def_node_search
20
+
21
+ Style/FormatStringToken:
22
+ # Because we parse a lot of source codes from strings. Percent arrays
23
+ # look like unannotated format string tokens to this cop.
24
+ Exclude:
25
+ - test/**/*
26
+
27
+ Metrics/ClassLength:
28
+ Exclude:
29
+ - test/**/*
30
+
31
+ Layout/EndOfLine:
32
+ EnforcedStyle: lf
33
+
34
+ Layout/ClassStructure:
35
+ Enabled: true
36
+ Categories:
37
+ module_inclusion:
38
+ - include
39
+ - prepend
40
+ - extend
41
+ ExpectedOrder:
42
+ - module_inclusion
43
+ - constants
44
+ - public_class_methods
45
+ - initializer
46
+ - instance_methods
47
+ - protected_methods
48
+ - private_methods
49
+
50
+ # Trailing white space is meaningful in code examples
51
+ Layout/TrailingWhitespace:
52
+ AllowInHeredoc: true
53
+
54
+ Lint/AmbiguousBlockAssociation:
55
+ Exclude:
56
+ - 'test/**/*.rb'
57
+
58
+ Lint/InterpolationCheck:
59
+ Exclude:
60
+ - 'test/**/*.rb'
61
+
62
+ Lint/UselessAccessModifier:
63
+ MethodCreatingMethods:
64
+ - 'def_matcher'
65
+ - 'def_node_matcher'
66
+
67
+ Lint/BooleanSymbol:
68
+ Enabled: false
69
+
70
+ Metrics/BlockLength:
71
+ Exclude:
72
+ - 'Rakefile'
73
+ - '**/*.rake'
74
+ - 'test/**/*.rb'
75
+
76
+ Naming/FileName:
77
+ Exclude:
78
+ - lib/rubocop-minitest.rb
79
+
80
+ Metrics/ModuleLength:
81
+ Exclude:
82
+ - 'test/**/*.rb'
83
+
84
+ Performance/ChainArrayAllocation:
85
+ Enabled: false
@@ -0,0 +1,23 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2019-08-07 15:41:02 +0900 using RuboCop version 0.74.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ Metrics/AbcSize:
11
+ Max: 17
12
+
13
+ # Offense count: 5
14
+ # Configuration parameters: CountComments, ExcludedMethods.
15
+ Metrics/MethodLength:
16
+ Max: 14
17
+
18
+ # Offense count: 2
19
+ # Cop supports --auto-correct.
20
+ # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
21
+ # URISchemes: http, https
22
+ Metrics/LineLength:
23
+ Max: 87
@@ -0,0 +1,11 @@
1
+ ## master (unreleased)
2
+
3
+ ## 0.1.0 (2019-09-01)
4
+
5
+ ### New features
6
+
7
+ * Create RuboCop Minitest gem. ([@koic][])
8
+ * [#6](https://github.com/rubocop-hq/rubocop-minitest/pull/6): Add new `Minitest/AssertNil` cop. ([@duduribeiro ][])
9
+
10
+ [@koic]: https://github.com/koic
11
+ [@duduribeiro]: https://github.com/duduribeiro
@@ -0,0 +1,68 @@
1
+ # Contributing
2
+
3
+ If you discover issues, have ideas for improvements or new features,
4
+ please report them to the [issue tracker][1] of the repository or
5
+ submit a pull request. Please, try to follow these guidelines when you
6
+ do so.
7
+
8
+ ## Issue reporting
9
+
10
+ * Check that the issue has not already been reported.
11
+ * Check that the issue has not already been fixed in the latest code
12
+ (a.k.a. `master`).
13
+ * Be clear, concise and precise in your description of the problem.
14
+ * Open an issue with a descriptive title and a summary in grammatically correct,
15
+ complete sentences.
16
+ * Include the output of `rubocop -V`:
17
+
18
+ ```
19
+ $ rubocop -V
20
+ 0.74.0 (using Parser 2.6.4.0, running on ruby 2.6.4 x86_64-darwin17)
21
+ ```
22
+
23
+ * Include any relevant code to the issue summary.
24
+
25
+ ## Pull requests
26
+
27
+ * Read [how to properly contribute to open source projects on GitHub][2].
28
+ * Fork the project.
29
+ * Use a topic/feature branch to easily amend a pull request later, if necessary.
30
+ * Write [good commit messages][3].
31
+ * Use the same coding conventions as the rest of the project.
32
+ * Commit and push until you are happy with your contribution.
33
+ * If your change has a corresponding open GitHub issue, prefix the commit message with `[Fix #github-issue-number]`.
34
+ * Make sure to add tests for it. This is important so I don't break it
35
+ in a future version unintentionally.
36
+ * Add an entry to the [Changelog](CHANGELOG.md) accordingly. See [changelog entry format](#changelog-entry-format).
37
+ * Please try not to mess with the Rakefile, version, or history. If
38
+ you want to have your own version, or is otherwise necessary, that
39
+ is fine, but please isolate to its own commit so I can cherry-pick
40
+ around it.
41
+ * Make sure the test suite is passing and the code you wrote doesn't produce
42
+ RuboCop offenses (usually this is as simple as running `bundle exec rake`).
43
+ * [Squash related commits together][5].
44
+ * Open a [pull request][4] that relates to *only* one subject with a clear title
45
+ and description in grammatically correct, complete sentences.
46
+
47
+ ### Changelog entry format
48
+
49
+ Here are a few examples:
50
+
51
+ ```
52
+ * [#716](https://github.com/rubocop-hq/rubocop-minitest/issues/716): Fixed a regression in the auto-correction logic of `MethodDefParentheses`. ([@bbatsov][])
53
+ * New cop `ElseLayout` checks for odd arrangement of code in the `else` branch of a conditional expression. ([@bbatsov][])
54
+ ```
55
+
56
+ * Mark it up in [Markdown syntax][6].
57
+ * The entry line should start with `* ` (an asterisk and a space).
58
+ * If the change has a related GitHub issue (e.g. a bug fix for a reported issue), put a link to the issue as `[#123](https://github.com/rubocop-hq/rubocop-minitest/issues/123): `.
59
+ * Describe the brief of the change. The sentence should end with a punctuation.
60
+ * At the end of the entry, add an implicit link to your GitHub user page as `([@username][])`.
61
+ * If this is your first contribution to RuboCop project, add a link definition for the implicit link to the bottom of the changelog as `[@username]: https://github.com/username`.
62
+
63
+ [1]: https://github.com/rubocop-hq/rubocop-minitest/issues
64
+ [2]: https://www.gun.io/blog/how-to-github-fork-branch-and-pull-request
65
+ [3]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
66
+ [4]: https://help.github.com/articles/about-pull-requests
67
+ [5]: http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
68
+ [6]: https://daringfireball.net/projects/markdown/syntax
data/Gemfile CHANGED
@@ -1,4 +1,12 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
2
6
 
3
- # Specify your gem's dependencies in rubocop-minitest.gemspec
4
7
  gemspec
8
+
9
+ gem 'rake'
10
+ gem 'rubocop', github: 'rubocop-hq/rubocop'
11
+ gem 'rubocop-performance', '~> 1.4.0'
12
+ gem 'yard', '~> 0.9'
data/README.md CHANGED
@@ -1,3 +1,79 @@
1
- # Rubocop minitest
1
+ # RuboCop Minitest
2
2
 
3
- This is a repository reserved for minitest-specific analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop-hq/rubocop).
3
+ A [RuboCop](https://github.com/rubocop-hq/rubocop) extension focused on enforcing Minitest best practices and coding conventions.
4
+
5
+ ## Installation
6
+
7
+ Just install the `rubocop-minitest` gem
8
+
9
+ ```bash
10
+ gem install rubocop-minitest
11
+ ```
12
+
13
+ or if you use bundler put this in your `Gemfile`
14
+
15
+ ```
16
+ gem 'rubocop-minitest'
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ You need to tell RuboCop to load the Minitest extension. There are three
22
+ ways to do this:
23
+
24
+ ### RuboCop configuration file
25
+
26
+ Put this into your `.rubocop.yml`.
27
+
28
+ ```yaml
29
+ require: rubocop-minitest
30
+ ```
31
+
32
+ Alternatively, use the following array notation when specifying multiple extensions.
33
+
34
+ ```yaml
35
+ require:
36
+ - rubocop-other-extension
37
+ - rubocop-minitest
38
+ ```
39
+
40
+ Now you can run `rubocop` and it will automatically load the RuboCop Minitest
41
+ cops together with the standard cops.
42
+
43
+ ### Command line
44
+
45
+ ```bash
46
+ rubocop --require rubocop-minitest
47
+ ```
48
+
49
+ ### Rake task
50
+
51
+ ```ruby
52
+ RuboCop::RakeTask.new do |task|
53
+ task.requires << 'rubocop-minitest'
54
+ end
55
+ ```
56
+
57
+ ## The Cops
58
+
59
+ All cops are located under
60
+ [`lib/rubocop/cop/minitest`](lib/rubocop/cop/minitest), and contain
61
+ examples/documentation.
62
+
63
+ In your `.rubocop.yml`, you may treat the Minitest cops just like any other
64
+ cop. For example:
65
+
66
+ ```yaml
67
+ Minitest/AssertNil:
68
+ Exclude:
69
+ - test/my_file_to_ignore_test.rb
70
+ ```
71
+
72
+ ## Contributing
73
+
74
+ Checkout the [contribution guidelines](CONTRIBUTING.md).
75
+
76
+ ## License
77
+
78
+ `rubocop-minitest` is MIT licensed. [See the accompanying file](LICENSE.txt) for
79
+ the full text.
data/Rakefile CHANGED
@@ -1,6 +1,38 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
3
2
 
4
- RSpec::Core::RakeTask.new(:spec)
3
+ require 'bundler'
4
+ require 'bundler/gem_tasks'
5
5
 
6
- task :default => :spec
6
+ Dir['tasks/**/*.rake'].each { |t| load t }
7
+
8
+ begin
9
+ Bundler.setup(:default, :development)
10
+ rescue Bundler::BundlerError => e
11
+ warn e.message
12
+ warn 'Run `bundle install` to install missing gems'
13
+ exit e.status_code
14
+ end
15
+
16
+ require 'rubocop/rake_task'
17
+ require 'rake/testtask'
18
+
19
+ Rake::TestTask.new do |t|
20
+ t.libs << 'test'
21
+ t.libs << 'lib'
22
+ t.test_files = FileList['test/**/*_test.rb']
23
+ end
24
+
25
+ desc 'Run RuboCop over itself'
26
+ RuboCop::RakeTask.new(:internal_investigation).tap do |task|
27
+ if RUBY_ENGINE == 'ruby' &&
28
+ RbConfig::CONFIG['host_os'] !~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
29
+ task.options = %w[--parallel]
30
+ end
31
+ end
32
+
33
+ task default: %i[
34
+ documentation_syntax_check
35
+ generate_cops_documentation
36
+ test
37
+ internal_investigation
38
+ ]
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "rubocop/minitest"
4
+ require 'bundler/setup'
5
+ require 'rubocop/minitest'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "rubocop/minitest"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -0,0 +1,9 @@
1
+ AllCops:
2
+ Include:
3
+ - '**/test/**/*'
4
+
5
+ Minitest/AssertNil:
6
+ Description: 'Check if your test uses `assert_nil` instead of `assert_equal(nil, something)`.'
7
+ StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-nil'
8
+ Enabled: true
9
+ VersionAdded: '0.1'
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'yaml'
5
+
6
+ require 'rubocop'
7
+
8
+ require_relative 'rubocop/minitest'
9
+ require_relative 'rubocop/minitest/version'
10
+ require_relative 'rubocop/minitest/inject'
11
+
12
+ RuboCop::Minitest::Inject.defaults!
13
+
14
+ require_relative 'rubocop/cop/minitest_cops'
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Check if your test uses `assert_nil` instead of `assert_equal(nil, something)`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # assert_equal(nil, actual)
11
+ # assert_equal(nil, actual, 'the message')
12
+ #
13
+ # # good
14
+ # assert_nil(actual)
15
+ # assert_nil(actual, 'the message')
16
+ #
17
+ class AssertNil < Cop
18
+ MSG = 'Prefer using `assert_nil(%<arguments>s)` over ' \
19
+ '`assert_equal(nil, %<arguments>s)`.'
20
+
21
+ def_node_matcher :assert_equal_with_nil, <<~PATTERN
22
+ (send nil? :assert_equal nil $_ $...)
23
+ PATTERN
24
+
25
+ def on_send(node)
26
+ assert_equal_with_nil(node) do |actual, message|
27
+ message = message.first
28
+
29
+ arguments = [actual.source, message&.source].compact.join(', ')
30
+
31
+ add_offense(node, message: format(MSG, arguments: arguments))
32
+ end
33
+ end
34
+
35
+ def autocorrect(node)
36
+ lambda do |corrector|
37
+ arguments = node.arguments.reject(&:nil_type?)
38
+ replacement = arguments.map(&:source).join(', ')
39
+ corrector.replace(node.loc.expression, "assert_nil(#{replacement})")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'minitest/assert_nil'
@@ -1,8 +1,12 @@
1
- require "rubocop/minitest/version"
1
+ # frozen_string_literal: true
2
2
 
3
- module Rubocop
3
+ module RuboCop
4
+ # RuboCop minitest project namespace
4
5
  module Minitest
5
- class Error < StandardError; end
6
- # Your code goes here...
6
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
+ CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
+ CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
9
+
10
+ private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
7
11
  end
8
12
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Minitest
5
+ # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
6
+ # bit of our configuration.
7
+ module Inject
8
+ def self.defaults!
9
+ path = CONFIG_DEFAULT.to_s
10
+ hash = ConfigLoader.send(:load_yaml_configuration, path)
11
+ config = Config.new(hash, path)
12
+ puts "configuration from #{path}" if ConfigLoader.debug?
13
+ config = ConfigLoader.merge_with_default(config, path)
14
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,7 @@
1
- module Rubocop
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
2
4
  module Minitest
3
- VERSION = "0.0.1"
5
+ VERSION = '0.1.0'
4
6
  end
5
7
  end
@@ -0,0 +1,6 @@
1
+ <!-- START_COP_LIST -->
2
+ #### Department [Minitest](cops_minitest.md)
3
+
4
+ * [Minitest/AssertNil](cops_minitest.md#minitestassertnil)
5
+
6
+ <!-- END_COP_LIST -->
@@ -0,0 +1,25 @@
1
+ # Minitest
2
+
3
+ ## Minitest/AssertNil
4
+
5
+ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
6
+ --- | --- | --- | --- | ---
7
+ Enabled | Yes | Yes | 0.1 | -
8
+
9
+ Check if your test uses `assert_nil` instead of `assert_equal(nil, something)`.
10
+
11
+ ### Examples
12
+
13
+ ```ruby
14
+ # bad
15
+ assert_equal(nil, actual)
16
+ assert_equal(nil, actual, 'the message')
17
+
18
+ # good
19
+ assert_nil(actual)
20
+ assert_nil(actual, 'the message')
21
+ ```
22
+
23
+ ### References
24
+
25
+ * [https://github.com/rubocop-hq/minitest-style-guide#assert-nil](https://github.com/rubocop-hq/minitest-style-guide#assert-nil)
@@ -0,0 +1 @@
1
+ A [RuboCop](https://github.com/rubocop-hq/rubocop) extension focused on enforcing Minitest best practices and coding conventions.
@@ -0,0 +1,11 @@
1
+ Just install the `rubocop-minitest` gem
2
+
3
+ ```sh
4
+ gem install rubocop-minitest
5
+ ```
6
+
7
+ or if you use bundler put this in your `Gemfile`
8
+
9
+ ```ruby
10
+ gem 'rubocop-minitest'
11
+ ```
@@ -0,0 +1,27 @@
1
+ You need to tell RuboCop to load the Minitest extension. There are three
2
+ ways to do this:
3
+
4
+ ### RuboCop configuration file
5
+
6
+ Put this into your `.rubocop.yml`.
7
+
8
+ ```yaml
9
+ require: rubocop-minitest
10
+ ```
11
+
12
+ Now you can run `rubocop` and it will automatically load the RuboCop Minitest
13
+ cops together with the standard cops.
14
+
15
+ ### Command line
16
+
17
+ ```sh
18
+ rubocop --require rubocop-minitest
19
+ ```
20
+
21
+ ### Rake task
22
+
23
+ ```ruby
24
+ RuboCop::RakeTask.new do |task|
25
+ task.requires << 'rubocop-minitest'
26
+ end
27
+ ```
@@ -1,29 +1,39 @@
1
- lib = File.expand_path("lib", __dir__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "rubocop/minitest/version"
5
+ require 'rubocop/minitest/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "rubocop-minitest"
7
- spec.version = Rubocop::Minitest::VERSION
8
- spec.authors = ['Bozhidar Batsov', 'Jonas Arvidsson', 'Koichi ITO']
8
+ spec.name = 'rubocop-minitest'
9
+ spec.version = RuboCop::Minitest::VERSION
10
+ spec.authors = ['Bozhidar Batsov', 'Jonas Arvidsson', 'Koichi ITO']
9
11
 
10
- spec.summary = 'This namespace is reserved by RuboCop HQ.'
11
- spec.description = 'This namespace is reserved by RuboCop HQ.'
12
- spec.license = 'MIT'
12
+ spec.summary = 'Automatic Minitest code style checking tool.'
13
+ spec.description = <<~DESCRIPTION
14
+ Automatic Minitest code style checking tool.
15
+ A RuboCop extension focused on enforcing Minitest best practices and coding conventions.
16
+ DESCRIPTION
17
+ spec.license = 'MIT'
13
18
 
14
- spec.metadata["homepage_uri"] = 'https://github.com/rubocop-hq/rubocop-minitest'
15
- spec.metadata["source_code_uri"] = 'https://github.com/rubocop-hq/rubocop-minitest'
19
+ spec.required_ruby_version = '>= 2.3.0'
20
+ spec.metadata = {
21
+ 'homepage_uri' => 'https://github.com/rubocop-hq/rubocop-minitest',
22
+ 'changelog_uri' => 'https://github.com/rubocop-hq/rubocop-minitest/blob/master/CHANGELOG.md',
23
+ 'source_code_uri' => 'https://github.com/rubocop-hq/rubocop-minitest',
24
+ 'documentation_uri' => 'https://github.com/rubocop-hq/rubocop-minitest/manual',
25
+ 'bug_tracker_uri' => 'https://github.com/rubocop-hq/rubocop-minitest/issues'
26
+ }
16
27
 
17
28
  # Specify which files should be added to the gem when it is released.
18
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
30
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
31
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
32
  end
22
- spec.bindir = "exe"
23
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
- spec.require_paths = ["lib"]
33
+ spec.bindir = 'exe'
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ['lib']
25
36
 
26
- spec.add_development_dependency "bundler", "~> 2.0"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "rspec", "~> 3.0"
37
+ spec.add_runtime_dependency 'rubocop', '>= 0.74'
38
+ spec.add_development_dependency 'minitest', '~> 5.11'
29
39
  end
@@ -0,0 +1,312 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+ require 'rubocop'
5
+ require 'rubocop-minitest'
6
+
7
+ YARD::Rake::YardocTask.new(:yard_for_generate_documentation) do |task|
8
+ task.files = ['lib/rubocop/cop/**/*.rb']
9
+ task.options = ['--no-output']
10
+ end
11
+
12
+ desc 'Generate docs of all cops departments'
13
+ task generate_cops_documentation: :yard_for_generate_documentation do
14
+ def cops_of_department(cops, department)
15
+ cops.with_department(department).sort!
16
+ end
17
+
18
+ def cops_body(config, cop, description, examples_objects, pars)
19
+ content = h2(cop.cop_name)
20
+ content << properties(config, cop)
21
+ content << "#{description}\n"
22
+ content << examples(examples_objects) if examples_objects.count.positive?
23
+ content << configurations(pars)
24
+ content << references(config, cop)
25
+ content
26
+ end
27
+
28
+ def examples(examples_object)
29
+ examples_object.each_with_object(h3('Examples').dup) do |example, content|
30
+ content << h4(example.name) unless example.name == ''
31
+ content << code_example(example)
32
+ end
33
+ end
34
+
35
+ # rubocop:disable Metrics/MethodLength
36
+ def properties(config, cop)
37
+ header = [
38
+ 'Enabled by default', 'Safe', 'Supports autocorrection', 'VersionAdded',
39
+ 'VersionChanged'
40
+ ]
41
+ config = config.for_cop(cop)
42
+ safe_auto_correct = config.fetch('SafeAutoCorrect', true)
43
+ autocorrect = if cop.new.support_autocorrect?
44
+ "Yes #{'(Unsafe)' unless safe_auto_correct}"
45
+ else
46
+ 'No'
47
+ end
48
+ content = [[
49
+ config.fetch('Enabled') ? 'Enabled' : 'Disabled',
50
+ config.fetch('Safe', true) ? 'Yes' : 'No',
51
+ autocorrect,
52
+ config.fetch('VersionAdded', '-'),
53
+ config.fetch('VersionChanged', '-')
54
+ ]]
55
+ to_table(header, content) + "\n"
56
+ end
57
+ # rubocop:enable Metrics/MethodLength
58
+
59
+ def h2(title)
60
+ content = +"\n"
61
+ content << "## #{title}\n"
62
+ content << "\n"
63
+ content
64
+ end
65
+
66
+ def h3(title)
67
+ content = +"\n"
68
+ content << "### #{title}\n"
69
+ content << "\n"
70
+ content
71
+ end
72
+
73
+ def h4(title)
74
+ content = +"#### #{title}\n"
75
+ content << "\n"
76
+ content
77
+ end
78
+
79
+ def code_example(ruby_code)
80
+ content = +"```ruby\n"
81
+ content << ruby_code.text
82
+ .gsub('@good', '# good').gsub('@bad', '# bad').strip
83
+ content << "\n```\n"
84
+ content
85
+ end
86
+
87
+ def configurations(pars)
88
+ return '' if pars.empty?
89
+
90
+ header = ['Name', 'Default value', 'Configurable values']
91
+ configs = pars.each_key.reject { |key| key.start_with?('Supported') }
92
+ content = configs.map do |name|
93
+ configurable = configurable_values(pars, name)
94
+ default = format_table_value(pars[name])
95
+ [name, default, configurable]
96
+ end
97
+
98
+ h3('Configurable attributes') + to_table(header, content)
99
+ end
100
+
101
+ # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
102
+ def configurable_values(pars, name)
103
+ case name
104
+ when /^Enforced/
105
+ supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
106
+ format_table_value(pars[supported_style_name])
107
+ when 'IndentationWidth'
108
+ 'Integer'
109
+ when 'Database'
110
+ format_table_value(pars['SupportedDatabases'])
111
+ else
112
+ case pars[name]
113
+ when String
114
+ 'String'
115
+ when Integer
116
+ 'Integer'
117
+ when Float
118
+ 'Float'
119
+ when true, false
120
+ 'Boolean'
121
+ when Array
122
+ 'Array'
123
+ else
124
+ ''
125
+ end
126
+ end
127
+ end
128
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/MethodLength
129
+
130
+ def to_table(header, content)
131
+ table = [
132
+ header.join(' | '),
133
+ Array.new(header.size, '---').join(' | ')
134
+ ]
135
+ table.concat(content.map { |c| c.join(' | ') })
136
+ table.join("\n") + "\n"
137
+ end
138
+
139
+ def format_table_value(val)
140
+ value =
141
+ case val
142
+ when Array
143
+ if val.empty?
144
+ '`[]`'
145
+ else
146
+ val.map { |config| format_table_value(config) }.join(', ')
147
+ end
148
+ else
149
+ "`#{val.nil? ? '<none>' : val}`"
150
+ end
151
+ value.gsub("#{Dir.pwd}/", '').rstrip
152
+ end
153
+
154
+ def references(config, cop)
155
+ cop_config = config.for_cop(cop)
156
+ urls = RuboCop::Cop::MessageAnnotator.new(
157
+ config, cop.name, cop_config, {}
158
+ ).urls
159
+ return '' if urls.empty?
160
+
161
+ content = h3('References')
162
+ content << urls.map { |url| "* [#{url}](#{url})" }.join("\n")
163
+ content << "\n"
164
+ content
165
+ end
166
+
167
+ def print_cops_of_department(cops, department, config)
168
+ selected_cops = cops_of_department(cops, department).select do |cop|
169
+ cop.to_s.start_with?('RuboCop::Cop::Minitest')
170
+ end
171
+ return if selected_cops.empty?
172
+
173
+ content = +"# #{department}\n"
174
+ selected_cops.each do |cop|
175
+ content << print_cop_with_doc(cop, config)
176
+ end
177
+ file_name = "#{Dir.pwd}/manual/cops_#{department.downcase}.md"
178
+ File.open(file_name, 'w') do |file|
179
+ puts "* generated #{file_name}"
180
+ file.write(content.strip + "\n")
181
+ end
182
+ end
183
+
184
+ def print_cop_with_doc(cop, config)
185
+ t = config.for_cop(cop)
186
+ non_display_keys = %w[
187
+ Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
188
+ VersionChanged
189
+ ]
190
+ pars = t.reject { |k| non_display_keys.include? k }
191
+ description = 'No documentation'
192
+ examples_object = []
193
+ YARD::Registry.all(:class).detect do |code_object|
194
+ next unless RuboCop::Cop::Badge.for(code_object.to_s) == cop.badge
195
+
196
+ description = code_object.docstring unless code_object.docstring.blank?
197
+ examples_object = code_object.tags('example')
198
+ end
199
+ cops_body(config, cop, description, examples_object, pars)
200
+ end
201
+
202
+ # rubocop:disable Metrics/AbcSize
203
+ def table_of_content_for_department(cops, department)
204
+ selected_cops = cops_of_department(cops, department.to_sym).select do |cop|
205
+ cop.to_s.start_with?('RuboCop::Cop::Minitest')
206
+ end
207
+ return if selected_cops.empty?
208
+
209
+ type_title = department[0].upcase + department[1..-1]
210
+ filename = "cops_#{department.downcase}.md"
211
+ content = +"#### Department [#{type_title}](#{filename})\n\n"
212
+ selected_cops.each do |cop|
213
+ anchor = cop.cop_name.sub('/', '').downcase
214
+ content << "* [#{cop.cop_name}](#{filename}##{anchor})\n"
215
+ end
216
+
217
+ content
218
+ end
219
+ # rubocop:enable Metrics/AbcSize
220
+
221
+ def print_table_of_contents(cops)
222
+ path = "#{Dir.pwd}/manual/cops.md"
223
+ original = File.read(path)
224
+ content = +"<!-- START_COP_LIST -->\n"
225
+
226
+ content << table_contents(cops)
227
+
228
+ content << "\n<!-- END_COP_LIST -->"
229
+
230
+ content = if original.empty?
231
+ content
232
+ else
233
+ original.sub(
234
+ /<!-- START_COP_LIST -->.+<!-- END_COP_LIST -->/m, content
235
+ )
236
+ end
237
+ File.write(path, content)
238
+ end
239
+
240
+ def table_contents(cops)
241
+ cops
242
+ .departments
243
+ .map(&:to_s)
244
+ .sort
245
+ .map { |department| table_of_content_for_department(cops, department) }
246
+ .reject(&:nil?)
247
+ .join("\n")
248
+ end
249
+
250
+ def assert_manual_synchronized
251
+ # Do not print diff and yield whether exit code was zero
252
+ sh('git diff --quiet manual') do |outcome, _|
253
+ return if outcome
254
+
255
+ # Output diff before raising error
256
+ sh('GIT_PAGER=cat git diff manual')
257
+
258
+ warn 'The manual directory is out of sync. ' \
259
+ 'Run `rake generate_cops_documentation` and commit the results.'
260
+ exit!
261
+ end
262
+ end
263
+
264
+ def main
265
+ cops = RuboCop::Cop::Cop.registry
266
+ config = RuboCop::ConfigLoader.load_file('config/default.yml')
267
+
268
+ YARD::Registry.load!
269
+ cops.departments.sort!.each do |department|
270
+ print_cops_of_department(cops, department, config)
271
+ end
272
+
273
+ print_table_of_contents(cops)
274
+
275
+ assert_manual_synchronized if ENV['CI'] == 'true'
276
+ ensure
277
+ RuboCop::ConfigLoader.default_configuration = nil
278
+ end
279
+
280
+ main
281
+ end
282
+
283
+ desc 'Syntax check for the documentation comments'
284
+ task documentation_syntax_check: :yard_for_generate_documentation do
285
+ require 'parser/ruby25'
286
+
287
+ ok = true
288
+ YARD::Registry.load!
289
+ cops = RuboCop::Cop::Cop.registry
290
+ cops.each do |cop|
291
+ examples = YARD::Registry.all(:class).find do |code_object|
292
+ next unless RuboCop::Cop::Badge.for(code_object.to_s) == cop.badge
293
+
294
+ break code_object.tags('example')
295
+ end
296
+
297
+ examples.to_a.each do |example|
298
+ begin
299
+ buffer = Parser::Source::Buffer.new('<code>', 1)
300
+ buffer.source = example.text
301
+ parser = Parser::Ruby25.new(RuboCop::AST::Builder.new)
302
+ parser.diagnostics.all_errors_are_fatal = true
303
+ parser.parse(buffer)
304
+ rescue Parser::SyntaxError => e
305
+ path = example.object.file
306
+ puts "#{path}: Syntax Error in an example. #{e}"
307
+ ok = false
308
+ end
309
+ end
310
+ end
311
+ abort unless ok
312
+ end
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.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,74 +10,82 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-08-05 00:00:00.000000000 Z
13
+ date: 2019-08-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: bundler
16
+ name: rubocop
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - "~>"
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '2.0'
22
- type: :development
21
+ version: '0.74'
22
+ type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - "~>"
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '2.0'
28
+ version: '0.74'
29
29
  - !ruby/object:Gem::Dependency
30
- name: rake
30
+ name: minitest
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '10.0'
35
+ version: '5.11'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '10.0'
43
- - !ruby/object:Gem::Dependency
44
- name: rspec
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '3.0'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - "~>"
55
- - !ruby/object:Gem::Version
56
- version: '3.0'
57
- description: This namespace is reserved by RuboCop HQ.
42
+ version: '5.11'
43
+ description: |
44
+ Automatic Minitest code style checking tool.
45
+ A RuboCop extension focused on enforcing Minitest best practices and coding conventions.
58
46
  email:
59
47
  executables: []
60
48
  extensions: []
61
49
  extra_rdoc_files: []
62
50
  files:
51
+ - ".circleci/config.yml"
52
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
53
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
54
+ - ".github/PULL_REQUEST_TEMPLATE.md"
63
55
  - ".gitignore"
64
- - ".rspec"
65
- - ".travis.yml"
56
+ - ".rubocop.yml"
57
+ - ".rubocop_todo.yml"
58
+ - CHANGELOG.md
59
+ - CONTRIBUTING.md
66
60
  - Gemfile
67
61
  - LICENSE.txt
68
62
  - README.md
69
63
  - Rakefile
70
64
  - bin/console
71
65
  - bin/setup
66
+ - config/default.yml
67
+ - lib/rubocop-minitest.rb
68
+ - lib/rubocop/cop/minitest/assert_nil.rb
69
+ - lib/rubocop/cop/minitest_cops.rb
72
70
  - lib/rubocop/minitest.rb
71
+ - lib/rubocop/minitest/inject.rb
73
72
  - lib/rubocop/minitest/version.rb
73
+ - manual/cops.md
74
+ - manual/cops_minitest.md
75
+ - manual/index.md
76
+ - manual/installation.md
77
+ - manual/usage.md
74
78
  - rubocop-minitest.gemspec
79
+ - tasks/cops_documentation.rake
75
80
  homepage:
76
81
  licenses:
77
82
  - MIT
78
83
  metadata:
79
84
  homepage_uri: https://github.com/rubocop-hq/rubocop-minitest
85
+ changelog_uri: https://github.com/rubocop-hq/rubocop-minitest/blob/master/CHANGELOG.md
80
86
  source_code_uri: https://github.com/rubocop-hq/rubocop-minitest
87
+ documentation_uri: https://github.com/rubocop-hq/rubocop-minitest/manual
88
+ bug_tracker_uri: https://github.com/rubocop-hq/rubocop-minitest/issues
81
89
  post_install_message:
82
90
  rdoc_options: []
83
91
  require_paths:
@@ -86,15 +94,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
94
  requirements:
87
95
  - - ">="
88
96
  - !ruby/object:Gem::Version
89
- version: '0'
97
+ version: 2.3.0
90
98
  required_rubygems_version: !ruby/object:Gem::Requirement
91
99
  requirements:
92
100
  - - ">="
93
101
  - !ruby/object:Gem::Version
94
102
  version: '0'
95
103
  requirements: []
96
- rubygems_version: 3.0.4
104
+ rubygems_version: 3.0.3
97
105
  signing_key:
98
106
  specification_version: 4
99
- summary: This namespace is reserved by RuboCop HQ.
107
+ summary: Automatic Minitest code style checking tool.
100
108
  test_files: []
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.3
7
- before_install: gem install bundler -v 2.0.2