Specs cleanup

This commit is contained in:
Sijawusz Pur Rahnama 2022-12-19 18:03:11 +01:00
parent e6ebca7a5b
commit 8112dddc8f
24 changed files with 267 additions and 251 deletions

View file

@ -10,29 +10,29 @@ module Ameba::AST
describe ".of" do
context "Crystal::If" do
it "constructs a branch in If.cond" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
if a = get_something # --> Crystal::Assign
puts a
end
end
)
CRYSTAL
branch.to_s.should eq "a = get_something"
end
it "constructs a branch in If.then" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
if true
a = 2 # --> Crystal::Assign
end
end
)
CRYSTAL
branch.to_s.should eq "a = 2"
end
it "constructs a branch in If.else" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
if true
nil
@ -40,45 +40,45 @@ module Ameba::AST
a = 2 # --> Crystal::Assign
end
end
)
CRYSTAL
branch.to_s.should eq "a = 2"
end
it "constructs a branch in inline If" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
a = 0 if a == 2 # --> Crystal::Assign
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
unless a = get_something # --> Crystal::Assign
puts a
end
end
)
CRYSTAL
branch.to_s.should eq "a = get_something"
end
it "constructs a branch in Unless.then" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
unless true
a = 2 # --> Crystal::Assign
end
end
)
CRYSTAL
branch.to_s.should eq "a = 2"
end
it "constructs a new branch in Unless.else" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method
unless true
nil
@ -86,188 +86,188 @@ module Ameba::AST
a = 2 # --> Crystal::Assign
end
end
)
CRYSTAL
branch.to_s.should eq "a = 2"
end
it "constructs a branch in inline Unless" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
(a = 0; b = 3) unless a == 2 # --> Crystal::Expressions
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
(a = 2) && do_something
end
)
CRYSTAL
branch.to_s.should eq "(a = 2)"
end
it "constructs a branch in right node" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
do_something || (a = 0)
end
)
CRYSTAL
branch.to_s.should eq "(a = 0)"
end
end
context "Crystal::Case" do
it "constructs a branch in cond" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
case (a = 2)
when true then nil
end
end
)
CRYSTAL
branch.to_s.should eq "(a = 2)"
end
it "constructs a branch in when" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
case a
when a = 3 then nil
end
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
case a
when true then nil
else a = 4
end
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
while a = 1
nil
end
end
)
CRYSTAL
branch.to_s.should eq "a = 1"
end
it "constructs a branch in body" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
while true
b = (a = 1)
end
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
until a = 1
nil
end
end
)
CRYSTAL
branch.to_s.should eq "a = 1"
end
it "constructs a branch in body" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
until false
b = (a = 1)
end
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
a = 1
rescue
nil
end
)
CRYSTAL
branch.to_s.should eq "a = 1"
end
it "constructs a branch in a rescue" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
rescue
a = 1
end
)
CRYSTAL
branch.to_s.should eq "a = 1"
end
it "constructs a branch in else" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
rescue
else
a = 1
end
)
CRYSTAL
branch.to_s.should eq "a = 1"
end
it "constructs a branch in ensure" do
branch = branch_of_assign_in_def %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
rescue
ensure
a = 1
end
)
CRYSTAL
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 %(
branch = branch_of_assign_in_def <<-CRYSTAL
def method(a)
{% if a = 2 %}
{% end %}
end
)
CRYSTAL
branch.to_s.should eq "a = 2"
end
it "constructs a branch in then" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a)
{% if true %}
a = 2
{% end %}
end
)
CRYSTAL
branch = Branch.of(nodes.macro_literal_nodes.first, nodes.def_nodes.first)
branch.to_s.strip.should eq "a = 2"
end
@ -275,24 +275,24 @@ module Ameba::AST
context "Crystal::MacroFor" do
it "constructs a branch in body" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a)
{% for x in [1, 2, 3] %}
a = 2
{% end %}
end
)
CRYSTAL
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 %(
nodes = as_nodes <<-CRYSTAL
def method
a = 2
end
)
CRYSTAL
branch = Branch.of(nodes.assign_nodes.first, nodes.def_nodes.first)
branch.should be_nil
end
@ -300,11 +300,11 @@ module Ameba::AST
describe "#initialize" do
it "creates new branch" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
if true
a = 2
end
)
CRYSTAL
branchable = Branchable.new nodes.if_nodes.first
branch = Branch.new nodes.assign_nodes.first, branchable
branch.node.should_not be_nil
@ -313,22 +313,22 @@ module Ameba::AST
describe "delegation" do
it "delegates to_s to node" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
if true
a = 2
end
)
CRYSTAL
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
it "delegates locations to node" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
if true
a = 2
end
)
CRYSTAL
branchable = Branchable.new nodes.if_nodes.first
branch = Branch.new nodes.assign_nodes.first, branchable
branch.location.should eq branch.node.location
@ -338,22 +338,22 @@ module Ameba::AST
describe "#in_loop?" do
it "returns true if branch is in a loop" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
while true
a = 1
end
)
CRYSTAL
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 %(
nodes = as_nodes <<-CRYSTAL
if a > 2
a = 1
end
)
CRYSTAL
branchable = Branchable.new nodes.if_nodes.first
branch = Branch.new nodes.assign_nodes.first, branchable
branch.in_loop?.should be_false

View file

@ -4,20 +4,20 @@ module Ameba::AST
describe Branchable do
describe "#initialize" do
it "creates a new branchable" do
branchable = Branchable.new as_node %(a = 2 if true)
branchable = Branchable.new as_node "a = 2 if true"
branchable.node.should_not be_nil
end
end
describe "delegation" do
it "delegates to_s to @node" do
node = as_node %(a = 2 if true)
node = as_node "a = 2 if true"
branchable = Branchable.new node
branchable.to_s.should eq node.to_s
end
it "delegates locations to @node" do
node = as_node %(a = 2 if true)
node = as_node "a = 2 if true"
branchable = Branchable.new node
branchable.location.should eq node.location
branchable.end_location.should eq node.end_location
@ -26,22 +26,22 @@ module Ameba::AST
describe "#loop?" do
it "returns true if it is a while loop" do
branchable = Branchable.new as_node %(while true; a = 2; end)
branchable = Branchable.new as_node "while true; a = 2; end"
branchable.loop?.should be_true
end
it "returns true if it is the until loop" do
branchable = Branchable.new as_node %(until false; a = 2; end)
branchable = Branchable.new as_node "until false; a = 2; end"
branchable.loop?.should be_true
end
it "returns true if it is loop" do
branchable = Branchable.new as_node %(loop {})
branchable = Branchable.new as_node "loop {}"
branchable.loop?.should be_true
end
it "returns false otherwise" do
branchable = Branchable.new as_node %(a = 2 if true)
branchable = Branchable.new as_node "a = 2 if true"
branchable.loop?.should be_false
end
end

View file

@ -18,7 +18,7 @@ module Ameba::AST
end
it "delegates locations to @node" do
node = as_node %(break if true)
node = as_node("break if true")
flow_expression = FlowExpression.new node, false
flow_expression.location.should eq node.location
flow_expression.end_location.should eq node.end_location
@ -27,20 +27,20 @@ module Ameba::AST
describe "#unreachable_nodes" do
it "returns unreachable nodes" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def foobar
return
a = 1
a = 2
end
)
CRYSTAL
node = nodes.expressions_nodes.first
flow_expression = FlowExpression.new node, false
flow_expression.unreachable_nodes.should eq nodes.assign_nodes
end
it "returns nil if there is no unreachable node after loop" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def run
idx = items.size - 1
while 0 <= idx
@ -49,19 +49,19 @@ module Ameba::AST
puts "foo"
end
)
CRYSTAL
node = nodes.expressions_nodes.first
flow_expression = FlowExpression.new node, false
flow_expression.unreachable_nodes.empty?.should eq true
end
it "returns nil if there is no unreachable node" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def foobar
a = 1
return a
end
)
CRYSTAL
node = nodes.expressions_nodes.first
flow_expression = FlowExpression.new node, false
flow_expression.unreachable_nodes.empty?.should eq true

View file

@ -49,14 +49,14 @@ module Ameba::AST
describe "#references?" do
it "returns true if current scope references variable" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method
a = 2
block do
3.times { |i| a = a + i }
end
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
var_node = nodes.var_nodes.first
scope.add_variable var_node
@ -69,14 +69,14 @@ module Ameba::AST
end
it "returns false if inner scopes are not checked" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method
a = 2
block do
3.times { |i| a = a + i }
end
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
var_node = nodes.var_nodes.first
scope.add_variable var_node
@ -89,7 +89,7 @@ module Ameba::AST
end
it "returns false if current scope does not reference variable" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method
a = 2
block do
@ -97,7 +97,7 @@ module Ameba::AST
3.times { |i| b = b + i }
end
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
var_node = nodes.var_nodes.first
scope.add_variable var_node
@ -150,57 +150,53 @@ module Ameba::AST
describe "#block?" do
it "returns true if Crystal::Block" do
nodes = as_nodes %(
3.times {}
)
nodes = as_nodes("3.times {}")
scope = Scope.new nodes.block_nodes.first
scope.block?.should be_true
end
it "returns false otherwise" do
scope = Scope.new as_node "a = 1"
scope = Scope.new as_node("a = 1")
scope.block?.should be_false
end
end
describe "#spawn_block?" do
it "returns true if a node is a spawn block" do
nodes = as_nodes %(
spawn {}
)
nodes = as_nodes("spawn {}")
scope = Scope.new nodes.block_nodes.first
scope.spawn_block?.should be_true
end
it "returns false otherwise" do
scope = Scope.new as_node "a = 1"
scope = Scope.new as_node("a = 1")
scope.spawn_block?.should be_false
end
end
describe "#in_macro?" do
it "returns true if Crystal::Macro" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
macro included
end
)
CRYSTAL
scope = Scope.new nodes.macro_nodes.first
scope.in_macro?.should be_true
end
it "returns true if node is nested to Crystal::Macro" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
macro included
{{ @type.each do |type| a = type end }}
end
)
CRYSTAL
outer_scope = Scope.new nodes.macro_nodes.first
scope = Scope.new nodes.block_nodes.first, outer_scope
scope.in_macro?.should be_true
end
it "returns false otherwise" do
scope = Scope.new as_node "a = 1"
scope = Scope.new as_node("a = 1")
scope.in_macro?.should be_false
end
end

View file

@ -41,15 +41,14 @@ module Ameba::AST
describe "#branch" do
it "returns the branch of the assignment" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a)
if a
a = 3 # --> Crystal::Expressions
puts a
end
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
variable = Variable.new(nodes.var_nodes.first, scope)
assignment = Assignment.new(nodes.assign_nodes.first, variable, scope)
@ -58,7 +57,7 @@ module Ameba::AST
end
it "returns inner branch" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a, b)
if a
if b
@ -66,7 +65,7 @@ module Ameba::AST
end
end
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
variable = Variable.new(nodes.var_nodes.first, scope)
assignment = Assignment.new(nodes.assign_nodes.first, variable, scope)
@ -75,12 +74,11 @@ module Ameba::AST
end
it "returns nil if assignment does not have a branch" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a)
a = 2
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
variable = Variable.new(nodes.var_nodes.first, scope)
assignment = Assignment.new(nodes.assign_nodes.first, variable, scope)
@ -90,12 +88,11 @@ module Ameba::AST
describe "#transformed?" do
it "returns false if the assignment is not transformed by the compiler" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method(a)
a = 2
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
variable = Variable.new(nodes.var_nodes.first, scope)
assignment = Assignment.new(nodes.assign_nodes.first, variable, scope)
@ -103,11 +100,10 @@ module Ameba::AST
end
it "returns true if the assignment is transformed by the compiler" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
array.each do |(a, b)|
end
)
CRYSTAL
scope = Scope.new nodes.block_nodes.first
variable = Variable.new(nodes.var_nodes.first, scope)
assignment = Assignment.new(nodes.assign_nodes.first, variable, scope)

View file

@ -79,12 +79,12 @@ module Ameba::AST
describe "#captured_by_block?" do
it "returns truthy if the variable is captured by block" do
nodes = as_nodes %(
nodes = as_nodes <<-CRYSTAL
def method
a = 2
3.times { |i| a = a + i }
end
)
CRYSTAL
scope = Scope.new nodes.def_nodes.first
var_node = nodes.var_nodes.first
scope.add_variable var_node
@ -95,12 +95,12 @@ module Ameba::AST
variable.captured_by_block?.should be_truthy
end
it "returns falsey if the variable is not captured by the block" do
scope = Scope.new as_node %(
it "returns falsy if the variable is not captured by the block" do
scope = Scope.new as_node <<-CRYSTAL
def method
a = 1
end
)
CRYSTAL
scope.add_variable Crystal::Var.new "a"
variable = scope.variables.first
variable.captured_by_block?.should be_falsey

View file

@ -19,33 +19,33 @@ module Ameba::AST
end
it "is 1 if there is Macro::For" do
code = %(
def initialize()
code = <<-CRYSTAL
def initialize
{% for c in ALL_NODES %}
true || false
{% end %}
end
)
CRYSTAL
node = Crystal::Parser.new(code).parse
visitor = CountingVisitor.new node
visitor.count.should eq 1
end
it "is 1 if there is Macro::If" do
code = %(
def initialize()
code = <<-CRYSTAL
def initialize
{% if foo.bar? %}
true || false
{% end %}
end
)
CRYSTAL
node = Crystal::Parser.new(code).parse
visitor = CountingVisitor.new node
visitor.count.should eq 1
end
it "increases count for every exhaustive case" do
code = %(
code = <<-CRYSTAL
def hello(a : Int32 | Int64 | Float32 | Float64)
case a
in Int32 then "int32"
@ -54,7 +54,7 @@ module Ameba::AST
in Float64 then "float64"
end
end
)
CRYSTAL
node = Crystal::Parser.new(code).parse
visitor = CountingVisitor.new node
visitor.count.should eq 2

View file

@ -6,17 +6,17 @@ module Ameba::AST
describe FlowExpressionVisitor do
it "creates an expression for return" do
rule = FlowExpressionRule.new
FlowExpressionVisitor.new rule, Source.new %(
FlowExpressionVisitor.new rule, Source.new <<-CRYSTAL
def foo
return :bar
end
)
CRYSTAL
rule.expressions.size.should eq 1
end
it "can create multiple expressions" do
rule = FlowExpressionRule.new
FlowExpressionVisitor.new rule, Source.new %(
FlowExpressionVisitor.new rule, Source.new <<-CRYSTAL
def foo
if bar
return :baz
@ -24,42 +24,42 @@ module Ameba::AST
return :foobar
end
end
)
CRYSTAL
rule.expressions.size.should eq 3
end
it "properly creates nested flow expressions" do
rule = FlowExpressionRule.new
FlowExpressionVisitor.new rule, Source.new %(
FlowExpressionVisitor.new rule, Source.new <<-CRYSTAL
def foo
return(
return (
loop do
break if a > 1
return a
end
)
end
)
CRYSTAL
rule.expressions.size.should eq 4
end
it "creates an expression for break" do
rule = FlowExpressionRule.new
FlowExpressionVisitor.new rule, Source.new %(
FlowExpressionVisitor.new rule, Source.new <<-CRYSTAL
while true
break
end
)
CRYSTAL
rule.expressions.size.should eq 1
end
it "creates an expression for next" do
rule = FlowExpressionRule.new
FlowExpressionVisitor.new rule, Source.new %(
FlowExpressionVisitor.new rule, Source.new <<-CRYSTAL
while true
next if something
end
)
CRYSTAL
rule.expressions.size.should eq 1
end
end

View file

@ -5,11 +5,11 @@ module Ameba::AST
rule = RedundantControlExpressionRule.new
describe RedundantControlExpressionVisitor do
node = as_node %(
node = as_node <<-CRYSTAL
a = 1
b = 2
return a + b
)
CRYSTAL
subject = RedundantControlExpressionVisitor.new(rule, source, node)
it "assigns valid attributes" do

View file

@ -4,37 +4,37 @@ module Ameba::AST
describe ScopeVisitor do
it "creates a scope for the def" do
rule = ScopeRule.new
ScopeVisitor.new rule, Source.new %(
ScopeVisitor.new rule, Source.new <<-CRYSTAL
def method
end
)
CRYSTAL
rule.scopes.size.should eq 1
end
it "creates a scope for the proc" do
rule = ScopeRule.new
ScopeVisitor.new rule, Source.new %(
ScopeVisitor.new rule, Source.new <<-CRYSTAL
-> {}
)
CRYSTAL
rule.scopes.size.should eq 1
end
it "creates a scope for the block" do
rule = ScopeRule.new
ScopeVisitor.new rule, Source.new %(
ScopeVisitor.new rule, Source.new <<-CRYSTAL
3.times {}
)
CRYSTAL
rule.scopes.size.should eq 2
end
context "inner scopes" do
it "creates scope for block inside def" do
rule = ScopeRule.new
ScopeVisitor.new rule, Source.new %(
ScopeVisitor.new rule, Source.new <<-CRYSTAL
def method
3.times {}
end
)
CRYSTAL
rule.scopes.size.should eq 2
rule.scopes.last.outer_scope.should_not be_nil
rule.scopes.first.outer_scope.should eq rule.scopes.last
@ -42,11 +42,11 @@ module Ameba::AST
it "creates scope for block inside block" do
rule = ScopeRule.new
ScopeVisitor.new rule, Source.new %(
ScopeVisitor.new rule, Source.new <<-CRYSTAL
3.times do
2.times {}
end
)
CRYSTAL
rule.scopes.size.should eq 3
inner_block = rule.scopes.first
outer_block = rule.scopes.last

View file

@ -4,10 +4,12 @@ module Ameba::AST
describe TopLevelNodesVisitor do
describe "#require_nodes" do
it "returns require node" do
source = Source.new %(
source = Source.new <<-CRYSTAL
require "foo"
def bar; end
)
def bar
end
CRYSTAL
visitor = TopLevelNodesVisitor.new(source.ast)
visitor.require_nodes.size.should eq 1
visitor.require_nodes.first.to_s.should eq %q(require "foo")