rubocop-minitest 0.0.1 → 0.1.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: 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