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