# Test cases for lists (compile and run)

[case testListPlusEquals]
from typing import Any
def append(x: Any) -> None:
    x += [1]

[file driver.py]
from native import append
x = []
append(x)
assert x == [1]

[case testListSum]
from typing import List
def sum(a: List[int], l: int) -> int:
    sum = 0
    i = 0
    while i < l:
        sum = sum + a[i]
        i = i + 1
    return sum
[file driver.py]
from native import sum
print(sum([], 0))
print(sum([3], 1))
print(sum([5, 6, -4], 3))
print(sum([2**128 + 5, -2**127 - 8], 2))
[out]
0
3
7
170141183460469231731687303715884105725

[case testListSet]
from typing import List
def copy(a: List[int], b: List[int], l: int) -> int:
    i = 0
    while i < l:
        a[i] = b[i]
        i = i + 1
    return 0
[file driver.py]
from native import copy
a = [0, '']
copy(a, [-1, 5], 2)
print(1, a)
copy(a, [2**128 + 5, -2**127 - 8], 2)
print(2, a)
[out]
1 [-1, 5]
2 [340282366920938463463374607431768211461, -170141183460469231731687303715884105736]

[case testSieve]
from typing import List

def primes(n: int) -> List[int]:
    a = [1] * (n + 1)
    a[0] = 0
    a[1] = 0
    i = 0
    while i < n:
        if a[i] == 1:
            j = i * i
            while j < n:
                a[j] = 0
                j = j + i
        i = i + 1
    return a
[file driver.py]
from native import primes
print(primes(3))
print(primes(13))
[out]
\[0, 0, 1, 1]
\[0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1]

[case testListBuild]
def test_list_build() -> None:
    # Currently LIST_BUILDING_EXPANSION_THRESHOLD equals to 10
    # long list built by list_build_op
    l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    l1.pop()
    l1.append(100)
    assert l1 == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]
    # short list built by Setmem
    l2 = [1, 2]
    l2.append(3)
    l2.pop()
    l2.pop()
    assert l2 == [1]
    # empty list
    l3 = []
    l3.append('a')
    assert l3 == ['a']

[case testListPrims]
from typing import List

def test_append() -> None:
    l = [1, 2]
    l.append(10)
    assert l == [1, 2, 10]
    l.append(3)
    l.append(4)
    l.append(5)
    assert l == [1, 2, 10, 3, 4, 5]

def test_pop_last() -> None:
    l = [1, 2, 10, 3, 4, 5]
    l.pop()
    l.pop()
    assert l == [1, 2, 10, 3]

def test_pop_index() -> None:
    l = [1, 2, 10, 3]
    l.pop(2)
    assert l == [1, 2, 3]
    l.pop(-2)
    assert l == [1, 3]

def test_count() -> None:
    l = [1, 3]
    assert l.count(1) == 1
    assert l.count(2) == 0

def test_insert() -> None:
    l = [1, 3]
    l.insert(0, 0)
    assert l == [0, 1, 3]
    l.insert(2, 2)
    assert l == [0, 1, 2, 3]
    l.insert(4, 4)
    assert l == [0, 1, 2, 3, 4]
    l.insert(-1, 5)
    assert l == [0, 1, 2, 3, 5, 4]
    l = [1, 3]
    l.insert(100, 5)
    assert l == [1, 3, 5]
    l.insert(-100, 6)
    assert l == [6, 1, 3, 5]
    for long_int in 1 << 100, -(1 << 100):
        try:
            l.insert(long_int, 5)
        except Exception as e:
            # The error message is used by CPython
            assert type(e).__name__ == 'OverflowError'
            assert str(e) == 'Python int too large to convert to C ssize_t'
        else:
            assert False

def test_sort() -> None:
    l = [1, 4, 3, 6, -1]
    l.sort()
    assert l == [-1, 1, 3, 4, 6]
    l.sort()
    assert l == [-1, 1, 3, 4, 6]
    l = []
    l.sort()
    assert l == []

def test_reverse() -> None:
    l = [1, 4, 3, 6, -1]
    l.reverse()
    assert l == [-1, 6, 3, 4, 1]
    l.reverse()
    assert l == [1, 4, 3, 6, -1]
    l = []
    l.reverse()
    assert l == []

def test_remove() -> None:
    l = [1, 3, 4, 3]
    l.remove(3)
    assert l == [1, 4, 3]
    l.remove(3)
    assert l == [1, 4]
    try:
        l.remove(3)
    except ValueError:
        pass
    else:
        assert False

def test_index() -> None:
    l = [1, 3, 4, 3]
    assert l.index(1) == 0
    assert l.index(3) == 1
    assert l.index(4) == 2
    try:
        l.index(0)
    except ValueError:
        pass
    else:
        assert False

[case testListOfUserDefinedClass]
class C:
    x: int

def f() -> int:
    c = C()
    c.x = 5
    a = [c]
    d = a[0]
    return d.x + 1

def g() -> int:
    a = [C()]
    a[0].x = 3
    return a[0].x + 4
[file driver.py]
from native import f, g
print(f())
print(g())
[out]
6
7

[case testListOps]
def test_slicing() -> None:
    # Use dummy adds to avoid constant folding
    zero = int()
    two = zero + 2
    s = ["f", "o", "o", "b", "a", "r"]
    assert s[two:] == ["o", "b", "a", "r"]
    assert s[:two] == ["f", "o"]
    assert s[two:-two] == ["o", "b"]
    assert s[two:two] == []
    assert s[two:two + 1] == ["o"]
    assert s[-two:] == ["a", "r"]
    assert s[:-two] == ["f", "o", "o", "b"]
    assert s[:] == ["f", "o", "o", "b", "a", "r"]
    assert s[two:333] == ["o", "b", "a", "r"]
    assert s[333:two] == []
    assert s[two:-333] == []
    assert s[-333:two] == ["f", "o"]
    long_int: int = 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000
    assert s[1:long_int] == ["o", "o", "b", "a", "r"]
    assert s[long_int:] == []
    assert s[-long_int:-1] == ["f", "o", "o", "b", "a"]

[case testOperatorInExpression]

def tuple_in_int0(i: int) -> bool:
    return i in []

def tuple_in_int1(i: int) -> bool:
    return i in (1,)

def tuple_in_int3(i: int) -> bool:
    return i in (1, 2, 3)

def tuple_not_in_int0(i: int) -> bool:
    return i not in []

def tuple_not_in_int1(i: int) -> bool:
    return i not in (1,)

def tuple_not_in_int3(i: int) -> bool:
    return i not in (1, 2, 3)

def tuple_in_str(s: "str") -> bool:
    return s in ("foo", "bar", "baz")

def tuple_not_in_str(s: "str") -> bool:
    return s not in ("foo", "bar", "baz")

def list_in_int0(i: int) -> bool:
    return i in []

def list_in_int1(i: int) -> bool:
    return i in (1,)

def list_in_int3(i: int) -> bool:
    return i in (1, 2, 3)

def list_not_in_int0(i: int) -> bool:
    return i not in []

def list_not_in_int1(i: int) -> bool:
    return i not in (1,)

def list_not_in_int3(i: int) -> bool:
    return i not in (1, 2, 3)

def list_in_str(s: "str") -> bool:
    return s in ("foo", "bar", "baz")

def list_not_in_str(s: "str") -> bool:
    return s not in ("foo", "bar", "baz")

def list_in_mixed(i: object):
    return i in [[], (), "", 0, 0.0, False, 0j, {}, set(), type]

[file driver.py]

from native import *

assert not tuple_in_int0(0)
assert not tuple_in_int1(0)
assert tuple_in_int1(1)
assert not tuple_in_int3(0)
assert tuple_in_int3(1)
assert tuple_in_int3(2)
assert tuple_in_int3(3)
assert not tuple_in_int3(4)

assert tuple_not_in_int0(0)
assert tuple_not_in_int1(0)
assert not tuple_not_in_int1(1)
assert tuple_not_in_int3(0)
assert not tuple_not_in_int3(1)
assert not tuple_not_in_int3(2)
assert not tuple_not_in_int3(3)
assert tuple_not_in_int3(4)

assert tuple_in_str("foo")
assert tuple_in_str("bar")
assert tuple_in_str("baz")
assert not tuple_in_str("apple")
assert not tuple_in_str("pie")
assert not tuple_in_str("\0")
assert not tuple_in_str("")

assert not list_in_int0(0)
assert not list_in_int1(0)
assert list_in_int1(1)
assert not list_in_int3(0)
assert list_in_int3(1)
assert list_in_int3(2)
assert list_in_int3(3)
assert not list_in_int3(4)

assert list_not_in_int0(0)
assert list_not_in_int1(0)
assert not list_not_in_int1(1)
assert list_not_in_int3(0)
assert not list_not_in_int3(1)
assert not list_not_in_int3(2)
assert not list_not_in_int3(3)
assert list_not_in_int3(4)

assert list_in_str("foo")
assert list_in_str("bar")
assert list_in_str("baz")
assert not list_in_str("apple")
assert not list_in_str("pie")
assert not list_in_str("\0")
assert not list_in_str("")

assert list_in_mixed(0)
assert list_in_mixed([])
assert list_in_mixed({})
assert list_in_mixed(())
assert list_in_mixed(False)
assert list_in_mixed(0.0)
assert not list_in_mixed([1])
assert not list_in_mixed(object)
assert list_in_mixed(type)

[case testListBuiltFromGenerator]
def test() -> None:
    source_a = ["a", "b", "c"]
    a = list(x + "f2" for x in source_a)
    assert a == ["af2", "bf2", "cf2"]
    source_b = [1, 2, 3, 4, 5]
    b = [x * 2 for x in source_b]
    assert b == [2, 4, 6, 8, 10]
    source_c = [10, 20, 30]
    c = [x + "f4" for x in (str(y) + "yy" for y in source_c)]
    assert c == ["10yyf4", "20yyf4", "30yyf4"]
    source_d = [True, False]
    d = [not x for x in source_d]
    assert d == [False, True]
    source_e = [0, 1, 2]
    e = list((x ** 2) for x in (y + 2 for y in source_e))
    assert e == [4, 9, 16]
    source_str = "abcd"
    f = list("str:" + x for x in source_str)
    assert f == ["str:a", "str:b", "str:c", "str:d"]

[case testNextBug]
from typing import List, Optional

def test(x: List[int]) -> None:
    res = next((i for i in x), None)

[case testListGetItemWithBorrow]
from typing import List

class D:
    def __init__(self, n: int) -> None:
        self.n = n

class C:
    def __init__(self, d: D) -> None:
        self.d = d

def test_index_with_literal() -> None:
    d1 = D(1)
    d2 = D(2)
    a = [C(d1), C(d2)]
    d = a[0].d
    assert d is d1
    d = a[1].d
    assert d is d2
    d = a[-1].d
    assert d is d2
    d = a[-2].d
    assert d is d1
