1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00
django/tests/gis_tests/test_ptr.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

74 lines
2.3 KiB
Python
Raw Permalink Normal View History

import ctypes
from unittest import mock
from django.contrib.gis.ptr import CPointerBase
from django.test import SimpleTestCase
class CPointerBaseTests(SimpleTestCase):
def test(self):
destructor_mock = mock.Mock()
class NullPointerException(Exception):
pass
class FakeGeom1(CPointerBase):
null_ptr_exception_class = NullPointerException
class FakeGeom2(FakeGeom1):
ptr_type = ctypes.POINTER(ctypes.c_float)
destructor = destructor_mock
fg1 = FakeGeom1()
fg2 = FakeGeom2()
# These assignments are OK. None is allowed because it's equivalent
# to the NULL pointer.
fg1.ptr = fg1.ptr_type()
fg1.ptr = None
fg2.ptr = fg2.ptr_type(ctypes.c_float(5.23))
fg2.ptr = None
# Because pointers have been set to NULL, an exception is raised on
# access. Raising an exception is preferable to a segmentation fault
# that commonly occurs when a C method is given a NULL reference.
for fg in (fg1, fg2):
with self.assertRaises(NullPointerException):
fg.ptr
# Anything that's either not None or the acceptable pointer type
# results in a TypeError when trying to assign it to the `ptr` property.
# Thus, memory addresses (integers) and pointers of the incorrect type
# (in `bad_ptrs`) aren't allowed.
bad_ptrs = (5, ctypes.c_char_p(b"foobar"))
for bad_ptr in bad_ptrs:
for fg in (fg1, fg2):
with self.assertRaisesMessage(TypeError, "Incompatible pointer type"):
fg.ptr = bad_ptr
# Object can be deleted without a destructor set.
fg = FakeGeom1()
fg.ptr = fg.ptr_type(1)
del fg
# A NULL pointer isn't passed to the destructor.
fg = FakeGeom2()
fg.ptr = None
del fg
self.assertFalse(destructor_mock.called)
# The destructor is called if set.
fg = FakeGeom2()
ptr = fg.ptr_type(ctypes.c_float(1.0))
fg.ptr = ptr
del fg
destructor_mock.assert_called_with(ptr)
def test_destructor_catches_importerror(self):
class FakeGeom(CPointerBase):
destructor = mock.Mock(side_effect=ImportError)
fg = FakeGeom()
fg.ptr = fg.ptr_type(1)
del fg