Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CaseNode#branches #87

Merged
merged 2 commits into from Aug 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@
* [#83](https://github.com/rubocop-hq/rubocop-ast/pull/83): Add `ProcessedSource#comment_at_line` ([@marcandre][])
* [#83](https://github.com/rubocop-hq/rubocop-ast/pull/83): Add `ProcessedSource#each_comment_in_lines` ([@marcandre][])
* [#84](https://github.com/rubocop-hq/rubocop-ast/pull/84): Add `Source::Range#line_span` ([@marcandre][])
* [#87](https://github.com/rubocop-hq/rubocop-ast/pull/87): Add `CaseNode#branches` ([@marcandre][])

### Bug fixes

Expand All @@ -20,6 +21,7 @@

* [#44](https://github.com/rubocop-hq/rubocop-ast/issue/44): **(Breaking)** Use `parser` flag `self.emit_forward_arg = true` by default. ([@marcandre][])
* [#86](https://github.com/rubocop-hq/rubocop-ast/pull/86): `PairNode#delimiter` and `inverse_delimiter` now accept their argument as a named argument. ([@marcandre][])
* [#87](https://github.com/rubocop-hq/rubocop-ast/pull/87): **(Potentially breaking)** Have `IfNode#branches` return a `nil` value if source has `else; end` ([@marcandre][])

## 0.2.0 (2020-07-19)

Expand Down
10 changes: 10 additions & 0 deletions lib/rubocop/ast/node/case_node.rb
Expand Up @@ -31,6 +31,16 @@ def when_branches
node_parts[1...-1]
end

# Returns an array of all the when branches in the `case` statement.
#
# @return [Array<Node, nil>] an array of the bodies of the when branches
# and the else (if any). Note that these bodies could be nil.
def branches
bodies = when_branches.map(&:body)
bodies.push(else_branch) if else?
bodies
end

# Returns the else branch of the `case` statement, if any.
#
# @return [Node] the else branch node of the `case` statement
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/ast/node/if_node.rb
Expand Up @@ -147,7 +147,7 @@ def node_parts
def branches
branches = [if_branch]

return branches unless else_branch
return branches unless else?

other_branches = if elsif_conditional?
else_branch.branches
Expand Down
68 changes: 67 additions & 1 deletion spec/rubocop/ast/case_node_spec.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true

RSpec.describe RuboCop::AST::CaseNode do
let(:case_node) { parse_source(source).ast }
let(:ast) { parse_source(source).ast }
let(:case_node) { ast }

describe '.new' do
let(:source) do
Expand Down Expand Up @@ -104,4 +105,69 @@
end
end
end

describe '#branches' do
context 'when there is an else' do
let(:source) { <<~RUBY }
case
when :foo then # do nothing
when :bar then 42
else 'hello'
end
RUBY

it 'returns all the bodies' do
expect(case_node.branches).to match [nil, be_int_type, be_str_type]
end

context 'with an empty else' do
let(:source) { <<~RUBY }
case
when :foo then # do nothing
when :bar then 42
else # do nothing
end
RUBY

it 'returns all the bodies' do
expect(case_node.branches).to match [nil, be_int_type, nil]
end
end
end

context 'when there is no else keyword' do
let(:source) { <<~RUBY }
case
when :foo then # do nothing
when :bar then 42
end
RUBY

it 'returns only then when bodies' do
expect(case_node.branches).to match [nil, be_int_type]
end
end

context 'when compared to an IfNode' do
let(:source) { <<~RUBY }
case
when foo then 1
when bar then 2
else
end

if foo then 1
elsif bar then 2
else
end
RUBY

let(:case_node) { ast.children.first }
let(:if_node) { ast.children.last }

it 'returns the same' do
expect(case_node.branches).to eq if_node.branches
end
end
end
end