diff options
Diffstat (limited to 'rubocop')
-rw-r--r-- | rubocop/cop/inject_enterprise_edition_module.rb | 48 | ||||
-rw-r--r-- | rubocop/cop/rspec/top_level_describe_path.rb | 35 | ||||
-rw-r--r-- | rubocop/rubocop.rb | 1 |
3 files changed, 77 insertions, 7 deletions
diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb index 1d37b1bd12d..e0e1b2d6c7d 100644 --- a/rubocop/cop/inject_enterprise_edition_module.rb +++ b/rubocop/cop/inject_enterprise_edition_module.rb @@ -6,23 +6,39 @@ module RuboCop # the last line of a file. Injecting a module in the middle of a file will # cause merge conflicts, while placing it on the last line will not. class InjectEnterpriseEditionModule < RuboCop::Cop::Cop - MSG = 'Injecting EE modules must be done on the last line of this file' \ - ', outside of any class or module definitions' + INVALID_LINE = 'Injecting EE modules must be done on the last line of this file' \ + ', outside of any class or module definitions' - METHODS = Set.new(%i[include extend prepend]).freeze + DISALLOWED_METHOD = + 'EE modules must be injected using `include_if_ee`, `extend_if_ee`, or `prepend_if_ee`' + + INVALID_ARGUMENT = 'EE modules to inject must be specified as a String' + + CHECK_LINE_METHODS = + Set.new(%i[include_if_ee extend_if_ee prepend_if_ee]).freeze + + DISALLOW_METHODS = Set.new(%i[include extend prepend]).freeze def ee_const?(node) line = node.location.expression.source_line # We use `match?` here instead of RuboCop's AST matching, as this makes # it far easier to handle nested constants such as `EE::Foo::Bar::Baz`. - line.match?(/(\s|\()(::)?EE::/) + line.match?(/(\s|\()('|")?(::)?EE::/) end def on_send(node) - return unless METHODS.include?(node.children[1]) - return unless ee_const?(node.children[2]) + return unless check_method?(node) + if DISALLOW_METHODS.include?(node.children[1]) + add_offense(node, message: DISALLOWED_METHOD) + else + verify_line_number(node) + verify_argument_type(node) + end + end + + def verify_line_number(node) line = node.location.line buffer = node.location.expression.source_buffer last_line = buffer.last_line @@ -32,7 +48,25 @@ module RuboCop # the expression is the last line _of code_. last_line -= 1 if buffer.source.end_with?("\n") - add_offense(node) if line < last_line + add_offense(node, message: INVALID_LINE) if line < last_line + end + + def verify_argument_type(node) + argument = node.children[2] + + return if argument.str_type? + + add_offense(argument, message: INVALID_ARGUMENT) + end + + def check_method?(node) + name = node.children[1] + + if CHECK_LINE_METHODS.include?(name) || DISALLOW_METHODS.include?(name) + ee_const?(node.children[2]) + else + false + end end # Automatically correcting these offenses is not always possible, as diff --git a/rubocop/cop/rspec/top_level_describe_path.rb b/rubocop/cop/rspec/top_level_describe_path.rb new file mode 100644 index 00000000000..61796e23af0 --- /dev/null +++ b/rubocop/cop/rspec/top_level_describe_path.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rubocop/rspec/top_level_describe' + +module RuboCop + module Cop + module RSpec + class TopLevelDescribePath < RuboCop::Cop::Cop + include RuboCop::RSpec::TopLevelDescribe + + MESSAGE = 'A file with a top-level `describe` must end in _spec.rb.' + SHARED_EXAMPLES = %i[shared_examples shared_examples_for].freeze + + def on_top_level_describe(node, args) + return if acceptable_file_path?(processed_source.buffer.name) + return if shared_example?(node) + + add_offense(node, message: MESSAGE) + end + + private + + def acceptable_file_path?(path) + File.fnmatch?('*_spec.rb', path) || File.fnmatch?('*/frontend/fixtures/*', path) + end + + def shared_example?(node) + node.ancestors.any? do |node| + node.respond_to?(:method_name) && SHARED_EXAMPLES.include?(node.method_name) + end + end + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index ba61a634d97..58a7ead6f13 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -32,6 +32,7 @@ require_relative 'cop/migration/update_large_table' require_relative 'cop/project_path_helper' require_relative 'cop/rspec/env_assignment' require_relative 'cop/rspec/factories_in_migration_specs' +require_relative 'cop/rspec/top_level_describe_path' require_relative 'cop/qa/element_with_pattern' require_relative 'cop/sidekiq_options_queue' require_relative 'cop/destroy_all' |