You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.2 KiB
140 lines
4.2 KiB
4 months ago
|
# Miscellaneous tests of Starlark evaluation.
|
||
|
# This is a "chunked" file: each "---" effectively starts a new file.
|
||
|
|
||
|
# TODO(adonovan): move these tests into more appropriate files.
|
||
|
# TODO(adonovan): test coverage:
|
||
|
# - stmts: pass; if cond fail; += and failures;
|
||
|
# for x fail; for x not iterable; for can't assign; for
|
||
|
# error in loop body
|
||
|
# - subassign fail
|
||
|
# - x[i]=x fail in both operands; frozen x; list index not int; boundscheck
|
||
|
# - x.f = ...
|
||
|
# - failure in list expr [...]; tuple expr; dict expr (bad key)
|
||
|
# - cond expr semantics; failures
|
||
|
# - x[i] failures in both args; dict and iterator key and range checks;
|
||
|
# unhandled operand types
|
||
|
# - +: list/list, int/int, string/string, tuple+tuple, dict/dict;
|
||
|
# - * and ** calls: various errors
|
||
|
# - call of non-function
|
||
|
# - slice x[ijk]
|
||
|
# - comprehension: unhashable dict key;
|
||
|
# scope of vars (local and toplevel); noniterable for clause
|
||
|
# - unknown unary op
|
||
|
# - ordering of values
|
||
|
# - freeze, transitivity of its effect.
|
||
|
# - add an application-defined type to the environment so we can test it.
|
||
|
# - even more:
|
||
|
#
|
||
|
# eval
|
||
|
# pass statement
|
||
|
# assign to tuple l-value -- illegal
|
||
|
# assign to list l-value -- illegal
|
||
|
# assign to field
|
||
|
# tuple + tuple
|
||
|
# call with *args, **kwargs
|
||
|
# slice with step
|
||
|
# tuple slice
|
||
|
# interpolate with %c, %%
|
||
|
|
||
|
load("assert.star", "assert")
|
||
|
|
||
|
# Ordered comparisons require values of the same type.
|
||
|
assert.fails(lambda: None < None, "not impl")
|
||
|
assert.fails(lambda: None < False, "not impl")
|
||
|
assert.fails(lambda: False < list, "not impl")
|
||
|
assert.fails(lambda: list < {}, "not impl")
|
||
|
assert.fails(lambda: {} < (lambda: None), "not impl")
|
||
|
assert.fails(lambda: (lambda: None) < 0, "not impl")
|
||
|
assert.fails(lambda: 0 < [], "not impl")
|
||
|
assert.fails(lambda: [] < "", "not impl")
|
||
|
assert.fails(lambda: "" < (), "not impl")
|
||
|
# Except int < float:
|
||
|
assert.lt(1, 2.0)
|
||
|
assert.lt(2.0, 3)
|
||
|
|
||
|
---
|
||
|
# cyclic data structures
|
||
|
load("assert.star", "assert")
|
||
|
|
||
|
cyclic = [1, 2, 3] # list cycle
|
||
|
cyclic[1] = cyclic
|
||
|
assert.eq(str(cyclic), "[1, [...], 3]")
|
||
|
assert.fails(lambda: cyclic < cyclic, "maximum recursion")
|
||
|
assert.fails(lambda: cyclic == cyclic, "maximum recursion")
|
||
|
cyclic2 = [1, 2, 3]
|
||
|
cyclic2[1] = cyclic2
|
||
|
assert.fails(lambda: cyclic2 == cyclic, "maximum recursion")
|
||
|
|
||
|
cyclic3 = [1, [2, 3]] # list-list cycle
|
||
|
cyclic3[1][0] = cyclic3
|
||
|
assert.eq(str(cyclic3), "[1, [[...], 3]]")
|
||
|
cyclic4 = {"x": 1}
|
||
|
cyclic4["x"] = cyclic4
|
||
|
assert.eq(str(cyclic4), "{\"x\": {...}}")
|
||
|
cyclic5 = [0, {"x": 1}] # list-dict cycle
|
||
|
cyclic5[1]["x"] = cyclic5
|
||
|
assert.eq(str(cyclic5), "[0, {\"x\": [...]}]")
|
||
|
assert.eq(str(cyclic5), "[0, {\"x\": [...]}]")
|
||
|
assert.fails(lambda: cyclic5 == cyclic5 ,"maximum recursion")
|
||
|
cyclic6 = [0, {"x": 1}]
|
||
|
cyclic6[1]["x"] = cyclic6
|
||
|
assert.fails(lambda: cyclic5 == cyclic6, "maximum recursion")
|
||
|
|
||
|
---
|
||
|
# regression
|
||
|
load("assert.star", "assert")
|
||
|
|
||
|
# was a parse error:
|
||
|
assert.eq(("ababab"[2:]).replace("b", "c"), "acac")
|
||
|
assert.eq("ababab"[2:].replace("b", "c"), "acac")
|
||
|
|
||
|
# test parsing of line continuation, at toplevel and in expression.
|
||
|
three = 1 + \
|
||
|
2
|
||
|
assert.eq(1 + \
|
||
|
2, three)
|
||
|
|
||
|
---
|
||
|
# A regression test for error position information.
|
||
|
|
||
|
_ = {}.get(1, default=2) ### "get: unexpected keyword arguments"
|
||
|
|
||
|
---
|
||
|
# Load exposes explicitly declared globals from other modules.
|
||
|
load('assert.star', 'assert', 'freeze')
|
||
|
assert.eq(str(freeze), '<built-in function freeze>')
|
||
|
|
||
|
---
|
||
|
# Load does not expose pre-declared globals from other modules.
|
||
|
# See github.com/google/skylark/issues/75.
|
||
|
load('assert.star', 'assert', 'matches') ### "matches not found in module"
|
||
|
|
||
|
---
|
||
|
# Load does not expose universals accessible in other modules.
|
||
|
load('assert.star', 'len') ### "len not found in module"
|
||
|
|
||
|
|
||
|
---
|
||
|
# Test plus folding optimization.
|
||
|
load('assert.star', 'assert')
|
||
|
|
||
|
s = "s"
|
||
|
l = [4]
|
||
|
t = (4,)
|
||
|
|
||
|
assert.eq("a" + "b" + "c", "abc")
|
||
|
assert.eq("a" + "b" + s + "c", "absc")
|
||
|
assert.eq(() + (1,) + (2, 3), (1, 2, 3))
|
||
|
assert.eq(() + (1,) + t + (2, 3), (1, 4, 2, 3))
|
||
|
assert.eq([] + [1] + [2, 3], [1, 2, 3])
|
||
|
assert.eq([] + [1] + l + [2, 3], [1, 4, 2, 3])
|
||
|
|
||
|
assert.fails(lambda: "a" + "b" + 1 + "c", "unknown binary op: string \\+ int")
|
||
|
assert.fails(lambda: () + () + 1 + (), "unknown binary op: tuple \\+ int")
|
||
|
assert.fails(lambda: [] + [] + 1 + [], "unknown binary op: list \\+ int")
|
||
|
|
||
|
|
||
|
|
||
|
---
|
||
|
load('assert.star', 'froze') ### `name froze not found .*did you mean freeze`
|