diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/gis_tests/geos_tests/test_geos.py | 47 | ||||
| -rw-r--r-- | tests/gis_tests/geos_tests/test_io.py | 2 | ||||
| -rw-r--r-- | tests/gis_tests/test_ptr.py | 65 |
3 files changed, 66 insertions, 48 deletions
diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 176ae3d482..2aee39072d 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -14,7 +14,6 @@ from django.contrib.gis.geos import ( LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, fromfile, fromstr, ) -from django.contrib.gis.geos.base import GEOSBase from django.contrib.gis.geos.libgeos import geos_version_info from django.contrib.gis.shortcuts import numpy from django.template import Context @@ -31,52 +30,6 @@ from ..test_data import TestDataMixin @skipUnless(HAS_GEOS, "Geos is required.") class GEOSTest(SimpleTestCase, TestDataMixin): - def test_base(self): - "Tests out the GEOSBase class." - # Testing out GEOSBase class, which provides a `ptr` property - # that abstracts out access to underlying C pointers. - class FakeGeom1(GEOSBase): - pass - - # This one only accepts pointers to floats - c_float_p = ctypes.POINTER(ctypes.c_float) - - class FakeGeom2(GEOSBase): - ptr_type = c_float_p - - # Default ptr_type is `c_void_p`. - fg1 = FakeGeom1() - # Default ptr_type is C float pointer - fg2 = FakeGeom2() - - # These assignments are OK -- None is allowed because - # it's equivalent to the NULL pointer. - fg1.ptr = ctypes.c_void_p() - fg1.ptr = None - fg2.ptr = c_float_p(ctypes.c_float(5.23)) - fg2.ptr = None - - # Because pointers have been set to NULL, an exception should be - # raised when we try to access it. Raising an exception is - # preferable to a segmentation fault that commonly occurs when - # a C method is given a NULL memory reference. - for fg in (fg1, fg2): - # Equivalent to `fg.ptr` - with self.assertRaises(GEOSException): - fg._get_ptr() - - # Anything that is either not None or the acceptable pointer type will - # result 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`) will not be allowed. - bad_ptrs = (5, ctypes.c_char_p(b'foobar')) - for bad_ptr in bad_ptrs: - # Equivalent to `fg.ptr = bad_ptr` - with self.assertRaises(TypeError): - fg1._set_ptr(bad_ptr) - with self.assertRaises(TypeError): - fg2._set_ptr(bad_ptr) - def test_wkt(self): "Testing WKT output." for g in self.geometries.wkt_out: diff --git a/tests/gis_tests/geos_tests/test_io.py b/tests/gis_tests/geos_tests/test_io.py index 601301331e..47995bf88c 100644 --- a/tests/gis_tests/geos_tests/test_io.py +++ b/tests/gis_tests/geos_tests/test_io.py @@ -37,7 +37,7 @@ class GEOSIOTest(SimpleTestCase): # Creating a WKTWriter instance, testing its ptr property. wkt_w = WKTWriter() with self.assertRaises(TypeError): - wkt_w._set_ptr(WKTReader.ptr_type()) + wkt_w.ptr = WKTReader.ptr_type() ref = GEOSGeometry('POINT (5 23)') ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)' diff --git a/tests/gis_tests/test_ptr.py b/tests/gis_tests/test_ptr.py new file mode 100644 index 0000000000..1b8beaf4e7 --- /dev/null +++ b/tests/gis_tests/test_ptr.py @@ -0,0 +1,65 @@ +import ctypes + +from django.contrib.gis.ptr import CPointerBase +from django.test import SimpleTestCase, mock + + +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.)) + fg.ptr = ptr + del fg + destructor_mock.assert_called_with(ptr) |
