tests: Add missing tests for builtins, and many other things.

This commit is contained in:
Damien George 2015-04-04 22:05:30 +01:00
parent 7e758b1cf8
commit 9dd3640464
37 changed files with 406 additions and 14 deletions

View File

@ -0,0 +1,9 @@
# test builtin chr (whether or not we support unicode)
print(chr(65))
try:
chr(0x110000)
except ValueError:
print("ValueError")

View File

@ -7,10 +7,9 @@ def have_compile():
except NameError:
return False
# global variable for compiled code to access
x = 1
def test():
global x
c = compile("print(x)", "file", "exec")
try:
@ -18,11 +17,31 @@ def test():
except NameError:
print("NameError")
# global variable for compiled code to access
x = 1
exec(c)
exec(c, {"x":2})
exec(c, {}, {"x":3})
# single/eval mode
exec(compile('print(1 + 1)', 'file', 'single'))
print(eval(compile('1 + 1', 'file', 'eval')))
# bad mode
try:
compile('1', 'file', '')
except ValueError:
print("ValueError")
# exception within compiled code
try:
exec(compile('noexist', 'file', 'exec'))
except NameError:
print("NameError")
print(x) # check 'x' still exists as a global
if have_compile():
test()
else:

View File

@ -0,0 +1,9 @@
# test builtin dir
# dir of locals
print('__name__' in dir())
# dir of module
import sys
print('platform' in dir(sys))

View File

@ -0,0 +1,16 @@
# test builtin divmod
print(divmod(0, 2))
print(divmod(3, 4))
print(divmod(20, 3))
try:
divmod(1, 0)
except ZeroDivisionError:
print("ZeroDivisionError")
try:
divmod('a', 'b')
except TypeError:
print("TypeError")

View File

@ -23,3 +23,9 @@ print(max(lst, key=lambda x:x))
print(max(lst, key=lambda x:-x))
print(max(1, 2, 3, 4, key=lambda x:-x))
print(max(4, 3, 2, 1, key=lambda x:-x))
# need at least 1 item in the iterable
try:
min([])
except ValueError:
print("ValueError")

View File

@ -0,0 +1,9 @@
# test builtin ord (whether or not we support unicode)
print(ord('a'))
try:
ord('')
except TypeError:
print("TypeError")

View File

@ -0,0 +1,11 @@
# test builtin pow() with integral values
# 2 arg version
print(pow(0, 1))
print(pow(1, 0))
print(pow(-2, 3))
print(pow(3, 8))
# 3 arg version
print(pow(3, 4, 7))

View File

@ -1,3 +1,16 @@
# test builtin property
# create a property object explicitly
property()
property(1, 2, 3)
# use its accessor methods
p = property()
p.getter(1)
p.setter(2)
p.deleter(3)
# basic use as a decorator
class A:
def __init__(self, x):
self._x = x
@ -15,6 +28,7 @@ try:
except AttributeError:
print("AttributeError")
# explicit use within a class
class B:
def __init__(self, x):
self._x = x
@ -27,13 +41,18 @@ class B:
print("x set")
self._x = value
x = property(xget, xset)
def xdel(self):
print("x del")
x = property(xget, xset, xdel)
b = B(3)
print(b.x)
b.x = 4
print(b.x)
del b.x
# full use as a decorator
class C:
def __init__(self, x):
self._x = x
@ -48,7 +67,12 @@ class C:
print("x set")
self._x = value
@x.deleter
def x(self):
print("x del")
c = C(5)
print(c.x)
c.x = 6
print(c.x)
del c.x

View File

@ -0,0 +1,7 @@
# test builtin slice
# print slice
class A:
def __getitem__(self, idx):
print(idx)
A()[1:2:3]

View File

@ -0,0 +1,10 @@
# test builtin sorted
print(sorted(set(range(100))))
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))
# need to use keyword argument
try:
sorted([], None)
except TypeError:
print("TypeError")

View File

@ -1,13 +1,19 @@
class Descriptor:
def __get__(self, obj, cls):
print('get')
print(type(obj) is Main)
print(cls is Main)
return 'result'
def __set__(self, obj, val):
print('set')
print(type(obj) is Main)
print(val)
def __delete__(self, obj):
print('delete')
print(type(obj) is Main)
class Main:
Forward = Descriptor()
@ -18,4 +24,5 @@ if 'Descriptor' in repr(r.__class__):
else:
print(r)
m.Forward = 'a'
del m.Forward

31
tests/basics/fun_error.py Normal file
View File

@ -0,0 +1,31 @@
# test errors from bad function calls
def test_exc(code, exc):
try:
exec(code)
print("no exception")
except exc:
print("right exception")
except:
print("wrong exception")
# function doesn't take keyword args
test_exc("[].append(x=1)", TypeError)
# function with variable number of positional args given too few
test_exc("round()", TypeError)
# function with variable number of positional args given too many
test_exc("round(1, 2, 3)", TypeError)
# function with fixed number of positional args given wrong number
test_exc("[].append(1, 2)", TypeError)
# function with keyword args given extra positional args
test_exc("[].sort(1)", TypeError)
# function with keyword args given extra keyword args
test_exc("[].sort(noexist=1)", TypeError)
# function with keyword args not given a specific keyword arg
test_exc("enumerate()", TypeError)

View File

@ -6,3 +6,18 @@ for rhs in range(2, 11):
print(lhs, '*', rhs, '=', res)
lhs = res
# below tests pos/neg combinations that overflow small int
# 31-bit overflow
i = 1 << 20
print(i * i)
print(i * -i)
print(-i * i)
print(-i * -i)
# 63-bit overflow
i = 1 << 40
print(i * i)
print(i * -i)
print(-i * i)
print(-i * -i)

13
tests/basics/module1.py Normal file
View File

@ -0,0 +1,13 @@
# test behaviour of module objects
# this module should always exist
import __main__
# print module
print(repr(__main__).startswith("<module '__main__'"))
# store new attribute
__main__.x = 1
# delete attribute
del __main__.x

6
tests/basics/module2.py Normal file
View File

@ -0,0 +1,6 @@
# uPy behaviour only: builtin modules are read-only
import sys
try:
sys.x = 1
except AttributeError:
print("AttributeError")

View File

@ -0,0 +1 @@
AttributeError

7
tests/basics/object1.py Normal file
View File

@ -0,0 +1,7 @@
# test builtin object()
# creation
object()
# printing
print(repr(object())[:7])

View File

@ -11,6 +11,7 @@ def test_exc(code, exc):
# unsupported unary operators
test_exc("~None", TypeError)
test_exc("~''", TypeError)
test_exc("~[]", TypeError)
test_exc("~bytearray()", TypeError)
@ -28,6 +29,8 @@ test_exc("(1 << 70) in 1", TypeError)
# unsupported subscription
test_exc("1[0]", TypeError)
test_exc("1[0] = 1", TypeError)
test_exc("''['']", TypeError)
test_exc("'a'[0] = 1", TypeError)
test_exc("del 1[0]", TypeError)
# not callable

View File

@ -1,2 +0,0 @@
print(sorted(set(range(100))))
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))

View File

@ -26,9 +26,11 @@ except IndexError:
# iter
print(list('str'))
# comparison
print('123' + '789' == '123789')
print('a' + 'b' != 'a' + 'b ')
print('1' + '2' > '2')
print('1' + '2' < '2')
# Not implemented so far
# print('1' + '2' > '2')
# print('1' + '2' < '2')
# printing quote char in string
print(repr('\'\"'))

21
tests/basics/sys1.py Normal file
View File

@ -0,0 +1,21 @@
# test sys module
import sys
print(sys.__name__)
print(type(sys.path))
print(type(sys.argv))
print(sys.version[:3])
print(sys.version_info[0], sys.version_info[1])
print(sys.byteorder in ('little', 'big'))
print(sys.maxsize > 100)
try:
sys.exit()
except SystemExit as e:
print("SystemExit", e.args)
try:
sys.exit(42)
except SystemExit as e:
print("SystemExit", e.args)

View File

@ -0,0 +1,21 @@
# check REPL allows to continue input
1 \
+ 2
'abc'
"abc"
'''abc
def'''
"""ABC
DEF"""
print(
1 + 2)
l = [1,
2]
print(l)
d = {1:'one',
2:'two'}
print(d[2])
def f(x):
print(x)
f(3)

View File

@ -0,0 +1,32 @@
Micro Python \.\+ linux version
>>> # check REPL allows to continue input
>>> 1 \
... + 2
3
>>> 'abc'
'abc'
>>> "abc"
'abc'
>>> '''abc
... def'''
'abc\ndef'
>>> """ABC
... DEF"""
'ABC\nDEF'
>>> print(
... 1 + 2)
3
>>> l = [1,
... 2]
>>> print(l)
[1, 2]
>>> d = {1:'one',
... 2:'two'}
>>> print(d[2])
two
>>> def f(x):
... print(x)
...
>>> f(3)
3
>>>

View File

@ -10,3 +10,7 @@ for t in tests:
# check .5 cases
for i in range(11):
print(round((i - 5) / 2))
# test second arg
# TODO uPy currently only supports second arg being 0
print(round(1.4, 0))

View File

@ -33,6 +33,9 @@ ans = 1j ** 2.5j; print("%.5g %.5g" % (ans.real, ans.imag))
print(abs(1j))
print("%.5g" % abs(1j + 2))
# float on lhs should delegate to complex
print(1.2 + 3j)
# convert bignum to complex on rhs
ans = 1j + (1 << 70); print("%.5g %.5g" % (ans.real, ans.imag))

View File

@ -1,4 +1,15 @@
# basic float
# test basic float capabilities
# float construction
print(float(1.2))
# unary operators
print(bool(0.0))
print(bool(1.2))
print(+(1.2))
print(-(1.2))
# division of integers
x = 1 / 2
print(x)
@ -7,9 +18,16 @@ a = 1
a /= 2
print(a)
# floor division
print(1.0 // 2)
print(2.0 // 2)
# comparison
print(1.2 <= 3.4)
print(1.2 <= -3.4)
print(1.2 >= 3.4)
print(1.2 >= -3.4)
try:
1.0 / 0
except ZeroDivisionError:
@ -20,6 +38,23 @@ try:
except ZeroDivisionError:
print("ZeroDivisionError")
try:
1.2 % 0
except ZeroDivisionError:
print("ZeroDivisionError")
# unsupported unary ops
try:
~1.2
except TypeError:
print("TypeError")
try:
1.2 in 3.4
except TypeError:
print("TypeError")
# can't convert list to float
try:
float([])

View File

@ -33,7 +33,9 @@ functions = [('sqrt', sqrt, p_test_values),
('ceil', ceil, test_values),
('fabs', fabs, test_values),
('floor', floor, test_values),
('trunc', trunc, test_values)
('trunc', trunc, test_values),
('radians', radians, test_values),
('degrees', degrees, test_values),
]
for function_name, function, test_vals in functions:
@ -52,10 +54,14 @@ for function_name, function, test_vals in tuple_functions:
print("{:.5g} {:.5g}".format(x, y))
binary_functions = [('copysign', copysign, [(23., 42.), (-23., 42.), (23., -42.),
(-23., -42.), (1., 0.0), (1., -0.0)])
(-23., -42.), (1., 0.0), (1., -0.0)]),
('pow', pow, ((1., 0.), (0., 1.), (2., 0.5), (-3., 5.), (-3., -4.),)),
('atan2', atan2, ((1., 0.), (0., 1.), (2., 0.5), (-3., 5.), (-3., -4.),)),
('fmod', fmod, ((1., 1.), (0., 1.), (2., 0.5), (-3., 5.), (-3., -4.),)),
('ldexp', ldexp, ((1., 0), (0., 1), (2., 2), (3., -2), (-3., -4),)),
]
for function_name, function, test_vals in binary_functions:
print(function_name)
for value1, value2 in test_vals:
print("{:.7g}".format(function(value1, value2)))
print("{:.5g}".format(function(value1, value2)))

View File

@ -1,6 +1,7 @@
import _io as io
a = io.StringIO()
print('io.StringIO' in repr(a))
print(a.getvalue())
print(a.read())

View File

@ -0,0 +1,6 @@
import _io as io
# test __enter__/__exit__
with io.StringIO() as b:
b.write("foo")
print(b.getvalue())

View File

@ -0,0 +1,12 @@
# tests meminfo functions in micropython module
import micropython
# these functions are not always available
if not hasattr(micropython, 'mem_info'):
print('SKIP')
else:
micropython.mem_info()
micropython.mem_info(1)
micropython.qstr_info()
micropython.qstr_info(1)

View File

@ -0,0 +1,14 @@
mem: total=\\d\+, current=\\d\+, peak=\\d\+
stack: \\d\+ out of \\d\+
GC: total: \\d\+, used: \\d\+, free: \\d\+
No. of 1-blocks: \\d\+, 2-blocks: \\d\+, max blk sz: \\d\+
mem: total=\\d\+, current=\\d\+, peak=\\d\+
stack: \\d\+ out of \\d\+
GC: total: \\d\+, used: \\d\+, free: \\d\+
No. of 1-blocks: \\d\+, 2-blocks: \\d\+, max blk sz: \\d\+
GC memory layout; from 0x\[0-9a-f\]\+:
########
qstr pool: n_pool=1, n_qstr=\\d, n_str_data_bytes=\\d\+, n_total_bytes=\\d\+
qstr pool: n_pool=1, n_qstr=\\d, n_str_data_bytes=\\d\+, n_total_bytes=\\d\+
########
Q(SKIP)

View File

@ -0,0 +1,17 @@
# tests meminfo functions in micropython module
import micropython
# these functions are not always available
if not hasattr(micropython, 'mem_total'):
print('SKIP')
else:
t = micropython.mem_total()
c = micropython.mem_current()
p = micropython.mem_peak()
l = list(range(10000))
print(micropython.mem_total() > t)
print(micropython.mem_current() > c)
print(micropython.mem_peak() > p)

View File

@ -0,0 +1,3 @@
True
True
True

View File

@ -29,7 +29,7 @@ def rm_f(fname):
def run_micropython(pyb, args, test_file):
if pyb is None:
# run on PC
if test_file.startswith('cmdline/'):
if test_file.startswith('cmdline/') or test_file == 'micropython/meminfo.py':
# special handling for tests of the unix cmdline program
# check for any cmdline options needed for this test
@ -141,6 +141,7 @@ def run_tests(pyb, tests, args):
if pyb is not None:
skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead
skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work
skip_tests.add('micropython/meminfo.py') # output is very different to PC output
# Some tests are known to fail on 64-bit machines
if pyb is None and platform.architecture()[0] == '64bit':
@ -162,6 +163,7 @@ def run_tests(pyb, tests, args):
skip_tests.add('float/cmath_fun.py') # requires f(*args) support
skip_tests.add('import/gen_context.py')
skip_tests.add('io/file_with.py')
skip_tests.add('io/stringio_with.py')
skip_tests.add('micropython/heapalloc.py')
skip_tests.add('misc/features.py')
skip_tests.add('misc/recursion.py')

View File

@ -16,3 +16,7 @@ for i in range(-len(s), len(s)):
# Test UTF-8 encode and decode
enc = s.encode()
print(enc, enc.decode() == s)
# printing of unicode chars using repr
# TODO we don't do this correctly
#print(repr(s))

View File

@ -0,0 +1,5 @@
# test builtin chr with unicode characters
print(chr(945))
print(chr(0x800))
print(chr(0x10000))

View File

@ -0,0 +1,3 @@
# test builtin ord with unicode characters
print(ord('α'))