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

Record embed and const field syntax #474

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions spec/declaration/record_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,158 @@ for i, name in ipairs({"records", "arrayrecords"}) do
]]))
end)
end

describe("embedding", function()
it("embed is not a reserved word", util.check [[
local record A
embed: number
end
]])
it("should make members of a record available to another", util.check [[
local record A
userdata
a_value: number
end
local record B
embed A
b_value: number
end
local record C
embed B
c_value: string
end
local b: B = {}
local c: C = {}
print(b.a_value, c.a_value + c.b_value, c.c_value)
local function f(a: A, b: B) end
f(b, b)
f(c, c)
local a: A = b
a = c
]])
it("should allow for generics", util.check [[
local record A<T>
property_of_a: T
end
local record B<T>
embed A<T>
property_of_b: T
end
local record C<T>
embed B<T>
property_of_c: string
end
local b: B<number> = {}
local c: C<number> = {}
print(b.property_of_a + 1, c.property_of_b + c.property_of_a, c.property_of_c)
local function f(a: A<number>, b: B<number>) end
f(b, b)
f(c, c)
local a: A<number> = b
a = c
]])
it("embed multiple records", util.check [[
local record A
x: number
end
local record B
y: string
end
local record C
embed A
embed B
z: boolean
end
local c: C = { x = 1, y = "hello", z = true }
print(c.x, c.y, c.z)
local function f(a: A, b: B, c: C) end
f(c, c, c)
]])
it("share the same element type with embeded arrayrecord", util.check [[
local record A
{ string }
x: number
end
local record B
embed A
y: string
end
local record C
embed B
z: boolean
end
local c: C = { x = 1, y = "hello", z = true }
local str: string = c[1]
print(c.x, c.y, c.z)
local strs: {string} = c
local b: B = c
strs = b
]])
it("subrecords should not be equal", util.check_type_error([[
local record A
end
local record B
embed A
end
local record C
embed A
end
local a: A
local b: B
local c: C
a = b
a = c
b = c
]], {
{ y = 14, msg = "in assignment: C is not a B" }
}))
end)

describe("const field", function()
it("const is not a reserved word", util.check [[
local record A
const: boolean
end
]])
it("cannot assign to a const field", util.check_type_error([[
local record A
const ["a field"]: string
const x: number
end
local record B
embed A
b: A
end
local r: B = {b = {["a field"] = "abc"}}
r.b[ [=[a field]=] ] = 456
r.x = 123
]], {
{ y = 10, msg = "cannot assign to const field \"a field\"" },
{ y = 10, msg = "in assignment: got integer, expected string" },
{ y = 11, msg = "cannot assign to const field \"x\"" }
}))
it("should work for generics", util.check_type_error([[
local record A<T>
const a: T
end
local record B<T>
embed A<T>
const b: T
end
local b: B<number> = { a = 1, b = 2 }
print(b.a, b.b)
b.a, b.b = 2, "3"
]], {
{ y = 10, msg = "cannot assign to const field \"a\"" },
{ y = 10, msg = "cannot assign to const field \"b\"" },
{ y = 10, msg = "in assignment: got string \"3\", expected number" }
}))
it("it is OK to modify const field with rawset", util.check [[
local record R
const x: boolean
end
local r: R = { x = true }
rawset(r, "x", false)
]])
end)

Loading