diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2017-11-06 21:44:57 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2017-11-06 21:44:57 +0800 |
commit | fc6aad0b4442c58fde1ac924cb2dd73823273537 (patch) | |
tree | 3f4a46a5b649cf623ab5e8e42eaa2e06cb2b20cf /rubocop | |
parent | 239332eed3fa870fd41be83864882c0f389840d8 (diff) | |
parent | cfc932cad10b1d6c494222e9d91aa75583b56145 (diff) | |
download | gitlab-ce-fc6aad0b4442c58fde1ac924cb2dd73823273537.tar.gz |
Merge remote-tracking branch 'upstream/master' into no-ivar-in-modules
* upstream/master: (1723 commits)
Resolve "Editor icons"
Refactor issuable destroy action
Ignore routes matching legacy_*_redirect in route specs
Gitlab::Git::RevList and LfsChanges use lazy popen
Gitlab::Git::Popen can lazily hand output to a block
Merge branch 'master-i18n' into 'master'
Remove unique validation from external_url in Environment
Expose `duration` in Job API entity
Add TimeCop freeze for DST and Regular time
Harcode project visibility
update a changelog
Put a condition to old migration that adds fast_forward column to MRs
Expose project visibility as CI variable
fix flaky tests by removing unneeded clicks and focus actions
fix flaky test in gfm_autocomplete_spec.rb
Use Gitlab::Git operations for repository mirroring
Encapsulate git operations for mirroring in Gitlab::Git
Create a Wiki Repository's raw_repository properly
Add `Gitlab::Git::Repository#fetch` command
Fix Gitlab::Metrics::System#real_time and #monotonic_time doc
...
Diffstat (limited to 'rubocop')
-rw-r--r-- | rubocop/cop/migration/datetime.rb | 20 | ||||
-rw-r--r-- | rubocop/cop/rspec/env_assignment.rb | 58 | ||||
-rw-r--r-- | rubocop/cop/rspec/verbose_include_metadata.rb | 74 | ||||
-rw-r--r-- | rubocop/rubocop.rb | 10 | ||||
-rw-r--r-- | rubocop/spec_helpers.rb | 12 |
5 files changed, 164 insertions, 10 deletions
diff --git a/rubocop/cop/migration/datetime.rb b/rubocop/cop/migration/datetime.rb index 651935dd53e..9cba3c35b26 100644 --- a/rubocop/cop/migration/datetime.rb +++ b/rubocop/cop/migration/datetime.rb @@ -7,14 +7,18 @@ module RuboCop class Datetime < RuboCop::Cop::Cop include MigrationHelpers - MSG = 'Do not use the `datetime` data type, use `datetime_with_timezone` instead'.freeze + MSG = 'Do not use the `%s` data type, use `datetime_with_timezone` instead'.freeze # Check methods in table creation. def on_def(node) return unless in_migration?(node) node.each_descendant(:send) do |send_node| - add_offense(send_node, :selector) if method_name(send_node) == :datetime + method_name = node.children[1] + + if method_name == :datetime || method_name == :timestamp + add_offense(send_node, :selector, format(MSG, method_name)) + end end end @@ -23,12 +27,14 @@ module RuboCop return unless in_migration?(node) node.each_descendant do |descendant| - add_offense(node, :expression) if descendant.type == :sym && descendant.children.last == :datetime - end - end + next unless descendant.type == :sym - def method_name(node) - node.children[1] + last_argument = descendant.children.last + + if last_argument == :datetime || last_argument == :timestamp + add_offense(node, :expression, format(MSG, last_argument)) + end + end end end end diff --git a/rubocop/cop/rspec/env_assignment.rb b/rubocop/cop/rspec/env_assignment.rb new file mode 100644 index 00000000000..257454af0e1 --- /dev/null +++ b/rubocop/cop/rspec/env_assignment.rb @@ -0,0 +1,58 @@ +require 'rubocop-rspec' +require_relative '../../spec_helpers' + +module RuboCop + module Cop + module RSpec + # This cop checks for ENV assignment in specs + # + # @example + # + # # bad + # before do + # ENV['FOO'] = 'bar' + # end + # + # # good + # before do + # stub_env('FOO', 'bar') + # end + class EnvAssignment < Cop + include SpecHelpers + + MESSAGE = "Don't assign to ENV, use `stub_env` instead.".freeze + + def_node_search :env_assignment?, <<~PATTERN + (send (const nil? :ENV) :[]= ...) + PATTERN + + # Following is what node.children looks like on a match + # [s(:const, nil, :ENV), :[]=, s(:str, "key"), s(:str, "value")] + def on_send(node) + return unless in_spec?(node) + return unless env_assignment?(node) + + add_offense(node, :expression, MESSAGE) + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.loc.expression, stub_env(env_key(node), env_value(node))) + end + end + + def env_key(node) + node.children[2].source + end + + def env_value(node) + node.children[3].source + end + + def stub_env(key, value) + "stub_env(#{key}, #{value})" + end + end + end + end +end diff --git a/rubocop/cop/rspec/verbose_include_metadata.rb b/rubocop/cop/rspec/verbose_include_metadata.rb new file mode 100644 index 00000000000..58390622d60 --- /dev/null +++ b/rubocop/cop/rspec/verbose_include_metadata.rb @@ -0,0 +1,74 @@ +# 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 diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index bb0d25f3c48..7db56349cd7 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -1,12 +1,14 @@ +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/active_record_serialize' -require_relative 'cop/redirect_with_status' +require_relative 'cop/in_batches' require_relative 'cop/polymorphic_associations' require_relative 'cop/project_path_helper' require_relative 'cop/active_record_dependent' require_relative 'cop/in_batches' require_relative 'cop/module_with_instance_variables' +require_relative 'cop/redirect_with_status' require_relative 'cop/migration/add_column' require_relative 'cop/migration/add_column_with_default_to_large_table' require_relative 'cop/migration/add_concurrent_foreign_key' @@ -14,11 +16,13 @@ require_relative 'cop/migration/add_concurrent_index' require_relative 'cop/migration/add_index' require_relative 'cop/migration/add_timestamps' require_relative 'cop/migration/datetime' -require_relative 'cop/migration/safer_boolean_column' require_relative 'cop/migration/hash_index' require_relative 'cop/migration/remove_concurrent_index' require_relative 'cop/migration/remove_index' require_relative 'cop/migration/reversible_add_column_with_default' +require_relative 'cop/migration/safer_boolean_column' require_relative 'cop/migration/timestamps' require_relative 'cop/migration/update_column_in_batches' +require_relative 'cop/rspec/env_assignment' require_relative 'cop/rspec/single_line_hook' +require_relative 'cop/rspec/verbose_include_metadata' diff --git a/rubocop/spec_helpers.rb b/rubocop/spec_helpers.rb new file mode 100644 index 00000000000..a702a083958 --- /dev/null +++ b/rubocop/spec_helpers.rb @@ -0,0 +1,12 @@ +module RuboCop + module SpecHelpers + SPEC_HELPERS = %w[spec_helper.rb rails_helper.rb].freeze + + # Returns true if the given node originated from the spec directory. + def in_spec?(node) + path = node.location.expression.source_buffer.name + + !SPEC_HELPERS.include?(File.basename(path)) && path.start_with?(File.join(Dir.pwd, 'spec')) + end + end +end |