#!/usr/bin/env bin/crystal -run require "../../spec_helper" describe "Codegen: const" do it "define a constant" do run("A = 1; A").to_i.should eq(1) end it "support nested constant" do run("class B; A = 1; end; B::A").to_i.should eq(1) end it "support constant inside a def" do run(" class Foo A = 1 def foo A end end Foo.new.foo ").to_i.should eq(1) end it "finds nearest constant first" do run(" A = 1 class Foo A = 2.5_f32 def foo A end end Foo.new.foo ").to_f32.should eq(2.5) end it "allows constants with same name" do run(" A = 1 class Foo A = 2.5_f32 def foo A end end A Foo.new.foo ").to_f32.should eq(2.5) end it "constants with expression" do run(" A = 1 + 1 A ").to_i.should eq(2) end it "finds global constant" do run(" A = 1 class Foo def foo A end end Foo.new.foo ").to_i.should eq(1) end it "define a constant in lib" do run("lib Foo; A = 1; end; Foo::A").to_i.should eq(1) end it "invokes block in const" do run("require \"prelude\"; A = [\"1\"].map { |x| x.to_i }; A[0]").to_i.should eq(1) end it "declare constants in right order" do run("A = 1 + 1; B = true ? A : 0; B").to_i.should eq(2) end it "uses correct types lookup" do run("module A; class B; def foo; 1; end; end; C = B.new; end; def foo; A::C.foo; end; foo").to_i.should eq(1) end it "codegens variable assignment in const" do run(" class Foo def initialize(@x) end def x @x end end A = begin f = Foo.new(1) f end def foo A.x end foo ").to_i.should eq(1) end it "declaring var" do run(" BAR = begin a = 1 while 1 == 2 b = 2 end a end class Foo def compile BAR end end Foo.new.compile ").to_i.should eq(1) end end