Skip to content

Commit

Permalink
parse_source: allow direct targetting of a node
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre committed Sep 24, 2020
1 parent 0c89003 commit 746171c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 67 deletions.
95 changes: 29 additions & 66 deletions spec/rubocop/ast/send_node_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true

RSpec.describe RuboCop::AST::SendNode do
let(:send_node) { parse_source(source).ast }
let(:send_node) { parse_source(source).node }

describe '.new' do
context 'with a regular method send' do
Expand Down Expand Up @@ -94,13 +94,11 @@
end

describe '#access_modifier?' do
let(:send_node) { parse_source(source).ast.children[1] }

context 'when node is a bare `module_function`' do
let(:source) do
<<~RUBY
module Foo
module_function
>> module_function <<
end
RUBY
end
Expand All @@ -112,7 +110,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
module_function :foo
>> module_function :foo <<
end
RUBY
end
Expand All @@ -124,7 +122,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
some_command
>> some_command <<
end
RUBY
end
Expand All @@ -134,13 +132,11 @@ module Foo
end

describe '#bare_access_modifier?' do
let(:send_node) { parse_source(source).ast.children[1] }

context 'when node is a bare `module_function`' do
let(:source) do
<<~RUBY
module Foo
module_function
>> module_function <<
end
RUBY
end
Expand All @@ -152,7 +148,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
private :foo
>> private :foo <<
end
RUBY
end
Expand All @@ -164,7 +160,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
some_command
>> some_command <<
end
RUBY
end
Expand All @@ -174,13 +170,11 @@ module Foo
end

describe '#non_bare_access_modifier?' do
let(:send_node) { parse_source(source).ast.children[1] }

context 'when node is a non-bare `module_function`' do
let(:source) do
<<~RUBY
module Foo
module_function :foo
>> module_function :foo <<
end
RUBY
end
Expand All @@ -192,7 +186,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
private
>> private <<
end
RUBY
end
Expand All @@ -204,7 +198,7 @@ module Foo
let(:source) do
<<~RUBY
module Foo
some_command
>> some_command <<
end
RUBY
end
Expand All @@ -216,11 +210,9 @@ module Foo
describe '#macro?' do
context 'without a receiver' do
context 'when parent is a class' do
let(:send_node) { parse_source(source).ast.children[2].children[0] }

let(:source) do
['class Foo',
' bar :baz',
'>>bar :baz<<',
' bar :qux',
'end'].join("\n")
end
Expand All @@ -229,11 +221,9 @@ module Foo
end

context 'when parent is a module' do
let(:send_node) { parse_source(source).ast.children[1].children[0] }

let(:source) do
['module Foo',
' bar :baz',
'>>bar :baz<<',
' bar :qux',
'end'].join("\n")
end
Expand All @@ -242,11 +232,9 @@ module Foo
end

context 'when parent is a class constructor' do
let(:send_node) { parse_source(source).ast.children[2].children[0] }

let(:source) do
['Module.new do',
' bar :baz',
'>>bar :baz<<',
' bar :qux',
'end'].join("\n")
end
Expand All @@ -255,11 +243,9 @@ module Foo
end

context 'when parent is a singleton class' do
let(:send_node) { parse_source(source).ast.children[1].children[0] }

let(:source) do
['class << self',
' bar :baz',
'>>bar :baz<<',
' bar :qux',
'end'].join("\n")
end
Expand All @@ -268,11 +254,9 @@ module Foo
end

context 'when parent is a block' do
let(:send_node) { parse_source(source).ast.children[2].children[0] }

let(:source) do
['concern :Auth do',
' bar :baz',
'>>bar :baz<<',
' bar :qux',
'end'].join("\n")
end
Expand All @@ -281,12 +265,10 @@ module Foo
end

context 'when parent is a keyword begin inside of an class' do
let(:send_node) { parse_source(source).ast.children[2].children[0] }

let(:source) do
['class Foo',
' begin',
' bar :qux',
'>> bar :qux <<',
' end',
'end'].join("\n")
end
Expand All @@ -301,23 +283,19 @@ module Foo
end

context 'when parent is a begin without a parent' do
let(:send_node) { parse_source(source).ast.children[0] }

let(:source) do
['begin',
' bar :qux',
'>>bar :qux<<',
'end'].join("\n")
end

it { expect(send_node.macro?).to be_truthy }
end

context 'when parent is a method definition' do
let(:send_node) { parse_source(source).ast.children[2] }

let(:source) do
['def foo',
' bar :baz',
'>>bar :baz<<',
'end'].join("\n")
end

Expand All @@ -327,23 +305,19 @@ module Foo

context 'with a receiver' do
context 'when parent is a class' do
let(:send_node) { parse_source(source).ast.children[2] }

let(:source) do
['class Foo',
' qux.bar :baz',
' >> qux.bar :baz <<',
'end'].join("\n")
end

it { expect(send_node.macro?).to be_falsey }
end

context 'when parent is a module' do
let(:send_node) { parse_source(source).ast.children[1] }

let(:source) do
['module Foo',
' qux.bar :baz',
' >> qux.bar :baz << ',
'end'].join("\n")
end

Expand Down Expand Up @@ -760,8 +734,7 @@ module Foo

describe '#enumerable_method?' do
context 'with an enumerable method' do
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { 'foo.all? { |e| bar?(e) }' }
let(:source) { '>> foo.all? << { |e| bar?(e) }' }

it { expect(send_node.enumerable_method?).to be_truthy }
end
Expand Down Expand Up @@ -992,9 +965,7 @@ module Foo

describe '#block_literal?' do
context 'with a block literal' do
let(:send_node) { parse_source(source).ast.children[0] }

let(:source) { 'foo.bar { |q| baz(q) }' }
let(:source) { '>> foo.bar << { |q| baz(q) }' }

it { expect(send_node.block_literal?).to be_truthy }
end
Expand Down Expand Up @@ -1034,9 +1005,7 @@ module Foo

describe '#block_node' do
context 'with a block literal' do
let(:send_node) { parse_source(source).ast.children[0] }

let(:source) { 'foo.bar { |q| baz(q) }' }
let(:source) { '>>foo.bar<< { |q| baz(q) }' }

it { expect(send_node.block_node.block_type?).to be(true) }
end
Expand Down Expand Up @@ -1162,22 +1131,19 @@ module Foo

describe '#lambda?' do
context 'with a lambda method' do
let(:source) { 'lambda { |foo| bar(foo) }' }
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { '>> lambda << { |foo| bar(foo) }' }

it { expect(send_node.lambda?).to be_truthy }
end

context 'with a method named lambda in a class' do
let(:source) { 'foo.lambda { |bar| baz }' }
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { '>> foo.lambda << { |bar| baz }' }

it { expect(send_node.lambda?).to be_falsey }
end

context 'with a stabby lambda method' do
let(:source) { '-> (foo) { do_something(foo) }' }
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { '>> -> << (foo) { do_something(foo) }' }

it { expect(send_node.lambda?).to be_truthy }
end
Expand All @@ -1191,15 +1157,13 @@ module Foo

describe '#lambda_literal?' do
context 'with a stabby lambda' do
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { '-> (foo) { do_something(foo) }' }
let(:source) { '>> -> << (foo) { do_something(foo) }' }

it { expect(send_node.lambda_literal?).to be(true) }
end

context 'with a lambda method' do
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { 'lambda { |foo| bar(foo) }' }
let(:source) { '>> lambda << { |foo| bar(foo) }' }

it { expect(send_node.lambda_literal?).to be(false) }
end
Expand All @@ -1212,8 +1176,7 @@ module Foo

# Regression test https://github.com/rubocop-hq/rubocop/pull/5194
context 'with `a.() {}` style method' do
let(:send_node) { parse_source(source).ast.send_node }
let(:source) { 'a.() {}' }
let(:source) { '>>a.()<< {}' }

it { expect(send_node.lambda?).to be_falsey }
end
Expand Down
21 changes: 20 additions & 1 deletion spec/spec_helper.rb
Expand Up @@ -41,10 +41,29 @@ module DefaultRubyVersion
let(:ruby_version) { 2.4 }
end

module RuboCop
module AST
# patch class
class ProcessedSource
attr_accessor :node
end
end
end

# ...
module ParseSourceHelper
def parse_source(source)
RuboCop::AST::ProcessedSource.new(source, ruby_version, nil)
lookup = nil
ruby = source.gsub(/>>(.*)<</) { lookup = Regexp.last_match(1).strip }
source = RuboCop::AST::ProcessedSource.new(ruby, ruby_version, nil)
source.node = if lookup
source.ast.each_node.find(
-> { raise "No node corresponds to source '#{lookup}'" }
) { |node| node.source == lookup }
else
source.ast
end
source
end
end

Expand Down

0 comments on commit 746171c

Please sign in to comment.