xref: /aosp_15_r20/external/starlark-go/starlark/testdata/builtins.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Tests of Starlark built-in functions
2*4947cdc7SCole Faust# option:set
3*4947cdc7SCole Faust
4*4947cdc7SCole Faustload("assert.star", "assert")
5*4947cdc7SCole Faust
6*4947cdc7SCole Faust# len
7*4947cdc7SCole Faustassert.eq(len([1, 2, 3]), 3)
8*4947cdc7SCole Faustassert.eq(len((1, 2, 3)), 3)
9*4947cdc7SCole Faustassert.eq(len({1: 2}), 1)
10*4947cdc7SCole Faustassert.fails(lambda: len(1), "int.*has no len")
11*4947cdc7SCole Faust
12*4947cdc7SCole Faust# and, or
13*4947cdc7SCole Faustassert.eq(123 or "foo", 123)
14*4947cdc7SCole Faustassert.eq(0 or "foo", "foo")
15*4947cdc7SCole Faustassert.eq(123 and "foo", "foo")
16*4947cdc7SCole Faustassert.eq(0 and "foo", 0)
17*4947cdc7SCole Faustnone = None
18*4947cdc7SCole Faust_1 = none and none[0]      # rhs is not evaluated
19*4947cdc7SCole Faust_2 = (not none) or none[0] # rhs is not evaluated
20*4947cdc7SCole Faust
21*4947cdc7SCole Faust# any, all
22*4947cdc7SCole Faustassert.true(all([]))
23*4947cdc7SCole Faustassert.true(all([1, True, "foo"]))
24*4947cdc7SCole Faustassert.true(not all([1, True, ""]))
25*4947cdc7SCole Faustassert.true(not any([]))
26*4947cdc7SCole Faustassert.true(any([0, False, "foo"]))
27*4947cdc7SCole Faustassert.true(not any([0, False, ""]))
28*4947cdc7SCole Faust
29*4947cdc7SCole Faust# in
30*4947cdc7SCole Faustassert.true(3 in [1, 2, 3])
31*4947cdc7SCole Faustassert.true(4 not in [1, 2, 3])
32*4947cdc7SCole Faustassert.true(3 in (1, 2, 3))
33*4947cdc7SCole Faustassert.true(4 not in (1, 2, 3))
34*4947cdc7SCole Faustassert.fails(lambda: 3 in "foo", "in.*requires string as left operand")
35*4947cdc7SCole Faustassert.true(123 in {123: ""})
36*4947cdc7SCole Faustassert.true(456 not in {123:""})
37*4947cdc7SCole Faustassert.true([] not in {123: ""})
38*4947cdc7SCole Faust
39*4947cdc7SCole Faust# sorted
40*4947cdc7SCole Faustassert.eq(sorted([42, 123, 3]), [3, 42, 123])
41*4947cdc7SCole Faustassert.eq(sorted([42, 123, 3], reverse=True), [123, 42, 3])
42*4947cdc7SCole Faustassert.eq(sorted(["wiz", "foo", "bar"]), ["bar", "foo", "wiz"])
43*4947cdc7SCole Faustassert.eq(sorted(["wiz", "foo", "bar"], reverse=True), ["wiz", "foo", "bar"])
44*4947cdc7SCole Faustassert.fails(lambda: sorted([1, 2, None, 3]), "int < NoneType not implemented")
45*4947cdc7SCole Faustassert.fails(lambda: sorted([1, "one"]), "string < int not implemented")
46*4947cdc7SCole Faust# custom key function
47*4947cdc7SCole Faustassert.eq(sorted(["two", "three", "four"], key=len),
48*4947cdc7SCole Faust          ["two", "four", "three"])
49*4947cdc7SCole Faustassert.eq(sorted(["two", "three", "four"], key=len, reverse=True),
50*4947cdc7SCole Faust          ["three", "four", "two"])
51*4947cdc7SCole Faustassert.fails(lambda: sorted([1, 2, 3], key=None), "got NoneType, want callable")
52*4947cdc7SCole Faust# sort is stable
53*4947cdc7SCole Faustpairs = [(4, 0), (3, 1), (4, 2), (2, 3), (3, 4), (1, 5), (2, 6), (3, 7)]
54*4947cdc7SCole Faustassert.eq(sorted(pairs, key=lambda x: x[0]),
55*4947cdc7SCole Faust          [(1, 5),
56*4947cdc7SCole Faust           (2, 3), (2, 6),
57*4947cdc7SCole Faust           (3, 1), (3, 4), (3, 7),
58*4947cdc7SCole Faust           (4, 0), (4, 2)])
59*4947cdc7SCole Faustassert.fails(lambda: sorted(1), 'sorted: for parameter iterable: got int, want iterable')
60*4947cdc7SCole Faust
61*4947cdc7SCole Faust# reversed
62*4947cdc7SCole Faustassert.eq(reversed([1, 144, 81, 16]), [16, 81, 144, 1])
63*4947cdc7SCole Faust
64*4947cdc7SCole Faust# set
65*4947cdc7SCole Faustassert.contains(set([1, 2, 3]), 1)
66*4947cdc7SCole Faustassert.true(4 not in set([1, 2, 3]))
67*4947cdc7SCole Faustassert.eq(len(set([1, 2, 3])), 3)
68*4947cdc7SCole Faustassert.eq(sorted([x for x in set([1, 2, 3])]), [1, 2, 3])
69*4947cdc7SCole Faust
70*4947cdc7SCole Faust# dict
71*4947cdc7SCole Faustassert.eq(dict([(1, 2), (3, 4)]), {1: 2, 3: 4})
72*4947cdc7SCole Faustassert.eq(dict([(1, 2), (3, 4)], foo="bar"), {1: 2, 3: 4, "foo": "bar"})
73*4947cdc7SCole Faustassert.eq(dict({1:2, 3:4}), {1: 2, 3: 4})
74*4947cdc7SCole Faustassert.eq(dict({1:2, 3:4}.items()), {1: 2, 3: 4})
75*4947cdc7SCole Faust
76*4947cdc7SCole Faust# range
77*4947cdc7SCole Faustassert.eq("range", type(range(10)))
78*4947cdc7SCole Faustassert.eq("range(10)", str(range(0, 10, 1)))
79*4947cdc7SCole Faustassert.eq("range(1, 10)", str(range(1, 10)))
80*4947cdc7SCole Faustassert.eq(range(0, 5, 10), range(0, 5, 11))
81*4947cdc7SCole Faustassert.eq("range(0, 10, -1)", str(range(0, 10, -1)))
82*4947cdc7SCole Faustassert.fails(lambda: {range(10): 10}, "unhashable: range")
83*4947cdc7SCole Faustassert.true(bool(range(1, 2)))
84*4947cdc7SCole Faustassert.true(not(range(2, 1))) # an empty range is false
85*4947cdc7SCole Faustassert.eq([x*x for x in range(5)], [0, 1, 4, 9, 16])
86*4947cdc7SCole Faustassert.eq(list(range(5)), [0, 1, 2, 3, 4])
87*4947cdc7SCole Faustassert.eq(list(range(-5)), [])
88*4947cdc7SCole Faustassert.eq(list(range(2, 5)), [2, 3, 4])
89*4947cdc7SCole Faustassert.eq(list(range(5, 2)), [])
90*4947cdc7SCole Faustassert.eq(list(range(-2, -5)), [])
91*4947cdc7SCole Faustassert.eq(list(range(-5, -2)), [-5, -4, -3])
92*4947cdc7SCole Faustassert.eq(list(range(2, 10, 3)), [2, 5, 8])
93*4947cdc7SCole Faustassert.eq(list(range(10, 2, -3)), [10, 7, 4])
94*4947cdc7SCole Faustassert.eq(list(range(-2, -10, -3)), [-2, -5, -8])
95*4947cdc7SCole Faustassert.eq(list(range(-10, -2, 3)), [-10, -7, -4])
96*4947cdc7SCole Faustassert.eq(list(range(10, 2, -1)), [10, 9, 8, 7, 6, 5, 4, 3])
97*4947cdc7SCole Faustassert.eq(list(range(5)[1:]), [1, 2, 3, 4])
98*4947cdc7SCole Faustassert.eq(len(range(5)[1:]), 4)
99*4947cdc7SCole Faustassert.eq(list(range(5)[:2]), [0, 1])
100*4947cdc7SCole Faustassert.eq(list(range(10)[1:]), [1, 2, 3, 4, 5, 6, 7, 8, 9])
101*4947cdc7SCole Faustassert.eq(list(range(10)[1:9:2]), [1, 3, 5, 7])
102*4947cdc7SCole Faustassert.eq(list(range(10)[1:10:2]), [1, 3, 5, 7, 9])
103*4947cdc7SCole Faustassert.eq(list(range(10)[1:11:2]), [1, 3, 5, 7, 9])
104*4947cdc7SCole Faustassert.eq(list(range(10)[::-2]), [9, 7, 5, 3, 1])
105*4947cdc7SCole Faustassert.eq(list(range(0, 10, 2)[::2]), [0, 4, 8])
106*4947cdc7SCole Faustassert.eq(list(range(0, 10, 2)[::-2]), [8, 4, 0])
107*4947cdc7SCole Faust# range() is limited by the width of the Go int type (int32 or int64).
108*4947cdc7SCole Faustassert.fails(lambda: range(1<<64), "... out of range .want value in signed ..-bit range")
109*4947cdc7SCole Faustassert.eq(len(range(0x7fffffff)), 0x7fffffff) # O(1)
110*4947cdc7SCole Faust# Two ranges compare equal if they denote the same sequence:
111*4947cdc7SCole Faustassert.eq(range(0), range(2, 1, 3))       # []
112*4947cdc7SCole Faustassert.eq(range(0, 3, 2), range(0, 4, 2)) # [0, 2]
113*4947cdc7SCole Faustassert.ne(range(1, 10), range(2, 10))
114*4947cdc7SCole Faustassert.fails(lambda: range(0) < range(0), "range < range not implemented")
115*4947cdc7SCole Faust# <number> in <range>
116*4947cdc7SCole Faustassert.contains(range(3), 1)
117*4947cdc7SCole Faustassert.contains(range(3), 2.0)    # acts like 2
118*4947cdc7SCole Faustassert.fails(lambda: True in range(3), "requires integer.*not bool") # bools aren't numbers
119*4947cdc7SCole Faustassert.fails(lambda: "one" in range(10), "requires integer.*not string")
120*4947cdc7SCole Faustassert.true(4 not in range(4))
121*4947cdc7SCole Faustassert.true(1e15 not in range(4)) # too big for int32
122*4947cdc7SCole Faustassert.true(1e100 not in range(4)) # too big for int64
123*4947cdc7SCole Faust# https://github.com/google/starlark-go/issues/116
124*4947cdc7SCole Faustassert.fails(lambda: range(0, 0, 2)[:][0], "index 0 out of range: empty range")
125*4947cdc7SCole Faust
126*4947cdc7SCole Faust# list
127*4947cdc7SCole Faustassert.eq(list("abc".elems()), ["a", "b", "c"])
128*4947cdc7SCole Faustassert.eq(sorted(list({"a": 1, "b": 2})), ['a', 'b'])
129*4947cdc7SCole Faust
130*4947cdc7SCole Faust# min, max
131*4947cdc7SCole Faustassert.eq(min(5, -2, 1, 7, 3), -2)
132*4947cdc7SCole Faustassert.eq(max(5, -2, 1, 7, 3), 7)
133*4947cdc7SCole Faustassert.eq(min([5, -2, 1, 7, 3]), -2)
134*4947cdc7SCole Faustassert.eq(min("one", "two", "three", "four"), "four")
135*4947cdc7SCole Faustassert.eq(max("one", "two", "three", "four"), "two")
136*4947cdc7SCole Faustassert.fails(min, "min requires at least one positional argument")
137*4947cdc7SCole Faustassert.fails(lambda: min(1), "not iterable")
138*4947cdc7SCole Faustassert.fails(lambda: min([]), "empty")
139*4947cdc7SCole Faustassert.eq(min(5, -2, 1, 7, 3, key=lambda x: x*x), 1) # min absolute value
140*4947cdc7SCole Faustassert.eq(min(5, -2, 1, 7, 3, key=lambda x: -x), 7) # min negated value
141*4947cdc7SCole Faust
142*4947cdc7SCole Faust# enumerate
143*4947cdc7SCole Faustassert.eq(enumerate("abc".elems()), [(0, "a"), (1, "b"), (2, "c")])
144*4947cdc7SCole Faustassert.eq(enumerate([False, True, None], 42), [(42, False), (43, True), (44, None)])
145*4947cdc7SCole Faust
146*4947cdc7SCole Faust# zip
147*4947cdc7SCole Faustassert.eq(zip(), [])
148*4947cdc7SCole Faustassert.eq(zip([]), [])
149*4947cdc7SCole Faustassert.eq(zip([1, 2, 3]), [(1,), (2,), (3,)])
150*4947cdc7SCole Faustassert.eq(zip("".elems()), [])
151*4947cdc7SCole Faustassert.eq(zip("abc".elems(),
152*4947cdc7SCole Faust              list("def".elems()),
153*4947cdc7SCole Faust              "hijk".elems()),
154*4947cdc7SCole Faust          [("a", "d", "h"), ("b", "e", "i"), ("c", "f", "j")])
155*4947cdc7SCole Faustz1 = [1]
156*4947cdc7SCole Faustassert.eq(zip(z1), [(1,)])
157*4947cdc7SCole Faustz1.append(2)
158*4947cdc7SCole Faustassert.eq(zip(z1), [(1,), (2,)])
159*4947cdc7SCole Faustassert.fails(lambda: zip(z1, 1), "zip: argument #2 is not iterable: int")
160*4947cdc7SCole Faustz1.append(3)
161*4947cdc7SCole Faust
162*4947cdc7SCole Faust# dir for builtin_function_or_method
163*4947cdc7SCole Faustassert.eq(dir(None), [])
164*4947cdc7SCole Faustassert.eq(dir({})[:3], ["clear", "get", "items"]) # etc
165*4947cdc7SCole Faustassert.eq(dir(1), [])
166*4947cdc7SCole Faustassert.eq(dir([])[:3], ["append", "clear", "extend"]) # etc
167*4947cdc7SCole Faust
168*4947cdc7SCole Faust# hasattr, getattr, dir
169*4947cdc7SCole Faust# hasfields is an application-defined type defined in eval_test.go.
170*4947cdc7SCole Fausthf = hasfields()
171*4947cdc7SCole Faustassert.eq(dir(hf), [])
172*4947cdc7SCole Faustassert.true(not hasattr(hf, "x"))
173*4947cdc7SCole Faustassert.fails(lambda: getattr(hf, "x"), "no .x field or method")
174*4947cdc7SCole Faustassert.eq(getattr(hf, "x", 42), 42)
175*4947cdc7SCole Fausthf.x = 1
176*4947cdc7SCole Faustassert.true(hasattr(hf, "x"))
177*4947cdc7SCole Faustassert.eq(getattr(hf, "x"), 1)
178*4947cdc7SCole Faustassert.eq(hf.x, 1)
179*4947cdc7SCole Fausthf.x = 2
180*4947cdc7SCole Faustassert.eq(getattr(hf, "x"), 2)
181*4947cdc7SCole Faustassert.eq(hf.x, 2)
182*4947cdc7SCole Faust# built-in types can have attributes (methods) too.
183*4947cdc7SCole Faustmyset = set([])
184*4947cdc7SCole Faustassert.eq(dir(myset), ["union"])
185*4947cdc7SCole Faustassert.true(hasattr(myset, "union"))
186*4947cdc7SCole Faustassert.true(not hasattr(myset, "onion"))
187*4947cdc7SCole Faustassert.eq(str(getattr(myset, "union")), "<built-in method union of set value>")
188*4947cdc7SCole Faustassert.fails(lambda: getattr(myset, "onion"), "no .onion field or method")
189*4947cdc7SCole Faustassert.eq(getattr(myset, "onion", 42), 42)
190*4947cdc7SCole Faust
191*4947cdc7SCole Faust# dir returns a new, sorted, mutable list
192*4947cdc7SCole Faustassert.eq(sorted(dir("")), dir("")) # sorted
193*4947cdc7SCole Faustdir("").append("!") # mutable
194*4947cdc7SCole Faustassert.true("!" not in dir("")) # new
195*4947cdc7SCole Faust
196*4947cdc7SCole Faust# error messages should suggest spelling corrections
197*4947cdc7SCole Fausthf.one = 1
198*4947cdc7SCole Fausthf.two = 2
199*4947cdc7SCole Fausthf.three = 3
200*4947cdc7SCole Fausthf.forty_five = 45
201*4947cdc7SCole Faustassert.fails(lambda: hf.One, 'no .One field.*did you mean .one')
202*4947cdc7SCole Faustassert.fails(lambda: hf.oone, 'no .oone field.*did you mean .one')
203*4947cdc7SCole Faustassert.fails(lambda: hf.FortyFive, 'no .FortyFive field.*did you mean .forty_five')
204*4947cdc7SCole Faustassert.fails(lambda: hf.trhee, 'no .trhee field.*did you mean .three')
205*4947cdc7SCole Faustassert.fails(lambda: hf.thirty, 'no .thirty field or method$') # no suggestion
206*4947cdc7SCole Faust
207*4947cdc7SCole Faust# spell check in setfield too
208*4947cdc7SCole Faustdef setfield(): hf.noForty_Five = 46  # "no" prefix => SetField returns NoSuchField
209*4947cdc7SCole Faustassert.fails(setfield, 'no .noForty_Five field.*did you mean .forty_five')
210*4947cdc7SCole Faust
211*4947cdc7SCole Faust# repr
212*4947cdc7SCole Faustassert.eq(repr(1), "1")
213*4947cdc7SCole Faustassert.eq(repr("x"), '"x"')
214*4947cdc7SCole Faustassert.eq(repr(["x", 1]), '["x", 1]')
215*4947cdc7SCole Faust
216*4947cdc7SCole Faust# fail
217*4947cdc7SCole Faust---
218*4947cdc7SCole Faustfail() ### `fail: $`
219*4947cdc7SCole Faustx = 1//0 # unreachable
220*4947cdc7SCole Faust---
221*4947cdc7SCole Faustfail(1) ### `fail: 1`
222*4947cdc7SCole Faust---
223*4947cdc7SCole Faustfail(1, 2, 3) ### `fail: 1 2 3`
224*4947cdc7SCole Faust---
225*4947cdc7SCole Faustfail(1, 2, 3, sep="/") ### `fail: 1/2/3`
226