ProjektAI/venv/Lib/site-packages/pygame/tests/base_test.py
2020-04-20 22:51:16 +02:00

639 lines
24 KiB
Python

# -*- coding: utf8 -*-
import sys
import unittest
import platform
IS_PYPY = 'PyPy' == platform.python_implementation()
try:
from pygame.tests.test_utils import arrinter
except NameError:
pass
import pygame
init_called = quit_called = 0
def __PYGAMEinit__(): #called automatically by pygame.init()
global init_called
init_called = init_called + 1
pygame.register_quit(pygame_quit)
def pygame_quit():
global quit_called
quit_called = quit_called + 1
quit_hook_ran = 0
def quit_hook():
global quit_hook_ran
quit_hook_ran = 1
class BaseModuleTest(unittest.TestCase):
def tearDown(self):
# Clean up after each test method.
pygame.quit()
def testAutoInit(self):
pygame.init()
pygame.quit()
self.assertEqual(init_called, 1)
self.assertEqual(quit_called, 1)
def test_get_sdl_byteorder(self):
"""Ensure the SDL byte order is valid"""
byte_order = pygame.get_sdl_byteorder()
expected_options = (pygame.LIL_ENDIAN, pygame.BIG_ENDIAN)
self.assertIn(byte_order, expected_options)
def test_get_sdl_version(self):
"""Ensure the SDL version is valid"""
self.assertEqual(len(pygame.get_sdl_version()), 3)
class ExporterBase(object):
def __init__(self, shape, typechar, itemsize):
import ctypes
ndim = len(shape)
self.ndim = ndim
self.shape = tuple(shape)
array_len = 1
for d in shape:
array_len *= d
self.size = itemsize * array_len
self.parent = ctypes.create_string_buffer(self.size)
self.itemsize = itemsize
strides = [itemsize] * ndim
for i in range(ndim - 1, 0, -1):
strides[i - 1] = strides[i] * shape[i]
self.strides = tuple(strides)
self.data = ctypes.addressof(self.parent), False
if self.itemsize == 1:
byteorder = '|'
elif sys.byteorder == 'big':
byteorder = '>'
else:
byteorder = '<'
self.typestr = byteorder + typechar + str(self.itemsize)
def assertSame(self, proxy, obj):
self.assertEqual(proxy.length, obj.size)
iface = proxy.__array_interface__
self.assertEqual(iface['typestr'], obj.typestr)
self.assertEqual(iface['shape'], obj.shape)
self.assertEqual(iface['strides'], obj.strides)
self.assertEqual(iface['data'], obj.data)
def test_PgObject_GetBuffer_array_interface(self):
from pygame.bufferproxy import BufferProxy
class Exporter(self.ExporterBase):
def get__array_interface__(self):
return {'version': 3,
'typestr': self.typestr,
'shape': self.shape,
'strides': self.strides,
'data': self.data}
__array_interface__ = property(get__array_interface__)
# Should be ignored by PgObject_GetBuffer
__array_struct__ = property(lambda self: None)
_shape = [2, 3, 5, 7, 11] # Some prime numbers
for ndim in range(1, len(_shape)):
o = Exporter(_shape[0:ndim], 'i', 2)
v = BufferProxy(o)
self.assertSame(v, o)
ndim = 2
shape = _shape[0:ndim]
for typechar in ('i', 'u'):
for itemsize in (1, 2, 4, 8):
o = Exporter(shape, typechar, itemsize)
v = BufferProxy(o)
self.assertSame(v, o)
for itemsize in (4, 8):
o = Exporter(shape, 'f', itemsize)
v = BufferProxy(o)
self.assertSame(v, o)
# Is the dict received from an exporting object properly released?
# The dict should be freed before PgObject_GetBuffer returns.
# When the BufferProxy v's length property is referenced, v calls
# PgObject_GetBuffer, which in turn references Exporter2 o's
# __array_interface__ property. The Exporter2 instance o returns a
# dict subclass for which it keeps both a regular reference and a
# weak reference. The regular reference should be the only
# remaining reference when PgObject_GetBuffer returns. This is
# verified by first checking the weak reference both before and
# after the regular reference held by o is removed.
import weakref, gc
class NoDictError(RuntimeError):
pass
class WRDict(dict):
"""Weak referenceable dict"""
pass
class Exporter2(Exporter):
def get__array_interface__2(self):
self.d = WRDict(Exporter.get__array_interface__(self))
self.dict_ref = weakref.ref(self.d)
return self.d
__array_interface__ = property(get__array_interface__2)
def free_dict(self):
self.d = None
def is_dict_alive(self):
try:
return self.dict_ref() is not None
except AttributeError:
raise NoDictError("__array_interface__ is unread")
o = Exporter2((2, 4), 'u', 4)
v = BufferProxy(o)
self.assertRaises(NoDictError, o.is_dict_alive)
length = v.length
self.assertTrue(o.is_dict_alive())
o.free_dict()
gc.collect()
self.assertFalse(o.is_dict_alive())
def test_GetView_array_struct(self):
from pygame.bufferproxy import BufferProxy
class Exporter(self.ExporterBase):
def __init__(self, shape, typechar, itemsize):
super(Exporter, self).__init__(shape, typechar, itemsize)
self.view = BufferProxy(self.__dict__)
def get__array_struct__(self):
return self.view.__array_struct__
__array_struct__ = property(get__array_struct__)
# Should not cause PgObject_GetBuffer to fail
__array_interface__ = property(lambda self: None)
_shape = [2, 3, 5, 7, 11] # Some prime numbers
for ndim in range(1, len(_shape)):
o = Exporter(_shape[0:ndim], 'i', 2)
v = BufferProxy(o)
self.assertSame(v, o)
ndim = 2
shape = _shape[0:ndim]
for typechar in ('i', 'u'):
for itemsize in (1, 2, 4, 8):
o = Exporter(shape, typechar, itemsize)
v = BufferProxy(o)
self.assertSame(v, o)
for itemsize in (4, 8):
o = Exporter(shape, 'f', itemsize)
v = BufferProxy(o)
self.assertSame(v, o)
# Check returned cobject/capsule reference count
try:
from sys import getrefcount
except ImportError:
# PyPy: no reference counting
pass
else:
o = Exporter(shape, typechar, itemsize)
self.assertEqual(getrefcount(o.__array_struct__), 1)
if pygame.HAVE_NEWBUF:
from pygame.tests.test_utils import buftools
def NEWBUF_assertSame(self, proxy, exp):
buftools = self.buftools
Importer = buftools.Importer
self.assertEqual(proxy.length, exp.len)
imp = Importer(proxy, buftools.PyBUF_RECORDS_RO)
self.assertEqual(imp.readonly, exp.readonly)
self.assertEqual(imp.format, exp.format)
self.assertEqual(imp.itemsize, exp.itemsize)
self.assertEqual(imp.ndim, exp.ndim)
self.assertEqual(imp.shape, exp.shape)
self.assertEqual(imp.strides, exp.strides)
self.assertTrue(imp.suboffsets is None)
@unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
def test_newbuf(self):
from pygame.bufferproxy import BufferProxy
Exporter = self.buftools.Exporter
_shape = [2, 3, 5, 7, 11] # Some prime numbers
for ndim in range(1, len(_shape)):
o = Exporter(_shape[0:ndim], '=h')
v = BufferProxy(o)
self.NEWBUF_assertSame(v, o)
ndim = 2
shape = _shape[0:ndim]
for format in ['b', 'B', '=h', '=H', '=i', '=I', '=q', '=Q', 'f', 'd',
'1h', '=1h', 'x', '1x', '2x', '3x', '4x', '5x', '6x',
'7x', '8x', '9x']:
o = Exporter(shape, format)
v = BufferProxy(o)
self.NEWBUF_assertSame(v, o)
@unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
def test_bad_format(self):
from pygame.bufferproxy import BufferProxy
from pygame.newbuffer import BufferMixin
from ctypes import create_string_buffer, addressof
buftools = self.buftools
Exporter = buftools.Exporter
Importer = buftools.Importer
PyBUF_FORMAT = buftools.PyBUF_FORMAT
for format in ['', '=', '1', ' ', '2h', '=2h',
'0x', '11x', '=!', 'h ', ' h', 'hh', '?']:
exp = Exporter((1,), format, itemsize=2)
b = BufferProxy(exp)
self.assertRaises(ValueError, Importer, b, PyBUF_FORMAT)
@unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
def test_PgDict_AsBuffer_PyBUF_flags(self):
from pygame.bufferproxy import BufferProxy
is_lil_endian = pygame.get_sdl_byteorder() == pygame.LIL_ENDIAN
fsys, frev = ('<', '>') if is_lil_endian else ('>', '<')
buftools = self.buftools
Importer = buftools.Importer
a = BufferProxy({'typestr': '|u4',
'shape': (10, 2),
'data': (9, False)}) # 9? No data accesses.
b = Importer(a, buftools.PyBUF_SIMPLE)
self.assertEqual(b.ndim, 0)
self.assertTrue(b.format is None)
self.assertEqual(b.len, a.length)
self.assertEqual(b.itemsize, 4)
self.assertTrue(b.shape is None)
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, 9)
b = Importer(a, buftools.PyBUF_WRITABLE)
self.assertEqual(b.ndim, 0)
self.assertTrue(b.format is None)
self.assertEqual(b.len, a.length)
self.assertEqual(b.itemsize, 4)
self.assertTrue(b.shape is None)
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, 9)
b = Importer(a, buftools.PyBUF_ND)
self.assertEqual(b.ndim, 2)
self.assertTrue(b.format is None)
self.assertEqual(b.len, a.length)
self.assertEqual(b.itemsize, 4)
self.assertEqual(b.shape, (10, 2))
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, 9)
a = BufferProxy({'typestr': fsys + 'i2',
'shape': (5, 10),
'strides': (24, 2),
'data': (42, False)}) # 42? No data accesses.
b = Importer(a, buftools.PyBUF_STRIDES)
self.assertEqual(b.ndim, 2)
self.assertTrue(b.format is None)
self.assertEqual(b.len, 100)
self.assertEqual(b.itemsize, 2)
self.assertEqual(b.shape, (5, 10))
self.assertEqual(b.strides, (24, 2))
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, 42)
b = Importer(a, buftools.PyBUF_FULL_RO)
self.assertEqual(b.ndim, 2)
self.assertEqual(b.format, '=h')
self.assertEqual(b.len, 100)
self.assertEqual(b.itemsize, 2)
self.assertEqual(b.shape, (5, 10))
self.assertEqual(b.strides, (24, 2))
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, 42)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_C_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_F_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_ANY_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_CONTIG)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_C_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_F_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_ANY_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_CONTIG)
a = BufferProxy({'typestr': frev + 'i2',
'shape': (3, 5, 10),
'strides': (120, 24, 2),
'data': (1000000, True)}) # 1000000? No data accesses.
b = Importer(a, buftools.PyBUF_FULL_RO)
self.assertEqual(b.ndim, 3)
self.assertEqual(b.format, frev + 'h')
self.assertEqual(b.len, 300)
self.assertEqual(b.itemsize, 2)
self.assertEqual(b.shape, (3, 5, 10))
self.assertEqual(b.strides, (120, 24, 2))
self.assertTrue(b.suboffsets is None)
self.assertTrue(b.readonly)
self.assertEqual(b.buf, 1000000)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_FULL)
@unittest.skipIf(IS_PYPY or (not pygame.HAVE_NEWBUF), 'newbuf with ctypes')
def test_PgObject_AsBuffer_PyBUF_flags(self):
from pygame.bufferproxy import BufferProxy
import ctypes
is_lil_endian = pygame.get_sdl_byteorder() == pygame.LIL_ENDIAN
fsys, frev = ('<', '>') if is_lil_endian else ('>', '<')
buftools = self.buftools
Importer = buftools.Importer
e = arrinter.Exporter((10, 2), typekind='f',
itemsize=ctypes.sizeof(ctypes.c_double))
a = BufferProxy(e)
b = Importer(a, buftools.PyBUF_SIMPLE)
self.assertEqual(b.ndim, 0)
self.assertTrue(b.format is None)
self.assertEqual(b.len, e.len)
self.assertEqual(b.itemsize, e.itemsize)
self.assertTrue(b.shape is None)
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, e.data)
b = Importer(a, buftools.PyBUF_WRITABLE)
self.assertEqual(b.ndim, 0)
self.assertTrue(b.format is None)
self.assertEqual(b.len, e.len)
self.assertEqual(b.itemsize, e.itemsize)
self.assertTrue(b.shape is None)
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, e.data)
b = Importer(a, buftools.PyBUF_ND)
self.assertEqual(b.ndim, e.nd)
self.assertTrue(b.format is None)
self.assertEqual(b.len, a.length)
self.assertEqual(b.itemsize, e.itemsize)
self.assertEqual(b.shape, e.shape)
self.assertTrue(b.strides is None)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, e.data)
e = arrinter.Exporter((5, 10), typekind='i', itemsize=2,
strides=(24, 2))
a = BufferProxy(e)
b = Importer(a, buftools.PyBUF_STRIDES)
self.assertEqual(b.ndim, e.nd)
self.assertTrue(b.format is None)
self.assertEqual(b.len, e.len)
self.assertEqual(b.itemsize, e.itemsize)
self.assertEqual(b.shape, e.shape)
self.assertEqual(b.strides, e.strides)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, e.data)
b = Importer(a, buftools.PyBUF_FULL_RO)
self.assertEqual(b.ndim, e.nd)
self.assertEqual(b.format, '=h')
self.assertEqual(b.len, e.len)
self.assertEqual(b.itemsize, e.itemsize)
self.assertEqual(b.shape, e.shape)
self.assertEqual(b.strides, e.strides)
self.assertTrue(b.suboffsets is None)
self.assertFalse(b.readonly)
self.assertEqual(b.buf, e.data)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_WRITABLE)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_WRITABLE)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_C_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_F_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_ANY_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_CONTIG)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_C_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_F_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a,
buftools.PyBUF_ANY_CONTIGUOUS)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_CONTIG)
e = arrinter.Exporter((3, 5, 10), typekind='i', itemsize=2,
strides=(120, 24, 2),
flags=arrinter.PAI_ALIGNED)
a = BufferProxy(e)
b = Importer(a, buftools.PyBUF_FULL_RO)
self.assertEqual(b.ndim, e.nd)
self.assertEqual(b.format, frev + 'h')
self.assertEqual(b.len, e.len)
self.assertEqual(b.itemsize, e.itemsize)
self.assertEqual(b.shape, e.shape)
self.assertEqual(b.strides, e.strides)
self.assertTrue(b.suboffsets is None)
self.assertTrue(b.readonly)
self.assertEqual(b.buf, e.data)
self.assertRaises(BufferError, Importer, a, buftools.PyBUF_FULL)
def test_PgObject_GetBuffer_exception(self):
# For consistency with surfarray
from pygame.bufferproxy import BufferProxy
bp = BufferProxy(1)
self.assertRaises(ValueError, getattr, bp, 'length')
def not_init_assertions(self):
self.assertFalse(pygame.get_init(), "pygame shouldn't be initialized")
self.assertFalse(pygame.display.get_init(),
"display shouldn't be initialized")
if 'pygame.mixer' in sys.modules:
self.assertFalse(pygame.mixer.get_init(),
"mixer shouldn't be initialized")
if 'pygame.font' in sys.modules:
self.assertFalse(pygame.font.get_init(),
"init shouldn't be initialized")
## !!! TODO : Remove when scrap works for OS X
import platform
if platform.system().startswith('Darwin'):
return
try:
self.assertRaises(pygame.error, pygame.scrap.get)
except NotImplementedError:
# Scrap is optional.
pass
# pygame.cdrom
# pygame.joystick
def init_assertions(self):
self.assertTrue(pygame.get_init())
self.assertTrue(pygame.display.get_init())
if 'pygame.mixer' in sys.modules:
self.assertTrue(pygame.mixer.get_init())
if 'pygame.font' in sys.modules:
self.assertTrue(pygame.font.get_init())
def test_quit__and_init(self):
# __doc__ (as of 2008-06-25) for pygame.base.quit:
# pygame.quit(): return None
# uninitialize all pygame modules
# Make sure everything is not init
self.not_init_assertions()
# Initiate it
pygame.init()
# Check
self.init_assertions()
# Quit
pygame.quit()
# All modules have quit
self.not_init_assertions()
def test_register_quit(self):
"""Ensure that a registered function is called on quit()"""
self.assertFalse(quit_hook_ran)
pygame.init()
pygame.register_quit(quit_hook)
pygame.quit()
self.assertTrue(quit_hook_ran)
def test_get_error(self):
# __doc__ (as of 2008-08-02) for pygame.base.get_error:
# pygame.get_error(): return errorstr
# get the current error message
#
# SDL maintains an internal error message. This message will usually
# be given to you when pygame.error is raised. You will rarely need to
# call this function.
#
# The first error could be all sorts of nonsense or empty.
e = pygame.get_error()
pygame.set_error("hi")
self.assertEqual(pygame.get_error(), "hi")
pygame.set_error("")
self.assertEqual(pygame.get_error(), "")
def test_set_error(self):
# The first error could be all sorts of nonsense or empty.
e = pygame.get_error()
pygame.set_error("hi")
self.assertEqual(pygame.get_error(), "hi")
pygame.set_error("")
self.assertEqual(pygame.get_error(), "")
def test_unicode_error(self):
if sys.version_info.major > 2:
pygame.set_error(u'你好')
self.assertEqual(u'你好', pygame.get_error())
else:
# no unicode objects for now
pygame.set_error(u'你好')
encstr = u'你好'.encode('utf8')
self.assertEqual(encstr, pygame.get_error())
def test_init(self):
# __doc__ (as of 2008-08-02) for pygame.base.init:
# pygame.init(): return (numpass, numfail)
# initialize all imported pygame modules
#
# Initialize all imported Pygame modules. No exceptions will be raised
# if a module fails, but the total number if successful and failed
# inits will be returned as a tuple. You can always initialize
# individual modules manually, but pygame.init is a convenient way to
# get everything started. The init() functions for individual modules
# will raise exceptions when they fail.
#
# You may want to initalise the different modules seperately to speed
# up your program or to not use things your game does not.
#
# It is safe to call this init() more than once: repeated calls will
# have no effect. This is true even if you have pygame.quit() all the
# modules.
#
# Make sure everything is not init
self.not_init_assertions()
# Initiate it
pygame.init()
# Check
self.init_assertions()
# Quit
pygame.quit()
# All modules have quit
self.not_init_assertions()
def test_get_init(self):
# Test if get_init() gets the init state.
self.assertFalse(pygame.get_init())
def test_get_init__after_init(self):
# Test if get_init() gets the init state after pygame.init() called.
pygame.init()
self.assertTrue(pygame.get_init())
def test_get_init__after_quit(self):
# Test if get_init() gets the init state after pygame.quit() called.
pygame.init()
pygame.quit()
self.assertFalse(pygame.get_init())
def todo_test_segfault(self):
# __doc__ (as of 2008-08-02) for pygame.base.segfault:
# crash
self.fail()
if __name__ == '__main__':
unittest.main()