Skip to content

Commit

Permalink
Add struct_constructor?, class_definition? and module_definition? mat…
Browse files Browse the repository at this point in the history
…chers

Closes rubocop#28
  • Loading branch information
tejasbubane committed Jun 10, 2020
1 parent f496d2b commit f594100
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
* [#4](https://github.com/rubocop-hq/rubocop-ast/issues/4): Add `interpolation?` for `RegexpNode`. ([@tejasbubane][])
* [#20](https://github.com/rubocop-hq/rubocop-ast/pull/20): Add option predicates for `RegexpNode`. ([@owst][])
* [#11](https://github.com/rubocop-hq/rubocop-ast/issues/11): Add `argument_type?` method to make it easy to recognize argument nodes. ([@tejasbubane][])
* [#28](https://github.com/rubocop-hq/rubocop-ast/issues/28): Add `struct_constructor?`, `class_definition?` and `module_definition?` matchers. ([@tejasbubane][])

## 0.0.3 (2020-05-15)

Expand Down
14 changes: 14 additions & 0 deletions lib/rubocop/ast/node.rb
Expand Up @@ -497,6 +497,20 @@ def guard_clause?
(block (send (const nil? {:Class :Module}) :new ...) ...)}
PATTERN

def_node_matcher :struct_constructor?, <<~PATTERN
(block (send (const nil? :Struct) :new ...) ...)
PATTERN

def_node_matcher :class_definition?, <<~PATTERN
{(class (const nil? _) {nil? (const nil? _)} ...)
(casgn nil? _ (block (send (const nil? {:Struct :Class}) :new ...) ...))}
PATTERN

def_node_matcher :module_definition?, <<~PATTERN
{(module (const nil? _) ...)
(casgn nil? _ (block (send (const nil? :Module) :new ...) ...))}
PATTERN

# Some expressions are evaluated for their value, some for their side
# effects, and some for both
# If we know that an expression is useful only for its side effects, that
Expand Down
142 changes: 142 additions & 0 deletions spec/rubocop/ast/node_spec.rb
Expand Up @@ -373,4 +373,146 @@ def used?
end
end
end

describe '#class_constructor?' do
context 'class definition with a block' do
let(:src) { 'Class.new { a = 42 }' }

it 'matches' do
expect(node.class_constructor?).to eq(true)
end
end

context 'module definition with a block' do
let(:src) { 'Module.new { a = 42 }' }

it 'matches' do
expect(node.class_constructor?).to eq(true)
end
end

context 'class definition' do
let(:src) { 'class Foo; a = 42; end' }

it 'does not match' do
expect(node.class_constructor?).to eq(nil)
end
end
end

describe '#struct_constructor?' do
context 'struct definition with a block' do
let(:src) { 'Struct.new { a = 42 }' }

it 'matches' do
expect(node.struct_constructor?).to eq(true)
end
end

context 'struct definition without block' do
let(:src) { 'Struct.new(:foo, :bar)' }

it 'does not matches' do
expect(node.struct_constructor?).to eq(nil)
end
end
end

describe '#class_definition?' do
context 'without inheritance' do
let(:src) { 'class Foo; a = 42; end' }

it 'matches' do
expect(node.class_definition?).to eq(true)
end
end

context 'with inheritance' do
let(:src) { 'class Foo < Bar; a = 42; end' }

it 'matches' do
expect(node.class_definition?).to eq(true)
end
end

context 'with Struct' do
let(:src) do
<<~RUBY
Person = Struct.new(:name, :age) do
a = 2
def details; end
end
RUBY
end

it 'matches' do
expect(node.class_definition?).to eq(true)
end
end

context 'constant defined as Struct without block' do
let(:src) { 'Person = Struct.new(:name, :age)' }

it 'does not match' do
expect(node.class_definition?).to eq(nil)
end
end

context 'with Class.new' do
let(:src) do
<<~RUBY
Person = Class.new(:name, :age) do
a = 2
def details; end
end
RUBY
end

it 'matches' do
expect(node.class_definition?).to eq(true)
end
end
end

describe '#module_definition?' do
context 'using module keyword' do
let(:src) { 'module Foo; A = 42; end' }

it 'matches' do
expect(node.module_definition?).to eq(true)
end
end

context 'with Module.new' do
let(:src) do
<<~RUBY
Person = Module.new(:name, :age) do
a = 2
def details; end
end
RUBY
end

it 'matches' do
expect(node.module_definition?).to eq(true)
end
end

context 'nested modules' do
let(:src) do
<<~RUBY
module Foo
module Bar
BAZ = 2
def variables; end
end
end
RUBY
end

it 'matches' do
expect(node.module_definition?).to eq(true)
end
end
end
end

0 comments on commit f594100

Please sign in to comment.