1*4947cdc7SCole Faust# Tests of Starlark 'set' 2*4947cdc7SCole Faust# option:set 3*4947cdc7SCole Faust 4*4947cdc7SCole Faust# Sets are not a standard part of Starlark, so the features 5*4947cdc7SCole Faust# tested in this file must be enabled in the application by setting 6*4947cdc7SCole Faust# resolve.AllowSet. (All sets are created by calls to the 'set' 7*4947cdc7SCole Faust# built-in or derived from operations on existing sets.) 8*4947cdc7SCole Faust# The semantics are subject to change as the spec evolves. 9*4947cdc7SCole Faust 10*4947cdc7SCole Faust# TODO(adonovan): support set mutation: 11*4947cdc7SCole Faust# - del set[k] 12*4947cdc7SCole Faust# - set.remove 13*4947cdc7SCole Faust# - set.update 14*4947cdc7SCole Faust# - set.clear 15*4947cdc7SCole Faust# - set += iterable, perhaps? 16*4947cdc7SCole Faust# Test iterator invalidation. 17*4947cdc7SCole Faust 18*4947cdc7SCole Faustload("assert.star", "assert") 19*4947cdc7SCole Faust 20*4947cdc7SCole Faust# literals 21*4947cdc7SCole Faust# Parser does not currently support {1, 2, 3}. 22*4947cdc7SCole Faust# TODO(adonovan): add test to syntax/testdata/errors.star. 23*4947cdc7SCole Faust 24*4947cdc7SCole Faust# set comprehensions 25*4947cdc7SCole Faust# Parser does not currently support {x for x in y}. 26*4947cdc7SCole Faust# See syntax/testdata/errors.star. 27*4947cdc7SCole Faust 28*4947cdc7SCole Faust# set constructor 29*4947cdc7SCole Faustassert.eq(type(set()), "set") 30*4947cdc7SCole Faustassert.eq(list(set()), []) 31*4947cdc7SCole Faustassert.eq(type(set([1, 3, 2, 3])), "set") 32*4947cdc7SCole Faustassert.eq(list(set([1, 3, 2, 3])), [1, 3, 2]) 33*4947cdc7SCole Faustassert.eq(type(set("hello".elems())), "set") 34*4947cdc7SCole Faustassert.eq(list(set("hello".elems())), ["h", "e", "l", "o"]) 35*4947cdc7SCole Faustassert.eq(list(set(range(3))), [0, 1, 2]) 36*4947cdc7SCole Faustassert.fails(lambda : set(1), "got int, want iterable") 37*4947cdc7SCole Faustassert.fails(lambda : set(1, 2, 3), "got 3 arguments") 38*4947cdc7SCole Faustassert.fails(lambda : set([1, 2, {}]), "unhashable type: dict") 39*4947cdc7SCole Faust 40*4947cdc7SCole Faust# truth 41*4947cdc7SCole Faustassert.true(not set()) 42*4947cdc7SCole Faustassert.true(set([False])) 43*4947cdc7SCole Faustassert.true(set([1, 2, 3])) 44*4947cdc7SCole Faust 45*4947cdc7SCole Faustx = set([1, 2, 3]) 46*4947cdc7SCole Fausty = set([3, 4, 5]) 47*4947cdc7SCole Faust 48*4947cdc7SCole Faust# set + any is not defined 49*4947cdc7SCole Faustassert.fails(lambda : x + y, "unknown.*: set \\+ set") 50*4947cdc7SCole Faust 51*4947cdc7SCole Faust# set | set (use resolve.AllowBitwise to enable it) 52*4947cdc7SCole Faustassert.eq(list(set("a".elems()) | set("b".elems())), ["a", "b"]) 53*4947cdc7SCole Faustassert.eq(list(set("ab".elems()) | set("bc".elems())), ["a", "b", "c"]) 54*4947cdc7SCole Faustassert.fails(lambda : set() | [], "unknown binary op: set | list") 55*4947cdc7SCole Faustassert.eq(type(x | y), "set") 56*4947cdc7SCole Faustassert.eq(list(x | y), [1, 2, 3, 4, 5]) 57*4947cdc7SCole Faustassert.eq(list(x | set([5, 1])), [1, 2, 3, 5]) 58*4947cdc7SCole Faustassert.eq(list(x | set((6, 5, 4))), [1, 2, 3, 6, 5, 4]) 59*4947cdc7SCole Faust 60*4947cdc7SCole Faust# set.union (allows any iterable for right operand) 61*4947cdc7SCole Faustassert.eq(list(set("a".elems()).union("b".elems())), ["a", "b"]) 62*4947cdc7SCole Faustassert.eq(list(set("ab".elems()).union("bc".elems())), ["a", "b", "c"]) 63*4947cdc7SCole Faustassert.eq(set().union([]), set()) 64*4947cdc7SCole Faustassert.eq(type(x.union(y)), "set") 65*4947cdc7SCole Faustassert.eq(list(x.union(y)), [1, 2, 3, 4, 5]) 66*4947cdc7SCole Faustassert.eq(list(x.union([5, 1])), [1, 2, 3, 5]) 67*4947cdc7SCole Faustassert.eq(list(x.union((6, 5, 4))), [1, 2, 3, 6, 5, 4]) 68*4947cdc7SCole Faustassert.fails(lambda : x.union([1, 2, {}]), "unhashable type: dict") 69*4947cdc7SCole Faust 70*4947cdc7SCole Faust# intersection, set & set (use resolve.AllowBitwise to enable it) 71*4947cdc7SCole Faustassert.eq(list(set("a".elems()) & set("b".elems())), []) 72*4947cdc7SCole Faustassert.eq(list(set("ab".elems()) & set("bc".elems())), ["b"]) 73*4947cdc7SCole Faust 74*4947cdc7SCole Faust# symmetric difference, set ^ set (use resolve.AllowBitwise to enable it) 75*4947cdc7SCole Faustassert.eq(set([1, 2, 3]) ^ set([4, 5, 3]), set([1, 2, 4, 5])) 76*4947cdc7SCole Faust 77*4947cdc7SCole Faustdef test_set_augmented_assign(): 78*4947cdc7SCole Faust x = set([1, 2, 3]) 79*4947cdc7SCole Faust x &= set([2, 3]) 80*4947cdc7SCole Faust assert.eq(x, set([2, 3])) 81*4947cdc7SCole Faust x |= set([1]) 82*4947cdc7SCole Faust assert.eq(x, set([1, 2, 3])) 83*4947cdc7SCole Faust x ^= set([4, 5, 3]) 84*4947cdc7SCole Faust assert.eq(x, set([1, 2, 4, 5])) 85*4947cdc7SCole Faust 86*4947cdc7SCole Fausttest_set_augmented_assign() 87*4947cdc7SCole Faust 88*4947cdc7SCole Faust# len 89*4947cdc7SCole Faustassert.eq(len(x), 3) 90*4947cdc7SCole Faustassert.eq(len(y), 3) 91*4947cdc7SCole Faustassert.eq(len(x | y), 5) 92*4947cdc7SCole Faust 93*4947cdc7SCole Faust# str 94*4947cdc7SCole Faustassert.eq(str(set([1])), "set([1])") 95*4947cdc7SCole Faustassert.eq(str(set([2, 3])), "set([2, 3])") 96*4947cdc7SCole Faustassert.eq(str(set([3, 2])), "set([3, 2])") 97*4947cdc7SCole Faust 98*4947cdc7SCole Faust# comparison 99*4947cdc7SCole Faustassert.eq(x, x) 100*4947cdc7SCole Faustassert.eq(y, y) 101*4947cdc7SCole Faustassert.true(x != y) 102*4947cdc7SCole Faustassert.eq(set([1, 2, 3]), set([3, 2, 1])) 103*4947cdc7SCole Faustassert.fails(lambda : x < y, "set < set not implemented") 104*4947cdc7SCole Faust 105*4947cdc7SCole Faust# iteration 106*4947cdc7SCole Faustassert.true(type([elem for elem in x]), "list") 107*4947cdc7SCole Faustassert.true(list([elem for elem in x]), [1, 2, 3]) 108*4947cdc7SCole Faust 109*4947cdc7SCole Faustdef iter(): 110*4947cdc7SCole Faust list = [] 111*4947cdc7SCole Faust for elem in x: 112*4947cdc7SCole Faust list.append(elem) 113*4947cdc7SCole Faust return list 114*4947cdc7SCole Faust 115*4947cdc7SCole Faustassert.eq(iter(), [1, 2, 3]) 116*4947cdc7SCole Faust 117*4947cdc7SCole Faust# sets are not indexable 118*4947cdc7SCole Faustassert.fails(lambda : x[0], "unhandled.*operation") 119