# Test cases for sets (compile and run)

[case testSets]
from typing import Set, List
def instantiateLiteral() -> Set[int]:
    return {1, 2, 3, 5, 8}

def fromIterator() -> List[Set[int]]:
    a = set([1, 3, 5])
    b = set((1, 3, 5))
    c = set({1: '1', 3: '3', 5: '5'})
    d = set(x for x in range(1, 6, 2))
    e = set((x for x in range(1, 6, 2)))
    return [a, b, c, d, e]

def fromIterator2() -> Set[int]:
    tmp_list = [1, 2, 3, 4, 5]
    return set((x + 1) for x in ((y * 10) for y in (z for z in tmp_list if z < 4)))

def addIncrementing(s : Set[int]) -> None:
    for a in [1, 2, 3]:
        if a not in s:
            s.add(a)
            return

def replaceWith1(s : Set[int]) -> None:
    s.clear()
    s.add(1)

def remove1(s : Set[int]) -> None:
    s.remove(1)

def discard1(s: Set[int]) -> None:
    s.discard(1)

def pop(s : Set[int]) -> int:
    return s.pop()

def update(s: Set[int], x: List[int]) -> None:
    s.update(x)

[file driver.py]
from native import instantiateLiteral
from testutil import assertRaises

val = instantiateLiteral()
assert 1 in val
assert 2 in val
assert 3 in val
assert 5 in val
assert 8 in val
assert len(val) == 5
assert val == {1, 2, 3, 5, 8}
s = 0
for i in val:
    s += i
assert s == 19

from native import fromIterator
sets = fromIterator()
for s in sets:
    assert s == {1, 3, 5}

from native import fromIterator2
s = fromIterator2()
assert s == {11, 21, 31}

from native import addIncrementing
s = set()
addIncrementing(s)
assert s == {1}
addIncrementing(s)
assert s == {1, 2}
addIncrementing(s)
assert s == {1, 2, 3}

from native import replaceWith1
s = {3, 7, 12}
replaceWith1(s)
assert s == {1}

from native import remove1
import traceback
s = {1, 4, 6}
remove1(s)
assert s == {4, 6}
with assertRaises(KeyError, '1'):
    remove1(s)

from native import discard1
s = {1, 4, 6}
discard1(s)
assert s == {4, 6}
discard1(s)
assert s == {4, 6}

from native import pop
s = {1, 2, 3}
x = pop(s)
assert len(s) == 2
assert x in [1, 2, 3]
y = pop(s)
assert len(s) == 1
assert y in [1, 2, 3]
assert x != y
z = pop(s)
assert len(s) == 0
assert z in [1, 2, 3]
assert x != z
assert y != z
with assertRaises(KeyError, 'pop from an empty set'):
    pop(s)

from native import update
s = {1, 2, 3}
update(s, [5, 4, 3])
assert s == {1, 2, 3, 4, 5}

[case testPrecomputedFrozenSets]
from typing import Any
from typing_extensions import Final

CONST: Final = "CONST"
non_const = "non_const"

def main_set(item: Any) -> bool:
    return item in {None, False, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}

def main_negated_set(item: Any) -> bool:
    return item not in {None, False, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST}

def non_final_name_set(item: Any) -> bool:
    return item in {non_const}

s = set()
for i in {None, False, 1, 2.0, "3", b"4", 5j, (6,), CONST}:
    s.add(i)

def test_in_set() -> None:
    for item in (None, False, 1, 2.0, "3", b"4", 5j, (6,), ((7,),), (), CONST):
        assert main_set(item), f"{item!r} should be in set_main"
        assert not main_negated_set(item), item

    global non_const
    assert non_final_name_set(non_const)
    non_const = "updated"
    assert non_final_name_set("updated")

def test_for_set() -> None:
    assert not s ^ {None, False, 1, 2.0, "3", b"4", 5j, (6,), CONST}, s
