xref: /aosp_15_r20/external/starlark-go/starlark/testdata/misc.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Miscellaneous tests of Starlark evaluation.
2*4947cdc7SCole Faust# This is a "chunked" file: each "---" effectively starts a new file.
3*4947cdc7SCole Faust
4*4947cdc7SCole Faust# TODO(adonovan): move these tests into more appropriate files.
5*4947cdc7SCole Faust# TODO(adonovan): test coverage:
6*4947cdc7SCole Faust# - stmts: pass; if cond fail; += and failures;
7*4947cdc7SCole Faust#    for x fail; for x not iterable; for can't assign; for
8*4947cdc7SCole Faust#    error in loop body
9*4947cdc7SCole Faust# - subassign fail
10*4947cdc7SCole Faust# - x[i]=x fail in both operands; frozen x; list index not int; boundscheck
11*4947cdc7SCole Faust# - x.f = ...
12*4947cdc7SCole Faust# - failure in list expr [...]; tuple expr; dict expr (bad key)
13*4947cdc7SCole Faust# - cond expr semantics; failures
14*4947cdc7SCole Faust# - x[i] failures in both args; dict and iterator key and range checks;
15*4947cdc7SCole Faust#   unhandled operand types
16*4947cdc7SCole Faust# - +: list/list, int/int, string/string, tuple+tuple, dict/dict;
17*4947cdc7SCole Faust# - * and ** calls: various errors
18*4947cdc7SCole Faust# - call of non-function
19*4947cdc7SCole Faust# - slice x[ijk]
20*4947cdc7SCole Faust# - comprehension: unhashable dict key;
21*4947cdc7SCole Faust#   scope of vars (local and toplevel); noniterable for clause
22*4947cdc7SCole Faust# - unknown unary op
23*4947cdc7SCole Faust# - ordering of values
24*4947cdc7SCole Faust# - freeze, transitivity of its effect.
25*4947cdc7SCole Faust# - add an application-defined type to the environment so we can test it.
26*4947cdc7SCole Faust# - even more:
27*4947cdc7SCole Faust#
28*4947cdc7SCole Faust# eval
29*4947cdc7SCole Faust#   pass statement
30*4947cdc7SCole Faust#   assign to tuple l-value -- illegal
31*4947cdc7SCole Faust#   assign to list l-value -- illegal
32*4947cdc7SCole Faust#   assign to field
33*4947cdc7SCole Faust#   tuple + tuple
34*4947cdc7SCole Faust#   call with *args, **kwargs
35*4947cdc7SCole Faust#   slice with step
36*4947cdc7SCole Faust#   tuple slice
37*4947cdc7SCole Faust#   interpolate with %c, %%
38*4947cdc7SCole Faust
39*4947cdc7SCole Faustload("assert.star", "assert")
40*4947cdc7SCole Faust
41*4947cdc7SCole Faust# Ordered comparisons require values of the same type.
42*4947cdc7SCole Faustassert.fails(lambda: None < None, "not impl")
43*4947cdc7SCole Faustassert.fails(lambda: None < False, "not impl")
44*4947cdc7SCole Faustassert.fails(lambda: False < list, "not impl")
45*4947cdc7SCole Faustassert.fails(lambda: list < {}, "not impl")
46*4947cdc7SCole Faustassert.fails(lambda: {} < (lambda: None), "not impl")
47*4947cdc7SCole Faustassert.fails(lambda: (lambda: None) < 0, "not impl")
48*4947cdc7SCole Faustassert.fails(lambda: 0 < [], "not impl")
49*4947cdc7SCole Faustassert.fails(lambda: [] < "", "not impl")
50*4947cdc7SCole Faustassert.fails(lambda: "" < (), "not impl")
51*4947cdc7SCole Faust# Except int < float:
52*4947cdc7SCole Faustassert.lt(1, 2.0)
53*4947cdc7SCole Faustassert.lt(2.0, 3)
54*4947cdc7SCole Faust
55*4947cdc7SCole Faust---
56*4947cdc7SCole Faust# cyclic data structures
57*4947cdc7SCole Faustload("assert.star", "assert")
58*4947cdc7SCole Faust
59*4947cdc7SCole Faustcyclic = [1, 2, 3] # list cycle
60*4947cdc7SCole Faustcyclic[1] = cyclic
61*4947cdc7SCole Faustassert.eq(str(cyclic), "[1, [...], 3]")
62*4947cdc7SCole Faustassert.fails(lambda: cyclic < cyclic, "maximum recursion")
63*4947cdc7SCole Faustassert.fails(lambda: cyclic == cyclic, "maximum recursion")
64*4947cdc7SCole Faustcyclic2 = [1, 2, 3]
65*4947cdc7SCole Faustcyclic2[1] = cyclic2
66*4947cdc7SCole Faustassert.fails(lambda: cyclic2 == cyclic, "maximum recursion")
67*4947cdc7SCole Faust
68*4947cdc7SCole Faustcyclic3 = [1, [2, 3]] # list-list cycle
69*4947cdc7SCole Faustcyclic3[1][0] = cyclic3
70*4947cdc7SCole Faustassert.eq(str(cyclic3), "[1, [[...], 3]]")
71*4947cdc7SCole Faustcyclic4 = {"x": 1}
72*4947cdc7SCole Faustcyclic4["x"] = cyclic4
73*4947cdc7SCole Faustassert.eq(str(cyclic4), "{\"x\": {...}}")
74*4947cdc7SCole Faustcyclic5 = [0, {"x": 1}] # list-dict cycle
75*4947cdc7SCole Faustcyclic5[1]["x"] = cyclic5
76*4947cdc7SCole Faustassert.eq(str(cyclic5), "[0, {\"x\": [...]}]")
77*4947cdc7SCole Faustassert.eq(str(cyclic5), "[0, {\"x\": [...]}]")
78*4947cdc7SCole Faustassert.fails(lambda: cyclic5 == cyclic5 ,"maximum recursion")
79*4947cdc7SCole Faustcyclic6 = [0, {"x": 1}]
80*4947cdc7SCole Faustcyclic6[1]["x"] = cyclic6
81*4947cdc7SCole Faustassert.fails(lambda: cyclic5 == cyclic6, "maximum recursion")
82*4947cdc7SCole Faust
83*4947cdc7SCole Faust---
84*4947cdc7SCole Faust# regression
85*4947cdc7SCole Faustload("assert.star", "assert")
86*4947cdc7SCole Faust
87*4947cdc7SCole Faust# was a parse error:
88*4947cdc7SCole Faustassert.eq(("ababab"[2:]).replace("b", "c"), "acac")
89*4947cdc7SCole Faustassert.eq("ababab"[2:].replace("b", "c"), "acac")
90*4947cdc7SCole Faust
91*4947cdc7SCole Faust# test parsing of line continuation, at toplevel and in expression.
92*4947cdc7SCole Faustthree = 1 + \
93*4947cdc7SCole Faust  2
94*4947cdc7SCole Faustassert.eq(1 + \
95*4947cdc7SCole Faust  2, three)
96*4947cdc7SCole Faust
97*4947cdc7SCole Faust---
98*4947cdc7SCole Faust# A regression test for error position information.
99*4947cdc7SCole Faust
100*4947cdc7SCole Faust_ = {}.get(1, default=2) ### "get: unexpected keyword arguments"
101*4947cdc7SCole Faust
102*4947cdc7SCole Faust---
103*4947cdc7SCole Faust# Load exposes explicitly declared globals from other modules.
104*4947cdc7SCole Faustload('assert.star', 'assert', 'freeze')
105*4947cdc7SCole Faustassert.eq(str(freeze), '<built-in function freeze>')
106*4947cdc7SCole Faust
107*4947cdc7SCole Faust---
108*4947cdc7SCole Faust# Load does not expose pre-declared globals from other modules.
109*4947cdc7SCole Faust# See github.com/google/skylark/issues/75.
110*4947cdc7SCole Faustload('assert.star', 'assert', 'matches') ### "matches not found in module"
111*4947cdc7SCole Faust
112*4947cdc7SCole Faust---
113*4947cdc7SCole Faust# Load does not expose universals accessible in other modules.
114*4947cdc7SCole Faustload('assert.star', 'len') ### "len not found in module"
115*4947cdc7SCole Faust
116*4947cdc7SCole Faust
117*4947cdc7SCole Faust---
118*4947cdc7SCole Faust# Test plus folding optimization.
119*4947cdc7SCole Faustload('assert.star', 'assert')
120*4947cdc7SCole Faust
121*4947cdc7SCole Fausts = "s"
122*4947cdc7SCole Faustl = [4]
123*4947cdc7SCole Faustt = (4,)
124*4947cdc7SCole Faust
125*4947cdc7SCole Faustassert.eq("a" + "b" + "c", "abc")
126*4947cdc7SCole Faustassert.eq("a" + "b" + s + "c", "absc")
127*4947cdc7SCole Faustassert.eq(() + (1,) + (2, 3), (1, 2, 3))
128*4947cdc7SCole Faustassert.eq(() + (1,) + t + (2, 3), (1, 4, 2, 3))
129*4947cdc7SCole Faustassert.eq([] + [1] + [2, 3], [1, 2, 3])
130*4947cdc7SCole Faustassert.eq([] + [1] + l + [2, 3], [1, 4, 2, 3])
131*4947cdc7SCole Faust
132*4947cdc7SCole Faustassert.fails(lambda: "a" + "b" + 1 + "c", "unknown binary op: string \\+ int")
133*4947cdc7SCole Faustassert.fails(lambda: () + () + 1 + (), "unknown binary op: tuple \\+ int")
134*4947cdc7SCole Faustassert.fails(lambda: [] + [] + 1 + [], "unknown binary op: list \\+ int")
135*4947cdc7SCole Faust
136*4947cdc7SCole Faust
137*4947cdc7SCole Faust
138*4947cdc7SCole Faust---
139*4947cdc7SCole Faustload('assert.star', 'froze') ### `name froze not found .*did you mean freeze`
140