2018-05-03 15:57:47 +00:00
|
|
|
require "../../spec_helper"
|
|
|
|
|
|
|
|
private def branch_of_assign_in_def(source)
|
|
|
|
nodes = as_nodes source
|
|
|
|
Ameba::AST::Branch.of(nodes.assign_nodes.first, nodes.def_nodes.first)
|
|
|
|
end
|
|
|
|
|
|
|
|
module Ameba::AST
|
|
|
|
describe Branch do
|
|
|
|
describe ".of" do
|
|
|
|
context "Crystal::If" do
|
|
|
|
it "constructs a branch in If.cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
if a = get_something # --> Crystal::Assign
|
|
|
|
puts a
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = get_something"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in If.then" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
if true
|
|
|
|
a = 2 # --> Crystal::Assign
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 2"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in If.else" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
if true
|
|
|
|
nil
|
|
|
|
else
|
|
|
|
a = 2 # --> Crystal::Assign
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 2"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in inline If" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
a = 0 if a == 2 # --> Crystal::Assign
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 0"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::Unless" do
|
|
|
|
it "constructs a branch in Unless.cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
unless a = get_something # --> Crystal::Assign
|
|
|
|
puts a
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = get_something"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in Unless.then" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
unless true
|
|
|
|
a = 2 # --> Crystal::Assign
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 2"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a new branch in Unless.else" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method
|
|
|
|
unless true
|
|
|
|
nil
|
|
|
|
else
|
|
|
|
a = 2 # --> Crystal::Assign
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 2"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in inline Unless" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
(a = 0; b = 3) unless a == 2 # --> Crystal::Expressions
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "(a = 0\nb = 3)"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::BinaryOp" do
|
|
|
|
it "constructs a branch in left node" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
(a = 2) && do_something
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "(a = 2)"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in right node" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
do_something || (a = 0)
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "(a = 0)"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::Case" do
|
2018-05-08 19:18:15 +00:00
|
|
|
it "constructs a branch in cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
case (a = 2)
|
|
|
|
when true then nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "(a = 2)"
|
|
|
|
end
|
2018-05-03 15:57:47 +00:00
|
|
|
|
|
|
|
it "constructs a branch in when" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
case a
|
|
|
|
when a = 3 then nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "when a = 3\n nil\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in else" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
case a
|
|
|
|
when true then nil
|
|
|
|
else a = 4
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 4"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::While" do
|
|
|
|
it "constructs a branch in cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
while a = 1
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in body" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
while true
|
|
|
|
b = (a = 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "b = (a = 1)"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::Until" do
|
|
|
|
it "constructs a branch in cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
until a = 1
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in body" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
until false
|
|
|
|
b = (a = 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "b = (a = 1)"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::ExceptionHandler" do
|
|
|
|
it "constructs a branch in body" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
a = 1
|
|
|
|
rescue
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in a rescue" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
rescue
|
|
|
|
a = 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in else" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
rescue
|
|
|
|
else
|
|
|
|
a = 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in ensure" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
rescue
|
|
|
|
ensure
|
|
|
|
a = 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 1"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::MacroIf" do
|
|
|
|
it "constructs a branch in cond" do
|
|
|
|
branch = branch_of_assign_in_def %(
|
|
|
|
def method(a)
|
|
|
|
{% if a = 2 %}
|
|
|
|
{% end %}
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch.to_s.should eq "a = 2"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "constructs a branch in then" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
def method(a)
|
|
|
|
{% if true %}
|
|
|
|
a = 2
|
|
|
|
{% end %}
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch = Branch.of(nodes.macro_literal_nodes.first, nodes.def_nodes.first)
|
|
|
|
branch.to_s.strip.should eq "a = 2"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "Crystal::MacroFor" do
|
|
|
|
it "constructs a branch in body" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
def method(a)
|
|
|
|
{% for x in [1, 2, 3] %}
|
|
|
|
a = 2
|
|
|
|
{% end %}
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch = Branch.of(nodes.macro_literal_nodes.first, nodes.def_nodes.first)
|
|
|
|
branch.to_s.strip.should eq "a = 2"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil if branch does not exist" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
def method
|
|
|
|
a = 2
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branch = Branch.of(nodes.assign_nodes.first, nodes.def_nodes.first)
|
|
|
|
branch.should be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#initialize" do
|
|
|
|
it "creates new branch" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
if true
|
|
|
|
a = 2
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branchable = Branchable.new nodes.if_nodes.first
|
|
|
|
branch = Branch.new nodes.assign_nodes.first, branchable
|
|
|
|
branch.node.should_not be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "delegation" do
|
|
|
|
it "delegates to_s to node" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
if true
|
|
|
|
a = 2
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branchable = Branchable.new nodes.if_nodes.first
|
|
|
|
branch = Branch.new nodes.assign_nodes.first, branchable
|
|
|
|
branch.to_s.should eq branch.node.to_s
|
|
|
|
end
|
|
|
|
|
2018-11-24 17:38:13 +00:00
|
|
|
it "delegates locations to node" do
|
2018-05-03 15:57:47 +00:00
|
|
|
nodes = as_nodes %(
|
|
|
|
if true
|
|
|
|
a = 2
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branchable = Branchable.new nodes.if_nodes.first
|
|
|
|
branch = Branch.new nodes.assign_nodes.first, branchable
|
|
|
|
branch.location.should eq branch.node.location
|
2018-11-24 17:38:13 +00:00
|
|
|
branch.end_location.should eq branch.node.end_location
|
2018-05-03 15:57:47 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#in_loop?" do
|
|
|
|
it "returns true if branch is in a loop" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
while true
|
|
|
|
a = 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branchable = Branchable.new nodes.while_nodes.first
|
|
|
|
branch = Branch.new nodes.assign_nodes.first, branchable
|
|
|
|
branch.in_loop?.should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns false if branch is not in a loop" do
|
|
|
|
nodes = as_nodes %(
|
|
|
|
if a > 2
|
|
|
|
a = 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
branchable = Branchable.new nodes.if_nodes.first
|
|
|
|
branch = Branch.new nodes.assign_nodes.first, branchable
|
|
|
|
branch.in_loop?.should be_false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|