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

Support tuple metaclass indexers with non-literal arguments #11834

186 changes: 133 additions & 53 deletions spec/std/named_tuple_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -80,80 +80,160 @@ describe "NamedTuple" do
{a: 1, b: 3}.size.should eq(2)
end

it "does [] with runtime key" do
tup = {a: 1, b: 'a'}
describe "#[] with non-literal index" do
it "gets named tuple value with Symbol key" do
tup = {a: 1, b: 'a'}

key = :a
val = tup[key]
val.should eq(1)
typeof(val).should eq(Int32 | Char)

key = :b
val = tup[key]
val.should eq('a')
typeof(val).should eq(Int32 | Char)
end

key = :a
val = tup[key]
val.should eq(1)
typeof(val).should eq(Int32 | Char)
it "gets named tuple value with String key" do
tup = {a: 1, b: 'a'}

key = "a"
val = tup[key]
val.should eq(1)
typeof(val).should eq(Int32 | Char)

key = :b
val = tup[key]
val.should eq('a')
typeof(val).should eq(Int32 | Char)
key = "b"
val = tup[key]
val.should eq('a')
typeof(val).should eq(Int32 | Char)
end

expect_raises(KeyError) do
it "raises missing key" do
tup = {a: 1, b: 'a'}
key = :c
tup[key]
expect_raises(KeyError) { tup[key] }
key = "d"
expect_raises(KeyError) { tup[key] }
end
end

it "does []? with runtime key" do
tup = {a: 1, b: 'a'}
describe "#[]? with non-literal index" do
it "gets named tuple value or nil with Symbol key" do
tup = {a: 1, b: 'a'}

key = :a
val = tup[key]?
val.should eq(1)
typeof(val).should eq(Int32 | Char | Nil)
key = :a
val = tup[key]?
val.should eq(1)
typeof(val).should eq(Int32 | Char | Nil)

key = :b
val = tup[key]?
val.should eq('a')
typeof(val).should eq(Int32 | Char | Nil)
key = :b
val = tup[key]?
val.should eq('a')
typeof(val).should eq(Int32 | Char | Nil)

key = :c
val = tup[key]?
val.should be_nil
typeof(val).should eq(Int32 | Char | Nil)
end
key = :c
val = tup[key]?
val.should be_nil
typeof(val).should eq(Int32 | Char | Nil)
end

it "does [] with string" do
tup = {a: 1, b: 'a'}
it "gets named tuple value or nil with String key" do
tup = {a: 1, b: 'a'}

key = "a"
val = tup[key]
val.should eq(1)
typeof(val).should eq(Int32 | Char)
key = "a"
val = tup[key]?
val.should eq(1)
typeof(val).should eq(Int32 | Char | Nil)

key = "b"
val = tup[key]
val.should eq('a')
typeof(val).should eq(Int32 | Char)
key = "b"
val = tup[key]?
val.should eq('a')
typeof(val).should eq(Int32 | Char | Nil)

expect_raises(KeyError) do
key = "c"
tup[key]
val = tup[key]?
val.should be_nil
typeof(val).should eq(Int32 | Char | Nil)
end
end

it "does []? with string" do
tup = {a: 1, b: 'a'}
describe ".[] with non-literal index" do
it "gets named tuple metaclass value with Symbol key" do
tup = NamedTuple(a: Int32, b: Char)

key = "a"
val = tup[key]?
val.should eq(1)
typeof(val).should eq(Int32 | Char | Nil)
key = :a
val = tup[key]
val.should eq(Int32)
typeof(val).should eq(Union(Int32.class, Char.class))

key = :b
val = tup[key]
val.should eq(Char)
typeof(val).should eq(Union(Int32.class, Char.class))
end

key = "b"
val = tup[key]?
val.should eq('a')
typeof(val).should eq(Int32 | Char | Nil)
it "gets named tuple metaclass value with String key" do
tup = NamedTuple(a: Int32, b: Char)

key = "c"
val = tup[key]?
val.should be_nil
typeof(val).should eq(Int32 | Char | Nil)
key = "a"
val = tup[key]
val.should eq(Int32)
typeof(val).should eq(Union(Int32.class, Char.class))

key = "b"
val = tup[key]
val.should eq(Char)
typeof(val).should eq(Union(Int32.class, Char.class))
end

it "raises missing key" do
tup = NamedTuple(a: Int32, b: Char)
key = :c
expect_raises(KeyError) { tup[key] }
key = "d"
expect_raises(KeyError) { tup[key] }
end
end

describe ".[]? with non-literal index" do
it "gets named tuple metaclass value or nil with Symbol key" do
tup = NamedTuple(a: Int32, b: Char)

key = :a
val = tup[key]?
val.should eq(Int32)
typeof(val).should eq(Union(Int32.class, Char.class, Nil))

key = :b
val = tup[key]?
val.should eq(Char)
typeof(val).should eq(Union(Int32.class, Char.class, Nil))

key = :c
val = tup[key]?
val.should be_nil
typeof(val).should eq(Union(Int32.class, Char.class, Nil))
end

it "gets named tuple metaclass value or nil with String key" do
tup = NamedTuple(a: Int32, b: Char)

key = "a"
val = tup[key]?
val.should eq(Int32)
typeof(val).should eq(Union(Int32.class, Char.class, Nil))

key = "b"
val = tup[key]?
val.should eq(Char)
typeof(val).should eq(Union(Int32.class, Char.class, Nil))

key = "c"
val = tup[key]?
val.should be_nil
typeof(val).should eq(Union(Int32.class, Char.class, Nil))
end
end

describe "#dig?" do
Expand Down
103 changes: 73 additions & 30 deletions spec/std/tuple_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,79 @@ describe "Tuple" do
{1}.empty?.should be_false
end

it "does []" do
a = {1, 2.5}
i = 0
a[i].should eq(1)
i = 1
a[i].should eq(2.5)
i = -1
a[i].should eq(2.5)
i = -2
a[i].should eq(1)
end

it "does [] raises index out of bounds" do
a = {1, 2.5}
i = 2
expect_raises(IndexError) { a[i] }
i = -3
expect_raises(IndexError) { a[i] }
end

it "does []?" do
a = {1, 2}
i = 1
a[i]?.should eq(2)
i = -1
a[i]?.should eq(2)
i = 2
a[i]?.should be_nil
i = -3
a[i]?.should be_nil
describe "#[] with non-literal index" do
it "gets tuple element" do
a = {1, 2.5}
i = 0
a[i].should eq(1)
i = 1
a[i].should eq(2.5)
i = -1
a[i].should eq(2.5)
i = -2
a[i].should eq(1)
typeof(a[i]).should eq(Int32 | Float64)
end

it "raises index out of bounds" do
a = {1, 2.5}
i = 2
expect_raises(IndexError) { a[i] }
i = -3
expect_raises(IndexError) { a[i] }
end
end

describe "#[]? with non-literal index" do
it "gets tuple element or nil" do
a = {1, 2.5}
i = 0
a[i]?.should eq(1)
i = -1
a[i]?.should eq(2.5)
i = 2
a[i]?.should be_nil
i = -3
a[i]?.should be_nil
typeof(a[i]?).should eq(Int32 | Float64 | Nil)
end
end

describe ".[] with non-literal index" do
it "gets tuple metaclass element" do
a = Tuple(Int32, Float64)
i = 0
a[i].should eq(Int32)
i = 1
a[i].should eq(Float64)
i = -1
a[i].should eq(Float64)
i = -2
a[i].should eq(Int32)
end

it "raises index out of bounds" do
a = Tuple(Int32, Float64)
i = 2
expect_raises(IndexError) { a[i] }
i = -3
expect_raises(IndexError) { a[i] }
end
end

describe ".[]? with non-literal index" do
it "gets tuple metaclass element or nil" do
a = Tuple(Int32, Float64)
i = 0
a[i]?.should eq(Int32)
i = -1
a[i]?.should eq(Float64)
i = 2
a[i]?.should be_nil
i = -3
a[i]?.should be_nil
typeof(a[i]?).should eq(Union(Int32.class, Float64.class, Nil))
end
end

it "does at" do
Expand Down
Loading