xref: /aosp_15_r20/external/starlark-go/starlarkstruct/testdata/struct.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Tests of Starlark 'struct' extension.
2*4947cdc7SCole Faust# This is not a standard feature and the Go and Starlark APIs may yet change.
3*4947cdc7SCole Faust
4*4947cdc7SCole Faustload("assert.star", "assert")
5*4947cdc7SCole Faust
6*4947cdc7SCole Faustassert.eq(str(struct), "<built-in function struct>")
7*4947cdc7SCole Faust
8*4947cdc7SCole Faust# struct is a constructor for "unbranded" structs.
9*4947cdc7SCole Fausts = struct(host = "localhost", port = 80)
10*4947cdc7SCole Faustassert.eq(s, s)
11*4947cdc7SCole Faustassert.eq(s, struct(host = "localhost", port = 80))
12*4947cdc7SCole Faustassert.ne(s, struct(host = "localhost", port = 81))
13*4947cdc7SCole Faustassert.eq(type(s), "struct")
14*4947cdc7SCole Faustassert.eq(str(s), 'struct(host = "localhost", port = 80)')
15*4947cdc7SCole Faustassert.eq(s.host, "localhost")
16*4947cdc7SCole Faustassert.eq(s.port, 80)
17*4947cdc7SCole Faustassert.fails(lambda : s.protocol, "struct has no .protocol attribute")
18*4947cdc7SCole Faustassert.eq(dir(s), ["host", "port"])
19*4947cdc7SCole Faust
20*4947cdc7SCole Faust# Use gensym to create "branded" struct types.
21*4947cdc7SCole Fausthostport = gensym(name = "hostport")
22*4947cdc7SCole Faustassert.eq(type(hostport), "symbol")
23*4947cdc7SCole Faustassert.eq(str(hostport), "hostport")
24*4947cdc7SCole Faust
25*4947cdc7SCole Faust# Call the symbol to instantiate a new type.
26*4947cdc7SCole Fausthttp = hostport(host = "localhost", port = 80)
27*4947cdc7SCole Faustassert.eq(type(http), "struct")
28*4947cdc7SCole Faustassert.eq(str(http), 'hostport(host = "localhost", port = 80)')  # includes name of constructor
29*4947cdc7SCole Faustassert.eq(http, http)
30*4947cdc7SCole Faustassert.eq(http, hostport(host = "localhost", port = 80))
31*4947cdc7SCole Faustassert.ne(http, hostport(host = "localhost", port = 443))
32*4947cdc7SCole Faustassert.eq(http.host, "localhost")
33*4947cdc7SCole Faustassert.eq(http.port, 80)
34*4947cdc7SCole Faustassert.fails(lambda : http.protocol, "hostport struct has no .protocol attribute")
35*4947cdc7SCole Faust
36*4947cdc7SCole Faustperson = gensym(name = "person")
37*4947cdc7SCole Faustbob = person(name = "bob", age = 50)
38*4947cdc7SCole Faustalice = person(name = "alice", city = "NYC")
39*4947cdc7SCole Faustassert.ne(http, bob)  # different constructor symbols
40*4947cdc7SCole Faustassert.ne(bob, alice)  # different fields
41*4947cdc7SCole Faust
42*4947cdc7SCole Fausthostport2 = gensym(name = "hostport")
43*4947cdc7SCole Faustassert.eq(hostport, hostport)
44*4947cdc7SCole Faustassert.ne(hostport, hostport2)  # same name, different symbol
45*4947cdc7SCole Faustassert.ne(http, hostport2(host = "localhost", port = 80))  # equal fields but different ctor symbols
46*4947cdc7SCole Faust
47*4947cdc7SCole Faust# dir
48*4947cdc7SCole Faustassert.eq(dir(alice), ["city", "name"])
49*4947cdc7SCole Faustassert.eq(dir(bob), ["age", "name"])
50*4947cdc7SCole Faustassert.eq(dir(http), ["host", "port"])
51*4947cdc7SCole Faust
52*4947cdc7SCole Faust# hasattr, getattr
53*4947cdc7SCole Faustassert.true(hasattr(alice, "city"))
54*4947cdc7SCole Faustassert.eq(hasattr(alice, "ageaa"), False)
55*4947cdc7SCole Faustassert.eq(getattr(alice, "city"), "NYC")
56*4947cdc7SCole Faust
57*4947cdc7SCole Faust# +
58*4947cdc7SCole Faustassert.eq(bob + bob, bob)
59*4947cdc7SCole Faustassert.eq(bob + alice, person(age = 50, city = "NYC", name = "alice"))
60*4947cdc7SCole Faustassert.eq(alice + bob, person(age = 50, city = "NYC", name = "bob"))  # not commutative! a misfeature
61*4947cdc7SCole Faustassert.fails(lambda : alice + 1, "struct \\+ int")
62*4947cdc7SCole Faustassert.eq(http + http, http)
63*4947cdc7SCole Faustassert.fails(lambda : http + bob, "different constructors: hostport \\+ person")
64