go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/starlark/testdata/set.star (about)

     1  # Tests of Starlark 'set'
     2  # option:set option:globalreassign
     3  
     4  # Sets are not a standard part of Starlark, so the features
     5  # tested in this file must be enabled in the application by setting
     6  # resolve.AllowSet.  (All sets are created by calls to the 'set'
     7  # built-in or derived from operations on existing sets.)
     8  # The semantics are subject to change as the spec evolves.
     9  
    10  # TODO(adonovan): support set mutation:
    11  # - del set[k]
    12  # - set.update
    13  # - set += iterable, perhaps?
    14  # Test iterator invalidation.
    15  
    16  load("assert.star", "assert", "freeze")
    17  
    18  # literals
    19  # Parser does not currently support {1, 2, 3}.
    20  # TODO(adonovan): add test to syntax/testdata/errors.star.
    21  
    22  # set comprehensions
    23  # Parser does not currently support {x for x in y}.
    24  # See syntax/testdata/errors.star.
    25  
    26  # set constructor
    27  assert.eq(type(set()), "set")
    28  assert.eq(list(set()), [])
    29  assert.eq(type(set([1, 3, 2, 3])), "set")
    30  assert.eq(list(set([1, 3, 2, 3])), [1, 3, 2])
    31  assert.eq(type(set("hello".elems())), "set")
    32  assert.eq(list(set("hello".elems())), ["h", "e", "l", "o"])
    33  assert.eq(list(set(range(3))), [0, 1, 2])
    34  assert.fails(lambda : set(1), "got int, want iterable")
    35  assert.fails(lambda : set(1, 2, 3), "got 3 arguments")
    36  assert.fails(lambda : set([1, 2, {}]), "unhashable type: dict")
    37  
    38  # truth
    39  assert.true(not set())
    40  assert.true(set([False]))
    41  assert.true(set([1, 2, 3]))
    42  
    43  x = set([1, 2, 3])
    44  y = set([3, 4, 5])
    45  
    46  # set + any is not defined
    47  assert.fails(lambda : x + y, "unknown.*: set \\+ set")
    48  
    49  # set | set
    50  assert.eq(list(set("a".elems()) | set("b".elems())), ["a", "b"])
    51  assert.eq(list(set("ab".elems()) | set("bc".elems())), ["a", "b", "c"])
    52  assert.fails(lambda : set() | [], "unknown binary op: set | list")
    53  assert.eq(type(x | y), "set")
    54  assert.eq(list(x | y), [1, 2, 3, 4, 5])
    55  assert.eq(list(x | set([5, 1])), [1, 2, 3, 5])
    56  assert.eq(list(x | set((6, 5, 4))), [1, 2, 3, 6, 5, 4])
    57  
    58  # set.union (allows any iterable for right operand)
    59  assert.eq(list(set("a".elems()).union("b".elems())), ["a", "b"])
    60  assert.eq(list(set("ab".elems()).union("bc".elems())), ["a", "b", "c"])
    61  assert.eq(set().union([]), set())
    62  assert.eq(type(x.union(y)), "set")
    63  assert.eq(list(x.union(y)), [1, 2, 3, 4, 5])
    64  assert.eq(list(x.union([5, 1])), [1, 2, 3, 5])
    65  assert.eq(list(x.union((6, 5, 4))), [1, 2, 3, 6, 5, 4])
    66  assert.fails(lambda : x.union([1, 2, {}]), "unhashable type: dict")
    67  
    68  # intersection, set & set or set.intersection(iterable)
    69  assert.eq(list(set("a".elems()) & set("b".elems())), [])
    70  assert.eq(list(set("ab".elems()) & set("bc".elems())), ["b"])
    71  assert.eq(list(set("a".elems()).intersection("b".elems())), [])
    72  assert.eq(list(set("ab".elems()).intersection("bc".elems())), ["b"])
    73  
    74  # symmetric difference, set ^ set or set.symmetric_difference(iterable)
    75  assert.eq(set([1, 2, 3]) ^ set([4, 5, 3]), set([1, 2, 4, 5]))
    76  assert.eq(set([1,2,3,4]).symmetric_difference([3,4,5,6]), set([1,2,5,6]))
    77  assert.eq(set([1,2,3,4]).symmetric_difference(set([])), set([1,2,3,4]))
    78  
    79  def test_set_augmented_assign():
    80      x = set([1, 2, 3])
    81      x &= set([2, 3])
    82      assert.eq(x, set([2, 3]))
    83      x |= set([1])
    84      assert.eq(x, set([1, 2, 3]))
    85      x ^= set([4, 5, 3])
    86      assert.eq(x, set([1, 2, 4, 5]))
    87  
    88  test_set_augmented_assign()
    89  
    90  # len
    91  assert.eq(len(x), 3)
    92  assert.eq(len(y), 3)
    93  assert.eq(len(x | y), 5)
    94  
    95  # str
    96  assert.eq(str(set([1])), "set([1])")
    97  assert.eq(str(set([2, 3])), "set([2, 3])")
    98  assert.eq(str(set([3, 2])), "set([3, 2])")
    99  
   100  # comparison
   101  assert.eq(x, x)
   102  assert.eq(y, y)
   103  assert.true(x != y)
   104  assert.eq(set([1, 2, 3]), set([3, 2, 1]))
   105  
   106  # iteration
   107  assert.true(type([elem for elem in x]), "list")
   108  assert.true(list([elem for elem in x]), [1, 2, 3])
   109  
   110  def iter():
   111      list = []
   112      for elem in x:
   113          list.append(elem)
   114      return list
   115  
   116  assert.eq(iter(), [1, 2, 3])
   117  
   118  # sets are not indexable
   119  assert.fails(lambda : x[0], "unhandled.*operation")
   120  
   121  # adding and removing
   122  add_set = set([1,2,3])
   123  add_set.add(4)
   124  assert.true(4 in add_set)
   125  freeze(add_set) # no mutation of frozen set because key already present
   126  add_set.add(4)
   127  assert.fails(lambda: add_set.add(5), "add: cannot insert into frozen hash table")
   128  
   129  # remove
   130  remove_set = set([1,2,3])
   131  remove_set.remove(3)
   132  assert.true(3 not in remove_set)
   133  assert.fails(lambda: remove_set.remove(3), "remove: missing key")
   134  freeze(remove_set)
   135  assert.fails(lambda: remove_set.remove(3), "remove: cannot delete from frozen hash table")
   136  
   137  # discard
   138  discard_set = set([1,2,3])
   139  discard_set.discard(3)
   140  assert.true(3 not in discard_set)
   141  assert.eq(discard_set.discard(3), None)
   142  freeze(discard_set)
   143  assert.eq(discard_set.discard(3), None)  # no mutation of frozen set because key doesn't exist
   144  assert.fails(lambda: discard_set.discard(1), "discard: cannot delete from frozen hash table")
   145  
   146  
   147  # pop
   148  pop_set = set([1,2,3])
   149  assert.eq(pop_set.pop(), 1)
   150  assert.eq(pop_set.pop(), 2)
   151  assert.eq(pop_set.pop(), 3)
   152  assert.fails(lambda: pop_set.pop(), "pop: empty set")
   153  pop_set.add(1)
   154  pop_set.add(2)
   155  freeze(pop_set)
   156  assert.fails(lambda: pop_set.pop(), "pop: cannot delete from frozen hash table")
   157  
   158  # clear
   159  clear_set = set([1,2,3])
   160  clear_set.clear()
   161  assert.eq(len(clear_set), 0)
   162  freeze(clear_set) # no mutation of frozen set because its already empty
   163  assert.eq(clear_set.clear(), None) 
   164  
   165  other_clear_set = set([1,2,3])
   166  freeze(other_clear_set)
   167  assert.fails(lambda: other_clear_set.clear(), "clear: cannot clear frozen hash table")
   168  
   169  # difference: set - set or set.difference(iterable)
   170  assert.eq(set([1,2,3,4]).difference([1,2,3,4]), set([]))
   171  assert.eq(set([1,2,3,4]).difference([1,2]), set([3,4]))
   172  assert.eq(set([1,2,3,4]).difference([]), set([1,2,3,4]))
   173  assert.eq(set([1,2,3,4]).difference(set([1,2,3])), set([4]))
   174  
   175  assert.eq(set([1,2,3,4]) - set([1,2,3,4]), set())
   176  assert.eq(set([1,2,3,4]) - set([1,2]), set([3,4]))
   177  
   178  # issuperset: set >= set or set.issuperset(iterable)
   179  assert.true(set([1,2,3]).issuperset([1,2]))
   180  assert.true(not set([1,2,3]).issuperset(set([1,2,4])))
   181  assert.true(set([1,2,3]) >= set([1,2,3]))
   182  assert.true(set([1,2,3]) >= set([1,2]))
   183  assert.true(not set([1,2,3]) >= set([1,2,4]))
   184  
   185  # proper superset: set > set
   186  assert.true(set([1, 2, 3]) > set([1, 2]))
   187  assert.true(not set([1,2, 3]) > set([1, 2, 3]))
   188  
   189  # issubset: set <= set or set.issubset(iterable)
   190  assert.true(set([1,2]).issubset([1,2,3]))
   191  assert.true(not set([1,2,3]).issubset(set([1,2,4])))
   192  assert.true(set([1,2,3]) <= set([1,2,3]))
   193  assert.true(set([1,2]) <= set([1,2,3]))
   194  assert.true(not set([1,2,3]) <= set([1,2,4]))
   195  
   196  # proper subset: set < set
   197  assert.true(set([1,2]) < set([1,2,3]))
   198  assert.true(not set([1,2,3]) < set([1,2,3]))