376 lines
7.8 KiB
Plaintext
376 lines
7.8 KiB
Plaintext
|
# Test cases for misc primitives (compile and run)
|
||
|
#
|
||
|
# Please only add tests that don't have an obvious place in type-specific test
|
||
|
# files such as run-strings.test, run-lists.test, etc.
|
||
|
|
||
|
[case testGenericEquality]
|
||
|
def eq(a: object, b: object) -> bool:
|
||
|
if a == b:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def ne(a: object, b: object) -> bool:
|
||
|
if a != b:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def f(o: object) -> bool:
|
||
|
if [1, 2] == o:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
[file driver.py]
|
||
|
from native import eq, ne, f
|
||
|
assert eq('xz', 'x' + 'z')
|
||
|
assert not eq('x', 'y')
|
||
|
assert not ne('xz', 'x' + 'z')
|
||
|
assert ne('x', 'y')
|
||
|
assert f([1, 2])
|
||
|
assert not f([2, 2])
|
||
|
assert not f(1)
|
||
|
|
||
|
[case testGenericBinaryOps]
|
||
|
from typing import Any
|
||
|
def add(x: Any, y: Any) -> Any:
|
||
|
return x + y
|
||
|
def subtract(x: Any, y: Any) -> Any:
|
||
|
return x - y
|
||
|
def multiply(x: Any, y: Any) -> Any:
|
||
|
return x * y
|
||
|
def floor_div(x: Any, y: Any) -> Any:
|
||
|
return x // y
|
||
|
def true_div(x: Any, y: Any) -> Any:
|
||
|
return x / y
|
||
|
def remainder(x: Any, y: Any) -> Any:
|
||
|
return x % y
|
||
|
def power(x: Any, y: Any) -> Any:
|
||
|
return x ** y
|
||
|
def lshift(x: Any, y: Any) -> Any:
|
||
|
return x << y
|
||
|
def rshift(x: Any, y: Any) -> Any:
|
||
|
return x >> y
|
||
|
def num_and(x: Any, y: Any) -> Any:
|
||
|
return x & y
|
||
|
def num_xor(x: Any, y: Any) -> Any:
|
||
|
return x ^ y
|
||
|
def num_or(x: Any, y: Any) -> Any:
|
||
|
return x | y
|
||
|
def lt(x: Any, y: Any) -> Any:
|
||
|
if x < y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def le(x: Any, y: Any) -> Any:
|
||
|
if x <= y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def gt(x: Any, y: Any) -> Any:
|
||
|
if x > y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def ge(x: Any, y: Any) -> Any:
|
||
|
if x >= y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def contains(x: Any, y: Any) -> Any:
|
||
|
if x in y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def identity(x: Any, y: Any) -> Any:
|
||
|
if x is y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def disidentity(x: Any, y: Any) -> Any:
|
||
|
if x is not y:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def not_eq_cond(a: Any, b: Any) -> bool:
|
||
|
if not (a == b):
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
def eq2(a: Any, b: Any) -> bool:
|
||
|
return a == b
|
||
|
def slice1(x: Any) -> Any:
|
||
|
return x[:]
|
||
|
def slice2(x: Any, y: Any) -> Any:
|
||
|
return x[y:]
|
||
|
def slice3(x: Any, y: Any) -> Any:
|
||
|
return x[:y]
|
||
|
def slice4(x: Any, y: Any, z: Any) -> Any:
|
||
|
return x[y:z]
|
||
|
def slice5(x: Any, y: Any, z: Any, zz: Any) -> Any:
|
||
|
return x[y:z:zz]
|
||
|
[file driver.py]
|
||
|
from native import *
|
||
|
assert add(5, 6) == 11
|
||
|
assert add('x', 'y') == 'xy'
|
||
|
assert subtract(8, 3) == 5
|
||
|
assert multiply(8, 3) == 24
|
||
|
assert floor_div(8, 3) == 2
|
||
|
assert true_div(7, 2) == 3.5
|
||
|
assert remainder(11, 4) == 3
|
||
|
assert remainder('%.3d', 5) == '005'
|
||
|
assert remainder('%d-%s', (5, 'xy')) == '5-xy'
|
||
|
assert power(3, 4) == 81
|
||
|
assert lshift(5, 3) == 40
|
||
|
assert rshift(41, 3) == 5
|
||
|
assert num_and(99, 56) == 32
|
||
|
assert num_xor(99, 56) == 91
|
||
|
assert num_or(99, 56) == 123
|
||
|
assert lt('a', 'b')
|
||
|
assert not lt('a', 'a')
|
||
|
assert not lt('b', 'a')
|
||
|
assert not gt('a', 'b')
|
||
|
assert not gt('a', 'a')
|
||
|
assert gt('b', 'a')
|
||
|
assert le('a', 'b')
|
||
|
assert le('a', 'a')
|
||
|
assert not le('b', 'a')
|
||
|
assert not ge('a', 'b')
|
||
|
assert ge('a', 'a')
|
||
|
assert ge('b', 'a')
|
||
|
assert contains('x', 'axb')
|
||
|
assert not contains('X', 'axb')
|
||
|
assert contains('x', {'x', 'y'})
|
||
|
a = [1, 3, 5]
|
||
|
assert slice1(a) == a
|
||
|
assert slice1(a) is not a
|
||
|
assert slice2(a, 1) == [3, 5]
|
||
|
assert slice3(a, -1) == [1, 3]
|
||
|
assert slice4(a, 1, -1) == [3]
|
||
|
assert slice5(a, 2, 0, -1) == [5, 3]
|
||
|
o1, o2 = object(), object()
|
||
|
assert identity(o1, o1)
|
||
|
assert not identity(o1, o2)
|
||
|
assert not disidentity(o1, o1)
|
||
|
assert disidentity(o1, o2)
|
||
|
assert eq2('xz', 'x' + 'z')
|
||
|
assert not eq2('x', 'y')
|
||
|
assert not not_eq_cond('xz', 'x' + 'z')
|
||
|
assert not_eq_cond('x', 'y')
|
||
|
|
||
|
[case testGenericMiscOps]
|
||
|
from typing import Any
|
||
|
def neg(x: Any) -> Any:
|
||
|
return -x
|
||
|
def pos(x: Any) -> Any:
|
||
|
return +x
|
||
|
def invert(x: Any) -> Any:
|
||
|
return ~x
|
||
|
def get_item(o: Any, k: Any) -> Any:
|
||
|
return o[k]
|
||
|
def set_item(o: Any, k: Any, v: Any) -> Any:
|
||
|
o[k] = v
|
||
|
[file driver.py]
|
||
|
from native import *
|
||
|
assert neg(6) == -6
|
||
|
assert pos(6) == 6
|
||
|
assert invert(6) == -7
|
||
|
d = {'x': 5}
|
||
|
assert get_item(d, 'x') == 5
|
||
|
set_item(d, 'y', 6)
|
||
|
assert d['y'] == 6
|
||
|
|
||
|
[case testAnyAttributeAndMethodAccess]
|
||
|
from typing import Any, List
|
||
|
class C:
|
||
|
a: int
|
||
|
def m(self, x: int, a: List[int]) -> int:
|
||
|
return self.a + x + a[0]
|
||
|
def get_a(x: Any) -> Any:
|
||
|
return x.a
|
||
|
def set_a(x: Any, y: Any) -> None:
|
||
|
x.a = y
|
||
|
def call_m(x: Any) -> Any:
|
||
|
return x.m(1, [3])
|
||
|
[file driver.py]
|
||
|
from native import C, get_a, set_a, call_m
|
||
|
class D:
|
||
|
def m(self, x, a):
|
||
|
return self.a + x + a[0]
|
||
|
|
||
|
c = C()
|
||
|
c.a = 6
|
||
|
d = D()
|
||
|
d.a = 2
|
||
|
assert get_a(c) == 6
|
||
|
assert get_a(d) == 2
|
||
|
assert call_m(c) == 10
|
||
|
assert call_m(d) == 6
|
||
|
set_a(c, 5)
|
||
|
assert c.a == 5
|
||
|
set_a(d, 4)
|
||
|
assert d.a == 4
|
||
|
try:
|
||
|
get_a(object())
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False
|
||
|
try:
|
||
|
call_m(object())
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False
|
||
|
try:
|
||
|
set_a(object(), 5)
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False
|
||
|
|
||
|
[case testFloat]
|
||
|
def assign_and_return_float_sum() -> float:
|
||
|
f1 = 1.0
|
||
|
f2 = 2.0
|
||
|
f3 = 3.0
|
||
|
return f1 * f2 + f3
|
||
|
|
||
|
def from_int(i: int) -> float:
|
||
|
return float(i)
|
||
|
|
||
|
def to_int(x: float) -> int:
|
||
|
return int(x)
|
||
|
|
||
|
def get_complex() -> complex:
|
||
|
return 5.2j + 3.5 + 1j
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import assign_and_return_float_sum, from_int, to_int, get_complex
|
||
|
sum = 0.0
|
||
|
for i in range(10):
|
||
|
sum += assign_and_return_float_sum()
|
||
|
assert sum == 50.0
|
||
|
|
||
|
assert str(from_int(10)) == '10.0'
|
||
|
assert str(to_int(3.14)) == '3'
|
||
|
assert str(to_int(3)) == '3'
|
||
|
assert get_complex() == 3.5 + 6.2j
|
||
|
|
||
|
[case testDel]
|
||
|
from typing import List
|
||
|
from testutil import assertRaises
|
||
|
|
||
|
def printDict(dict) -> None:
|
||
|
l = list(dict.keys()) # type: List[str]
|
||
|
l.sort()
|
||
|
for key in l:
|
||
|
print(key, dict[key])
|
||
|
print("#########")
|
||
|
|
||
|
def delList() -> None:
|
||
|
l = [1, 2, 3]
|
||
|
print(tuple(l))
|
||
|
del l[1]
|
||
|
print(tuple(l))
|
||
|
|
||
|
def delDict() -> None:
|
||
|
d = {"one":1, "two":2}
|
||
|
printDict(d)
|
||
|
del d["one"]
|
||
|
printDict(d)
|
||
|
|
||
|
def delListMultiple() -> None:
|
||
|
l = [1, 2, 3, 4, 5, 6, 7]
|
||
|
print(tuple(l))
|
||
|
del l[1], l[2], l[3]
|
||
|
print(tuple(l))
|
||
|
|
||
|
def delDictMultiple() -> None:
|
||
|
d = {"one":1, "two":2, "three":3, "four":4}
|
||
|
printDict(d)
|
||
|
del d["two"], d["four"]
|
||
|
printDict(d)
|
||
|
|
||
|
class Dummy():
|
||
|
__deletable__ = ('x', 'y')
|
||
|
|
||
|
def __init__(self, x: int, y: int) -> None:
|
||
|
self.x = x
|
||
|
self.y = y
|
||
|
|
||
|
def delAttribute() -> None:
|
||
|
dummy = Dummy(1, 2)
|
||
|
del dummy.x
|
||
|
with assertRaises(AttributeError):
|
||
|
dummy.x
|
||
|
|
||
|
def delAttributeMultiple() -> None:
|
||
|
dummy = Dummy(1, 2)
|
||
|
del dummy.x, dummy.y
|
||
|
with assertRaises(AttributeError):
|
||
|
dummy.x
|
||
|
with assertRaises(AttributeError):
|
||
|
dummy.y
|
||
|
|
||
|
def delLocal(b: bool) -> int:
|
||
|
dummy = 10
|
||
|
if b:
|
||
|
del dummy
|
||
|
return dummy
|
||
|
|
||
|
def delLocalLoop() -> None:
|
||
|
# Try deleting a local in a loop to make sure the control flow analysis works
|
||
|
dummy = 1
|
||
|
for i in range(10):
|
||
|
print(dummy)
|
||
|
dummy *= 2
|
||
|
if i == 4:
|
||
|
del dummy
|
||
|
|
||
|
global_var = 10
|
||
|
del global_var
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import (
|
||
|
delList, delDict, delListMultiple, delDictMultiple, delAttribute,
|
||
|
delAttributeMultiple, delLocal, delLocalLoop,
|
||
|
)
|
||
|
import native
|
||
|
from testutil import assertRaises
|
||
|
|
||
|
delList()
|
||
|
delDict()
|
||
|
delListMultiple()
|
||
|
delDictMultiple()
|
||
|
delAttribute()
|
||
|
delAttributeMultiple()
|
||
|
with assertRaises(AttributeError):
|
||
|
native.global_var
|
||
|
with assertRaises(NameError, 'local variable "dummy" referenced before assignment'):
|
||
|
delLocal(True)
|
||
|
assert delLocal(False) == 10
|
||
|
with assertRaises(NameError, 'local variable "dummy" referenced before assignment'):
|
||
|
delLocalLoop()
|
||
|
[out]
|
||
|
(1, 2, 3)
|
||
|
(1, 3)
|
||
|
one 1
|
||
|
two 2
|
||
|
#########
|
||
|
two 2
|
||
|
#########
|
||
|
(1, 2, 3, 4, 5, 6, 7)
|
||
|
(1, 3, 5, 7)
|
||
|
four 4
|
||
|
one 1
|
||
|
three 3
|
||
|
two 2
|
||
|
#########
|
||
|
one 1
|
||
|
three 3
|
||
|
#########
|
||
|
1
|
||
|
2
|
||
|
4
|
||
|
8
|
||
|
16
|