Commit 1702ca76 authored by Rémy Coutable's avatar Rémy Coutable Committed by Robert Speicher

[EE] Use gitlab-styles

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent 6bdfe9a2
......@@ -16,6 +16,7 @@ engines:
enabled: true
rubocop:
enabled: true
channel: "gitlab-rubocop-0-52"
ratings:
paths:
- Gemfile.lock
......
......@@ -619,7 +619,7 @@ codequality:
script:
- cp .rubocop.yml .rubocop.yml.bak
- grep -v "rubocop-gitlab-security" .rubocop.yml.bak > .rubocop.yml
- docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate analyze -f json > raw_codeclimate.json
- docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc dev.gitlab.org:5005/gitlab/gitlab-build-images:gitlab-codeclimate-v2 analyze -f json > raw_codeclimate.json
- cat raw_codeclimate.json | docker run -i stedolan/jq -c 'map({check_name,fingerprint,location})' > codeclimate.json
- mv .rubocop.yml.bak .rubocop.yml
artifacts:
......
This diff is collapsed.
This diff is collapsed.
......@@ -346,9 +346,11 @@ group :development, :test do
gem 'spring-commands-rspec', '~> 1.0.4'
gem 'spring-commands-spinach', '~> 1.1.0'
gem 'rubocop', '~> 0.49.1', require: false
gem 'rubocop-rspec', '~> 1.15.1', require: false
gem 'rubocop-gitlab-security', '~> 0.1.0', require: false
gem 'gitlab-styles', '~> 2.2.0', require: false
# Pin these dependencies, otherwise a new rule could break the CI pipelines
gem 'rubocop', '~> 0.52.0'
gem 'rubocop-rspec', '~> 1.20.1'
gem 'scss_lint', '~> 0.54.0', require: false
gem 'haml_lint', '~> 0.26.0', require: false
gem 'simplecov', '~> 0.14.0', require: false
......
......@@ -328,6 +328,10 @@ GEM
posix-spawn (~> 0.3)
gitlab-license (1.0.0)
gitlab-markup (1.6.3)
gitlab-styles (2.2.0)
rubocop (~> 0.51)
rubocop-gitlab-security (~> 0.1.0)
rubocop-rspec (~> 1.19)
gitlab_omniauth-ldap (2.0.4)
net-ldap (~> 0.16)
omniauth (~> 1.3)
......@@ -806,21 +810,21 @@ GEM
pg
rails
sqlite3
rubocop (0.49.1)
rubocop (0.52.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
parser (>= 2.4.0.2, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-gitlab-security (0.1.0)
rubocop (>= 0.47.1)
rubocop-rspec (1.15.1)
rubocop (>= 0.42.0)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
rubocop-rspec (1.20.1)
rubocop (>= 0.51.0)
ruby-fogbugz (0.2.1)
crack (~> 0.4)
ruby-prof (0.16.2)
ruby-progressbar (1.8.1)
ruby-progressbar (1.9.0)
ruby-saml (1.4.1)
nokogiri (>= 1.5.10)
ruby_parser (3.9.0)
......@@ -1082,6 +1086,7 @@ DEPENDENCIES
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-license (~> 1.0)
gitlab-markup (~> 1.6.2)
gitlab-styles (~> 2.2.0)
gitlab_omniauth-ldap (~> 2.0.4)
gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.4)
......@@ -1186,9 +1191,8 @@ DEPENDENCIES
rspec-retry (~> 0.4.5)
rspec-set (~> 0.1.3)
rspec_profiling (~> 0.0.5)
rubocop (~> 0.49.1)
rubocop-gitlab-security (~> 0.1.0)
rubocop-rspec (~> 1.15.1)
rubocop (~> 0.52.0)
rubocop-rspec (~> 1.20.1)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.16.2)
ruby_parser (~> 3.8)
......
......@@ -24,10 +24,10 @@ class Projects::DeployKeysController < Projects::ApplicationController
def create
@key = DeployKeys::CreateService.new(current_user, create_params).execute
unless @key.valid? && @project.deploy_keys << @key
flash[:alert] = @key.errors.full_messages.join(', ').html_safe
else
if @key.valid? && @project.deploy_keys << @key
log_audit_event(@key.title, action: :create)
else
flash[:alert] = @key.errors.full_messages.join(', ').html_safe
end
redirect_to_repository_settings(@project)
......
......@@ -27,9 +27,8 @@ module BranchesHelper
# Returns a hash were keys are types of access levels (user, role), and
# values are the number of access levels of the particular type.
def access_level_frequencies(access_levels)
access_levels.reduce(Hash.new(0)) do |frequencies, access_level|
access_levels.each_with_object(Hash.new(0)) do |access_level, frequencies|
frequencies[access_level.type] += 1
frequencies
end
end
......
......@@ -7,7 +7,7 @@ class LfsObject < ActiveRecord::Base
validates :oid, presence: true, uniqueness: true
scope :with_files_stored_locally, ->() { where(file_store: [nil, LfsObjectUploader::LOCAL_STORE]) }
scope :with_files_stored_locally, -> { where(file_store: [nil, LfsObjectUploader::LOCAL_STORE]) }
mount_uploader :file, LfsObjectUploader
......
......@@ -181,7 +181,7 @@ class HipchatService < Service
description = obj_attr[:description]
title = render_line(obj_attr[:title])
action = obj_attr[:action]
state_or_action_text = (action == 'approved') ? action : state
state_or_action_text = action == 'approved' ? action : state
merge_request_url = "#{project_url}/merge_requests/#{merge_request_iid}"
merge_request_link = "<a href=\"#{merge_request_url}\">merge request !#{merge_request_iid}</a>"
message = "#{user_name} #{state_or_action_text} #{merge_request_link} in " \
......
......@@ -4,7 +4,7 @@ module Prependable
def prepend_features(base)
if base.instance_variable_defined?(:@_dependencies)
base.instance_variable_get(:@_dependencies) << self
return false
false
else
return false if base < self
......
......@@ -18,7 +18,7 @@ Peek.into Peek::Views::Rblineprof
Peek.into Peek::Views::GC
Peek.into Peek::Views::Gitaly
# rubocop:disable Style/ClassAndModuleCamelCase
# rubocop:disable Naming/ClassAndModuleCamelCase
class PEEK_DB_CLIENT
class << self
attr_accessor :query_details
......
# rubocop:disable Rails/ReversibleMigration
class UpdateGroupLinks < ActiveRecord::Migration
def change
provider = quote_string(Gitlab::LDAP::Config.providers.first)
......
......@@ -8,7 +8,7 @@ module EE
def method_missing(method_sym, *arguments, &block)
case method_sym.to_s
when /\Acheck_(.*)_available!\z/
check_group_feature_available!($1.to_sym)
check_group_feature_available!(Regexp.last_match(1).to_sym)
else
super
end
......
......@@ -33,9 +33,7 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController
private
def authorize_manage_ldap_group_links!
unless can?(current_user, :admin_ldap_group_links, group)
return render_404
end
render_404 unless can?(current_user, :admin_ldap_group_links, group)
end
def require_ldap_enabled
......
......@@ -67,7 +67,7 @@ module LicenseHelper
end
def new_trial_url
return_to_url = URI.encode(Gitlab.config.gitlab.url)
return_to_url = CGI.escape(Gitlab.config.gitlab.url)
uri = URI.parse(Gitlab::SUBSCRIPTIONS_URL)
uri.path = '/trials/new'
uri.query = "return_to=#{return_to_url}"
......
......@@ -93,9 +93,8 @@ module Elastic
end
def highlight_options(fields)
es_fields = fields.map { |field| field.split('^').first }.inject({}) do |memo, field|
es_fields = fields.map { |field| field.split('^').first }.each_with_object({}) do |field, memo|
memo[field.to_sym] = {}
memo
end
{ fields: es_fields }
......
......@@ -49,7 +49,7 @@ module Elastic
def self.elastic_search(query, options: {})
query_hash =
if query =~ /#(\d+)\z/
iid_query_hash($1)
iid_query_hash(Regexp.last_match(1))
else
basic_query_hash(%w(title^2 description), query)
end
......
......@@ -62,7 +62,7 @@ module Elastic
def self.elastic_search(query, options: {})
query_hash =
if query =~ /\!(\d+)\z/
iid_query_hash($1)
iid_query_hash(Regexp.last_match(1))
else
basic_query_hash(%w(title^2 description), query)
end
......
......@@ -3,7 +3,7 @@ module EE
extend ActiveSupport::Concern
def author_name
details[:author_name].blank? ? user&.name : details[:author_name]
details[:author_name].presence || user&.name
end
def entity
......
......@@ -66,9 +66,9 @@ module EE
allow_destroy: true,
reject_if: ->(attrs) { attrs[:id].blank? && attrs[:url].blank? }
with_options if: :mirror? do |project|
project.validates :import_url, presence: true
project.validates :mirror_user, presence: true
with_options if: :mirror? do
validates :import_url, presence: true
validates :mirror_user, presence: true
end
end
......@@ -357,7 +357,7 @@ module EE
unless ::Gitlab::UrlSanitizer.valid?(value)
self.import_url = value
self.import_data&.user = nil
return value
value
end
url = ::Gitlab::UrlSanitizer.new(value)
......
......@@ -3,7 +3,7 @@ module Geo
class LfsObject < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('lfs_objects')
scope :with_files_stored_locally, ->() { where(file_store: [nil, LfsObjectUploader::LOCAL_STORE]) }
scope :with_files_stored_locally, -> { where(file_store: [nil, LfsObjectUploader::LOCAL_STORE]) }
end
end
end
......@@ -2,7 +2,8 @@ class GeoNodeStatus < ActiveRecord::Base
belongs_to :geo_node
# Whether we were successful in reaching this node
attr_accessor :success, :health_status, :version, :revision
attr_accessor :success, :version, :revision
attr_writer :health_status
# Be sure to keep this consistent with Prometheus naming conventions
PROMETHEUS_METRICS = {
......
......@@ -4,16 +4,16 @@ class LdapGroupLink < ActiveRecord::Base
BLANK_ATTRIBUTES = %w[cn filter].freeze
with_options if: :cn do |link|
link.validates :cn, uniqueness: { scope: [:group_id, :provider] }
link.validates :cn, presence: true
link.validates :filter, absence: true
with_options if: :cn do
validates :cn, uniqueness: { scope: [:group_id, :provider] }
validates :cn, presence: true
validates :filter, absence: true
end
with_options if: :filter do |link|
link.validates :filter, uniqueness: { scope: [:group_id, :provider] }
link.validates :filter, ldap_filter: true, presence: true
link.validates :cn, absence: true
with_options if: :filter do
validates :filter, uniqueness: { scope: [:group_id, :provider] }
validates :filter, ldap_filter: true, presence: true
validates :cn, absence: true
end
validates :group_access, :group_id, presence: true
......
......@@ -61,7 +61,7 @@ class JenkinsDeprecatedService < CiService
def build_page(sha, ref = nil)
if multiproject_enabled? && ref.present?
URI.encode("#{base_project_url}/#{project.name}_#{ref.tr('/', '_')}/scm/bySHA1/#{sha}").to_s
"#{base_project_url}/#{project.name}_#{ref.tr('/', '_')}/scm/bySHA1/#{sha}"
else
"#{project_url}/scm/bySHA1/#{sha}"
end
......@@ -93,8 +93,8 @@ class JenkinsDeprecatedService < CiService
else
get_url = build_page(sha, ref).gsub("#{parsed_url.userinfo}@", "")
auth = {
username: URI.decode(parsed_url.user),
password: URI.decode(parsed_url.password)
username: CGI.unescape(parsed_url.user),
password: CGI.unescape(parsed_url.password)
}
response = HTTParty.get(get_url, verify: false, basic_auth: auth)
end
......
......@@ -117,7 +117,7 @@ class RemoteMirror < ActiveRecord::Base
end
def url=(value)
return super(value) unless Gitlab::UrlSanitizer.valid?(value)
super(value) && return unless Gitlab::UrlSanitizer.valid?(value)
mirror_url = Gitlab::UrlSanitizer.new(value)
self.credentials = mirror_url.credentials
......
......@@ -40,7 +40,7 @@ module Geo
private
def schedule_file_removal(uploads)
paths_to_remove = uploads.find_each(batch_size: BATCH_SIZE).reduce([]) do |to_remove, upload|
paths_to_remove = uploads.find_each(batch_size: BATCH_SIZE).each_with_object([]) do |upload, to_remove|
file_path = File.join(base_dir, upload.path)
if File.exist?(file_path)
......@@ -48,8 +48,6 @@ module Geo
log_info("Scheduled to remove file", file_path: file_path)
end
to_remove
end
Geo::FileRemovalWorker.bulk_perform_async(paths_to_remove)
......
......@@ -28,13 +28,11 @@ module Geo
private
def move_repositories!
begin
project.ensure_storage_path_exists
move_project_repository && move_wiki_repository
rescue => ex
log_error('Repository cannot be renamed', error: ex)
false
end
project.ensure_storage_path_exists
move_project_repository && move_wiki_repository
rescue => ex
log_error('Repository cannot be renamed', error: ex)
false
end
def move_project_repository
......
......@@ -9,7 +9,7 @@ class ObjectStoreUploader < CarrierWave::Uploader::Base
REMOTE_STORE = 2
class << self
def storage_options(options)
def storage_options(options) # rubocop:disable Style/TrivialAccessors
@storage_options = options
end
......
......@@ -14,9 +14,9 @@ class AdminEmailsWorker
when 'all'
User.active.subscribed_for_admin_email
when /group-(\d+)\z/
Group.find($1).users_with_descendants.subscribed_for_admin_email
Group.find(Regexp.last_match(1)).users_with_descendants.subscribed_for_admin_email
when /project-(\d+)\z/
Project.find($1).authorized_users.active.subscribed_for_admin_email
Project.find(Regexp.last_match(1)).authorized_users.active.subscribed_for_admin_email
end
end
end
......@@ -92,7 +92,7 @@ module Geo
end
def resources_remain?
pending_resources.size > 0
!pending_resources.empty?
end
def over_time?
......
......@@ -5,8 +5,10 @@ module EE
strong_memoize(:current_user) do
user = super
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :user, user.id) if user
if user
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :user, user.id)
end
user
end
......
......@@ -5,8 +5,10 @@ module EE
def authenticate_job!
id = params[:id]
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :build, id) if id
if id
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :build, id)
end
super
end
......@@ -14,8 +16,10 @@ module EE
def current_runner
token = params[:token]
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :runner, token) if token
if token
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :runner, token)
end
super
end
......
......@@ -5,8 +5,10 @@ module EE
def authenticate_build!
id = params[:id]
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :build, id) if id
if id
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :build, id)
end
super
end
......@@ -14,8 +16,10 @@ module EE
def current_runner
token = params[:token]
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :runner, token) if token
if token
::Gitlab::Database::LoadBalancing::RackMiddleware
.stick_or_unstick(env, :runner, token)
end
super
end
......
......@@ -3,6 +3,7 @@ module EE
module LDAP
class Group
attr_accessor :adapter
attr_reader :entry
def self.find_by_cn(cn, adapter)
cn = Net::LDAP::Filter.escape(cn)
......@@ -57,10 +58,6 @@ module EE
private
def entry
@entry
end
# Active Directory range member methods
def has_member_range?(entry)
......
......@@ -99,9 +99,9 @@ module Gitlab
ActiveRecord::Migrator.migrations_paths.flat_map do |path|
# match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
Dir.foreach(path).grep(/^(\d{3,})_(.+)\.rb$/) do
version = ActiveRecord::SchemaMigration.normalize_migration_number($1)
version = ActiveRecord::SchemaMigration.normalize_migration_number(Regexp.last_match(1))
status = db_list.delete(version) ? 'up' : 'down'
[status, version, $2.humanize]
[status, version, Regexp.last_match(2).humanize]
end
end
......
......@@ -8,7 +8,7 @@ module Gitlab
IAT_LEEWAY = 60.seconds.to_i
def self.geo_auth_attempt?(header)
token_type, _ = header&.split(' ', 2)
token_type, = header&.split(' ', 2)
token_type == ::Gitlab::Geo::BaseRequest::GITLAB_GEO_AUTH_TOKEN_TYPE
end
......
......@@ -98,17 +98,15 @@ module Gitlab
end
def open_temp_file(target_filename)
begin
# Make sure the file is in the same directory to prevent moves across filesystems
pathname = Pathname.new(target_filename)
temp = Tempfile.new(TEMP_PREFIX, pathname.dirname.to_s)
temp.chmod(default_permissions)
temp.binmode
temp
rescue StandardError => e
log_error("Error creating temporary file", error: e)
nil
end
# Make sure the file is in the same directory to prevent moves across filesystems
pathname = Pathname.new(target_filename)
temp = Tempfile.new(TEMP_PREFIX, pathname.dirname.to_s)
temp.chmod(default_permissions)
temp.binmode
temp
rescue StandardError => e
log_error("Error creating temporary file", error: e)
nil
end
end
end
......
......@@ -12,6 +12,8 @@
# CsvBuilder.new(@posts, columns).render
#
class CsvBuilder
attr_reader :rows_written
#
# * +collection+ - The data collection to be used
# * +header_to_hash_value+ - A hash of 'Column Heading' => 'value_method'.
......@@ -46,10 +48,6 @@ class CsvBuilder
@truncated
end
def rows_written
@rows_written
end
def rows_expected
if truncated? || rows_written == 0
@collection.count
......
......@@ -254,7 +254,7 @@ module Elasticsearch
from_rev
end
return from, to_rev
[from, to_rev]
end
def index_new_branch?(from)
......@@ -282,16 +282,18 @@ module Elasticsearch
else
repository_for_indexing.index.each do |blob|
b = LiteBlob.new(repository_for_indexing, blob)
result.push(
{
type: 'blob',
id: "#{target_sha}_#{b.path}",
rid: repository_id,
oid: b.id,
content: b.data,
commit_sha: target_sha
}
) if b.text?
if b.text?
result.push(
{
type: 'blob',
id: "#{target_sha}_#{b.path}",
rid: repository_id,
oid: b.id,
content: b.data,
commit_sha: target_sha
})
end
end
end
......@@ -304,16 +306,18 @@ module Elasticsearch
tree.each_blob do |blob|
blob[:path] = path + blob[:name]
b = LiteBlob.new(repository_for_indexing, blob)
result.push(
{
type: 'blob',
id: "#{repository_for_indexing.head.target.oid}_#{path}#{blob[:name]}",
rid: repository_id,
oid: b.id,
content: b.data,
commit_sha: repository_for_indexing.head.target.oid
}
) if b.text?
if b.text?
result.push(
{
type: 'blob',
id: "#{repository_for_indexing.head.target.oid}_#{path}#{blob[:name]}",
rid: repository_id,
oid: b.id,
content: b.data,
commit_sha: repository_for_indexing.head.target.oid
})
end
end
tree.each_tree do |nested_tree|
......@@ -363,11 +367,7 @@ module Elasticsearch
unless defined?(path_to_repo)
def path_to_repo
if @path_to_repo.blank?
raise NotImplementedError, 'Please, define "path_to_repo" method, or set "path_to_repo" via "repository_for_indexing" method'
else
@path_to_repo
end
@path_to_repo.presence || raise(NotImplementedError, 'Please, define "path_to_repo" method, or set "path_to_repo" via "repository_for_indexing" method')
end
end
......@@ -443,9 +443,8 @@ module Elasticsearch
end
if options[:highlight]
es_fields = fields.map { |field| field.split('^').first }.inject({}) do |memo, field|
es_fields = fields.map { |field| field.split('^').first }.each_with_object({}) do |field, memo|
memo[field.to_sym] = {}
memo
end
query_hash[:highlight] = {
......
......@@ -93,9 +93,7 @@ module Gitlab
private
def entries
@entries
end
attr_reader :entries
end
end
end
......
......@@ -56,11 +56,12 @@ module Gitlab
# Do nothing if hooks already exist
unless real_local_hooks_path == File.realpath(global_hooks_path)
# Move the existing hooks somewhere safe
FileUtils.mv(
local_hooks_path,
"#{local_hooks_path}.old.#{Time.now.to_i}"
) if File.exist?(local_hooks_path)
if File.exist?(local_hooks_path)
# Move the existing hooks somewhere safe
FileUtils.mv(
local_hooks_path,
"#{local_hooks_path}.old.#{Time.now.to_i}")
end
# Create the hooks symlink
FileUtils.ln_sf(global_hooks_path, local_hooks_path)
......
require_relative '../model_helpers'
module RuboCop
module Cop
# Cop that prevents the use of `dependent: ...` in ActiveRecord models.
class ActiveRecordDependent < RuboCop::Cop::Cop
include ModelHelpers
MSG = 'Do not use `dependent: to remove associated data, ' \
'use foreign keys with cascading deletes instead'.freeze
METHOD_NAMES = [:has_many, :has_one, :belongs_to].freeze
def on_send(node)
return unless in_model?(node)
return unless METHOD_NAMES.include?(node.children[1])
node.children.last.each_node(:pair) do |pair|
key_name = pair.children[0].children[0]
add_offense(pair, :expression) if key_name == :dependent
end
end
end
end
end
require_relative '../model_helpers'
module RuboCop
module Cop
# Cop that prevents the use of `serialize` in ActiveRecord models.
class ActiveRecordSerialize < RuboCop::Cop::Cop
include ModelHelpers
MSG = 'Do not store serialized data in the database, use separate columns and/or tables instead'.freeze
def on_send(node)
return unless in_model?(node)
add_offense(node, :selector) if node.children[1] == :serialize
end
end
end
end
module RuboCop
module Cop
# This cop makes sure that custom error classes, when empty, are declared
# with Class.new.
#
# @example
# # bad
# class FooError < StandardError
# end
#
# # okish
# class FooError < StandardError; end
#
# # good
# FooError = Class.new(StandardError)
class CustomErrorClass < RuboCop::Cop::Cop
MSG = 'Use `Class.new(SuperClass)` to define an empty custom error class.'.freeze
def on_class(node)
_klass, parent, body = node.children
return if body
parent_klass = class_name_from_node(parent)
return unless parent_klass && parent_klass.to_s.end_with?('Error')
add_offense(node, :expression)
end
def autocorrect(node)
klass, parent, _body = node.children
replacement = "#{class_name_from_node(klass)} = Class.new(#{class_name_from_node(parent)})"
lambda do |corrector|
corrector.replace(node.source_range, replacement)
end
end
private
# The nested constant `Foo::Bar::Baz` looks like:
#
# s(:const,
# s(:const,
# s(:const, nil, :Foo), :Bar), :Baz)
#
# So recurse through that to get the name as written in the source.
#
def class_name_from_node(node, suffix = nil)
return unless node&.type == :const
name = node.children[1].to_s
name = "#{name}::#{suffix}" if suffix
if node.children[0]
class_name_from_node(node.children[0], name)
else
name
end
end
end
end
end
module RuboCop
module Cop
# This cop prevents usage of the `git` and `github` arguments to `gem` in a
# `Gemfile` in order to avoid additional points of failure beyond
# rubygems.org.
class GemFetcher < RuboCop::Cop::Cop
MSG = 'Do not use gems from git repositories, only use gems from RubyGems.'.freeze
GIT_KEYS = [:git, :github].freeze
def on_send(node)
return unless gemfile?(node)
func_name = node.children[1]
return unless func_name == :gem
node.children.last.each_node(:pair) do |pair|
key_name = pair.children[0].children[0].to_sym
if GIT_KEYS.include?(key_name)
add_offense(node, pair.source_range, MSG)
end
end
end
private
def gemfile?(node)
node
.location
.expression
.source_buffer
.name
.end_with?("Gemfile")
end
end
end
end
......@@ -30,12 +30,12 @@ module RuboCop
if only_ivar_or_assignment?(definition)
# We don't allow if any other ivar is used
definition.each_descendant(:ivar) do |offense|
add_offense(offense, :expression)
add_offense(offense, location: :expression)
end
# We allow initialize method and single ivar
elsif !initialize_method?(definition) && !single_ivar?(definition)
definition.each_descendant(:ivar, :ivasgn) do |offense|
add_offense(offense, :expression)
add_offense(offense, location: :expression)
end
end
end
......
require_relative '../model_helpers'
module RuboCop
module Cop
# Cop that prevents the use of `in_batches`
class InBatches < RuboCop::Cop::Cop
MSG = 'Do not use `in_batches`, use `each_batch` from the EachBatch module instead'.freeze
def on_send(node)
return unless node.children[1] == :in_batches
add_offense(node, :selector)
end
end
end
end
......@@ -9,14 +9,14 @@ module RuboCop
MSG = 'Include `ApplicationWorker`, not `Sidekiq::Worker`.'.freeze
def_node_matcher :includes_sidekiq_worker?, <<~PATTERN
(send nil :include (const (const nil :Sidekiq) :Worker))
(send nil? :include (const (const nil? :Sidekiq) :Worker))
PATTERN
def on_send(node)
return if in_spec?(node)
return unless includes_sidekiq_worker?(node)
add_offense(node.arguments.first, :expression)
add_offense(node.arguments.first, location: :expression)
end
def autocorrect(node)
......
# frozen_string_literal: true
module RuboCop
module Cop
# Ensures a line break after guard clauses.
#
# @example
# # bad
# return unless condition
# do_stuff
#
# # good
# return unless condition
#
# do_stuff
#
# # bad
# raise if condition
# do_stuff
#
# # good
# raise if condition
#
# do_stuff
#
# Multiple guard clauses are allowed without
# line break.
#
# # good
# return unless condition_a
# return unless condition_b
#
# do_stuff
#
# Guard clauses in case statement are allowed without
# line break.
#
# # good
# case model
# when condition_a
# return true unless condition_b
# when
# ...
# end
#
# Guard clauses before end are allowed without
# line break.
#
# # good
# if condition_a
# do_something
# else
# do_something_else
# return unless condition
# end
#
# do_something_more
class LineBreakAfterGuardClauses < RuboCop::Cop::Cop
MSG = 'Add a line break after guard clauses'
def_node_matcher :guard_clause_node?, <<-PATTERN
[{(send nil? {:raise :fail :throw} ...) return break next} single_line?]
PATTERN
def on_if(node)
return unless node.single_line?
return unless guard_clause?(node)
return if next_line(node).blank? || clause_last_line?(next_line(node)) || guard_clause?(next_sibling(node))
add_offense(node, :expression, MSG)
end
def autocorrect(node)
lambda do |corrector|
corrector.insert_after(node.loc.expression, "\n")
end
end
private
def guard_clause?(node)
return false unless node.if_type?
guard_clause_node?(node.if_branch)
end
def next_sibling(node)
node.parent.children[node.sibling_index + 1]
end
def next_line(node)
processed_source[node.loc.line]
end
def clause_last_line?(line)
line =~ /^\s*(?:end|elsif|else|when|rescue|ensure)/
end
end
end
end
......@@ -29,7 +29,7 @@ module RuboCop
opts.each_node(:pair) do |pair|
if hash_key_type(pair) == :sym && hash_key_name(pair) == :default
add_offense(node, :selector)
add_offense(node, location: :selector)
end
end
end
......
......@@ -15,7 +15,7 @@ module RuboCop
name = node.children[1]
add_offense(node, :selector) if name == :add_foreign_key
add_offense(node, location: :selector) if name == :add_foreign_key
end
def method_name(node)
......
......@@ -21,7 +21,7 @@ module RuboCop
node.each_ancestor(:def) do |def_node|
next unless method_name(def_node) == :change
add_offense(def_node, :name)
add_offense(def_node, location: :name)
end
end
......
......@@ -27,7 +27,7 @@ module RuboCop
# data in these tables yet.
next if new_tables.include?(first_arg)
add_offense(send_node, :selector)
add_offense(send_node, location: :selector)
end
end
......
......@@ -13,7 +13,7 @@ module RuboCop
def on_send(node)
return unless in_migration?(node)
add_offense(node, :selector) if method_name(node) == :add_timestamps
add_offense(node, location: :selector) if method_name(node) == :add_timestamps
end
def method_name(node)
......
......@@ -17,7 +17,7 @@ module RuboCop
method_name = node.children[1]
if method_name == :datetime || method_name == :timestamp
add_offense(send_node, :selector, format(MSG, method_name))
add_offense(send_node, location: :selector, message: format(MSG, method_name))
end
end
end
......@@ -32,7 +32,7 @@ module RuboCop
last_argument = descendant.children.last
if last_argument == :datetime || last_argument == :timestamp
add_offense(node, :expression, format(MSG, last_argument))
add_offense(node, location: :expression, message: format(MSG, last_argument))
end
end
end
......
......@@ -29,7 +29,7 @@ module RuboCop
hash_key_name(pair) == :using
if hash_key_value(pair).to_s == 'hash'
add_offense(pair, :expression)
add_offense(pair, location: :expression)
end
end
end
......
......@@ -20,7 +20,7 @@ module RuboCop
send_method = send_node.children[1]
if send_method == :remove_column
add_offense(send_node, :selector)
add_offense(send_node, location: :selector)
end
end
end
......
......@@ -16,7 +16,7 @@ module RuboCop
return unless node.children[1] == :remove_concurrent_index
node.each_ancestor(:def) do |def_node|
add_offense(def_node, :name) if method_name(def_node) == :change
add_offense(def_node, location: :name) if method_name(def_node) == :change
end
end
......
......@@ -13,7 +13,7 @@ module RuboCop
return unless in_migration?(node)
node.each_descendant(:send) do |send_node|
add_offense(send_node, :selector) if method_name(send_node) == :remove_index
add_offense(send_node, location: :selector) if method_name(send_node) == :remove_index
end
end
......
......@@ -9,7 +9,7 @@ module RuboCop
include MigrationHelpers
def_node_matcher :add_column_with_default?, <<~PATTERN
(send nil :add_column_with_default $...)
(send nil? :add_column_with_default $...)
PATTERN
def_node_matcher :defines_change?, <<~PATTERN
......@@ -26,7 +26,7 @@ module RuboCop
node.each_ancestor(:def) do |def_node|
next unless defines_change?(def_node)
add_offense(def_node, :name)
add_offense(def_node, location: :name)
end
end
end
......
......@@ -28,7 +28,7 @@ module RuboCop
].freeze
def_node_matcher :add_column?, <<~PATTERN
(send nil :add_column $...)
(send nil? :add_column $...)
PATTERN
def on_send(node)
......@@ -54,7 +54,7 @@ module RuboCop
NULL_OFFENSE
end
add_offense(node, :expression, format(offense, table)) if offense
add_offense(node, location: :expression, message: format(offense, table)) if offense
end
def no_default?(opts)
......
......@@ -14,7 +14,7 @@ module RuboCop
return unless in_migration?(node)
node.each_descendant(:send) do |send_node|
add_offense(send_node, :selector) if method_name(send_node) == :timestamps
add_offense(send_node, location: :selector) if method_name(send_node) == :timestamps
end
end
......
......@@ -18,7 +18,7 @@ module RuboCop
spec_path = spec_filename(node)
unless File.exist?(File.expand_path(spec_path, rails_root))
add_offense(node, :expression, format(MSG, spec_path))
add_offense(node, location: :expression, message: format(MSG, spec_path))
end
end
......
......@@ -35,7 +35,7 @@ module RuboCop
].freeze
def_node_matcher :batch_update?, <<~PATTERN
(send nil ${:add_column_with_default :update_column_in_batches} $(sym ...) ...)
(send nil? ${:add_column_with_default :update_column_in_batches} $(sym ...) ...)
PATTERN
def on_send(node)
......@@ -49,7 +49,7 @@ module RuboCop
return unless LARGE_TABLES.include?(table)
add_offense(node, :expression, format(MSG, update_method, table))
add_offense(node, location: :expression, message: format(MSG, update_method, table))
end
end
end
......
require_relative '../model_helpers'
module RuboCop
module Cop
# Cop that prevents the use of polymorphic associations
class PolymorphicAssociations < RuboCop::Cop::Cop
include ModelHelpers
MSG = 'Do not use polymorphic associations, use separate tables instead'.freeze
def on_send(node)
return unless in_model?(node)
return unless node.children[1] == :belongs_to
node.children.last.each_node(:pair) do |pair|
key_name = pair.children[0].children[0]
add_offense(pair, :expression) if key_name == :polymorphic
end
end
end
end
end
......@@ -17,7 +17,7 @@ module RuboCop
return unless method_name(namespace_expr) == :namespace
return unless receiver(namespace_expr) == project_expr
add_offense(node, :selector)
add_offense(node, location: :selector)
end
def autocorrect(node)
......
module RuboCop
module Cop
# This cop prevents usage of 'redirect_to' in actions 'destroy' without specifying 'status'.
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/31840
class RedirectWithStatus < RuboCop::Cop::Cop
MSG = 'Do not use "redirect_to" without "status" in "destroy" action'.freeze
def on_def(node)
return unless in_controller?(node)
return unless destroy?(node) || destroy_all?(node)
node.each_descendant(:send) do |def_node|
next unless redirect_to?(def_node)
methods = []
def_node.children.last.each_node(:pair) do |pair|
methods << pair.children.first.children.first
end
add_offense(def_node, :selector) unless methods.include?(:status)
end
end
private
def in_controller?(node)
node.location.expression.source_buffer.name.end_with?('_controller.rb')
end
def destroy?(node)
node.children.first == :destroy
end
def destroy_all?(node)
node.children.first == :destroy_all
end
def redirect_to?(node)
node.children[1] == :redirect_to
end
end
end
end
require 'rubocop-rspec'
require_relative '../../spec_helpers'
module RuboCop
......@@ -17,7 +16,7 @@ module RuboCop
# before do
# stub_env('FOO', 'bar')
# end
class EnvAssignment < Cop
class EnvAssignment < RuboCop::Cop::Cop
include SpecHelpers
MESSAGE = "Don't assign to ENV, use `stub_env` instead.".freeze
......@@ -32,7 +31,7 @@ module RuboCop
return unless in_spec?(node)
return unless env_assignment?(node)
add_offense(node, :expression, MESSAGE)
add_offense(node, location: :expression, message: MESSAGE)
end
def autocorrect(node)
......
require 'rubocop-rspec'
module RuboCop
module Cop
module RSpec
# This cop checks for single-line hook blocks
#
# @example
#
# # bad
# before { do_something }
# after(:each) { undo_something }
#
# # good
# before do
# do_something
# end
#
# after(:each) do
# undo_something
# end
class SingleLineHook < Cop
MESSAGE = "Don't use single-line hook blocks.".freeze
def_node_search :rspec_hook?, <<~PATTERN
(send nil {:after :around :before} ...)
PATTERN
def on_block(node)
return unless rspec_hook?(node)
return unless node.single_line?
add_offense(node, :expression, MESSAGE)
end
end
end
end
end
# frozen_string_literal: true
require 'rubocop-rspec'
module RuboCop
module Cop
module RSpec
# Checks for verbose include metadata used in the specs.
#
# @example
# # bad
# describe MyClass, js: true do
# end
#
# # good
# describe MyClass, :js do
# end
class VerboseIncludeMetadata < Cop
MSG = 'Use `%s` instead of `%s`.'
SELECTORS = %i[describe context feature example_group it specify example scenario its].freeze
def_node_matcher :include_metadata, <<-PATTERN
(send {(const nil :RSpec) nil} {#{SELECTORS.map(&:inspect).join(' ')}}
!const
...
(hash $...))
PATTERN
def_node_matcher :invalid_metadata?, <<-PATTERN
(pair
(sym $...)
(true))
PATTERN
def on_send(node)
invalid_metadata_matches(node) do |match|
add_offense(node, :expression, format(MSG, good(match), bad(match)))
end
end
def autocorrect(node)
lambda do |corrector|
invalid_metadata_matches(node) do |match|
corrector.replace(match.loc.expression, good(match))
end
end
end
private
def invalid_metadata_matches(node)
include_metadata(node) do |matches|
matches.select(&method(:invalid_metadata?)).each do |match|
yield match
end
end
end
def bad(match)
"#{metadata_key(match)}: true"
end
def good(match)
":#{metadata_key(match)}"
end
def metadata_key(match)
match.children[0].source
end
end
end
end
end
......@@ -9,7 +9,7 @@ module RuboCop
MSG = 'Do not manually set a queue; `ApplicationWorker` sets one automatically.'.freeze
def_node_matcher :sidekiq_options?, <<~PATTERN
(send nil :sidekiq_options $...)
(send nil? :sidekiq_options $...)
PATTERN
def on_send(node)
......@@ -19,7 +19,7 @@ module RuboCop
node.arguments.first.each_node(:pair) do |pair|
key_name = pair.key.children[0]
add_offense(pair, :expression) if key_name == :queue
add_offense(pair, location: :expression) if key_name == :queue
end
end
end
......
module RuboCop
module ModelHelpers
# Returns true if the given node originated from the models directory.
def in_model?(node)
path = node.location.expression.source_buffer.name
models_path = File.join(Dir.pwd, 'app', 'models')
path.start_with?(models_path)
end
end
end
require_relative 'cop/active_record_dependent'
require_relative 'cop/active_record_serialize'
require_relative 'cop/custom_error_class'
require_relative 'cop/gem_fetcher'
require_relative 'cop/in_batches'
require_relative 'cop/include_sidekiq_worker'
require_relative 'cop/line_break_after_guard_clauses'
require_relative 'cop/polymorphic_associations'
require_relative 'cop/project_path_helper'
require_relative 'cop/redirect_with_status'
require_relative 'cop/gitlab/module_with_instance_variables'
require_relative 'cop/sidekiq_options_queue'
require_relative 'cop/include_sidekiq_worker'
require_relative 'cop/migration/add_column'
require_relative 'cop/migration/add_concurrent_foreign_key'
require_relative 'cop/migration/add_concurrent_index'
......@@ -25,6 +16,8 @@ require_relative 'cop/migration/safer_boolean_column'
require_relative 'cop/migration/timestamps'
require_relative 'cop/migration/update_column_in_batches'
require_relative 'cop/migration/update_large_table'
require_relative 'cop/project_path_helper'
require_relative 'cop/rspec/env_assignment'
require_relative 'cop/rspec/single_line_hook'
require_relative 'cop/rspec/verbose_include_metadata'
require_relative 'cop/sidekiq_options_queue'
......@@ -4,16 +4,13 @@ feature 'Profile > Pipeline Quota' do
before do
# This would make sure that the user won't try to create another namespace
allow_any_instance_of(User).to receive(:ensure_namespace_correct)
gitlab_sign_in(user)
end
let(:user) { create(:user) }
let(:namespace) { create(:namespace, owner: user) }
let!(:project) { create(:project, namespace: namespace, shared_runners_enabled: true) }
before do
gitlab_sign_in(user)
end
it 'is linked within the profile page' do
visit profile_path
......
......@@ -3,12 +3,12 @@ require 'spec_helper'
describe Gitlab::LDAP::Adapter do
include LdapHelpers
let(:adapter) { ldap_adapter('ldapmain') }
it 'includes the EE module' do
expect(described_class).to include_module(EE::Gitlab::LDAP::Adapter)
end
let(:adapter) { ldap_adapter('ldapmain') }
describe '#groups' do
before do
stub_ldap_config(
......
......@@ -211,7 +211,7 @@ describe GeoNode, type: :model do
end
describe '#oauth_logout_url' do
let(:fake_state) { URI.encode('fakestate') }
let(:fake_state) { CGI.escape('fakestate') }
let(:oauth_logout_url) { "https://localhost:3000/gitlab/oauth/geo/logout?state=#{fake_state}" }
it 'returns oauth logout url based on node uri' do
......
......@@ -10,7 +10,7 @@ FactoryBot.define do
factory :doorkeeper_access_token, class: Doorkeeper::AccessToken do
sequence(:resource_owner_id) { |n| n }
association :application, factory: :doorkeeper_application
expires_in 2.hours
expires_in { 2.hours }
factory :clientless_access_token do
application nil
......
......@@ -18,10 +18,10 @@ FactoryBot.define do
wikis_synced_count 4
wikis_failed_count 1
last_event_id 2
last_event_timestamp Time.now.to_i
last_event_timestamp { Time.now.to_i }
cursor_last_event_id 1
cursor_last_event_timestamp Time.now.to_i
last_successful_status_check_timestamp Time.now.beginning_of_day
cursor_last_event_timestamp { Time.now.to_i }
last_successful_status_check_timestamp { Time.now.beginning_of_day }
end
trait :unhealthy do
......
......@@ -14,7 +14,7 @@ FactoryBot.define do
trait :closed do
state :closed
closed_at Time.now
closed_at { Time.now }
end
factory :closed_issue, traits: [:closed]
......
......@@ -91,12 +91,12 @@ FactoryBot.define do
trait :import_failed do
import_status :failed
mirror_last_update_at Time.now
mirror_last_update_at { Time.now }
end
trait :import_hard_failed do
import_status :failed
mirror_last_update_at Time.now - 1.minute
mirror_last_update_at { Time.now - 1.minute }
after(:create) do |project|
project.mirror_data&.update_attributes(retry_count: Gitlab::Mirror::MAX_RETRY + 1)
......
......@@ -44,6 +44,11 @@ describe 'GitLab Markdown' do
before do
stub_licensed_features(epics: true)
@feat = MarkdownFeature.new
# `markdown` helper expects a `@project` and `@group` variable
@project = @feat.project
@group = @feat.group
end
# Shared behavior that all pipelines should exhibit
......@@ -208,14 +213,6 @@ describe 'GitLab Markdown' do
end
end
before do
@feat = MarkdownFeature.new
# `markdown` helper expects a `@project` and `@group` variable
@project = @feat.project
@group = @feat.group
end
context 'default pipeline' do
before do
@html = markdown(@feat.raw_markdown)
......
......@@ -199,9 +199,7 @@ describe Gitlab::Database::LoadBalancing::Host, :postgresql do
it 'returns the lag size as an Integer' do
# On newer versions of Ruby the class is Integer, but on CI we run a
# version that still uses Fixnum.
classes = [Fixnum, Integer] # rubocop: disable Lint/UnifiedInteger
expect(classes).to include(host.replication_lag_size.class)
expect([Fixnum, Integer]).to include(host.replication_lag_size.class) # rubocop: disable Lint/UnifiedInteger
end
it 'returns nil when the database query returned no rows' do
......
......@@ -79,9 +79,7 @@ describe Gitlab::Database::LoadBalancing::LoadBalancer do
it 'uses the primary if no secondaries are available' do
allow(lb).to receive(:connection_error?).and_return(true)
lb.host_list.hosts.each do |host|
expect(host).to receive(:online?).and_return(false)
end
expect(lb.host_list.hosts).to all(receive(:online?).and_return(false))
expect(lb).to receive(:read_write).and_call_original
......@@ -154,9 +152,7 @@ describe Gitlab::Database::LoadBalancing::LoadBalancer do
describe '#all_caught_up?' do
it 'returns true if all hosts caught up to the write location' do
lb.host_list.hosts.each do |host|
expect(host).to receive(:caught_up?).with('foo').and_return(true)
end
expect(lb.host_list.hosts).to all(receive(:caught_up?).with('foo').and_return(true))
expect(lb.all_caught_up?('foo')).to eq(true)
end
......
......@@ -2,7 +2,7 @@ require 'spec_helper'
describe OmniAuth::Strategies::KerberosSpnego do
subject { described_class.new(:app) }
let(:session) { Hash.new }
let(:session) { {} }
before do
allow(subject).to receive(:session).and_return(session)
......
......@@ -301,7 +301,7 @@ describe License do
context "when the license is valid" do
it "returns the license" do
expect(described_class.current)
expect(described_class.current).to be_present
end
end
end
......
......@@ -10,13 +10,13 @@ describe JenkinsDeprecatedService, use_clean_rails_memory_store_caching: true do
describe 'commits methods' do
def status_body_for_icon(state)
<<eos
<<ICON_STATUS_HTML
<h1 class="build-caption page-headline">
<img src="/static/8b0a9b52/images/48x48/#{state}" alt="Success" tooltip="Success" style="width: 48px; height: 48px; " class="icon-#{state} icon-xlg" />
Build #188
(Oct 15, 2014 9:45:21 PM)
</h1>
eos
ICON_STATUS_HTML
end
describe '#calculate_reactive_cache' do
......@@ -83,11 +83,7 @@ eos
end
describe '#build_page' do
it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://jenkins.gitlab.org/job/#{project.name}_master/scm/bySHA1/2ab7834c") }
end
describe '#build_page with branch' do
it { expect(@service.build_page("2ab7834c", 'test_branch')).to eq("http://jenkins.gitlab.org/job/#{project.name}_test_branch/scm/bySHA1/2ab7834c") }
it { expect(@service.build_page("2ab7834c", 'feature/my-branch')).to eq("http://jenkins.gitlab.org/job/#{project.name}_feature_my-branch/scm/bySHA1/2ab7834c") }
end
end
......
require 'spec_helper'
describe JenkinsService do
describe 'Associations' do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
end
let(:project) { create(:project) }
let(:jenkins_url) { 'http://jenkins.example.com/' }
let(:jenkins_hook_url) { jenkins_url + 'project/my_project' }
let(:jenkins_username) { 'u$er name%2520' }
......@@ -28,6 +22,11 @@ describe JenkinsService do
let(:jenkins_authorization) { "Basic " + ::Base64.strict_encode64(jenkins_username + ':' + jenkins_password) }
describe 'Associations' do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
end
describe 'username validation' do
before do
@jenkins_service = described_class.create(
......
......@@ -202,7 +202,7 @@ describe RemoteMirror do
end
it 'returns false when last update started before the timestamp' do
expect(remote_mirror.updated_since?(Time.now + 5.minutes)).to be false
expect(remote_mirror.updated_since?(Time.now + 5.minutes)).to be false
end
end
......
......@@ -58,7 +58,7 @@ describe Service do
end
describe "Available services" do
it { expect(described_class.available_services_names).to include("jenkins", "jira")}
it { expect(described_class.available_services_names).to include("jenkins", "jira") }
end
describe "Template" do
......
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/active_record_dependent'
describe RuboCop::Cop::ActiveRecordDependent do
include CopHelper
subject(:cop) { described_class.new }
context 'inside the app/models directory' do
it 'registers an offense when dependent: is used' do
allow(cop).to receive(:in_model?).and_return(true)
inspect_source(cop, 'belongs_to :foo, dependent: :destroy')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([1])
end
end
end
context 'outside the app/models directory' do
it 'does nothing' do
allow(cop).to receive(:in_model?).and_return(false)
inspect_source(cop, 'belongs_to :foo, dependent: :destroy')
expect(cop.offenses).to be_empty
end
end
end
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/active_record_serialize'
describe RuboCop::Cop::ActiveRecordSerialize do
include CopHelper
subject(:cop) { described_class.new }
context 'inside the app/models directory' do
it 'registers an offense when serialize is used' do
allow(cop).to receive(:in_model?).and_return(true)
inspect_source(cop, 'serialize :foo')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([1])
end
end
end
context 'outside the app/models directory' do
it 'does nothing' do
allow(cop).to receive(:in_model?).and_return(false)
inspect_source(cop, 'serialize :foo')
expect(cop.offenses).to be_empty
end
end
end
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/custom_error_class'
describe RuboCop::Cop::CustomErrorClass do
include CopHelper
subject(:cop) { described_class.new }
context 'when a class has a body' do
it 'does nothing' do
inspect_source(cop, 'class CustomError < StandardError; def foo; end; end')
expect(cop.offenses).to be_empty
end
end
context 'when a class has no explicit superclass' do
it 'does nothing' do
inspect_source(cop, 'class CustomError; end')
expect(cop.offenses).to be_empty
end
end
context 'when a class has a superclass that does not end in Error' do
it 'does nothing' do
inspect_source(cop, 'class CustomError < BasicObject; end')
expect(cop.offenses).to be_empty
end
end
context 'when a class is empty and inherits from a class ending in Error' do
context 'when the class is on a single line' do
let(:source) do
<<-SOURCE
module Foo
class CustomError < Bar::Baz::BaseError; end
end
SOURCE
end
let(:expected) do
<<-EXPECTED
module Foo
CustomError = Class.new(Bar::Baz::BaseError)
end
EXPECTED
end
it 'registers an offense' do
expected_highlights = source.split("\n")[1].strip
inspect_source(cop, source)
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([2])
expect(cop.highlights).to contain_exactly(expected_highlights)
end
end
it 'autocorrects to the right version' do
autocorrected = autocorrect_source(cop, source, 'foo/custom_error.rb')
expect(autocorrected).to eq(expected)
end
end
context 'when the class is on multiple lines' do
let(:source) do
<<-SOURCE
module Foo
class CustomError < Bar::Baz::BaseError
end
end
SOURCE
end
let(:expected) do
<<-EXPECTED
module Foo
CustomError = Class.new(Bar::Baz::BaseError)
end
EXPECTED
end
it 'registers an offense' do
expected_highlights = source.split("\n")[1..2].join("\n").strip
inspect_source(cop, source)
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([2])
expect(cop.highlights).to contain_exactly(expected_highlights)
end
end
it 'autocorrects to the right version' do
autocorrected = autocorrect_source(cop, source, 'foo/custom_error.rb')
expect(autocorrected).to eq(expected)
end
end
end
end
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/gem_fetcher'
describe RuboCop::Cop::GemFetcher do
include CopHelper
subject(:cop) { described_class.new }
context 'in Gemfile' do
before do
allow(cop).to receive(:gemfile?).and_return(true)
end
it 'registers an offense when a gem uses `git`' do
inspect_source(cop, 'gem "foo", git: "https://gitlab.com/foo/bar.git"')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([1])
expect(cop.highlights).to eq(['git: "https://gitlab.com/foo/bar.git"'])
end
end
it 'registers an offense when a gem uses `github`' do
inspect_source(cop, 'gem "foo", github: "foo/bar.git"')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([1])
expect(cop.highlights).to eq(['github: "foo/bar.git"'])
end
end
end
context 'outside of Gemfile' do
it 'registers no offense' do
inspect_source(cop, 'gem "foo", git: "https://gitlab.com/foo/bar.git"')
expect(cop.offenses.size).to eq(0)
end
end
end
......@@ -12,7 +12,7 @@ describe RuboCop::Cop::Gitlab::ModuleWithInstanceVariables do
let(:offending_lines) { options[:offending_lines] }
it 'registers an offense when instance variable is used in a module' do
inspect_source(cop, source)
inspect_source(source)
aggregate_failures do
expect(cop.offenses.size).to eq(offending_lines.size)
......@@ -23,7 +23,7 @@ describe RuboCop::Cop::Gitlab::ModuleWithInstanceVariables do
shared_examples('not registering offense') do
it 'does not register offenses' do
inspect_source(cop, source)
inspect_source(source)
expect(cop.offenses).to be_empty
end
......
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/in_batches'
describe RuboCop::Cop::InBatches do
include CopHelper
subject(:cop) { described_class.new }
it 'registers an offense when in_batches is used' do
inspect_source(cop, 'foo.in_batches do; end')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([1])
end
end
end
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/include_sidekiq_worker'
describe RuboCop::Cop::IncludeSidekiqWorker do
......@@ -13,7 +15,7 @@ describe RuboCop::Cop::IncludeSidekiqWorker do
let(:correct_source) { 'include ApplicationWorker' }
it 'registers an offense ' do
inspect_source(cop, source)
inspect_source(source)
aggregate_failures do
expect(cop.offenses.size).to eq(1)
......@@ -23,7 +25,7 @@ describe RuboCop::Cop::IncludeSidekiqWorker do
end
it 'autocorrects to the right version' do
autocorrected = autocorrect_source(cop, source)
autocorrected = autocorrect_source(source)
expect(autocorrected).to eq(correct_source)
end
......
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/line_break_after_guard_clauses'
describe RuboCop::Cop::LineBreakAfterGuardClauses do
include CopHelper
subject(:cop) { described_class.new }
shared_examples 'examples with guard clause' do |title|
%w[if unless].each do |conditional|
it "flags violation for #{title} #{conditional} without line breaks" do
source = <<~RUBY
#{title} #{conditional} condition
do_stuff
RUBY
inspect_source(cop, source)
expect(cop.offenses.size).to eq(1)
offense = cop.offenses.first
expect(offense.line).to eq(1)
expect(cop.highlights).to eq(["#{title} #{conditional} condition"])
expect(offense.message).to eq('Add a line break after guard clauses')
end
it "doesn't flag violation for #{title} #{conditional} with line break" do
source = <<~RUBY
#{title} #{conditional} condition
do_stuff
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} on multiple lines without line break" do
source = <<~RUBY
#{conditional} condition
#{title}
end
do_stuff
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by end keyword" do
source = <<~RUBY
def test
#{title} #{conditional} condition
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by elsif keyword" do
source = <<~RUBY
if model
#{title} #{conditional} condition
elsif
do_something
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by else keyword" do
source = <<~RUBY
if model
#{title} #{conditional} condition
else
do_something
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by when keyword" do
source = <<~RUBY
case model
when condition_a
#{title} #{conditional} condition
when condition_b
do_something
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by rescue keyword" do
source = <<~RUBY
begin
#{title} #{conditional} condition
rescue StandardError
do_something
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by ensure keyword" do
source = <<~RUBY
def foo
#{title} #{conditional} condition
ensure
do_something
end
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for #{title} #{conditional} without line breaks when followed by another guard clause" do
source = <<~RUBY
#{title} #{conditional} condition
#{title} #{conditional} condition
do_stuff
RUBY
inspect_source(cop, source)
expect(cop.offenses).to be_empty
end
it "autocorrects #{title} #{conditional} guard clauses without line break" do
source = <<~RUBY
#{title} #{conditional} condition
do_stuff
RUBY
autocorrected = autocorrect_source(cop, source)
expected_source = <<~RUBY
#{title} #{conditional} condition
do_stuff
RUBY
expect(autocorrected).to eql(expected_source)
end
end
end
%w[return fail raise next break throw].each do |example|
it_behaves_like 'examples with guard clause', example
end
end
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../../rubocop/cop/migration/add_concurrent_foreign_key'
describe RuboCop::Cop::Migration::AddConcurrentForeignKey do
......@@ -10,7 +12,7 @@ describe RuboCop::Cop::Migration::AddConcurrentForeignKey do
context 'outside of a migration' do
it 'does not register any offenses' do
inspect_source(cop, 'def up; add_foreign_key(:projects, :users, column: :user_id); end')
inspect_source('def up; add_foreign_key(:projects, :users, column: :user_id); end')
expect(cop.offenses).to be_empty
end
......@@ -22,7 +24,7 @@ describe RuboCop::Cop::Migration::AddConcurrentForeignKey do
end
it 'registers an offense when using add_foreign_key' do
inspect_source(cop, 'def up; add_foreign_key(:projects, :users, column: :user_id); end')
inspect_source('def up; add_foreign_key(:projects, :users, column: :user_id); end')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
......
......@@ -16,7 +16,7 @@ describe RuboCop::Cop::Migration::AddConcurrentIndex do
end
it 'registers an offense when add_concurrent_index is used inside a change method' do
inspect_source(cop, 'def change; add_concurrent_index :table, :column; end')
inspect_source('def change; add_concurrent_index :table, :column; end')
aggregate_failures do
expect(cop.offenses.size).to eq(1)
......@@ -25,7 +25,7 @@ describe RuboCop::Cop::Migration::AddConcurrentIndex do
end
it 'registers no offense when add_concurrent_index is used inside an up method' do
inspect_source(cop, 'def up; add_concurrent_index :table, :column; end')
inspect_source('def up; add_concurrent_index :table, :column; end')
expect(cop.offenses.size).to eq(0)
end
......@@ -33,7 +33,7 @@ describe RuboCop::Cop::Migration::AddConcurrentIndex do
context 'outside of migration' do
it 'registers no offense' do
inspect_source(cop, 'def change; add_concurrent_index :table, :column; end')
inspect_source('def change; add_concurrent_index :table, :column; end')
expect(cop.offenses.size).to eq(0)
end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment