Merge pull request #9087 from Homebrew/dependabot/bundler/Library/Homebrew/rubocop-1.2.0

build(deps): bump rubocop from 0.93.1 to 1.2.0 in /Library/Homebrew
This commit is contained in:
Jonathan Chang 2020-11-11 00:53:11 +11:00 committed by GitHub
commit 49bb2561aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
149 changed files with 814 additions and 841 deletions

2
.gitignore vendored
View File

@ -128,7 +128,7 @@
**/vendor/bundle/ruby/*/gems/rspec-retry-*/
**/vendor/bundle/ruby/*/gems/rspec-support-*/
**/vendor/bundle/ruby/*/gems/rspec-wait-*/
**/vendor/bundle/ruby/*/gems/rubocop-0*/
**/vendor/bundle/ruby/*/gems/rubocop-1*/
**/vendor/bundle/ruby/*/gems/rubocop-ast-*/
**/vendor/bundle/ruby/*/gems/ruby-prof-*/
**/vendor/bundle/ruby/*/gems/simplecov-*/

View File

@ -197,6 +197,11 @@ Layout/RescueEnsureAlignment:
Lint/AmbiguousBlockAssociation:
Enabled: false
# needed for lazy_object magic
Naming/MemoizedInstanceVariableName:
Exclude:
- 'Homebrew/lazy_object.rb'
# so many of these in formulae and can't be autocorrected
# TODO: fix these as `ruby -w` complains about them.
Lint/AmbiguousRegexpLiteral:

View File

@ -22,3 +22,15 @@ Style/Documentation:
- 'utils/popen.rb'
- 'utils/shell.rb'
- 'version.rb'
Lint/EmptyBlock:
Exclude:
- 'dependency.rb'
- 'dev-cmd/extract.rb'
- 'test/cache_store_spec.rb'
- 'test/checksum_verification_spec.rb'
- 'test/compiler_failure_spec.rb'
- 'test/formula_spec.rb'
- 'test/formula_validation_spec.rb'
- 'test/pathname_spec.rb'
- 'test/support/fixtures/cask/Casks/*flight*.rb'

View File

@ -54,7 +54,7 @@ GEM
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
ntlm-http (0.1.1)
parallel (1.19.2)
parallel (1.20.0)
parallel_tests (3.3.0)
parallel
parlour (4.0.1)
@ -98,23 +98,23 @@ GEM
rspec-support (3.10.0)
rspec-wait (0.0.9)
rspec (>= 3, < 4)
rubocop (0.93.1)
rubocop (1.2.0)
parallel (~> 1.10)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8)
rexml
rubocop-ast (>= 0.6.0)
rubocop-ast (>= 1.0.1)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.8.0)
rubocop-ast (1.1.1)
parser (>= 2.7.1.5)
rubocop-performance (1.8.1)
rubocop (>= 0.87.0)
rubocop-ast (>= 0.4.0)
rubocop-rspec (1.44.1)
rubocop (~> 0.87)
rubocop-ast (>= 0.7.1)
rubocop-rspec (2.0.0)
rubocop (~> 1.0)
rubocop-ast (>= 1.1.0)
rubocop-sorbet (0.5.1)
rubocop
ruby-macho (2.2.0)

View File

@ -142,9 +142,9 @@ module Cask
end
def language_eval
return @language if defined?(@language)
return @language_eval if defined?(@language_eval)
return @language = nil if @language_blocks.nil? || @language_blocks.empty?
return @language_eval = nil if @language_blocks.nil? || @language_blocks.empty?
raise CaskInvalidError.new(cask, "No default language specified.") if @language_blocks.default.nil?
@ -161,10 +161,10 @@ module Cask
next if key.nil?
return @language = @language_blocks[key].call
return @language_eval = @language_blocks[key].call
end
@language = @language_blocks.default.call
@language_eval = @language_blocks.default.call
end
def languages

View File

@ -84,9 +84,11 @@ module Homebrew
formula = begin
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
return false
nil
end
return false if formula.blank?
resource_name = basename.to_s[/\A.*?--(.*?)--?(?:#{Regexp.escape(version)})/, 1]
if resource_name == "patch"
@ -113,9 +115,11 @@ module Homebrew
cask = begin
Cask::CaskLoader.load(name)
rescue Cask::CaskError
return false
nil
end
return false if cask.blank?
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
return true if scrub && !cask.versions.include?(cask.version)

View File

@ -511,10 +511,10 @@ module Homebrew
arg1 = "--#{arg1.tr("_", "-")}"
arg2 = "--#{arg2.tr("_", "-")}"
message = if !missing
"`#{arg1}` and `#{arg2}` should be passed together."
else
message = if missing
"`#{arg2}` cannot be passed without `#{arg1}`."
else
"`#{arg1}` and `#{arg2}` should be passed together."
end
super message
end

View File

@ -113,9 +113,7 @@ module Homebrew
updated = true
end
if !updated
puts "Already up-to-date." if !args.preinstall? && !ENV["HOMEBREW_UPDATE_FAILED"]
else
if updated
if hub.empty?
puts "No changes to formulae."
else
@ -128,6 +126,8 @@ module Homebrew
end
end
puts if args.preinstall?
elsif !args.preinstall? && !ENV["HOMEBREW_UPDATE_FAILED"]
puts "Already up-to-date."
end
Commands.rebuild_commands_completion_list

View File

@ -101,13 +101,13 @@ module Homebrew
def extract
args = extract_args.parse
if args.named.first !~ HOMEBREW_TAP_FORMULA_REGEX
if (match = args.named.first.match(HOMEBREW_TAP_FORMULA_REGEX))
name = match[3].downcase
source_tap = Tap.fetch(match[1], match[2])
raise TapFormulaUnavailableError.new(source_tap, name) unless source_tap.installed?
else
name = args.named.first.downcase
source_tap = CoreTap.instance
else
name = Regexp.last_match(3).downcase
source_tap = Tap.fetch(Regexp.last_match(1), Regexp.last_match(2))
raise TapFormulaUnavailableError.new(source_tap, name) unless source_tap.installed?
end
destination_tap = Tap.fetch(args.named.second)

View File

@ -111,15 +111,19 @@ module Homebrew
new_formula = begin
Formulary.from_contents(formula_name, formula_path, new_contents, :stable)
rescue FormulaUnavailableError
return "#{formula_name}: delete #{reason}".strip
nil
end
return "#{formula_name}: delete #{reason}".strip if new_formula.blank?
old_formula = begin
Formulary.from_contents(formula_name, formula_path, old_contents, :stable)
rescue FormulaUnavailableError
return "#{formula_name} #{new_formula.stable.version} (new formula)"
nil
end
return "#{formula_name} #{new_formula.stable.version} (new formula)" if old_formula.blank?
if old_formula.stable.version != new_formula.stable.version
"#{formula_name} #{new_formula.stable.version}"
elsif old_formula.revision != new_formula.revision

View File

@ -758,14 +758,14 @@ module Homebrew
def check_for_unlinked_but_not_keg_only
unlinked = Formula.racks.reject do |rack|
if !(HOMEBREW_LINKED_KEGS/rack.basename).directory?
if (HOMEBREW_LINKED_KEGS/rack.basename).directory?
true
else
begin
Formulary.from_rack(rack).keg_only?
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
false
end
else
true
end
end.map(&:basename)
return if unlinked.empty?

View File

@ -509,6 +509,12 @@ end
# @api public
class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
def mirrors
combined_mirrors
end
private
def combined_mirrors
return @combined_mirrors if defined?(@combined_mirrors)
backup_mirrors = apache_mirrors.fetch("backup", [])
@ -517,8 +523,6 @@ class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
@combined_mirrors = [*@mirrors, *backup_mirrors]
end
private
def resolve_url_basename_time(url)
if url == self.url
super("#{apache_mirrors["preferred"]}#{apache_mirrors["path_info"]}")
@ -929,9 +933,7 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
def commit_outdated?(commit)
@last_commit ||= github_last_commit
if !@last_commit
super
else
if @last_commit
return true unless commit
return true unless @last_commit.start_with?(commit)
@ -941,6 +943,8 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
version.update_commit(commit)
false
end
else
super
end
end
end

View File

@ -8,11 +8,11 @@ class Module
attrs.each do |attr|
module_eval <<-EOS, file, line
def #{attr}(val=nil)
@#{attr} ||= nil
return @#{attr} if val.nil?
@#{attr} = val
end
def #{attr}(val=nil) # def prefix(val=nil)
@#{attr} ||= nil # @prefix ||= nil
return @#{attr} if val.nil? # return @prefix if val.nil?
@#{attr} = val # @prefix = val
end # end
EOS
end
end

View File

@ -22,10 +22,10 @@ module SystemConfig
def describe_homebrew_ruby
s = describe_homebrew_ruby_version
if !RUBY_PATH.to_s.match?(%r{^/System/Library/Frameworks/Ruby\.framework/Versions/[12]\.[089]/usr/bin/ruby})
"#{s} => #{RUBY_PATH}"
else
if RUBY_PATH.to_s.match?(%r{^/System/Library/Frameworks/Ruby\.framework/Versions/[12]\.[089]/usr/bin/ruby})
s
else
"#{s} => #{RUBY_PATH}"
end
end

View File

@ -26,16 +26,18 @@ module UnpackStrategy
end
result = begin
T.let(super, SystemCommand::Result)
T.let(super, T.nilable(SystemCommand::Result))
rescue ErrorDuringExecution => e
raise unless e.stderr.include?("End-of-central-directory signature not found.")
system_command! "ditto",
args: ["-x", "-k", path, unpack_dir],
verbose: verbose
return
nil
end
return if result.blank?
volumes = result.stderr.chomp
.split("\n")
.map { |l| l[/\A skipping: (.+) volume label\Z/, 1] }

View File

@ -36,9 +36,11 @@ module Utils
tag_version = begin
MacOS::Version.from_symbol(tag)
rescue MacOSVersionError
return
nil
end
return if tag_version.blank?
keys.find do |key|
MacOS::Version.from_symbol(key) <= tag_version
rescue MacOSVersionError

View File

@ -47,7 +47,7 @@ module Homebrew
# content
# @return [Array]
def self.page_matches(url, regex)
page = URI.open(url).read
page = URI.parse(url).open.read
matches = page.scan(regex)
matches.map(&:first).uniq
end

View File

@ -87,7 +87,7 @@ module Homebrew
match_data = { matches: {}, regex: regex, url: page_url }
# Cache responses to avoid unnecessary duplicate fetches
@page_data[page_url] = URI.open(page_url).read unless @page_data.key?(page_url)
@page_data[page_url] = URI.parse(page_url).open.read unless @page_data.key?(page_url)
matches = @page_data[page_url].scan(regex)
matches.map(&:first).uniq.each do |match|

View File

@ -71,9 +71,7 @@ module OS
def sdk_paths
@sdk_paths ||= begin
# Bail out if there is no SDK prefix at all
if !File.directory? sdk_prefix
{}
else
if File.directory? sdk_prefix
paths = {}
Dir[File.join(sdk_prefix, "MacOSX*.sdk")].each do |sdk_path|
@ -82,6 +80,8 @@ module OS
end
paths
else
{}
end
end
end
@ -130,10 +130,10 @@ module OS
# return nil SDKs for Xcode 9 and older.
def sdk_prefix
@sdk_prefix ||= begin
if !CLT.provides_sdk?
""
else
if CLT.provides_sdk?
"#{CLT::PKG_PATH}/SDKs"
else
""
end
end
end

View File

@ -58,9 +58,9 @@ module RuboCop
Constants::STANZA_ORDER.each do |stanza_name|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{stanza_name}?
stanza_name == :#{stanza_name}
end
def #{stanza_name}? # def url?
stanza_name == :#{stanza_name} # stanza_name == :url
end # end
RUBY
end
end

View File

@ -139,9 +139,11 @@ module RuboCop
URI(remove_non_ascii(host))
rescue URI::InvalidURIError
# Can't check if we can't parse.
return true
nil
end
return true if host_uri.blank?
host = if host.match?(/:\d/) && host_uri.port != 80
"#{host_uri.host}:#{host_uri.port}"
else

View File

@ -77,11 +77,11 @@ class Sandbox
def deny_write_homebrew_repository
deny_write HOMEBREW_BREW_FILE
if HOMEBREW_PREFIX.to_s != HOMEBREW_REPOSITORY.to_s
deny_write_path HOMEBREW_REPOSITORY
else
if HOMEBREW_PREFIX.to_s == HOMEBREW_REPOSITORY.to_s
deny_write_path HOMEBREW_LIBRARY
deny_write_path HOMEBREW_REPOSITORY/".git"
else
deny_write_path HOMEBREW_REPOSITORY
end
end

View File

@ -50,9 +50,11 @@ module Homebrew
)
rescue GitHub::Error => e
opoo "Error searching on GitHub: #{e}\n"
return results
nil
end
return results if matches.blank?
matches.each do |match|
name = File.basename(match["path"], ".rb")
tap = Tap.fetch(match["repository"]["full_name"])

View File

@ -100,12 +100,11 @@ class SystemCommand
end
def env_args
set_variables = env.reject { |_, value| value.nil? }
.map do |name, value|
sanitized_name = Shellwords.escape(name)
sanitized_value = Shellwords.escape(value)
"#{sanitized_name}=#{sanitized_value}"
end
set_variables = env.compact.map do |name, value|
sanitized_name = Shellwords.escape(name)
sanitized_value = Shellwords.escape(value)
"#{sanitized_name}=#{sanitized_value}"
end
return [] if set_variables.empty?

View File

@ -2,7 +2,6 @@ inherit_from:
- ../.rubocop.yml
- .rubocop_todo.yml
AllCops:
RSpec:
Patterns:
- ./*
RSpec:
Include:
- ./*

View File

@ -22,7 +22,7 @@ module Test
return super(block) unless @tty
colored_tty_block = lambda do
instance_eval("$#{@output}", __FILE__, __LINE__).extend(Module.new do
instance_eval("$#{@output} # $stdout", __FILE__, __LINE__).extend(Module.new do
def tty?
true
end
@ -36,17 +36,17 @@ module Test
uncolored_tty_block = lambda do
instance_eval <<-EOS, __FILE__, __LINE__ + 1
begin
captured_stream = StringIO.new
begin # begin
captured_stream = StringIO.new # captured_stream = StringIO.new
original_stream = $#{@output}
$#{@output} = captured_stream
original_stream = $#{@output} # original_stream = $stdout
$#{@output} = captured_stream # $stdout = captured_stream
colored_tty_block.call
ensure
$#{@output} = original_stream
$#{@output}.print Tty.strip_ansi(captured_stream.string)
end
colored_tty_block.call # colored_tty_block.call
ensure # ensure
$#{@output} = original_stream # $stdout = original_stream
$#{@output}.print Tty.strip_ansi(captured_stream.string) # $stdout.print Tty.strip_ansi(captured_stream.string)
end # end
EOS
end

View File

@ -141,43 +141,37 @@ module GitHub
end
end
# Given an API response from GitHub, warn the user if their credentials
# have insufficient permissions.
def api_credentials_error_message(response_headers, needed_scopes)
return if response_headers.empty?
@api_credentials_error_message ||= begin
unauthorized = (response_headers["http/1.1"] == "401 Unauthorized")
scopes = response_headers["x-accepted-oauth-scopes"].to_s.split(", ")
if unauthorized && scopes.blank?
needed_human_scopes = needed_scopes.join(", ")
credentials_scopes = response_headers["x-oauth-scopes"]
return if needed_human_scopes.blank? && credentials_scopes.blank?
unauthorized = (response_headers["http/1.1"] == "401 Unauthorized")
scopes = response_headers["x-accepted-oauth-scopes"].to_s.split(", ")
return unless unauthorized && scopes.blank?
needed_human_scopes = "none" if needed_human_scopes.blank?
credentials_scopes = "none" if credentials_scopes.blank?
needed_human_scopes = needed_scopes.join(", ")
credentials_scopes = response_headers["x-oauth-scopes"]
return if needed_human_scopes.blank? && credentials_scopes.blank?
case GitHub.api_credentials_type
when :keychain_username_password
onoe <<~EOS
Your macOS keychain GitHub credentials do not have sufficient scope!
Scopes they need: #{needed_human_scopes}
Scopes they have: #{credentials_scopes}
Create a personal access token:
#{ALL_SCOPES_URL}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
when :env_token
onoe <<~EOS
Your HOMEBREW_GITHUB_API_TOKEN does not have sufficient scope!
Scopes it needs: #{needed_human_scopes}
Scopes it has: #{credentials_scopes}
Create a new personal access token:
#{ALL_SCOPES_URL}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
end
end
true
needed_human_scopes = "none" if needed_human_scopes.blank?
credentials_scopes = "none" if credentials_scopes.blank?
what = case GitHub.api_credentials_type
when :keychain_username_password
"macOS keychain GitHub"
when :env_token
"HOMEBREW_GITHUB_API_TOKEN"
end
@api_credentials_error_message ||= onoe <<~EOS
Your #{what} credentials do not have sufficient scope!
Scopes required: #{needed_human_scopes}
Scopes present: #{credentials_scopes}
Create a personal access token:
#{ALL_SCOPES_URL}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
end
def open_api(url, data: nil, data_binary_path: nil, request_method: nil, scopes: [].freeze, parse_json: true)

View File

@ -70,28 +70,20 @@ module SharedAudits
def gitlab_repo_data(user, repo)
@gitlab_repo_data ||= {}
@gitlab_repo_data["#{user}/#{repo}"] ||= begin
out, _, status= curl_output("--request", "GET", "https://gitlab.com/api/v4/projects/#{user}%2F#{repo}")
return unless status.success?
JSON.parse(out)
out, _, status = curl_output("https://gitlab.com/api/v4/projects/#{user}%2F#{repo}")
JSON.parse(out) if status.success?
end
@gitlab_repo_data["#{user}/#{repo}"]
end
def gitlab_release_data(user, repo, tag)
id = "#{user}/#{repo}/#{tag}"
@gitlab_release_data ||= {}
@gitlab_release_data[id] ||= begin
out, _, status= curl_output(
out, _, status = curl_output(
"https://gitlab.com/api/v4/projects/#{user}%2F#{repo}/releases/#{tag}", "--fail"
)
return unless status.success?
JSON.parse(out)
JSON.parse(out) if status.success?
end
@gitlab_release_data[id]
end
GITLAB_PRERELEASE_ALLOWLIST = {}.freeze

View File

@ -19,7 +19,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwi
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/json-2.3.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/docile-1.3.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-html-0.12.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.19.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.19.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/codecov-0.2.12/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/coderay-1.1.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/colorize-0.8.1/lib"
@ -47,11 +47,11 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrobots-0.1.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mechanize-2.7.6/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/method_source-1.0.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mustache-1.1.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.19.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.20.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.3.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.7.2.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.5981/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.6036/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-4.0.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.3.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.5.0/lib"
@ -61,25 +61,25 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rdiscount-2.2.0.2/lib
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/regexp_parser-1.8.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rexml-3.2.4/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ronn-0.7.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.9.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-core-3.9.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-expectations-3.9.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-mocks-3.9.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.9.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.10.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-core-3.10.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-expectations-3.10.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-mocks-3.10.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.10.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.8.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-1.1.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.7.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.93.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.2.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.8.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.44.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.0.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.5.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.2.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-static-0.5.5949-universal-darwin-19/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-0.5.5949/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-static-0.5.6036-universal-darwin-19/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-0.5.6036/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-stub-0.2.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.0.1/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.0.4/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.4.7/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.4.8/lib"

View File

@ -1,76 +0,0 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# @abstract parent class to RSpec cops
#
# The criteria for whether rubocop-rspec analyzes a certain ruby file
# is configured via `AllCops/RSpec`. For example, if you want to
# customize your project to scan all files within a `test/` directory
# then you could add this to your configuration:
#
# @example configuring analyzed paths
# # .rubocop.yml
# # AllCops:
# # RSpec:
# # Patterns:
# # - '_test.rb$'
# # - '(?:^|/)test/'
class Base < ::RuboCop::Cop::Base
include RuboCop::RSpec::Language
include RuboCop::RSpec::Language::NodePattern
DEFAULT_CONFIGURATION =
RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
DEFAULT_PATTERN_RE = Regexp.union(
DEFAULT_CONFIGURATION.fetch('Patterns')
.map(&Regexp.public_method(:new))
)
exclude_from_registry
# Invoke the original inherited hook so our cops are recognized
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
RuboCop::Cop::Base.inherited(subclass)
end
def relevant_file?(file)
relevant_rubocop_rspec_file?(file) && super
end
private
def relevant_rubocop_rspec_file?(file)
rspec_pattern.match?(file)
end
def rspec_pattern
if rspec_pattern_config?
Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
else
DEFAULT_PATTERN_RE
end
end
def all_cops_config
config
.for_all_cops
end
def rspec_pattern_config?
return unless all_cops_config.key?('RSpec')
all_cops_config.fetch('RSpec').key?('Patterns')
end
def rspec_pattern_config
all_cops_config
.fetch('RSpec', DEFAULT_CONFIGURATION)
.fetch('Patterns')
end
end
end
end
end

View File

@ -1,10 +0,0 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# @deprecated Use ::RuboCop::Cop::RSpec::Base instead
Cop = Base
end
end
end

View File

@ -1,41 +0,0 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Checks invalid usage for predicate matcher.
#
# Predicate matcher does not need a question.
# This cop checks an unnecessary question in predicate matcher.
#
# @example
#
# # bad
# expect(foo).to be_something?
#
# # good
# expect(foo).to be_something
class InvalidPredicateMatcher < Base
MSG = 'Omit `?` from `%<matcher>s`.'
def_node_matcher :invalid_predicate_matcher?, <<-PATTERN
(send (send nil? :expect ...) #{Runners::ALL.node_pattern_union} $(send nil? #predicate?))
PATTERN
def on_send(node)
invalid_predicate_matcher?(node) do |predicate|
add_offense(predicate,
message: format(MSG, matcher: predicate.method_name))
end
end
private
def predicate?(name)
name = name.to_s
name.start_with?('be_', 'have_') && name.end_with?('?')
end
end
end
end
end

View File

@ -1,12 +0,0 @@
# frozen_string_literal: true
module RuboCop
# RuboCop RSpec project namespace
module RSpec
PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
end
end

View File

@ -1,48 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# Helps determine the offending location if there is not an empty line
# following the node. Allows comments to follow directly after.
module EmptyLineSeparation
include FinalEndLocation
include RuboCop::Cop::RangeHelp
def missing_separating_line_offense(node)
return if last_child?(node)
missing_separating_line(node) do |location|
msg = yield(node.method_name)
add_offense(location, message: msg) do |corrector|
corrector.insert_after(location.end, "\n")
end
end
end
def missing_separating_line(node)
line = final_end_location(node).line
line += 1 while comment_line?(processed_source[line])
return if processed_source[line].blank?
yield offending_loc(line)
end
def offending_loc(last_line)
offending_line = processed_source[last_line - 1]
content_length = offending_line.lstrip.length
start = offending_line.length - content_length
source_range(processed_source.buffer, last_line, start, content_length)
end
def last_child?(node)
return true unless node.parent&.begin_type?
node.equal?(node.parent.children.last)
end
end
end
end

View File

@ -1,17 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# Helps find the true end location of nodes which might contain heredocs.
module FinalEndLocation
def final_end_location(start_node)
heredoc_endings =
start_node.each_node(:str, :dstr, :xstr)
.select(&:heredoc?)
.map { |node| node.loc.heredoc_end }
[start_node.loc.end, *heredoc_endings].max_by(&:line)
end
end
end
end

View File

@ -1,153 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# RSpec public API methods that are commonly used in cops
module Language
# Set of method selectors
class SelectorSet
def initialize(selectors)
@selectors = selectors.freeze
freeze
end
def ==(other)
selectors.eql?(other.selectors)
end
def +(other)
self.class.new(selectors + other.selectors)
end
def include?(selector)
selectors.include?(selector)
end
def block_pattern
"(block #{send_pattern} ...)"
end
def block_pass_pattern
"(send #rspec? #{node_pattern_union} _ block_pass)"
end
def block_or_block_pass_pattern
"{#{block_pattern} #{block_pass_pattern}}"
end
def send_pattern
"(send #rspec? #{node_pattern_union} ...)"
end
def send_or_block_or_block_pass_pattern
"{#{send_pattern} #{block_pattern} #{block_pass_pattern}}"
end
def node_pattern_union
"{#{node_pattern}}"
end
def node_pattern
selectors.map(&:inspect).join(' ')
end
def to_a
selectors
end
protected
attr_reader :selectors
end
module ExampleGroups
GROUPS = SelectorSet.new(%i[describe context feature example_group])
SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature])
FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature])
ALL = GROUPS + SKIPPED + FOCUSED
end
module SharedGroups
EXAMPLES = SelectorSet.new(%i[shared_examples shared_examples_for])
CONTEXT = SelectorSet.new(%i[shared_context])
ALL = EXAMPLES + CONTEXT
end
module Includes
EXAMPLES = SelectorSet.new(
%i[
it_behaves_like
it_should_behave_like
include_examples
]
)
CONTEXT = SelectorSet.new(%i[include_context])
ALL = EXAMPLES + CONTEXT
end
module Examples
EXAMPLES = SelectorSet.new(%i[it specify example scenario its])
FOCUSED = SelectorSet.new(%i[fit fspecify fexample fscenario focus])
SKIPPED = SelectorSet.new(%i[xit xspecify xexample xscenario skip])
PENDING = SelectorSet.new(%i[pending])
ALL = EXAMPLES + FOCUSED + SKIPPED + PENDING
end
module Hooks
ALL = SelectorSet.new(
%i[
prepend_before
before
append_before
around
prepend_after
after
append_after
]
)
module Scopes
ALL = SelectorSet.new(
%i[
each
example
context
all
suite
]
)
end
end
module Helpers
ALL = SelectorSet.new(%i[let let!])
end
module Subject
ALL = SelectorSet.new(%i[subject subject!])
end
module Expectations
ALL = SelectorSet.new(%i[expect is_expected expect_any_instance_of])
end
module Runners
ALL = SelectorSet.new(%i[to to_not not_to])
end
ALL =
ExampleGroups::ALL +
SharedGroups::ALL +
Examples::ALL +
Hooks::ALL +
Helpers::ALL +
Subject::ALL +
Expectations::ALL +
Runners::ALL
end
end
end

View File

@ -1,35 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
module Language
# Common node matchers used for matching against the rspec DSL
module NodePattern
extend RuboCop::NodePattern::Macros
def_node_matcher :rspec?, '{(const {nil? cbase} :RSpec) nil?}'
def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern
def_node_matcher :shared_group?, SharedGroups::ALL.block_pattern
spec_groups = ExampleGroups::ALL + SharedGroups::ALL
def_node_matcher :spec_group?, spec_groups.block_pattern
def_node_matcher :example_group_with_body?, <<-PATTERN
(block #{ExampleGroups::ALL.send_pattern} args !nil?)
PATTERN
def_node_matcher :example?, Examples::ALL.block_pattern
def_node_matcher :hook?, Hooks::ALL.block_pattern
def_node_matcher :let?, Helpers::ALL.block_or_block_pass_pattern
def_node_matcher :include?,
Includes::ALL.send_or_block_or_block_pass_pattern
def_node_matcher :subject?, Subject::ALL.block_pattern
end
end
end
end

View File

@ -1,52 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# Helper methods for top level describe cops
module TopLevelDescribe
extend NodePattern::Macros
def on_send(node)
return unless respond_to?(:on_top_level_describe)
return unless top_level_describe?(node)
on_top_level_describe(node, node.arguments)
end
private
def top_level_describe?(node)
return false unless node.method?(:describe)
top_level_nodes.include?(node)
end
def top_level_nodes
nodes = describe_statement_children(root_node)
# If we have no top level describe statements, we need to check any
# blocks on the top level (e.g. after a require).
if nodes.empty?
nodes = root_node.each_child_node(:block).flat_map do |child|
describe_statement_children(child)
end
end
nodes
end
def root_node
processed_source.ast
end
def single_top_level_describe?
top_level_nodes.one?
end
def describe_statement_children(node)
node.each_child_node(:send).select do |element|
element.method?(:describe)
end
end
end
end
end

View File

@ -1,57 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# Helper methods for top level example group cops
module TopLevelGroup
extend RuboCop::NodePattern::Macros
include RuboCop::RSpec::Language
def_node_matcher :example_or_shared_group?,
(ExampleGroups::ALL + SharedGroups::ALL).block_pattern
def on_new_investigation
super
return unless root_node
top_level_groups.each do |node|
on_top_level_example_group(node) if example_group?(node)
on_top_level_group(node)
end
end
def top_level_groups
@top_level_groups ||=
top_level_nodes(root_node).select { |n| example_or_shared_group?(n) }
end
private
# Dummy methods to be overridden in the consumer
def on_top_level_example_group(_node); end
def on_top_level_group(_node); end
def top_level_group?(node)
top_level_groups.include?(node)
end
def top_level_nodes(node)
if node.nil?
[]
elsif node.begin_type?
node.children
elsif node.module_type? || node.class_type?
top_level_nodes(node.body)
else
[node]
end
end
def root_node
processed_source.ast
end
end
end
end

View File

@ -1,16 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
# Helps check offenses with variable definitions
module Variable
include Language
extend RuboCop::NodePattern::Macros
def_node_matcher :variable_definition?, <<~PATTERN
(send nil? #{(Helpers::ALL + Subject::ALL).node_pattern_union}
$({sym str dsym dstr} ...) ...)
PATTERN
end
end
end

View File

@ -1,14 +1,85 @@
---
AllCops:
RSpec:
Patterns:
- _spec.rb
- "(?:^|/)spec/"
RSpec/FactoryBot:
Patterns:
- spec/factories.rb
- spec/factories/**/*.rb
- features/support/factories/**/*.rb
RSpec:
Include:
- "**/*_spec.rb"
- "**/spec/**/*"
Language:
ExampleGroups:
Regular:
- describe
- context
- feature
- example_group
Skipped:
- xdescribe
- xcontext
- xfeature
Focused:
- fdescribe
- fcontext
- ffeature
Examples:
Regular:
- it
- specify
- example
- scenario
- its
Focused:
- fit
- fspecify
- fexample
- fscenario
- focus
Skipped:
- xit
- xspecify
- xexample
- xscenario
- skip
Pending:
- pending
Expectations:
- expect
- is_expected
- expect_any_instance_of
Helpers:
- let
- let!
Hooks:
- prepend_before
- before
- append_before
- around
- prepend_after
- after
- append_after
HookScopes:
- each
- example
- context
- all
- suite
Includes:
Examples:
- it_behaves_like
- it_should_behave_like
- include_examples
Context:
- include_context
Runners:
- to
- to_not
- not_to
SharedGroups:
Examples:
- shared_examples
- shared_examples_for
Context:
- shared_context
Subjects:
- subject
- subject!
RSpec/AlignLeftLetBrace:
Description: Checks that left braces for adjacent single line lets are aligned.
@ -136,8 +207,8 @@ RSpec/Dialect:
RSpec/EmptyExampleGroup:
Description: Checks if an example group does not include any tests.
Enabled: true
CustomIncludeMethods: []
VersionAdded: '1.7'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyExampleGroup
RSpec/EmptyHook:
@ -241,6 +312,9 @@ RSpec/ExpectOutput:
RSpec/FilePath:
Description: Checks that spec file paths are consistent and well-formed.
Enabled: true
Include:
- "**/*_spec*rb*"
- "**/spec/**/*"
CustomTransform:
RuboCop: rubocop
RSpec: rspec
@ -315,12 +389,6 @@ RSpec/InstanceVariable:
VersionChanged: '1.7'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InstanceVariable
RSpec/InvalidPredicateMatcher:
Description: Checks invalid usage for predicate matcher.
Enabled: true
VersionAdded: '1.16'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InvalidPredicateMatcher
RSpec/ItBehavesLike:
Description: Checks that only one `it_behaves_like` style is used.
Enabled: true
@ -561,7 +629,7 @@ RSpec/SingleArgumentMessageChain:
RSpec/StubbedMock:
Description: Checks that message expectations do not have a configured response.
Enabled: pending
Enabled: true
VersionAdded: '1.44'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StubbedMock
@ -620,49 +688,68 @@ RSpec/Yield:
VersionAdded: '1.32'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
Capybara/CurrentPathExpectation:
RSpec/Capybara/CurrentPathExpectation:
Description: Checks that no expectations are set on Capybara's `current_path`.
Enabled: true
VersionAdded: '1.18'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/CurrentPathExpectation
Capybara/FeatureMethods:
RSpec/Capybara/FeatureMethods:
Description: Checks for consistent method usage in feature specs.
Enabled: true
EnabledMethods: []
VersionAdded: '1.17'
VersionChanged: '1.25'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
Capybara/VisibilityMatcher:
RSpec/Capybara/VisibilityMatcher:
Description: Checks for boolean visibility in capybara finders.
Enabled: true
VersionAdded: '1.39'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/VisibilityMatcher
FactoryBot/AttributeDefinedStatically:
RSpec/FactoryBot/AttributeDefinedStatically:
Description: Always declare attribute values as blocks.
Enabled: true
Include:
- spec/factories.rb
- spec/factories/**/*.rb
- features/support/factories/**/*.rb
VersionAdded: '1.28'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/AttributeDefinedStatically
FactoryBot/CreateList:
RSpec/FactoryBot/CreateList:
Description: Checks for create_list usage.
Enabled: true
Include:
- "**/*_spec.rb"
- "**/spec/**/*"
- spec/factories.rb
- spec/factories/**/*.rb
- features/support/factories/**/*.rb
EnforcedStyle: create_list
SupportedStyles:
- create_list
- n_times
VersionAdded: '1.25'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/CreateList
FactoryBot/FactoryClassName:
RSpec/FactoryBot/FactoryClassName:
Description: Use string value when setting the class attribute explicitly.
Enabled: true
Include:
- spec/factories.rb
- spec/factories/**/*.rb
- features/support/factories/**/*.rb
VersionAdded: '1.37'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryClassName
Rails/HttpStatus:
RSpec/Rails/HttpStatus:
Description: Enforces use of symbolic or numeric value to describe HTTP status.
Enabled: true
EnforcedStyle: symbolic
@ -670,4 +757,5 @@ Rails/HttpStatus:
- numeric
- symbolic
VersionAdded: '1.23'
VersionChanged: '2.0'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus

View File

@ -5,26 +5,25 @@ require 'yaml'
require 'rubocop'
require_relative 'rubocop/rspec'
require_relative 'rubocop/rspec/version'
require_relative 'rubocop/rspec/inject'
require_relative 'rubocop/rspec/node'
require_relative 'rubocop/rspec/top_level_describe'
require_relative 'rubocop/rspec/wording'
require_relative 'rubocop/rspec/language'
require_relative 'rubocop/rspec/language/node_pattern'
require_relative 'rubocop/rspec/top_level_group'
require_relative 'rubocop/rspec/language'
require_relative 'rubocop/cop/rspec/mixin/top_level_group'
require_relative 'rubocop/cop/rspec/mixin/variable'
require_relative 'rubocop/cop/rspec/mixin/final_end_location'
require_relative 'rubocop/cop/rspec/mixin/empty_line_separation'
require_relative 'rubocop/rspec/concept'
require_relative 'rubocop/rspec/example_group'
require_relative 'rubocop/rspec/example'
require_relative 'rubocop/rspec/hook'
require_relative 'rubocop/rspec/variable'
require_relative 'rubocop/cop/rspec/base'
require_relative 'rubocop/cop/rspec/cop'
require_relative 'rubocop/rspec/align_let_brace'
require_relative 'rubocop/rspec/factory_bot'
require_relative 'rubocop/rspec/final_end_location'
require_relative 'rubocop/rspec/empty_line_separation'
require_relative 'rubocop/rspec/corrector/move_node'
RuboCop::RSpec::Inject.defaults!

View File

@ -27,11 +27,9 @@ module RuboCop
end
def on_new_investigation
super
return if processed_source.blank?
token_aligner =
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
token_aligner.offending_tokens.each do |let|
add_offense(let.loc.begin) do |corrector|
corrector.insert_before(
@ -40,6 +38,12 @@ module RuboCop
end
end
end
private
def token_aligner
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
end
end
end
end

View File

@ -27,11 +27,9 @@ module RuboCop
end
def on_new_investigation
super
return if processed_source.blank?
token_aligner =
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
token_aligner.offending_tokens.each do |let|
add_offense(let.loc.end) do |corrector|
corrector.insert_before(
@ -40,6 +38,12 @@ module RuboCop
end
end
end
private
def token_aligner
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
end
end
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# @abstract parent class to RSpec cops
class Base < ::RuboCop::Cop::Base
include RuboCop::RSpec::Language
extend RuboCop::RSpec::Language::NodePattern
exclude_from_registry
# Invoke the original inherited hook so our cops are recognized
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
RuboCop::Cop::Base.inherited(subclass)
end
# Set the config for dynamic DSL configuration-aware helpers
# that have no other means of accessing the configuration.
def on_new_investigation
super
RuboCop::RSpec::Language.config = config['RSpec']['Language']
end
end
end
end
end

View File

@ -23,7 +23,7 @@ module RuboCop
MSG = 'Don\'t use `be` without an argument.'
def_node_matcher :be_without_args, <<-PATTERN
(send _ #{Runners::ALL.node_pattern_union} $(send nil? :be))
(send _ #Runners.all $(send nil? :be))
PATTERN
def on_send(node)

View File

@ -37,13 +37,13 @@ module RuboCop
# Supported matchers: eq(...) / match(/regexp/) / match('regexp')
def_node_matcher :as_is_matcher, <<-PATTERN
(send
#expectation_set_on_current_path $#{Runners::ALL.node_pattern_union}
#expectation_set_on_current_path $#Runners.all
${(send nil? :eq ...) (send nil? :match (regexp ...))})
PATTERN
def_node_matcher :regexp_str_matcher, <<-PATTERN
(send
#expectation_set_on_current_path $#{Runners::ALL.node_pattern_union}
#expectation_set_on_current_path $#Runners.all
$(send nil? :match (str $_)))
PATTERN

View File

@ -55,8 +55,9 @@ module RuboCop
feature: :describe
}.freeze
def_node_matcher :capybara_speak,
SelectorSet.new(MAP.keys).node_pattern_union
def_node_matcher :capybara_speak, <<-PATTERN
{#{MAP.keys.map(&:inspect).join(' ')}}
PATTERN
def_node_matcher :spec?, <<-PATTERN
(block

View File

@ -35,7 +35,7 @@ module RuboCop
# describe "A feature example", type: :feature do
# end
class DescribeClass < Base
include RuboCop::RSpec::TopLevelGroup
include TopLevelGroup
MSG = 'The first argument to describe should be '\
'the class or module being tested.'

View File

@ -17,7 +17,7 @@ module RuboCop
# describe MyClass, '.my_class_method' do
# end
class DescribeMethod < Base
include RuboCop::RSpec::TopLevelGroup
include TopLevelGroup
MSG = 'The second argument to describe should be the method '\
"being tested. '#instance' or '.class'."

View File

@ -65,8 +65,7 @@ module RuboCop
(block (send (const nil? {:Class :Module :Struct}) :new ...) ...)
PATTERN
def_node_matcher :rspec_block?,
RuboCop::RSpec::Language::ALL.block_pattern
def_node_matcher :rspec_block?, block_pattern('#ALL.all')
def_node_matcher :scope_changing_syntax?, '{def class module}'

View File

@ -22,8 +22,7 @@ module RuboCop
class DescribedClassModuleWrapping < Base
MSG = 'Avoid opening modules and defining specs within them.'
def_node_search :find_rspec_blocks,
ExampleGroups::ALL.block_pattern
def_node_search :find_rspec_blocks, block_pattern('#ExampleGroups.all')
def on_module(node)
find_rspec_blocks(node) do

View File

@ -47,7 +47,7 @@ module RuboCop
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
def_node_matcher :rspec_method?, ALL.send_pattern
def_node_matcher :rspec_method?, send_pattern('#ALL.all')
def on_send(node)
return unless rspec_method?(node)

View File

@ -5,8 +5,6 @@ module RuboCop
module RSpec
# Checks if an example group does not include any tests.
#
# This cop is configurable using the `CustomIncludeMethods` option
#
# @example usage
#
# # bad
@ -37,31 +35,6 @@ module RuboCop
# describe Bacon do
# pending 'will add tests later'
# end
#
# @example configuration
#
# # .rubocop.yml
# # RSpec/EmptyExampleGroup:
# # CustomIncludeMethods:
# # - include_tests
#
# # spec_helper.rb
# RSpec.configure do |config|
# config.alias_it_behaves_like_to(:include_tests)
# end
#
# # bacon_spec.rb
# describe Bacon do
# let(:bacon) { Bacon.new(chunkiness) }
# let(:chunkiness) { false }
#
# context 'extra chunky' do # not flagged by rubocop
# let(:chunkiness) { true }
#
# include_tests 'shared tests'
# end
# end
#
class EmptyExampleGroup < Base
MSG = 'Empty example group detected.'
@ -76,7 +49,7 @@ module RuboCop
# @param node [RuboCop::AST::Node]
# @yield [RuboCop::AST::Node] example group body
def_node_matcher :example_group_body, <<~PATTERN
(block #{ExampleGroups::ALL.send_pattern} args $_)
(block #{send_pattern('#ExampleGroups.all')} args $_)
PATTERN
# @!method example_or_group_or_include?(node)
@ -95,12 +68,10 @@ module RuboCop
# @return [Array<RuboCop::AST::Node>] matching nodes
def_node_matcher :example_or_group_or_include?, <<~PATTERN
{
#{Examples::ALL.send_pattern}
#{Examples::ALL.block_pattern}
#{ExampleGroups::ALL.block_pattern}
#{Includes::ALL.send_pattern}
#{Includes::ALL.block_pattern}
(send nil? #custom_include? ...)
#{block_pattern(
'{#Examples.all #ExampleGroups.all #Includes.all}'
)}
#{send_pattern('{#Examples.all #Includes.all}')}
}
PATTERN
@ -120,7 +91,7 @@ module RuboCop
# @param node [RuboCop::AST::Node]
# @return [Array<RuboCop::AST::Node>] matching nodes
def_node_matcher :examples_inside_block?, <<~PATTERN
(block !#{Hooks::ALL.send_pattern} _ #examples?)
(block !#{send_pattern('#Hooks.all')} _ #examples?)
PATTERN
# @!method examples_directly_or_in_block?(node)
@ -192,16 +163,6 @@ module RuboCop
def examples_in_branches?(if_node)
if_node.branches.any? { |branch| examples?(branch) }
end
def custom_include?(method_name)
custom_include_methods.include?(method_name)
end
def custom_include_methods
cop_config
.fetch('CustomIncludeMethods', [])
.map(&:to_sym)
end
end
end
end

View File

@ -29,7 +29,7 @@ module RuboCop
MSG = 'Empty hook detected.'
def_node_matcher :empty_hook?, <<~PATTERN
(block $#{Hooks::ALL.send_pattern} _ nil?)
(block $#{send_pattern('#Hooks.all')} _ nil?)
PATTERN
def on_block(node)

View File

@ -43,7 +43,7 @@ module RuboCop
#
class EmptyLineAfterExample < Base
extend AutoCorrector
include RuboCop::RSpec::EmptyLineSeparation
include EmptyLineSeparation
MSG = 'Add an empty line after `%<example>s`.'

View File

@ -25,7 +25,7 @@ module RuboCop
#
class EmptyLineAfterExampleGroup < Base
extend AutoCorrector
include RuboCop::RSpec::EmptyLineSeparation
include EmptyLineSeparation
MSG = 'Add an empty line after `%<example_group>s`.'

View File

@ -18,7 +18,7 @@ module RuboCop
# it { does_something }
class EmptyLineAfterFinalLet < Base
extend AutoCorrector
include RuboCop::RSpec::EmptyLineSeparation
include EmptyLineSeparation
MSG = 'Add an empty line after the last `%<let>s`.'

View File

@ -35,7 +35,7 @@ module RuboCop
#
class EmptyLineAfterHook < Base
extend AutoCorrector
include RuboCop::RSpec::EmptyLineSeparation
include EmptyLineSeparation
MSG = 'Add an empty line after `%<hook>s`.'

View File

@ -16,7 +16,7 @@ module RuboCop
# let(:foo) { bar }
class EmptyLineAfterSubject < Base
extend AutoCorrector
include RuboCop::RSpec::EmptyLineSeparation
include EmptyLineSeparation
MSG = 'Add an empty line after `%<subject>s`.'
@ -32,7 +32,7 @@ module RuboCop
def in_spec_block?(node)
node.each_ancestor(:block).any? do |ancestor|
Examples::ALL.include?(ancestor.method_name)
Examples.all(ancestor.method_name)
end
end
end

View File

@ -48,7 +48,7 @@ module RuboCop
def_node_matcher :expect_literal, <<~PATTERN
(send
(send nil? :expect $#literal?)
#{Runners::ALL.node_pattern_union}
#Runners.all
{
(send (send nil? $:be) :== $_)
(send nil? $_ $_ ...)

View File

@ -23,7 +23,7 @@ module RuboCop
class ExpectInHook < Base
MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'
def_node_search :expectation, Expectations::ALL.send_pattern
def_node_search :expectation, send_pattern('#Expectations.all')
def on_block(node)
return unless hook?(node)

View File

@ -57,7 +57,7 @@ module RuboCop
# my_class_spec.rb # describe MyClass, '#method'
#
class FilePath < Base
include RuboCop::RSpec::TopLevelGroup
include TopLevelGroup
MSG = 'Spec path should end with `%<suffix>s`.'

View File

@ -22,19 +22,25 @@ module RuboCop
class Focus < Base
MSG = 'Focused spec found.'
focused = ExampleGroups::FOCUSED + Examples::FOCUSED
def_node_matcher :focusable_selector?,
(ExampleGroups::GROUPS + ExampleGroups::SKIPPED +
Examples::EXAMPLES + Examples::SKIPPED +
Examples::PENDING).node_pattern_union
def_node_matcher :focusable_selector?, <<-PATTERN
{
#ExampleGroups.regular
#ExampleGroups.skipped
#Examples.regular
#Examples.skipped
#Examples.pending
}
PATTERN
def_node_matcher :metadata, <<-PATTERN
{(send #rspec? #focusable_selector? <$(sym :focus) ...>)
(send #rspec? #focusable_selector? ... (hash <$(pair (sym :focus) true) ...>))}
PATTERN
def_node_matcher :focused_block?, focused.send_pattern
def_node_matcher :focused_block?,
send_pattern(<<~PATTERN)
{#ExampleGroups.focused #Examples.focused}
PATTERN
def on_send(node)
focus_metadata(node) do |focus|

View File

@ -64,13 +64,11 @@ module RuboCop
IMPLICIT_MSG = 'Omit the default `%<scope>p` argument for RSpec hooks.'
EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'
def_node_matcher :hook?, Hooks::ALL.node_pattern_union
def_node_matcher :scoped_hook, <<-PATTERN
(block $(send _ #hook? (sym ${:each :example})) ...)
(block $(send _ #Hooks.all (sym ${:each :example})) ...)
PATTERN
def_node_matcher :unscoped_hook, '(block $(send _ #hook?) ...)'
def_node_matcher :unscoped_hook, '(block $(send _ #Hooks.all) ...)'
def on_block(node)
hook(node) do |method_send, scope_name|

View File

@ -30,8 +30,8 @@ module RuboCop
def_node_matcher :example_or_group?, <<-PATTERN
{
#{(Examples::ALL + ExampleGroups::ALL).block_pattern}
#{Includes::EXAMPLES.send_pattern}
#{block_pattern('{#ExampleGroups.all #Examples.all}')}
#{send_pattern('#Includes.examples')}
}
PATTERN

View File

@ -33,7 +33,7 @@ module RuboCop
def_node_matcher :implicit_expect, <<-PATTERN
{
(send nil? ${:should :should_not} ...)
(send (send nil? $:is_expected) #{Runners::ALL.node_pattern_union} ...)
(send (send nil? $:is_expected) #Runners.all ...)
}
PATTERN

View File

@ -47,7 +47,7 @@ module RuboCop
# end
#
class InstanceVariable < Base
include RuboCop::RSpec::TopLevelGroup
include TopLevelGroup
MSG = 'Avoid instance variables use let, ' \
'a method call, or a local variable (if possible).'

View File

@ -37,8 +37,8 @@ module RuboCop
def_node_matcher :example_or_group?, <<-PATTERN
{
#{(Examples::ALL + ExampleGroups::ALL).block_pattern}
#{Includes::EXAMPLES.send_pattern}
#{block_pattern('{#ExampleGroups.all #Examples.all}')}
#{send_pattern('#Includes.examples')}
}
PATTERN

View File

@ -29,10 +29,13 @@ module RuboCop
MSG = 'Do not use `let!` to setup objects not referenced in tests.'
def_node_matcher :example_or_shared_group_or_including?,
(
ExampleGroups::ALL + SharedGroups::ALL +
Includes::ALL
).block_pattern
block_pattern(<<~PATTERN)
{
#SharedGroups.all
#ExampleGroups.all
#Includes.all
}
PATTERN
def_node_matcher :let_bang, <<-PATTERN
{

View File

@ -36,7 +36,7 @@ module RuboCop
SUPPORTED_STYLES = %w[have_received receive].freeze
def_node_matcher :message_expectation, %(
(send (send nil? :expect $_) #{Runners::ALL.node_pattern_union} ...)
(send (send nil? :expect $_) #Runners.all ...)
)
def_node_search :receive_message, %(

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helps determine the offending location if there is not an empty line
# following the node. Allows comments to follow directly after.
module EmptyLineSeparation
include FinalEndLocation
include RangeHelp
def missing_separating_line_offense(node)
return if last_child?(node)
missing_separating_line(node) do |location|
msg = yield(node.method_name)
add_offense(location, message: msg) do |corrector|
corrector.insert_after(location.end, "\n")
end
end
end
def missing_separating_line(node)
line = final_end_location(node).line
line += 1 while comment_line?(processed_source[line])
return if processed_source[line].blank?
yield offending_loc(line)
end
def offending_loc(last_line)
offending_line = processed_source[last_line - 1]
content_length = offending_line.lstrip.length
start = offending_line.length - content_length
source_range(processed_source.buffer,
last_line, start, content_length)
end
def last_child?(node)
return true unless node.parent&.begin_type?
node.equal?(node.parent.children.last)
end
end
end
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helps find the true end location of nodes which might contain heredocs.
module FinalEndLocation
def final_end_location(start_node)
heredoc_endings =
start_node.each_node(:str, :dstr, :xstr)
.select(&:heredoc?)
.map { |node| node.loc.heredoc_end }
[start_node.loc.end, *heredoc_endings].max_by(&:line)
end
end
end
end
end

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helper methods for top level example group cops
module TopLevelGroup
extend RuboCop::NodePattern::Macros
def on_new_investigation
super
top_level_groups.each do |node|
on_top_level_example_group(node) if example_group?(node)
on_top_level_group(node)
end
end
def top_level_groups
@top_level_groups ||=
top_level_nodes(root_node).select { |n| spec_group?(n) }
end
private
# Dummy methods to be overridden in the consumer
def on_top_level_example_group(_node); end
def on_top_level_group(_node); end
def top_level_group?(node)
top_level_groups.include?(node)
end
def top_level_nodes(node)
return [] if node.nil?
case node.type
when :begin
node.children
when :module, :class
top_level_nodes(node.body)
else
[node]
end
end
def root_node
processed_source.ast
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show More