Newer
Older
#!/usr/bin/env bin/crystal --run
require "../../spec_helper"
describe "Code gen: macro" do
it "expands macro" do
run("macro foo; 1 + 2; end; foo").to_i.should eq(3)
end
it "expands macro with arguments" do
run(%(
macro foo(n)
{{n}} + 2
end
foo(1)
)).to_i.should eq(3)
end
it "expands macro that invokes another macro" do
run(%(
macro foo
def x
1 + 2
end
end
macro bar
foo
end
bar
x
)).to_i.should eq(3)
end
it "expands macro defined in class" do
foo
end
foo = Foo.new
foo.bar
end
it "expands macro defined in base class" do
end
class Foo
foo
end
foo = Foo.new
foo.bar
it "expands inline macro" do
run(%(
a = {{ 1 }}
a
)).to_i.should eq(1)
end
it "expands inline macro for" do
run(%(
a = 0
{% for i in [1, 2, 3] %}
{% end %}
a
)).to_i.should eq(6)
end
it "expands inline macro if (true)" do
run(%(
a = 0
{% if 1 == 1 %}
{% end %}
a
)).to_i.should eq(1)
end
it "expands inline macro if (false)" do
run(%(
a = 0
{% if 1 == 2 %}
{% end %}
it "finds macro in class" do
run(%(
class Foo
macro foo
1 + 2
end
def bar
foo
end
end
Foo.new.bar
)).to_i.should eq(3)
end
Ary Borenszweig
committed
it "expands def macro" do
run(%(
def bar_baz
1
end
def foo : Int32
Ary Borenszweig
committed
bar_{{ "baz".id }}
Ary Borenszweig
committed
end
foo
)).to_i.should eq(1)
end
it "expands def macro with var" do
run(%(
def foo : Int32
a = {{ 1 }}
end
foo
)).to_i.should eq(1)
end
Ary Borenszweig
committed
it "expands def macro with @instance_vars" do
run(%(
class Foo
def initialize(@x)
end
def to_s : String
{{ @instance_vars.first.stringify }}
end
end
foo = Foo.new(1)
foo.to_s
)).to_string.should eq("@x")
end
Ary Borenszweig
committed
it "expands def macro with @instance_vars with subclass" do
run(%(
class Reference
def to_s : String
{{ @instance_vars.last.stringify }}
end
end
class Foo
def initialize(@x)
end
end
class Bar < Foo
def initialize(@x, @y)
end
end
Bar.new(1, 2).to_s
)).to_string.should eq("@y")
end
it "expands def macro with @instance_vars with hierarchy" do
Ary Borenszweig
committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
run(%(
class Reference
def to_s : String
{{ @instance_vars.last.stringify }}
end
end
class Foo
def initialize(@x)
end
end
class Bar < Foo
def initialize(@x, @y)
end
end
(Bar.new(1, 2) || Foo.new(1)).to_s
)).to_string.should eq("@y")
end
it "expands def macro with @name" do
run(%(
class Foo
def initialize(@x)
end
def to_s : String
Ary Borenszweig
committed
{{@name}}
Ary Borenszweig
committed
end
end
foo = Foo.new(1)
foo.to_s
)).to_string.should eq("Foo")
end
it "expands macro and resolves type correctly" do
run(%(
class Foo
def foo : Int32
1
end
end
class Bar < Foo
Int32 = 2
end
Bar.new.foo
)).to_i.should eq(1)
end
Ary Borenszweig
committed
it "allows overriding macro definition when redefining base class" do
run(%(
class Foo
def inspect : String
Ary Borenszweig
committed
{{@name}}
Ary Borenszweig
committed
end
end
class Bar < Foo
end
class Foo
def inspect
"OH NO"
end
end
Bar.new.inspect
)).to_string.should eq("OH NO")
end
it "uses invocation context" do
run(%(
macro foo
def bar
Ary Borenszweig
committed
{{@name}}
end
end
class Foo
foo
end
Foo.new.bar
)).to_string.should eq("Foo")
end
it "allows macro with default arguments" do
run(%(
def bar
2
end
macro foo(x, y = :bar)
{{x}} + {{y.id}}
end
foo(1)
)).to_i.should eq(3)
end