From bd88c07e7e043b1591210e3b2634ccc47e08a2cc Mon Sep 17 00:00:00 2001 From: John Backus Date: Mon, 19 Dec 2016 19:02:59 -0800 Subject: [PATCH] Add SelectorSet#send_pattern and #block_pattern Resolves duplicated pattern definitions of the formats (block (send _ #{SELECTOR_SET.node_pattern_union})) and (send _ #{SELECTOR_SET.node_pattern_union}) --- lib/rubocop/cop/rspec/described_class.rb | 7 ++----- lib/rubocop/cop/rspec/empty_example_group.rb | 2 +- lib/rubocop/cop/rspec/focus.rb | 5 +---- lib/rubocop/cop/rspec/instance_variable.rb | 4 +--- lib/rubocop/cop/rspec/multiple_expectations.rb | 4 +--- lib/rubocop/cop/rspec/nested_groups.rb | 4 +--- lib/rubocop/rspec/language.rb | 12 ++++++++++-- lib/rubocop/rspec/language/node_pattern.rb | 4 +--- spec/rubocop/rspec/language/selector_set_spec.rb | 14 ++++++++++++++ 9 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lib/rubocop/cop/rspec/described_class.rb b/lib/rubocop/cop/rspec/described_class.rb index 406a1e150..c68a5d033 100644 --- a/lib/rubocop/cop/rspec/described_class.rb +++ b/lib/rubocop/cop/rspec/described_class.rb @@ -25,15 +25,12 @@ class DescribedClass < Cop DESCRIBED_CLASS = 'described_class'.freeze MSG = "Use `#{DESCRIBED_CLASS}` instead of `%s`".freeze - RSPEC_BLOCK_METHODS = RuboCop::RSpec::Language::ALL.node_pattern_union - def_node_matcher :common_instance_exec_closure?, <<-PATTERN (block (send (const nil {:Class :Module}) :new ...) ...) PATTERN - def_node_matcher :rspec_block?, <<-PATTERN - (block (send nil #{RSPEC_BLOCK_METHODS} ...) ...) - PATTERN + def_node_matcher :rspec_block?, + RuboCop::RSpec::Language::ALL.block_pattern def_node_matcher :scope_changing_syntax?, '{def class module}' diff --git a/lib/rubocop/cop/rspec/empty_example_group.rb b/lib/rubocop/cop/rspec/empty_example_group.rb index 49d749524..075b3de78 100644 --- a/lib/rubocop/cop/rspec/empty_example_group.rb +++ b/lib/rubocop/cop/rspec/empty_example_group.rb @@ -62,7 +62,7 @@ class EmptyExampleGroup < Cop def_node_search :contains_example?, <<-PATTERN { - (send _ #{(Examples::ALL + Includes::ALL).node_pattern_union} ...) + #{(Examples::ALL + Includes::ALL).send_pattern} (send _ #custom_include? ...) } PATTERN diff --git a/lib/rubocop/cop/rspec/focus.rb b/lib/rubocop/cop/rspec/focus.rb index 8b190956c..81aa39eaf 100644 --- a/lib/rubocop/cop/rspec/focus.rb +++ b/lib/rubocop/cop/rspec/focus.rb @@ -31,7 +31,6 @@ class Focus < Cop focused = ExampleGroups::FOCUSED + Examples::FOCUSED FOCUSABLE_SELECTORS = focusable.node_pattern_union - FOCUSING_SELECTORS = focused.node_pattern_union FOCUS_SYMBOL = s(:sym, :focus) FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true)) @@ -41,9 +40,7 @@ class Focus < Cop (send nil #{FOCUSABLE_SELECTORS} $...)} PATTERN - def_node_matcher :focused_block?, <<-PATTERN - (send nil #{FOCUSING_SELECTORS} ...) - PATTERN + def_node_matcher :focused_block?, focused.send_pattern def on_send(node) focus_metadata(node) do |focus| diff --git a/lib/rubocop/cop/rspec/instance_variable.rb b/lib/rubocop/cop/rspec/instance_variable.rb index bb3c2f5ec..fc10c8fba 100644 --- a/lib/rubocop/cop/rspec/instance_variable.rb +++ b/lib/rubocop/cop/rspec/instance_variable.rb @@ -51,9 +51,7 @@ class InstanceVariable < Cop EXAMPLE_GROUP_METHODS = ExampleGroups::ALL + SharedGroups::ALL - def_node_matcher :spec_group?, <<-PATTERN - (block (send _ #{EXAMPLE_GROUP_METHODS.node_pattern_union} ...) ...) - PATTERN + def_node_matcher :spec_group?, EXAMPLE_GROUP_METHODS.block_pattern def_node_search :ivar_usage, '$(ivar $_)' diff --git a/lib/rubocop/cop/rspec/multiple_expectations.rb b/lib/rubocop/cop/rspec/multiple_expectations.rb index 2d45fa817..873b04221 100644 --- a/lib/rubocop/cop/rspec/multiple_expectations.rb +++ b/lib/rubocop/cop/rspec/multiple_expectations.rb @@ -50,9 +50,7 @@ class MultipleExpectations < Cop MSG = 'Too many expectations.'.freeze - def_node_matcher :example?, <<-PATTERN - (block (send _ #{Examples::ALL.node_pattern_union} ...) ...) - PATTERN + def_node_matcher :example?, Examples::ALL.block_pattern def_node_search :expect, '(send _ :expect ...)' diff --git a/lib/rubocop/cop/rspec/nested_groups.rb b/lib/rubocop/cop/rspec/nested_groups.rb index a5511042a..fb246661a 100644 --- a/lib/rubocop/cop/rspec/nested_groups.rb +++ b/lib/rubocop/cop/rspec/nested_groups.rb @@ -89,9 +89,7 @@ class NestedGroups < Cop MSG = 'Maximum example group nesting exceeded'.freeze - def_node_search :find_contexts, <<-PATTERN - (block (send nil #{ExampleGroups::ALL.node_pattern_union} ...) (args) ...) - PATTERN + def_node_search :find_contexts, ExampleGroups::ALL.block_pattern def on_block(node) describe, = described_constant(node) diff --git a/lib/rubocop/rspec/language.rb b/lib/rubocop/rspec/language.rb index 9282871a7..0301a22a9 100644 --- a/lib/rubocop/rspec/language.rb +++ b/lib/rubocop/rspec/language.rb @@ -22,14 +22,22 @@ def include?(selector) selectors.include?(selector) end - def node_pattern - selectors.map(&:inspect).join(' ') + def block_pattern + "(block #{send_pattern} ...)" + end + + def send_pattern + "(send _ #{node_pattern_union} ...)" end def node_pattern_union "{#{node_pattern}}" end + def node_pattern + selectors.map(&:inspect).join(' ') + end + protected attr_reader :selectors diff --git a/lib/rubocop/rspec/language/node_pattern.rb b/lib/rubocop/rspec/language/node_pattern.rb index 00d1adbae..67f08c547 100644 --- a/lib/rubocop/rspec/language/node_pattern.rb +++ b/lib/rubocop/rspec/language/node_pattern.rb @@ -7,9 +7,7 @@ module Language module NodePattern extend RuboCop::NodePattern::Macros - def_node_matcher :example_group?, <<-PATTERN - (block (send _ #{ExampleGroups::ALL.node_pattern_union} ...) ...) - PATTERN + def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern end end end diff --git a/spec/rubocop/rspec/language/selector_set_spec.rb b/spec/rubocop/rspec/language/selector_set_spec.rb index a5a79e757..a0cefdd8e 100644 --- a/spec/rubocop/rspec/language/selector_set_spec.rb +++ b/spec/rubocop/rspec/language/selector_set_spec.rb @@ -32,4 +32,18 @@ expect(selector_set.node_pattern_union).to eql('{:foo :bar}') end end + + context '#send_pattern' do + it 'builds a send matching pattern' do + expect(selector_set.send_pattern).to eql('(send _ {:foo :bar} ...)') + end + end + + context '#block_pattern' do + it 'builds a block matching pattern' do + expect(selector_set.block_pattern).to eql( + '(block (send _ {:foo :bar} ...) ...)' + ) + end + end end