diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 01ed3ab834..bee4588b97 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -37,9 +37,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_wkt(self): "Testing WKT output." for g in self.geometries.wkt_out: - geom = fromstr(g.wkt) - if geom.hasz: - self.assertEqual(g.ewkt, geom.wkt) + with self.subTest(g=g): + geom = fromstr(g.wkt) + if geom.hasz: + self.assertEqual(g.ewkt, geom.wkt) def test_wkt_invalid(self): msg = "String input unrecognized as WKT EWKT, and HEXEWKB." @@ -51,8 +52,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_hex(self): "Testing HEX output." for g in self.geometries.hex_wkt: - geom = fromstr(g.wkt) - self.assertEqual(g.hex, geom.hex.decode()) + with self.subTest(g=g): + geom = fromstr(g.wkt) + self.assertEqual(g.hex, geom.hex.decode()) def test_hexewkb(self): "Testing (HEX)EWKB output." @@ -89,11 +91,12 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_kml(self): "Testing KML output." - for tg in self.geometries.wkt_out: - geom = fromstr(tg.wkt) - kml = getattr(tg, "kml", False) - if kml: - self.assertEqual(kml, geom.kml) + for g in self.geometries.wkt_out: + with self.subTest(g=g): + geom = fromstr(g.wkt) + kml = getattr(g, "kml", False) + if kml: + self.assertEqual(kml, geom.kml) def test_errors(self): "Testing the Error handlers." @@ -133,40 +136,44 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_create_hex(self): "Testing creation from HEX." for g in self.geometries.hex_wkt: - geom_h = GEOSGeometry(g.hex) - # we need to do this so decimal places get normalized - geom_t = fromstr(g.wkt) - self.assertEqual(geom_t.wkt, geom_h.wkt) + with self.subTest(g=g): + geom_h = GEOSGeometry(g.hex) + # we need to do this so decimal places get normalized + geom_t = fromstr(g.wkt) + self.assertEqual(geom_t.wkt, geom_h.wkt) def test_create_wkb(self): "Testing creation from WKB." for g in self.geometries.hex_wkt: - wkb = memoryview(bytes.fromhex(g.hex)) - geom_h = GEOSGeometry(wkb) - # we need to do this so decimal places get normalized - geom_t = fromstr(g.wkt) - self.assertEqual(geom_t.wkt, geom_h.wkt) + with self.subTest(g=g): + wkb = memoryview(bytes.fromhex(g.hex)) + geom_h = GEOSGeometry(wkb) + # we need to do this so decimal places get normalized + geom_t = fromstr(g.wkt) + self.assertEqual(geom_t.wkt, geom_h.wkt) def test_ewkt(self): "Testing EWKT." srids = (-1, 32140) for srid in srids: for p in self.geometries.polygons: - ewkt = "SRID=%d;%s" % (srid, p.wkt) - poly = fromstr(ewkt) - self.assertEqual(srid, poly.srid) - self.assertEqual(srid, poly.shell.srid) - self.assertEqual(srid, fromstr(poly.ewkt).srid) # Checking export + with self.subTest(p=p): + ewkt = "SRID=%d;%s" % (srid, p.wkt) + poly = fromstr(ewkt) + self.assertEqual(srid, poly.srid) + self.assertEqual(srid, poly.shell.srid) + self.assertEqual(srid, fromstr(poly.ewkt).srid) # Checking export def test_json(self): "Testing GeoJSON input/output (via GDAL)." for g in self.geometries.json_geoms: - geom = GEOSGeometry(g.wkt) - if not hasattr(g, "not_equal"): - # Loading jsons to prevent decimal differences - self.assertEqual(json.loads(g.json), json.loads(geom.json)) - self.assertEqual(json.loads(g.json), json.loads(geom.geojson)) - self.assertEqual(GEOSGeometry(g.wkt, 4326), GEOSGeometry(geom.json)) + with self.subTest(g=g): + geom = GEOSGeometry(g.wkt) + if not hasattr(g, "not_equal"): + # Loading jsons to prevent decimal differences + self.assertEqual(json.loads(g.json), json.loads(geom.json)) + self.assertEqual(json.loads(g.json), json.loads(geom.geojson)) + self.assertEqual(GEOSGeometry(g.wkt, 4326), GEOSGeometry(geom.json)) def test_json_srid(self): geojson_data = { @@ -193,9 +200,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin): # Other tests use `fromfile()` on string filenames so those # aren't tested here. for fh in (wkt_f, wkb_f): - fh.seek(0) - pnt = fromfile(fh) - self.assertEqual(ref_pnt, pnt) + with self.subTest(fh=fh): + fh.seek(0) + pnt = fromfile(fh) + self.assertEqual(ref_pnt, pnt) def test_eq(self): "Testing equivalence." @@ -209,9 +217,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin): # Error shouldn't be raise on equivalence testing with # an invalid type. for g in (p, ls): - self.assertIsNotNone(g) - self.assertNotEqual(g, {"foo": "bar"}) - self.assertIsNot(g, False) + with self.subTest(g=g): + self.assertIsNotNone(g) + self.assertNotEqual(g, {"foo": "bar"}) + self.assertIsNot(g, False) def test_hash(self): point_1 = Point(5, 23) @@ -323,57 +332,58 @@ class GEOSTest(SimpleTestCase, TestDataMixin): "Testing Point objects." prev = fromstr("POINT(0 0)") for p in self.geometries.points: - # Creating the point from the WKT - pnt = fromstr(p.wkt) - self.assertEqual(pnt.geom_type, "Point") - self.assertEqual(pnt.geom_typeid, 0) - self.assertEqual(pnt.dims, 0) - self.assertEqual(p.x, pnt.x) - self.assertEqual(p.y, pnt.y) - self.assertEqual(pnt, fromstr(p.wkt)) - self.assertIs(pnt == prev, False) # Use assertIs() to test __eq__. + with self.subTest(p=p): + # Creating the point from the WKT + pnt = fromstr(p.wkt) + self.assertEqual(pnt.geom_type, "Point") + self.assertEqual(pnt.geom_typeid, 0) + self.assertEqual(pnt.dims, 0) + self.assertEqual(p.x, pnt.x) + self.assertEqual(p.y, pnt.y) + self.assertEqual(pnt, fromstr(p.wkt)) + self.assertIs(pnt == prev, False) # Use assertIs() to test __eq__. - # Making sure that the point's X, Y components are what we expect - self.assertAlmostEqual(p.x, pnt.tuple[0], 9) - self.assertAlmostEqual(p.y, pnt.tuple[1], 9) + # Making sure that the point's X, Y components are what we expect + self.assertAlmostEqual(p.x, pnt.tuple[0], 9) + self.assertAlmostEqual(p.y, pnt.tuple[1], 9) - # Testing the third dimension, and getting the tuple arguments - if hasattr(p, "z"): - self.assertIs(pnt.hasz, True) - self.assertEqual(p.z, pnt.z) - self.assertEqual(p.z, pnt.tuple[2], 9) - tup_args = (p.x, p.y, p.z) - set_tup1 = (2.71, 3.14, 5.23) - set_tup2 = (5.23, 2.71, 3.14) - else: - self.assertIs(pnt.hasz, False) - self.assertIsNone(pnt.z) - tup_args = (p.x, p.y) - set_tup1 = (2.71, 3.14) - set_tup2 = (3.14, 2.71) + # Testing the third dimension, and getting the tuple arguments + if hasattr(p, "z"): + self.assertIs(pnt.hasz, True) + self.assertEqual(p.z, pnt.z) + self.assertEqual(p.z, pnt.tuple[2], 9) + tup_args = (p.x, p.y, p.z) + set_tup1 = (2.71, 3.14, 5.23) + set_tup2 = (5.23, 2.71, 3.14) + else: + self.assertIs(pnt.hasz, False) + self.assertIsNone(pnt.z) + tup_args = (p.x, p.y) + set_tup1 = (2.71, 3.14) + set_tup2 = (3.14, 2.71) - # Centroid operation on point should be point itself - self.assertEqual(p.centroid, pnt.centroid.tuple) + # Centroid operation on point should be point itself + self.assertEqual(p.centroid, pnt.centroid.tuple) - # Now testing the different constructors - pnt2 = Point(tup_args) # e.g., Point((1, 2)) - pnt3 = Point(*tup_args) # e.g., Point(1, 2) - self.assertEqual(pnt, pnt2) - self.assertEqual(pnt, pnt3) + # Now testing the different constructors + pnt2 = Point(tup_args) # e.g., Point((1, 2)) + pnt3 = Point(*tup_args) # e.g., Point(1, 2) + self.assertEqual(pnt, pnt2) + self.assertEqual(pnt, pnt3) - # Now testing setting the x and y - pnt.y = 3.14 - pnt.x = 2.71 - self.assertEqual(3.14, pnt.y) - self.assertEqual(2.71, pnt.x) + # Now testing setting the x and y + pnt.y = 3.14 + pnt.x = 2.71 + self.assertEqual(3.14, pnt.y) + self.assertEqual(2.71, pnt.x) - # Setting via the tuple/coords property - pnt.tuple = set_tup1 - self.assertEqual(set_tup1, pnt.tuple) - pnt.coords = set_tup2 - self.assertEqual(set_tup2, pnt.coords) + # Setting via the tuple/coords property + pnt.tuple = set_tup1 + self.assertEqual(set_tup1, pnt.tuple) + pnt.coords = set_tup2 + self.assertEqual(set_tup2, pnt.coords) - prev = pnt # setting the previous geometry + prev = pnt # setting the previous geometry def test_point_reverse(self): point = GEOSGeometry("POINT(144.963 -37.8143)", 4326) @@ -384,61 +394,65 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_multipoints(self): "Testing MultiPoint objects." for mp in self.geometries.multipoints: - mpnt = fromstr(mp.wkt) - self.assertEqual(mpnt.geom_type, "MultiPoint") - self.assertEqual(mpnt.geom_typeid, 4) - self.assertEqual(mpnt.dims, 0) + with self.subTest(mp=mp): + mpnt = fromstr(mp.wkt) + self.assertEqual(mpnt.geom_type, "MultiPoint") + self.assertEqual(mpnt.geom_typeid, 4) + self.assertEqual(mpnt.dims, 0) - self.assertAlmostEqual(mp.centroid[0], mpnt.centroid.tuple[0], 9) - self.assertAlmostEqual(mp.centroid[1], mpnt.centroid.tuple[1], 9) + self.assertAlmostEqual(mp.centroid[0], mpnt.centroid.tuple[0], 9) + self.assertAlmostEqual(mp.centroid[1], mpnt.centroid.tuple[1], 9) - mpnt_len = len(mpnt) - msg = f"invalid index: {mpnt_len}" - with self.assertRaisesMessage(IndexError, msg): - mpnt.__getitem__(mpnt_len) - self.assertEqual(mp.centroid, mpnt.centroid.tuple) - self.assertEqual(mp.coords, tuple(m.tuple for m in mpnt)) - for p in mpnt: - self.assertEqual(p.geom_type, "Point") - self.assertEqual(p.geom_typeid, 0) - self.assertIs(p.empty, False) - self.assertIs(p.valid, True) + mpnt_len = len(mpnt) + msg = f"invalid index: {mpnt_len}" + with self.assertRaisesMessage(IndexError, msg): + mpnt.__getitem__(mpnt_len) + self.assertEqual(mp.centroid, mpnt.centroid.tuple) + self.assertEqual(mp.coords, tuple(m.tuple for m in mpnt)) + for p in mpnt: + self.assertEqual(p.geom_type, "Point") + self.assertEqual(p.geom_typeid, 0) + self.assertIs(p.empty, False) + self.assertIs(p.valid, True) def test_linestring(self): "Testing LineString objects." prev = fromstr("POINT(0 0)") for line in self.geometries.linestrings: - ls = fromstr(line.wkt) - self.assertEqual(ls.geom_type, "LineString") - self.assertEqual(ls.geom_typeid, 1) - self.assertEqual(ls.dims, 1) - self.assertIs(ls.empty, False) - self.assertIs(ls.ring, False) - if hasattr(line, "centroid"): - self.assertEqual(line.centroid, ls.centroid.tuple) - if hasattr(line, "tup"): - self.assertEqual(line.tup, ls.tuple) + with self.subTest(line=line): + ls = fromstr(line.wkt) + self.assertEqual(ls.geom_type, "LineString") + self.assertEqual(ls.geom_typeid, 1) + self.assertEqual(ls.dims, 1) + self.assertIs(ls.empty, False) + self.assertIs(ls.ring, False) + if hasattr(line, "centroid"): + self.assertEqual(line.centroid, ls.centroid.tuple) + if hasattr(line, "tup"): + self.assertEqual(line.tup, ls.tuple) - self.assertEqual(ls, fromstr(line.wkt)) - self.assertIs(ls == prev, False) # Use assertIs() to test __eq__. - ls_len = len(ls) - msg = f"invalid index: {ls_len}" - with self.assertRaisesMessage(IndexError, msg): - ls.__getitem__(ls_len) - prev = ls + self.assertEqual(ls, fromstr(line.wkt)) + self.assertIs(ls == prev, False) # Use assertIs() to test __eq__. + ls_len = len(ls) + msg = f"invalid index: {ls_len}" + with self.assertRaisesMessage(IndexError, msg): + ls.__getitem__(ls_len) + prev = ls - # Creating a LineString from a tuple, list, and numpy array - self.assertEqual(ls, LineString(ls.tuple)) # tuple - self.assertEqual(ls, LineString(*ls.tuple)) # as individual arguments - self.assertEqual(ls, LineString([list(tup) for tup in ls.tuple])) # as list - # Point individual arguments - self.assertEqual( - ls.wkt, LineString(*tuple(Point(tup) for tup in ls.tuple)).wkt - ) - if numpy: + # Creating a LineString from a tuple, list, and numpy array + self.assertEqual(ls, LineString(ls.tuple)) # tuple + self.assertEqual(ls, LineString(*ls.tuple)) # as individual arguments self.assertEqual( - ls, LineString(numpy.array(ls.tuple)) - ) # as numpy array + ls, LineString([list(tup) for tup in ls.tuple]) + ) # as list + # Point individual arguments + self.assertEqual( + ls.wkt, LineString(*tuple(Point(tup) for tup in ls.tuple)).wkt + ) + if numpy: + self.assertEqual( + ls, LineString(numpy.array(ls.tuple)) + ) # as numpy array with self.assertRaisesMessage( TypeError, "Each coordinate should be a sequence (list or tuple)" @@ -496,49 +510,53 @@ class GEOSTest(SimpleTestCase, TestDataMixin): "Testing MultiLineString objects." prev = fromstr("POINT(0 0)") for line in self.geometries.multilinestrings: - ml = fromstr(line.wkt) - self.assertEqual(ml.geom_type, "MultiLineString") - self.assertEqual(ml.geom_typeid, 5) - self.assertEqual(ml.dims, 1) + with self.subTest(line=line): + ml = fromstr(line.wkt) + self.assertEqual(ml.geom_type, "MultiLineString") + self.assertEqual(ml.geom_typeid, 5) + self.assertEqual(ml.dims, 1) - self.assertAlmostEqual(line.centroid[0], ml.centroid.x, 9) - self.assertAlmostEqual(line.centroid[1], ml.centroid.y, 9) + self.assertAlmostEqual(line.centroid[0], ml.centroid.x, 9) + self.assertAlmostEqual(line.centroid[1], ml.centroid.y, 9) - self.assertEqual(ml, fromstr(line.wkt)) - self.assertIs(ml == prev, False) # Use assertIs() to test __eq__. - prev = ml + self.assertEqual(ml, fromstr(line.wkt)) + self.assertIs(ml == prev, False) # Use assertIs() to test __eq__. + prev = ml - for ls in ml: - self.assertEqual(ls.geom_type, "LineString") - self.assertEqual(ls.geom_typeid, 1) - self.assertIs(ls.empty, False) + for ls in ml: + self.assertEqual(ls.geom_type, "LineString") + self.assertEqual(ls.geom_typeid, 1) + self.assertIs(ls.empty, False) - ml_len = len(ml) - msg = f"invalid index: {ml_len}" - with self.assertRaisesMessage(IndexError, msg): - ml.__getitem__(ml_len) - self.assertEqual(ml.wkt, MultiLineString(*tuple(s.clone() for s in ml)).wkt) - self.assertEqual( - ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml)) - ) + ml_len = len(ml) + msg = f"invalid index: {ml_len}" + with self.assertRaisesMessage(IndexError, msg): + ml.__getitem__(ml_len) + self.assertEqual( + ml.wkt, MultiLineString(*tuple(s.clone() for s in ml)).wkt + ) + self.assertEqual( + ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml)) + ) def test_linearring(self): "Testing LinearRing objects." for rr in self.geometries.linearrings: - lr = fromstr(rr.wkt) - self.assertEqual(lr.geom_type, "LinearRing") - self.assertEqual(lr.geom_typeid, 2) - self.assertEqual(lr.dims, 1) - self.assertEqual(rr.n_p, len(lr)) - self.assertIs(lr.valid, True) - self.assertIs(lr.empty, False) + with self.subTest(rr=rr): + lr = fromstr(rr.wkt) + self.assertEqual(lr.geom_type, "LinearRing") + self.assertEqual(lr.geom_typeid, 2) + self.assertEqual(lr.dims, 1) + self.assertEqual(rr.n_p, len(lr)) + self.assertIs(lr.valid, True) + self.assertIs(lr.empty, False) - # Creating a LinearRing from a tuple, list, and numpy array - self.assertEqual(lr, LinearRing(lr.tuple)) - self.assertEqual(lr, LinearRing(*lr.tuple)) - self.assertEqual(lr, LinearRing([list(tup) for tup in lr.tuple])) - if numpy: - self.assertEqual(lr, LinearRing(numpy.array(lr.tuple))) + # Creating a LinearRing from a tuple, list, and numpy array + self.assertEqual(lr, LinearRing(lr.tuple)) + self.assertEqual(lr, LinearRing(*lr.tuple)) + self.assertEqual(lr, LinearRing([list(tup) for tup in lr.tuple])) + if numpy: + self.assertEqual(lr, LinearRing(numpy.array(lr.tuple))) with self.assertRaisesMessage( ValueError, "LinearRing requires at least 4 points, got 3." @@ -580,76 +598,79 @@ class GEOSTest(SimpleTestCase, TestDataMixin): prev = fromstr("POINT(0 0)") for p in self.geometries.polygons: - # Creating the Polygon, testing its properties. - poly = fromstr(p.wkt) - self.assertEqual(poly.geom_type, "Polygon") - self.assertEqual(poly.geom_typeid, 3) - self.assertEqual(poly.dims, 2) - self.assertIs(poly.empty, False) - self.assertIs(poly.ring, False) - self.assertEqual(p.n_i, poly.num_interior_rings) - self.assertEqual(p.n_i + 1, len(poly)) # Testing __len__ - self.assertEqual(p.n_p, poly.num_points) + with self.subTest(p=p): + # Creating the Polygon, testing its properties. + poly = fromstr(p.wkt) + self.assertEqual(poly.geom_type, "Polygon") + self.assertEqual(poly.geom_typeid, 3) + self.assertEqual(poly.dims, 2) + self.assertIs(poly.empty, False) + self.assertIs(poly.ring, False) + self.assertEqual(p.n_i, poly.num_interior_rings) + self.assertEqual(p.n_i + 1, len(poly)) # Testing __len__ + self.assertEqual(p.n_p, poly.num_points) - # Area & Centroid - self.assertAlmostEqual(p.area, poly.area, 9) - self.assertAlmostEqual(p.centroid[0], poly.centroid.tuple[0], 9) - self.assertAlmostEqual(p.centroid[1], poly.centroid.tuple[1], 9) + # Area & Centroid + self.assertAlmostEqual(p.area, poly.area, 9) + self.assertAlmostEqual(p.centroid[0], poly.centroid.tuple[0], 9) + self.assertAlmostEqual(p.centroid[1], poly.centroid.tuple[1], 9) - # Testing the geometry equivalence - self.assertEqual(poly, fromstr(p.wkt)) - # Should not be equal to previous geometry - self.assertIs(poly == prev, False) # Use assertIs() to test __eq__. - self.assertIs(poly != prev, True) # Use assertIs() to test __ne__. + # Testing the geometry equivalence + self.assertEqual(poly, fromstr(p.wkt)) + # Should not be equal to previous geometry + self.assertIs(poly == prev, False) # Use assertIs() to test __eq__. + self.assertIs(poly != prev, True) # Use assertIs() to test __ne__. - # Testing the exterior ring - ring = poly.exterior_ring - self.assertEqual(ring.geom_type, "LinearRing") - self.assertEqual(ring.geom_typeid, 2) - if p.ext_ring_cs: - self.assertEqual(p.ext_ring_cs, ring.tuple) - self.assertEqual(p.ext_ring_cs, poly[0].tuple) # Testing __getitem__ + # Testing the exterior ring + ring = poly.exterior_ring + self.assertEqual(ring.geom_type, "LinearRing") + self.assertEqual(ring.geom_typeid, 2) + if p.ext_ring_cs: + self.assertEqual(p.ext_ring_cs, ring.tuple) + self.assertEqual( + p.ext_ring_cs, poly[0].tuple + ) # Testing __getitem__ - # Testing __getitem__ and __setitem__ on invalid indices - poly_len = len(poly) - msg = f"invalid index: {poly_len}" - with self.assertRaisesMessage(IndexError, msg): - poly.__getitem__(poly_len) - with self.assertRaisesMessage(IndexError, msg): - poly.__setitem__(poly_len, False) - negative_index = -1 * poly_len - 1 - msg = f"invalid index: {negative_index}" - with self.assertRaisesMessage(IndexError, msg): - poly.__getitem__(negative_index) + # Testing __getitem__ and __setitem__ on invalid indices + poly_len = len(poly) + msg = f"invalid index: {poly_len}" + with self.assertRaisesMessage(IndexError, msg): + poly.__getitem__(poly_len) + with self.assertRaisesMessage(IndexError, msg): + poly.__setitem__(poly_len, False) + negative_index = -1 * poly_len - 1 + msg = f"invalid index: {negative_index}" + with self.assertRaisesMessage(IndexError, msg): + poly.__getitem__(negative_index) - # Testing __iter__ - for r in poly: - self.assertEqual(r.geom_type, "LinearRing") - self.assertEqual(r.geom_typeid, 2) + # Testing __iter__ + for r in poly: + self.assertEqual(r.geom_type, "LinearRing") + self.assertEqual(r.geom_typeid, 2) - # Testing polygon construction. - msg = ( - "Parameter must be a sequence of LinearRings or " - "objects that can initialize to LinearRings" - ) - with self.assertRaisesMessage(TypeError, msg): - Polygon(0, [1, 2, 3]) - with self.assertRaisesMessage(TypeError, msg): - Polygon("foo") + # Testing polygon construction. + msg = ( + "Parameter must be a sequence of LinearRings or " + "objects that can initialize to LinearRings" + ) + with self.assertRaisesMessage(TypeError, msg): + Polygon(0, [1, 2, 3]) + with self.assertRaisesMessage(TypeError, msg): + Polygon("foo") - # Polygon(shell, (hole1, ... holeN)) - ext_ring, *int_rings = poly - self.assertEqual(poly, Polygon(ext_ring, int_rings)) + # Polygon(shell, (hole1, ... holeN)) + ext_ring, *int_rings = poly + self.assertEqual(poly, Polygon(ext_ring, int_rings)) - # Polygon(shell_tuple, hole_tuple1, ... , hole_tupleN) - ring_tuples = tuple(r.tuple for r in poly) - self.assertEqual(poly, Polygon(*ring_tuples)) + # Polygon(shell_tuple, hole_tuple1, ... , hole_tupleN) + ring_tuples = tuple(r.tuple for r in poly) + self.assertEqual(poly, Polygon(*ring_tuples)) - # Constructing with tuples of LinearRings. - self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt) - self.assertEqual( - poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt - ) + # Constructing with tuples of LinearRings. + self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt) + self.assertEqual( + poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt + ) def test_polygons_templates(self): # Accessing Polygon attributes in templates should work. @@ -674,27 +695,29 @@ class GEOSTest(SimpleTestCase, TestDataMixin): "Testing MultiPolygon objects." fromstr("POINT (0 0)") for mp in self.geometries.multipolygons: - mpoly = fromstr(mp.wkt) - self.assertEqual(mpoly.geom_type, "MultiPolygon") - self.assertEqual(mpoly.geom_typeid, 6) - self.assertEqual(mpoly.dims, 2) - self.assertEqual(mp.valid, mpoly.valid) + with self.subTest(mp=mp): + mpoly = fromstr(mp.wkt) + self.assertEqual(mpoly.geom_type, "MultiPolygon") + self.assertEqual(mpoly.geom_typeid, 6) + self.assertEqual(mpoly.dims, 2) + self.assertEqual(mp.valid, mpoly.valid) - if mp.valid: - mpoly_len = len(mpoly) - self.assertEqual(mp.num_geom, mpoly.num_geom) - self.assertEqual(mp.n_p, mpoly.num_coords) - self.assertEqual(mp.num_geom, mpoly_len) - msg = f"invalid index: {mpoly_len}" - with self.assertRaisesMessage(IndexError, msg): - mpoly.__getitem__(mpoly_len) - for p in mpoly: - self.assertEqual(p.geom_type, "Polygon") - self.assertEqual(p.geom_typeid, 3) - self.assertIs(p.valid, True) - self.assertEqual( - mpoly.wkt, MultiPolygon(*tuple(poly.clone() for poly in mpoly)).wkt - ) + if mp.valid: + mpoly_len = len(mpoly) + self.assertEqual(mp.num_geom, mpoly.num_geom) + self.assertEqual(mp.n_p, mpoly.num_coords) + self.assertEqual(mp.num_geom, mpoly_len) + msg = f"invalid index: {mpoly_len}" + with self.assertRaisesMessage(IndexError, msg): + mpoly.__getitem__(mpoly_len) + for p in mpoly: + self.assertEqual(p.geom_type, "Polygon") + self.assertEqual(p.geom_typeid, 3) + self.assertIs(p.valid, True) + self.assertEqual( + mpoly.wkt, + MultiPolygon(*tuple(poly.clone() for poly in mpoly)).wkt, + ) def test_memory_hijinks(self): "Testing Geometry __del__() on rings and polygons." @@ -723,35 +746,36 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_coord_seq(self): "Testing Coordinate Sequence objects." for p in self.geometries.polygons: - if p.ext_ring_cs: - # Constructing the polygon and getting the coordinate sequence - poly = fromstr(p.wkt) - cs = poly.exterior_ring.coord_seq + with self.subTest(p=p): + if p.ext_ring_cs: + # Constructing the polygon and getting the coordinate sequence + poly = fromstr(p.wkt) + cs = poly.exterior_ring.coord_seq - self.assertEqual( - p.ext_ring_cs, cs.tuple - ) # done in the Polygon test too. - self.assertEqual( - len(p.ext_ring_cs), len(cs) - ) # Making sure __len__ works + self.assertEqual( + p.ext_ring_cs, cs.tuple + ) # done in the Polygon test too. + self.assertEqual( + len(p.ext_ring_cs), len(cs) + ) # Making sure __len__ works - # Checks __getitem__ and __setitem__ - for i in range(len(p.ext_ring_cs)): - c1 = p.ext_ring_cs[i] # Expected value - c2 = cs[i] # Value from coordseq - self.assertEqual(c1, c2) + # Checks __getitem__ and __setitem__ + for i in range(len(p.ext_ring_cs)): + c1 = p.ext_ring_cs[i] # Expected value + c2 = cs[i] # Value from coordseq + self.assertEqual(c1, c2) - # Constructing the test value to set the coordinate sequence with - if len(c1) == 2: - tset = (5, 23) - else: - tset = (5, 23, 8) - cs[i] = tset - - # Making sure every set point matches what we expect - for j in range(len(tset)): + # Construct the test value to set the coordinate sequence with + if len(c1) == 2: + tset = (5, 23) + else: + tset = (5, 23, 8) cs[i] = tset - self.assertEqual(tset[j], cs[i][j]) + + # Making sure every set point matches what we expect + for j in range(len(tset)): + cs[i] = tset + self.assertEqual(tset[j], cs[i][j]) def test_relate_pattern(self): "Testing relate() and relate_pattern()." @@ -760,70 +784,76 @@ class GEOSTest(SimpleTestCase, TestDataMixin): with self.assertRaisesMessage(GEOSException, msg): g.relate_pattern(0, "invalid pattern, yo") for rg in self.geometries.relate_geoms: - a = fromstr(rg.wkt_a) - b = fromstr(rg.wkt_b) - self.assertEqual(rg.result, a.relate_pattern(b, rg.pattern)) - self.assertEqual(rg.pattern, a.relate(b)) + with self.subTest(rg=rg): + a = fromstr(rg.wkt_a) + b = fromstr(rg.wkt_b) + self.assertEqual(rg.result, a.relate_pattern(b, rg.pattern)) + self.assertEqual(rg.pattern, a.relate(b)) def test_intersection(self): "Testing intersects() and intersection()." for i in range(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - i1 = fromstr(self.geometries.intersect_geoms[i].wkt) - self.assertIs(a.intersects(b), True) - i2 = a.intersection(b) - self.assertTrue(i1.equals(i2)) - self.assertTrue(i1.equals(a & b)) # __and__ is intersection operator - a &= b # testing __iand__ - self.assertTrue(i1.equals(a)) + with self.subTest(i=i): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + i1 = fromstr(self.geometries.intersect_geoms[i].wkt) + self.assertIs(a.intersects(b), True) + i2 = a.intersection(b) + self.assertTrue(i1.equals(i2)) + self.assertTrue(i1.equals(a & b)) # __and__ is intersection operator + a &= b # testing __iand__ + self.assertTrue(i1.equals(a)) def test_union(self): "Testing union()." for i in range(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - u1 = fromstr(self.geometries.union_geoms[i].wkt) - u2 = a.union(b) - self.assertTrue(u1.equals(u2)) - self.assertTrue(u1.equals(a | b)) # __or__ is union operator - a |= b # testing __ior__ - self.assertTrue(u1.equals(a)) + with self.subTest(i=i): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + u1 = fromstr(self.geometries.union_geoms[i].wkt) + u2 = a.union(b) + self.assertTrue(u1.equals(u2)) + self.assertTrue(u1.equals(a | b)) # __or__ is union operator + a |= b # testing __ior__ + self.assertTrue(u1.equals(a)) def test_unary_union(self): "Testing unary_union." for i in range(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - u1 = fromstr(self.geometries.union_geoms[i].wkt) - u2 = GeometryCollection(a, b).unary_union - self.assertTrue(u1.equals(u2)) + with self.subTest(i=i): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + u1 = fromstr(self.geometries.union_geoms[i].wkt) + u2 = GeometryCollection(a, b).unary_union + self.assertTrue(u1.equals(u2)) def test_difference(self): "Testing difference()." for i in range(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - d1 = fromstr(self.geometries.diff_geoms[i].wkt) - d2 = a.difference(b) - self.assertTrue(d1.equals(d2)) - self.assertTrue(d1.equals(a - b)) # __sub__ is difference operator - a -= b # testing __isub__ - self.assertTrue(d1.equals(a)) + with self.subTest(i=i): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + d1 = fromstr(self.geometries.diff_geoms[i].wkt) + d2 = a.difference(b) + self.assertTrue(d1.equals(d2)) + self.assertTrue(d1.equals(a - b)) # __sub__ is difference operator + a -= b # testing __isub__ + self.assertTrue(d1.equals(a)) def test_symdifference(self): "Testing sym_difference()." for i in range(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - d1 = fromstr(self.geometries.sdiff_geoms[i].wkt) - d2 = a.sym_difference(b) - self.assertTrue(d1.equals(d2)) - self.assertTrue( - d1.equals(a ^ b) - ) # __xor__ is symmetric difference operator - a ^= b # testing __ixor__ - self.assertTrue(d1.equals(a)) + with self.subTest(i=i): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + d1 = fromstr(self.geometries.sdiff_geoms[i].wkt) + d2 = a.sym_difference(b) + self.assertTrue(d1.equals(d2)) + self.assertTrue( + d1.equals(a ^ b) + ) # __xor__ is symmetric difference operator + a ^= b # testing __ixor__ + self.assertTrue(d1.equals(a)) def test_buffer(self): bg = self.geometries.buffer_geoms[0] @@ -902,37 +932,38 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def _test_buffer(self, geometries, buffer_method_name): for bg in geometries: - g = fromstr(bg.wkt) + with self.subTest(bg=bg): + g = fromstr(bg.wkt) - # The buffer we expect - exp_buf = fromstr(bg.buffer_wkt) + # The buffer we expect + exp_buf = fromstr(bg.buffer_wkt) - # Constructing our buffer - buf_kwargs = { - kwarg_name: getattr(bg, kwarg_name) - for kwarg_name in ( - "width", - "quadsegs", - "end_cap_style", - "join_style", - "mitre_limit", - ) - if hasattr(bg, kwarg_name) - } - buf = getattr(g, buffer_method_name)(**buf_kwargs) - self.assertEqual(exp_buf.num_coords, buf.num_coords) - self.assertEqual(len(exp_buf), len(buf)) + # Constructing our buffer + buf_kwargs = { + kwarg_name: getattr(bg, kwarg_name) + for kwarg_name in ( + "width", + "quadsegs", + "end_cap_style", + "join_style", + "mitre_limit", + ) + if hasattr(bg, kwarg_name) + } + buf = getattr(g, buffer_method_name)(**buf_kwargs) + self.assertEqual(exp_buf.num_coords, buf.num_coords) + self.assertEqual(len(exp_buf), len(buf)) - # Now assuring that each point in the buffer is almost equal - for j in range(len(exp_buf)): - exp_ring = exp_buf[j] - buf_ring = buf[j] - self.assertEqual(len(exp_ring), len(buf_ring)) - for k in range(len(exp_ring)): - # Asserting the X, Y of each point are almost equal (due to - # floating point imprecision). - self.assertAlmostEqual(exp_ring[k][0], buf_ring[k][0], 9) - self.assertAlmostEqual(exp_ring[k][1], buf_ring[k][1], 9) + # Now assuring that each point in the buffer is almost equal + for j in range(len(exp_buf)): + exp_ring = exp_buf[j] + buf_ring = buf[j] + self.assertEqual(len(exp_ring), len(buf_ring)) + for k in range(len(exp_ring)): + # Asserting the X, Y of each point are almost equal (due to + # floating point imprecision). + self.assertAlmostEqual(exp_ring[k][0], buf_ring[k][0], 9) + self.assertAlmostEqual(exp_ring[k][1], buf_ring[k][1], 9) def test_covers(self): poly = Polygon(((0, 0), (0, 10), (10, 10), (10, 0), (0, 0))) @@ -966,7 +997,8 @@ class GEOSTest(SimpleTestCase, TestDataMixin): poly = fromstr(self.geometries.polygons[1].wkt, srid=4269) self.assertEqual(4269, poly.srid) for ring in poly: - self.assertEqual(4269, ring.srid) + with self.subTest(ring=ring): + self.assertEqual(4269, ring.srid) poly.srid = 4326 self.assertEqual(4326, poly.shell.srid) @@ -976,7 +1008,8 @@ class GEOSTest(SimpleTestCase, TestDataMixin): ) self.assertEqual(32021, gc.srid) for i in range(len(gc)): - self.assertEqual(32021, gc[i].srid) + with self.subTest(i=i): + self.assertEqual(32021, gc[i].srid) # GEOS may get the SRID from HEXEWKB # 'POINT(5 23)' at SRID=4326 in hex form -- obtained from PostGIS @@ -1009,90 +1042,94 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_custom_srid(self): """Test with a null srid and a srid unknown to GDAL.""" for srid in [None, 999999]: - pnt = Point(111200, 220900, srid=srid) - self.assertTrue( - pnt.ewkt.startswith( - ("SRID=%s;" % srid if srid else "") + "POINT (111200" + with self.subTest(srid=srid): + pnt = Point(111200, 220900, srid=srid) + self.assertTrue( + pnt.ewkt.startswith( + ("SRID=%s;" % srid if srid else "") + "POINT (111200" + ) ) - ) - self.assertIsInstance(pnt.ogr, gdal.OGRGeometry) - self.assertIsNone(pnt.srs) + self.assertIsInstance(pnt.ogr, gdal.OGRGeometry) + self.assertIsNone(pnt.srs) - # Test conversion from custom to a known srid - c2w = gdal.CoordTransform( - gdal.SpatialReference( - "+proj=mill +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R_A +datum=WGS84 " - "+units=m +no_defs" - ), - gdal.SpatialReference(4326), - ) - new_pnt = pnt.transform(c2w, clone=True) - self.assertEqual(new_pnt.srid, 4326) - self.assertAlmostEqual(new_pnt.x, 1, 1) - self.assertAlmostEqual(new_pnt.y, 2, 1) + # Test conversion from custom to a known srid + c2w = gdal.CoordTransform( + gdal.SpatialReference( + "+proj=mill +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R_A +datum=WGS84 " + "+units=m +no_defs" + ), + gdal.SpatialReference(4326), + ) + new_pnt = pnt.transform(c2w, clone=True) + self.assertEqual(new_pnt.srid, 4326) + self.assertAlmostEqual(new_pnt.x, 1, 1) + self.assertAlmostEqual(new_pnt.y, 2, 1) def test_mutable_geometries(self): "Testing the mutability of Polygons and Geometry Collections." # ### Testing the mutability of Polygons ### for p in self.geometries.polygons: - poly = fromstr(p.wkt) + with self.subTest(p=p): + poly = fromstr(p.wkt) - # Should only be able to use __setitem__ with LinearRing geometries. - msg = ( - "Parameter must be a sequence of LinearRings or " - "objects that can initialize to LinearRings" - ) + # Should only be able to use __setitem__ with LinearRing geometries. + msg = ( + "Parameter must be a sequence of LinearRings or " + "objects that can initialize to LinearRings" + ) - with self.assertRaisesMessage(TypeError, msg): - poly.__setitem__(0, LineString((1, 1), (2, 2))) + with self.assertRaisesMessage(TypeError, msg): + poly.__setitem__(0, LineString((1, 1), (2, 2))) - # Constructing the new shell by adding 500 to every point in the old shell. - shell_tup = poly.shell.tuple - new_coords = [] - for point in shell_tup: - new_coords.append((point[0] + 500.0, point[1] + 500.0)) - new_shell = LinearRing(*tuple(new_coords)) + # Construct the new shell by adding 500 to every point in the old shell. + shell_tup = poly.shell.tuple + new_coords = [] + for point in shell_tup: + new_coords.append((point[0] + 500.0, point[1] + 500.0)) + new_shell = LinearRing(*tuple(new_coords)) - # Assigning polygon's exterior ring w/the new shell - poly.exterior_ring = new_shell - str(new_shell) # new shell is still accessible - self.assertEqual(poly.exterior_ring, new_shell) - self.assertEqual(poly[0], new_shell) + # Assigning polygon's exterior ring w/the new shell + poly.exterior_ring = new_shell + str(new_shell) # new shell is still accessible + self.assertEqual(poly.exterior_ring, new_shell) + self.assertEqual(poly[0], new_shell) # ### Testing the mutability of Geometry Collections for tg in self.geometries.multipoints: - mp = fromstr(tg.wkt) - for i in range(len(mp)): - # Creating a random point. - pnt = mp[i] - new = Point(random.randint(21, 100), random.randint(21, 100)) - # Testing the assignment - mp[i] = new - str(new) # what was used for the assignment is still accessible - self.assertEqual(mp[i], new) - self.assertEqual(mp[i].wkt, new.wkt) - self.assertNotEqual(pnt, mp[i]) + with self.subTest(tg=tg): + mp = fromstr(tg.wkt) + for i in range(len(mp)): + # Creating a random point. + pnt = mp[i] + new = Point(random.randint(21, 100), random.randint(21, 100)) + # Testing the assignment + mp[i] = new + str(new) # what was used for the assignment is still accessible + self.assertEqual(mp[i], new) + self.assertEqual(mp[i].wkt, new.wkt) + self.assertNotEqual(pnt, mp[i]) # MultiPolygons involve much more memory management because each # Polygon w/in the collection has its own rings. for tg in self.geometries.multipolygons: - mpoly = fromstr(tg.wkt) - for i in range(len(mpoly)): - poly = mpoly[i] - old_poly = mpoly[i] - # Offsetting the each ring in the polygon by 500. - for j in range(len(poly)): - r = poly[j] - for k in range(len(r)): - r[k] = (r[k][0] + 500.0, r[k][1] + 500.0) - poly[j] = r + with self.subTest(tg=tg): + mpoly = fromstr(tg.wkt) + for i in range(len(mpoly)): + poly = mpoly[i] + old_poly = mpoly[i] + # Offsetting the each ring in the polygon by 500. + for j in range(len(poly)): + r = poly[j] + for k in range(len(r)): + r[k] = (r[k][0] + 500.0, r[k][1] + 500.0) + poly[j] = r - self.assertNotEqual(mpoly[i], poly) - # Testing the assignment - mpoly[i] = poly - str(poly) # Still accessible - self.assertEqual(mpoly[i], poly) - self.assertNotEqual(mpoly[i], old_poly) + self.assertNotEqual(mpoly[i], poly) + # Testing the assignment + mpoly[i] = poly + str(poly) # Still accessible + self.assertEqual(mpoly[i], poly) + self.assertNotEqual(mpoly[i], old_poly) # Extreme (!!) __setitem__ -- no longer works, have to detect # in the first object that __setitem__ is called in the subsequent @@ -1250,39 +1287,40 @@ class GEOSTest(SimpleTestCase, TestDataMixin): geoms.append(LineString(numpy.array([]))) for g in geoms: - self.assertIs(g.empty, True) + with self.subTest(g=g): + self.assertIs(g.empty, True) - # Testing len() and num_geom. - if isinstance(g, Polygon): - self.assertEqual(1, len(g)) # Has one empty linear ring - self.assertEqual(1, g.num_geom) - self.assertEqual(0, len(g[0])) - elif isinstance(g, (Point, LineString)): - self.assertEqual(1, g.num_geom) - self.assertEqual(0, len(g)) - else: - self.assertEqual(0, g.num_geom) - self.assertEqual(0, len(g)) + # Testing len() and num_geom. + if isinstance(g, Polygon): + self.assertEqual(1, len(g)) # Has one empty linear ring + self.assertEqual(1, g.num_geom) + self.assertEqual(0, len(g[0])) + elif isinstance(g, (Point, LineString)): + self.assertEqual(1, g.num_geom) + self.assertEqual(0, len(g)) + else: + self.assertEqual(0, g.num_geom) + self.assertEqual(0, len(g)) - # Testing __getitem__ (doesn't work on Point or Polygon) - if isinstance(g, Point): - # IndexError is not raised in GEOS 3.8.0. - if geos_version_tuple() != (3, 8, 0): - msg = "invalid GEOS Geometry index:" + # Testing __getitem__ (doesn't work on Point or Polygon) + if isinstance(g, Point): + # IndexError is not raised in GEOS 3.8.0. + if geos_version_tuple() != (3, 8, 0): + msg = "invalid GEOS Geometry index:" + with self.assertRaisesMessage(IndexError, msg): + g.x + elif isinstance(g, Polygon): + lr = g.shell + self.assertEqual("LINEARRING EMPTY", lr.wkt) + self.assertEqual(0, len(lr)) + self.assertIs(lr.empty, True) + msg = "invalid index: 0" with self.assertRaisesMessage(IndexError, msg): - g.x - elif isinstance(g, Polygon): - lr = g.shell - self.assertEqual("LINEARRING EMPTY", lr.wkt) - self.assertEqual(0, len(lr)) - self.assertIs(lr.empty, True) - msg = "invalid index: 0" - with self.assertRaisesMessage(IndexError, msg): - lr.__getitem__(0) - else: - msg = "invalid index: 0" - with self.assertRaisesMessage(IndexError, msg): - g.__getitem__(0) + lr.__getitem__(0) + else: + msg = "invalid index: 0" + with self.assertRaisesMessage(IndexError, msg): + g.__getitem__(0) def test_collection_dims(self): gc = GeometryCollection([]) @@ -1373,8 +1411,9 @@ class GEOSTest(SimpleTestCase, TestDataMixin): # correct as having a 1 meter accuracy. prec = -1 for p in (t1, t2, t3, k2): - self.assertAlmostEqual(trans.x, p.x, prec) - self.assertAlmostEqual(trans.y, p.y, prec) + with self.subTest(p=p): + self.assertAlmostEqual(trans.x, p.x, prec) + self.assertAlmostEqual(trans.y, p.y, prec) def test_transform_3d(self): p3d = GEOSGeometry("POINT (5 23 100)", 4326) @@ -1448,10 +1487,11 @@ class GEOSTest(SimpleTestCase, TestDataMixin): tgeoms.append(Point(srid=4326)) tgeoms.append(Point()) for geom in tgeoms: - s1 = pickle.dumps(geom) - g1 = pickle.loads(s1) - self.assertEqual(geom, g1) - self.assertEqual(geom.srid, g1.srid) + with self.subTest(geom=geom): + s1 = pickle.dumps(geom) + g1 = pickle.loads(s1) + self.assertEqual(geom, g1) + self.assertEqual(geom.srid, g1.srid) def test_prepared(self): "Testing PreparedGeometry support." @@ -1464,10 +1504,11 @@ class GEOSTest(SimpleTestCase, TestDataMixin): # A set of test points. pnts = [Point(5, 5), Point(7.5, 7.5), Point(2.5, 7.5)] for pnt in pnts: - # Results should be the same (but faster) - self.assertEqual(mpoly.contains(pnt), prep.contains(pnt)) - self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt)) - self.assertEqual(mpoly.covers(pnt), prep.covers(pnt)) + with self.subTest(pnt=pnt): + # Results should be the same (but faster) + self.assertEqual(mpoly.contains(pnt), prep.contains(pnt)) + self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt)) + self.assertEqual(mpoly.covers(pnt), prep.covers(pnt)) self.assertTrue(prep.crosses(fromstr("LINESTRING(1 1, 15 15)"))) self.assertTrue(prep.disjoint(Point(-5, -5))) diff --git a/tests/gis_tests/geos_tests/test_geos_mutation.py b/tests/gis_tests/geos_tests/test_geos_mutation.py index 642e96df45..0ab00be07d 100644 --- a/tests/gis_tests/geos_tests/test_geos_mutation.py +++ b/tests/gis_tests/geos_tests/test_geos_mutation.py @@ -86,7 +86,8 @@ class GEOSMutationTest(SimpleTestCase): "Testing Geometry IndexError" p = Point(1, 2) for i in range(-2, 2): - p._checkindex(i) + with self.subTest(i=i): + p._checkindex(i) msg = "invalid index: 2" with self.assertRaisesMessage(IndexError, msg): p._checkindex(2) @@ -97,17 +98,18 @@ class GEOSMutationTest(SimpleTestCase): def test01_PointMutations(self): "Testing Point mutations" for p in (Point(1, 2, 3), fromstr("POINT (1 2 3)")): - self.assertEqual( - p._get_single_external(1), 2.0, "Point _get_single_external" - ) + with self.subTest(p=p): + self.assertEqual( + p._get_single_external(1), 2.0, "Point _get_single_external" + ) - # _set_single - p._set_single(0, 100) - self.assertEqual(p.coords, (100.0, 2.0, 3.0), "Point _set_single") + # _set_single + p._set_single(0, 100) + self.assertEqual(p.coords, (100.0, 2.0, 3.0), "Point _set_single") - # _set_list - p._set_list(2, (50, 3141)) - self.assertEqual(p.coords, (50.0, 3141.0), "Point _set_list") + # _set_list + p._set_list(2, (50, 3141)) + self.assertEqual(p.coords, (50.0, 3141.0), "Point _set_list") def test02_PointExceptions(self): "Testing Point exceptions" @@ -121,9 +123,10 @@ class GEOSMutationTest(SimpleTestCase): "Testing Point API" q = Point(4, 5, 3) for p in (Point(1, 2, 3), fromstr("POINT (1 2 3)")): - p[0:2] = [4, 5] - for f in geos_function_tests: - self.assertEqual(f(q), f(p), "Point " + f.__name__) + with self.subTest(p=p): + p[0:2] = [4, 5] + for f in geos_function_tests: + self.assertEqual(f(q), f(p), "Point " + f.__name__) def test04_LineStringMutations(self): "Testing LineString mutations" @@ -131,29 +134,31 @@ class GEOSMutationTest(SimpleTestCase): LineString((1, 0), (4, 1), (6, -1)), fromstr("LINESTRING (1 0,4 1,6 -1)"), ): - self.assertEqual( - ls._get_single_external(1), - (4.0, 1.0), - "LineString _get_single_external", - ) + with self.subTest(ls=ls): + self.assertEqual( + ls._get_single_external(1), + (4.0, 1.0), + "LineString _get_single_external", + ) - # _set_single - ls._set_single(0, (-50, 25)) - self.assertEqual( - ls.coords, - ((-50.0, 25.0), (4.0, 1.0), (6.0, -1.0)), - "LineString _set_single", - ) + # _set_single + ls._set_single(0, (-50, 25)) + self.assertEqual( + ls.coords, + ((-50.0, 25.0), (4.0, 1.0), (6.0, -1.0)), + "LineString _set_single", + ) - # _set_list - ls._set_list(2, ((-50.0, 25.0), (6.0, -1.0))) - self.assertEqual( - ls.coords, ((-50.0, 25.0), (6.0, -1.0)), "LineString _set_list" - ) + # _set_list + ls._set_list(2, ((-50.0, 25.0), (6.0, -1.0))) + self.assertEqual( + ls.coords, ((-50.0, 25.0), (6.0, -1.0)), "LineString _set_list" + ) - lsa = LineString(ls.coords) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(ls), "LineString " + f.__name__) + lsa = LineString(ls.coords) + for f in geos_function_tests: + with self.subTest(f=f): + self.assertEqual(f(lsa), f(ls), "LineString " + f.__name__) def test05_Polygon(self): "Testing Polygon mutations" @@ -164,37 +169,45 @@ class GEOSMutationTest(SimpleTestCase): ), fromstr("POLYGON ((1 0,4 1,6 -1,8 10,1 0),(5 4,6 4,6 3,5 4))"), ): - self.assertEqual( - pg._get_single_external(0), - LinearRing((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)), - "Polygon _get_single_external(0)", - ) - self.assertEqual( - pg._get_single_external(1), - LinearRing((5, 4), (6, 4), (6, 3), (5, 4)), - "Polygon _get_single_external(1)", - ) + with self.subTest(pg=pg): + self.assertEqual( + pg._get_single_external(0), + LinearRing((1, 0), (4, 1), (6, -1), (8, 10), (1, 0)), + "Polygon _get_single_external(0)", + ) + self.assertEqual( + pg._get_single_external(1), + LinearRing((5, 4), (6, 4), (6, 3), (5, 4)), + "Polygon _get_single_external(1)", + ) - # _set_list - pg._set_list( - 2, - ( - ((1, 2), (10, 0), (12, 9), (-1, 15), (1, 2)), - ((4, 2), (5, 2), (5, 3), (4, 2)), - ), - ) - self.assertEqual( - pg.coords, - ( - ((1.0, 2.0), (10.0, 0.0), (12.0, 9.0), (-1.0, 15.0), (1.0, 2.0)), - ((4.0, 2.0), (5.0, 2.0), (5.0, 3.0), (4.0, 2.0)), - ), - "Polygon _set_list", - ) + # _set_list + pg._set_list( + 2, + ( + ((1, 2), (10, 0), (12, 9), (-1, 15), (1, 2)), + ((4, 2), (5, 2), (5, 3), (4, 2)), + ), + ) + self.assertEqual( + pg.coords, + ( + ( + (1.0, 2.0), + (10.0, 0.0), + (12.0, 9.0), + (-1.0, 15.0), + (1.0, 2.0), + ), + ((4.0, 2.0), (5.0, 2.0), (5.0, 3.0), (4.0, 2.0)), + ), + "Polygon _set_list", + ) - lsa = Polygon(*pg.coords) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(pg), "Polygon " + f.__name__) + lsa = Polygon(*pg.coords) + for f in geos_function_tests: + with self.subTest(f=f): + self.assertEqual(f(lsa), f(pg), "Polygon " + f.__name__) def test06_Collection(self): "Testing Collection mutations" @@ -203,17 +216,21 @@ class GEOSMutationTest(SimpleTestCase): fromstr("MULTIPOINT (3 4,-1 2,5 -4,2 8)"), ) for mp in points: - self.assertEqual( - mp._get_single_external(2), - Point(5, -4), - "Collection _get_single_external", - ) + with self.subTest(mp=mp): + self.assertEqual( + mp._get_single_external(2), + Point(5, -4), + "Collection _get_single_external", + ) - mp._set_list(3, map(Point, ((5, 5), (3, -2), (8, 1)))) - self.assertEqual( - mp.coords, ((5.0, 5.0), (3.0, -2.0), (8.0, 1.0)), "Collection _set_list" - ) + mp._set_list(3, map(Point, ((5, 5), (3, -2), (8, 1)))) + self.assertEqual( + mp.coords, + ((5.0, 5.0), (3.0, -2.0), (8.0, 1.0)), + "Collection _set_list", + ) - lsa = MultiPoint(*map(Point, ((5, 5), (3, -2), (8, 1)))) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(mp), "MultiPoint " + f.__name__) + lsa = MultiPoint(*map(Point, ((5, 5), (3, -2), (8, 1)))) + for f in geos_function_tests: + with self.subTest(f=f): + self.assertEqual(f(lsa), f(mp), "MultiPoint " + f.__name__) diff --git a/tests/gis_tests/geos_tests/test_io.py b/tests/gis_tests/geos_tests/test_io.py index e6d21db2a3..a206933065 100644 --- a/tests/gis_tests/geos_tests/test_io.py +++ b/tests/gis_tests/geos_tests/test_io.py @@ -23,9 +23,8 @@ class GEOSIOTest(SimpleTestCase): ref = GEOSGeometry(wkt) g1 = wkt_r.read(wkt.encode()) g2 = wkt_r.read(wkt) - - for geom in (g1, g2): - self.assertEqual(ref, geom) + self.assertEqual(g1, ref) + self.assertEqual(g2, ref) # Should only accept string objects. msg = "'wkt' must be bytes or str." @@ -71,14 +70,16 @@ class GEOSIOTest(SimpleTestCase): g1 = wkb_r.read(wkb) g2 = wkb_r.read(hex_bin) g3 = wkb_r.read(hex_str) - for geom in (g1, g2, g3): - self.assertEqual(ref, geom) + self.assertEqual(ref, g1) + self.assertEqual(ref, g2) + self.assertEqual(ref, g3) bad_input = (1, 5.23, None, False) msg = "'wkb' must be bytes, str or memoryview." for bad_wkb in bad_input: - with self.assertRaisesMessage(TypeError, msg): - wkb_r.read(bad_wkb) + with self.subTest(bad_wkb=bad_wkb): + with self.assertRaisesMessage(TypeError, msg): + wkb_r.read(bad_wkb) def test04_wkbwriter(self): wkb_w = WKBWriter() @@ -96,10 +97,13 @@ class GEOSIOTest(SimpleTestCase): # Ensuring bad byteorders are not accepted. for bad_byteorder in (-1, 2, 523, "foo", None): - # Equivalent of `wkb_w.byteorder = bad_byteorder` - msg = "Byte order parameter must be 0 (Big Endian) or 1 (Little Endian)." - with self.assertRaisesMessage(ValueError, msg): - wkb_w._set_byteorder(bad_byteorder) + with self.subTest(bad_byteorder=bad_byteorder): + # Equivalent of `wkb_w.byteorder = bad_byteorder` + msg = ( + "Byte order parameter must be 0 (Big Endian) or 1 (Little Endian)." + ) + with self.assertRaisesMessage(ValueError, msg): + wkb_w._set_byteorder(bad_byteorder) # Setting the byteorder to 0 (for Big Endian) wkb_w.byteorder = 0 @@ -122,10 +126,11 @@ class GEOSIOTest(SimpleTestCase): # Ensuring bad output dimensions are not accepted for bad_outdim in (-1, 0, 1, 4, 423, "foo", None): - with self.assertRaisesMessage( - ValueError, "WKB output dimension must be 2 or 3" - ): - wkb_w.outdim = bad_outdim + with self.subTest(bad_outdim=bad_outdim): + with self.assertRaisesMessage( + ValueError, "WKB output dimension must be 2 or 3" + ): + wkb_w.outdim = bad_outdim # Now setting the output dimensions to be 3 wkb_w.outdim = 3 @@ -225,12 +230,15 @@ class GEOSIOTest(SimpleTestCase): (b"010300000000000000", b"0103000020E610000000000000"), ] ): - wkb_w.byteorder = byteorder - for srid, hex in enumerate(hexes): - wkb_w.srid = srid - self.assertEqual(wkb_w.write_hex(p), hex) - self.assertEqual( - GEOSGeometry(wkb_w.write_hex(p)), p if srid else p_no_srid - ) - self.assertEqual(wkb_w.write(p), memoryview(binascii.a2b_hex(hex))) - self.assertEqual(GEOSGeometry(wkb_w.write(p)), p if srid else p_no_srid) + with self.subTest(byteorder=byteorder, hexes=hexes): + wkb_w.byteorder = byteorder + for srid, hex in enumerate(hexes): + wkb_w.srid = srid + self.assertEqual(wkb_w.write_hex(p), hex) + self.assertEqual( + GEOSGeometry(wkb_w.write_hex(p)), p if srid else p_no_srid + ) + self.assertEqual(wkb_w.write(p), memoryview(binascii.a2b_hex(hex))) + self.assertEqual( + GEOSGeometry(wkb_w.write(p)), p if srid else p_no_srid + ) diff --git a/tests/gis_tests/geos_tests/test_mutable_list.py b/tests/gis_tests/geos_tests/test_mutable_list.py index 83c7ac7d50..fc08f8382a 100644 --- a/tests/gis_tests/geos_tests/test_mutable_list.py +++ b/tests/gis_tests/geos_tests/test_mutable_list.py @@ -78,22 +78,24 @@ class ListMixinTest(SimpleTestCase): "Slice retrieval" pl, ul = self.lists_of_len() for i in self.limits_plus(1): - self.assertEqual(pl[i:], ul[i:], "slice [%d:]" % (i)) - self.assertEqual(pl[:i], ul[:i], "slice [:%d]" % (i)) + with self.subTest(i=i): + self.assertEqual(pl[i:], ul[i:], "slice [%d:]" % (i)) + self.assertEqual(pl[:i], ul[:i], "slice [:%d]" % (i)) + + for j in self.limits_plus(1): + self.assertEqual(pl[i:j], ul[i:j], "slice [%d:%d]" % (i, j)) + for k in self.step_range(): + self.assertEqual( + pl[i:j:k], ul[i:j:k], "slice [%d:%d:%d]" % (i, j, k) + ) - for j in self.limits_plus(1): - self.assertEqual(pl[i:j], ul[i:j], "slice [%d:%d]" % (i, j)) for k in self.step_range(): - self.assertEqual( - pl[i:j:k], ul[i:j:k], "slice [%d:%d:%d]" % (i, j, k) - ) - - for k in self.step_range(): - self.assertEqual(pl[i::k], ul[i::k], "slice [%d::%d]" % (i, k)) - self.assertEqual(pl[:i:k], ul[:i:k], "slice [:%d:%d]" % (i, k)) + self.assertEqual(pl[i::k], ul[i::k], "slice [%d::%d]" % (i, k)) + self.assertEqual(pl[:i:k], ul[:i:k], "slice [:%d:%d]" % (i, k)) for k in self.step_range(): - self.assertEqual(pl[::k], ul[::k], "slice [::%d]" % (k)) + with self.subTest(k=k): + self.assertEqual(pl[::k], ul[::k], "slice [::%d]" % (k)) def test02_setslice(self): "Slice assignment" @@ -103,129 +105,136 @@ class ListMixinTest(SimpleTestCase): pl, ul = self.lists_of_len() for slen in range(self.limit + 1): - ssl = nextRange(slen) - ul[:] = ssl - pl[:] = ssl - self.assertEqual(pl, ul[:], "set slice [:]") - - for i in self.limits_plus(1): + with self.subTest(slen=slen): ssl = nextRange(slen) - ul[i:] = ssl - pl[i:] = ssl - self.assertEqual(pl, ul[:], "set slice [%d:]" % (i)) + ul[:] = ssl + pl[:] = ssl + self.assertEqual(pl, ul[:], "set slice [:]") - ssl = nextRange(slen) - ul[:i] = ssl - pl[:i] = ssl - self.assertEqual(pl, ul[:], "set slice [:%d]" % (i)) - - for j in self.limits_plus(1): + for i in self.limits_plus(1): ssl = nextRange(slen) - ul[i:j] = ssl - pl[i:j] = ssl - self.assertEqual(pl, ul[:], "set slice [%d:%d]" % (i, j)) + ul[i:] = ssl + pl[i:] = ssl + self.assertEqual(pl, ul[:], "set slice [%d:]" % (i)) - for k in self.step_range(): - ssl = nextRange(len(ul[i:j:k])) - ul[i:j:k] = ssl - pl[i:j:k] = ssl - self.assertEqual(pl, ul[:], "set slice [%d:%d:%d]" % (i, j, k)) + ssl = nextRange(slen) + ul[:i] = ssl + pl[:i] = ssl + self.assertEqual(pl, ul[:], "set slice [:%d]" % (i)) - sliceLen = len(ul[i:j:k]) - msg = ( - f"attempt to assign sequence of size {sliceLen + 1} " - f"to extended slice of size {sliceLen}" - ) - with self.assertRaisesMessage(ValueError, msg): - setfcn(ul, i, j, k, sliceLen + 1) - if sliceLen > 2: + for j in self.limits_plus(1): + ssl = nextRange(slen) + ul[i:j] = ssl + pl[i:j] = ssl + self.assertEqual(pl, ul[:], "set slice [%d:%d]" % (i, j)) + + for k in self.step_range(): + ssl = nextRange(len(ul[i:j:k])) + ul[i:j:k] = ssl + pl[i:j:k] = ssl + self.assertEqual( + pl, ul[:], "set slice [%d:%d:%d]" % (i, j, k) + ) + + sliceLen = len(ul[i:j:k]) msg = ( - f"attempt to assign sequence of size {sliceLen - 1} " + f"attempt to assign sequence of size {sliceLen + 1} " f"to extended slice of size {sliceLen}" ) with self.assertRaisesMessage(ValueError, msg): - setfcn(ul, i, j, k, sliceLen - 1) + setfcn(ul, i, j, k, sliceLen + 1) + if sliceLen > 2: + msg = ( + f"attempt to assign sequence of size {sliceLen - 1}" + f" to extended slice of size {sliceLen}" + ) + with self.assertRaisesMessage(ValueError, msg): + setfcn(ul, i, j, k, sliceLen - 1) + + for k in self.step_range(): + ssl = nextRange(len(ul[i::k])) + ul[i::k] = ssl + pl[i::k] = ssl + self.assertEqual(pl, ul[:], "set slice [%d::%d]" % (i, k)) + + ssl = nextRange(len(ul[:i:k])) + ul[:i:k] = ssl + pl[:i:k] = ssl + self.assertEqual(pl, ul[:], "set slice [:%d:%d]" % (i, k)) for k in self.step_range(): - ssl = nextRange(len(ul[i::k])) - ul[i::k] = ssl - pl[i::k] = ssl - self.assertEqual(pl, ul[:], "set slice [%d::%d]" % (i, k)) - - ssl = nextRange(len(ul[:i:k])) - ul[:i:k] = ssl - pl[:i:k] = ssl - self.assertEqual(pl, ul[:], "set slice [:%d:%d]" % (i, k)) - - for k in self.step_range(): - ssl = nextRange(len(ul[::k])) - ul[::k] = ssl - pl[::k] = ssl - self.assertEqual(pl, ul[:], "set slice [::%d]" % (k)) + ssl = nextRange(len(ul[::k])) + ul[::k] = ssl + pl[::k] = ssl + self.assertEqual(pl, ul[:], "set slice [::%d]" % (k)) def test03_delslice(self): "Delete slice" for Len in range(self.limit): - pl, ul = self.lists_of_len(Len) - del pl[:] - del ul[:] - self.assertEqual(pl[:], ul[:], "del slice [:]") - for i in range(-Len - 1, Len + 1): + with self.subTest(Len=Len): pl, ul = self.lists_of_len(Len) - del pl[i:] - del ul[i:] - self.assertEqual(pl[:], ul[:], "del slice [%d:]" % (i)) - pl, ul = self.lists_of_len(Len) - del pl[:i] - del ul[:i] - self.assertEqual(pl[:], ul[:], "del slice [:%d]" % (i)) - for j in range(-Len - 1, Len + 1): + del pl[:] + del ul[:] + self.assertEqual(pl[:], ul[:], "del slice [:]") + for i in range(-Len - 1, Len + 1): pl, ul = self.lists_of_len(Len) - del pl[i:j] - del ul[i:j] - self.assertEqual(pl[:], ul[:], "del slice [%d:%d]" % (i, j)) + del pl[i:] + del ul[i:] + self.assertEqual(pl[:], ul[:], "del slice [%d:]" % (i)) + pl, ul = self.lists_of_len(Len) + del pl[:i] + del ul[:i] + self.assertEqual(pl[:], ul[:], "del slice [:%d]" % (i)) + for j in range(-Len - 1, Len + 1): + pl, ul = self.lists_of_len(Len) + del pl[i:j] + del ul[i:j] + self.assertEqual(pl[:], ul[:], "del slice [%d:%d]" % (i, j)) + for k in [*range(-Len - 1, 0), *range(1, Len)]: + pl, ul = self.lists_of_len(Len) + del pl[i:j:k] + del ul[i:j:k] + self.assertEqual( + pl[:], ul[:], "del slice [%d:%d:%d]" % (i, j, k) + ) + for k in [*range(-Len - 1, 0), *range(1, Len)]: pl, ul = self.lists_of_len(Len) - del pl[i:j:k] - del ul[i:j:k] - self.assertEqual( - pl[:], ul[:], "del slice [%d:%d:%d]" % (i, j, k) - ) + del pl[:i:k] + del ul[:i:k] + self.assertEqual(pl[:], ul[:], "del slice [:%d:%d]" % (i, k)) + + pl, ul = self.lists_of_len(Len) + del pl[i::k] + del ul[i::k] + self.assertEqual(pl[:], ul[:], "del slice [%d::%d]" % (i, k)) for k in [*range(-Len - 1, 0), *range(1, Len)]: pl, ul = self.lists_of_len(Len) - del pl[:i:k] - del ul[:i:k] - self.assertEqual(pl[:], ul[:], "del slice [:%d:%d]" % (i, k)) - - pl, ul = self.lists_of_len(Len) - del pl[i::k] - del ul[i::k] - self.assertEqual(pl[:], ul[:], "del slice [%d::%d]" % (i, k)) - - for k in [*range(-Len - 1, 0), *range(1, Len)]: - pl, ul = self.lists_of_len(Len) - del pl[::k] - del ul[::k] - self.assertEqual(pl[:], ul[:], "del slice [::%d]" % (k)) + del pl[::k] + del ul[::k] + self.assertEqual(pl[:], ul[:], "del slice [::%d]" % (k)) def test04_get_set_del_single(self): "Get/set/delete single item" pl, ul = self.lists_of_len() for i in self.limits_plus(0): - self.assertEqual(pl[i], ul[i], "get single item [%d]" % i) + with self.subTest(i=i): + self.assertEqual(pl[i], ul[i], "get single item [%d]" % i) for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - pl[i] = 100 - ul[i] = 100 - self.assertEqual(pl[:], ul[:], "set single item [%d]" % i) + with self.subTest(i=i): + pl, ul = self.lists_of_len() + pl[i] = 100 + ul[i] = 100 + self.assertEqual(pl[:], ul[:], "set single item [%d]" % i) for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - del pl[i] - del ul[i] - self.assertEqual(pl[:], ul[:], "del single item [%d]" % i) + with self.subTest(i=i): + pl, ul = self.lists_of_len() + del pl[i] + del ul[i] + self.assertEqual(pl[:], ul[:], "del single item [%d]" % i) def test05_out_of_range_exceptions(self): "Out of range exceptions" @@ -242,12 +251,13 @@ class ListMixinTest(SimpleTestCase): pl, ul = self.lists_of_len() for i in (-1 - self.limit, self.limit): msg = f"invalid index: {i}" - with self.assertRaisesMessage(IndexError, msg): # 'set index %d' % i) - setfcn(ul, i) - with self.assertRaisesMessage(IndexError, msg): # 'get index %d' % i) - getfcn(ul, i) - with self.assertRaisesMessage(IndexError, msg): # 'del index %d' % i) - delfcn(ul, i) + with self.subTest(i=i): + with self.assertRaisesMessage(IndexError, msg): # 'set index %d' % i) + setfcn(ul, i) + with self.assertRaisesMessage(IndexError, msg): # 'get index %d' % i) + getfcn(ul, i) + with self.assertRaisesMessage(IndexError, msg): # 'del index %d' % i) + delfcn(ul, i) def test06_list_methods(self): "List methods" @@ -265,15 +275,17 @@ class ListMixinTest(SimpleTestCase): self.assertEqual(pl[:], ul[:], "reverse") for i in self.limits_plus(1): - pl, ul = self.lists_of_len() - pl.insert(i, 50) - ul.insert(i, 50) - self.assertEqual(pl[:], ul[:], "insert at %d" % i) + with self.subTest(i=i): + pl, ul = self.lists_of_len() + pl.insert(i, 50) + ul.insert(i, 50) + self.assertEqual(pl[:], ul[:], "insert at %d" % i) for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - self.assertEqual(pl.pop(i), ul.pop(i), "popped value at %d" % i) - self.assertEqual(pl[:], ul[:], "after pop at %d" % i) + with self.subTest(i=i): + pl, ul = self.lists_of_len() + self.assertEqual(pl.pop(i), ul.pop(i), "popped value at %d" % i) + self.assertEqual(pl[:], ul[:], "after pop at %d" % i) pl, ul = self.lists_of_len() self.assertEqual(pl.pop(), ul.pop(i), "popped value") @@ -293,16 +305,19 @@ class ListMixinTest(SimpleTestCase): pl, ul = self.lists_of_len() for val in range(self.limit): - self.assertEqual(pl.index(val), ul.index(val), "index of %d" % val) + with self.subTest(val=val): + self.assertEqual(pl.index(val), ul.index(val), "index of %d" % val) for val in self.limits_plus(2): - self.assertEqual(pl.count(val), ul.count(val), "count %d" % val) + with self.subTest(val=val): + self.assertEqual(pl.count(val), ul.count(val), "count %d" % val) for val in range(self.limit): - pl, ul = self.lists_of_len() - pl.remove(val) - ul.remove(val) - self.assertEqual(pl[:], ul[:], "after remove val %d" % val) + with self.subTest(val=val): + pl, ul = self.lists_of_len() + pl.remove(val) + ul.remove(val) + self.assertEqual(pl[:], ul[:], "after remove val %d" % val) def indexfcn(x, v): return x.index(v) @@ -345,15 +360,17 @@ class ListMixinTest(SimpleTestCase): msg = "Must have at least 3 items" for i in range(len(ul) - ul._minlength + 1, len(ul)): - with self.assertRaisesMessage(ValueError, msg): - delfcn(ul, i) - with self.assertRaisesMessage(ValueError, msg): - setfcn(ul, i) + with self.subTest(i=i): + with self.assertRaisesMessage(ValueError, msg): + delfcn(ul, i) + with self.assertRaisesMessage(ValueError, msg): + setfcn(ul, i) del ul[: len(ul) - ul._minlength] ul._maxlength = 4 for i in range(0, ul._maxlength - len(ul)): - ul.append(i) + with self.subTest(i=i): + ul.append(i) msg = "Cannot have more than 4 items" with self.assertRaisesMessage(ValueError, msg): ul.append(10) @@ -373,17 +390,19 @@ class ListMixinTest(SimpleTestCase): "Index check" pl, ul = self.lists_of_len() for i in self.limits_plus(0): - if i < 0: - self.assertEqual( - ul._checkindex(i), i + self.limit, "_checkindex(neg index)" - ) - else: - self.assertEqual(ul._checkindex(i), i, "_checkindex(pos index)") + with self.subTest(i=i): + if i < 0: + self.assertEqual( + ul._checkindex(i), i + self.limit, "_checkindex(neg index)" + ) + else: + self.assertEqual(ul._checkindex(i), i, "_checkindex(pos index)") for i in (-self.limit - 1, self.limit): msg = f"invalid index: {i}" - with self.assertRaisesMessage(IndexError, msg): - ul._checkindex(i) + with self.subTest(i=i): + with self.assertRaisesMessage(IndexError, msg): + ul._checkindex(i) def test_11_sorting(self): "Sorting"