From 9722158c15300dd4507cbb49b4230ab36b36ae65 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 16 Jan 2019 15:21:50 +0100 Subject: [PATCH] Fix detecting nested EE constants in RuboCop The InjectEnterpriseEditionModule cop would not detect certain nested EE constants such as `EE::Foo::Bar::Baz`. This could result in it not enforcing `prepend` being placed on the last line. This commit fixes this by just performing a string match on the line, instead of relying on AST matching. --- .../cop/inject_enterprise_edition_module.rb | 10 ++++-- .../inject_enterprise_edition_module_spec.rb | 35 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb index c8b8aca51ab6..1d37b1bd12d4 100644 --- a/rubocop/cop/inject_enterprise_edition_module.rb +++ b/rubocop/cop/inject_enterprise_edition_module.rb @@ -11,9 +11,13 @@ class InjectEnterpriseEditionModule < RuboCop::Cop::Cop METHODS = Set.new(%i[include extend prepend]).freeze - def_node_matcher :ee_const?, <<~PATTERN - (const (const _ :EE) _) - PATTERN + 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::/) + end def on_send(node) return unless METHODS.include?(node.children[1]) diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb index 08ffc3c3a530..0ff777388e5f 100644 --- a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb +++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb @@ -19,6 +19,41 @@ class Foo SOURCE end + it 'does not flag the use of `prepend EEFoo` in the middle of a file' do + expect_no_offenses(<<~SOURCE) + class Foo + prepend EEFoo + end + SOURCE + end + + it 'flags the use of `prepend EE::Foo::Bar` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend EE::Foo::Bar + ^^^^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `prepend(EE::Foo::Bar)` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend(EE::Foo::Bar) + ^^^^^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `prepend EE::Foo::Bar::Baz` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend EE::Foo::Bar::Baz + ^^^^^^^^^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + it 'flags the use of `prepend ::EE` in the middle of a file' do expect_offense(<<~SOURCE) class Foo