/[thuban]/branches/WIP-pyshapelib-bramz/test/test_postgis_db.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/test/test_postgis_db.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2472 - (hide annotations)
Thu Dec 16 15:18:57 2004 UTC (20 years, 2 months ago) by bh
Original Path: trunk/thuban/test/test_postgis_db.py
File MIME type: text/x-python
File size: 37112 byte(s)
Add support for PostGIS tables with LINESTRING geomentries.
Fixes RT#2299

* Thuban/Model/postgisdb.py (shapetype_map): Add LINESTRING

* test/postgissupport.py
(PostgreSQLServer.get_default_static_data_db): Rename the "roads"
table to "roads-multi" because it now uses MULTILINESTRING
geometries and introduce a new "roads" table that uses LINESTRING
(coords_to_multilinestring): Make the doc string more precise
(coords_to_linestring): New.  Create a LINESTRING WKT
representatin
(wkt_converter): Add coords_to_linestring
(upload_shapefile): Rephrase the doc-string a bit.

* test/test_postgis_db.py (TestPostGISShapestoreArc)
(LineStringTests)
(TestPostGISShapestoreLineString)
(TestPostGISShapestoreMultiLineString): Split
TestPostGISShapestoreArc into a base class LineStringTests and two
derived classes TestPostGISShapestoreLineString for LINESTRING
geometries and TestPostGISShapestoreMultiLineString for
MULTILINESTRING geometries.  Most test methods are in the base
class with the exception of tests that explicitly check the raw
format.

1 bh 2057 # Copyright (C) 2003, 2004 by Intevation GmbH
2 bh 1605 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with the software for details.
7    
8     """Test for Thuban.Model.postgisdb"""
9    
10     import os
11     import unittest
12    
13    
14     try:
15     import psycopg
16     except ImportError:
17     # No psycopg available. Nothing to be done here because the
18     # postgis.py support module determines this too and the tests will
19     # be skipped completely.
20     pass
21    
22     import postgissupport
23    
24     import support
25     support.initthuban()
26    
27 bh 1636 from Thuban.Model.postgisdb import ConnectionError, PostGISConnection, \
28     PostGISTable, PostGISShapeStore
29 bh 1605 from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_STRING, \
30     FIELDTYPE_DOUBLE
31     from Thuban.Model.data import SHAPETYPE_POINT, SHAPETYPE_POLYGON, \
32     SHAPETYPE_ARC, RAW_WKT
33    
34    
35 bh 1620 class NonConnection(PostGISConnection):
36    
37     """Special connection class that doesn't actually connect"""
38    
39     def connect(self):
40     pass
41    
42    
43    
44 bh 1957 class TestPostGISSimple(unittest.TestCase):
45 bh 1620
46 bh 1957 """Some simple PostGISConnection tests that don't need a real connection"""
47    
48     def test_brief_description(self):
49 bh 1620 """Test PostGISConnection.BriefDescription()"""
50     self.assertEquals(NonConnection("somedb").BriefDescription(),
51     "postgis://@:/somedb")
52     self.assertEquals(NonConnection("db", host="here",
53     port="123").BriefDescription(),
54     "postgis://@here:123/db")
55     self.assertEquals(NonConnection("db", user="me",
56     port="123").BriefDescription(),
57     "postgis://me@:123/db")
58    
59 bh 1957 def test_matches_parameters(self):
60     """Test PostGISConnection.MatchesParameters()"""
61     def do_test(testfn, conn, host = "", port="", dbname = "", user = ""):
62     testfn(conn.MatchesParameters({"host": host, "port": port,
63     "dbname": dbname, "user": user}))
64 bh 1620
65 bh 1957 do_test(self.assert_, NonConnection("somedb"),
66     dbname="somedb")
67     do_test(self.assert_, NonConnection("somedb", host="here"),
68     dbname="somedb", host="here")
69     do_test(self.assert_, NonConnection("db", user="me", port="123"),
70     dbname="db", port="123", user="me")
71    
72     do_test(self.failIf, NonConnection("somedb"),
73     dbname="someotherdb")
74     do_test(self.failIf, NonConnection("somedb", host="here"),
75     dbname="somedb", host="here", port="765")
76     do_test(self.failIf, NonConnection("db", user="me", port="123"),
77     dbname="db", port="123", user="you")
78    
79    
80 bh 1605 class TestPostGISConnection(unittest.TestCase):
81    
82     def setUp(self):
83     """Start the server and create a database.
84    
85     The database name will be stored in self.dbname, the server
86     object in self.server and the db object in self.db.
87     """
88     postgissupport.skip_if_no_postgis()
89     self.server = postgissupport.get_test_server()
90     self.dbname = ".".join(self.id().split(".")[-2:])[-31:]
91     self.db = self.server.new_postgis_db(self.dbname)
92    
93     def test_gis_tables_empty(self):
94     """Test PostGISConnection.GISTables() on empty DB"""
95 bh 1634 db = PostGISConnection(dbname = self.dbname,
96     **self.server.connection_params("user"))
97 bh 1605
98     # An empty database doesn't have any GIS tables
99     self.assertEquals(db.GeometryTables(), [])
100    
101 bh 2102 def test_gis_tables_with_views_and_tables(self):
102 bh 1634 db = PostGISConnection(dbname = self.dbname,
103     **self.server.connection_params("user"))
104 bh 1605
105 bh 1634 conn = psycopg.connect("dbname=%s " % self.dbname
106     + self.server.connection_string("admin"))
107 bh 1605 cursor = conn.cursor()
108 bh 2102 # First a normal table, i.e. one without a geometry column
109     cursor.execute("CREATE TABLE normal (A INT, B VARCHAR);"
110     "GRANT SELECT ON normal TO PUBLIC;")
111    
112     # Then a table with a geometry column
113     cursor.execute("CREATE TABLE geo (A INT);"
114     "GRANT SELECT ON geo TO PUBLIC;")
115     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'geo',"
116     " 'the_geom', -1, 'POINT', 2);",
117 bh 1605 {"dbname": self.dbname})
118 bh 2102
119     # And create a view containing a geometry column
120     cursor.execute("CREATE VIEW my_view AS"
121     " (SELECT * FROM geo WHERE a > 100);"
122     "GRANT SELECT ON my_view TO PUBLIC;")
123 bh 1605 conn.commit()
124    
125 bh 2102 self.assertEquals(db.GeometryTables(), ["geo", "my_view"])
126     self.assertEquals(db.table_columns("geo"),
127     [("oid", FIELDTYPE_INT), ("a", FIELDTYPE_INT),
128     ("the_geom", "geometry")])
129     self.assertEquals(db.table_columns("my_view"),
130     [("a", FIELDTYPE_INT), ("the_geom", "geometry")])
131     self.assertEquals(db.table_columns("normal"),
132     [("oid", FIELDTYPE_INT), ("a", FIELDTYPE_INT),
133     ("b", FIELDTYPE_STRING)])
134 bh 1605
135    
136 bh 1636 class TestPostgisDBExceptions(unittest.TestCase):
137    
138     def setUp(self):
139     """Start the postgis server and switch on authentication"""
140     postgissupport.skip_if_no_postgis()
141     self.server = postgissupport.get_test_server()
142     self.postgisdb = self.server.get_default_static_data_db()
143     self.server.require_authentication(True)
144    
145     def tearDown(self):
146     """Extend the inherited method to switch off postgresql authentication
147     """
148     self.server.require_authentication(False)
149    
150     def test_no_password(self):
151     """Test PostGISConnection with omitted but required password"""
152     connection_params = self.server.connection_params("user")
153     # remove the password deliberately
154     del connection_params["password"]
155    
156     self.assertRaises(ConnectionError,
157     PostGISConnection, dbname = self.postgisdb.dbname,
158     **connection_params)
159    
160    
161 bh 1948 class TestPostGISSpecialCases(unittest.TestCase):
162 bh 1693
163 bh 1948 """Tests for special cases of PostGIS table usage"""
164    
165 bh 1693 def setUp(self):
166     """Start the server and create a database.
167    
168     The database name will be stored in self.dbname, the server
169     object in self.server and the db object in self.db.
170     """
171     postgissupport.skip_if_no_postgis()
172     self.server = postgissupport.get_test_server()
173     self.dbname = ".".join(self.id().split(".")[-2:])[-31:]
174     self.db = self.server.new_postgis_db(self.dbname)
175    
176 bh 1948 def test_unsupported_types(self):
177 bh 1693 """test PostGISTable on a table with unsupported data types"""
178     stmt = """CREATE TABLE foo (
179     gid integer,
180     ignored bigint,
181     length float);
182     GRANT SELECT ON foo TO PUBLIC;
183     """
184     self.server.execute_sql(self.dbname, "admin", stmt)
185    
186     db = PostGISConnection(dbname = self.dbname,
187     **self.server.connection_params("user"))
188     table = PostGISTable(db, "foo")
189    
190     # The bigint column will be ignored because it's not mapped to a
191     # known integer type, so there are only two colunns
192     self.assertEquals(table.NumColumns(), 2)
193     self.assertEquals(table.Column(0).name, "gid")
194     self.assertEquals(table.Column(1).name, "length")
195    
196 bh 1948 def test_table_name_quoting(self):
197     """Test whether PostGISTable quotes table names properly"""
198     stmt = '''CREATE TABLE "name with ""quotes"" and spaces" (gid integer);
199     GRANT SELECT ON "name with ""quotes"" and spaces" TO PUBLIC;'''
200     self.server.execute_sql(self.dbname, "admin", stmt)
201 bh 1693
202 bh 1948 db = PostGISConnection(dbname = self.dbname,
203     **self.server.connection_params("user"))
204     table = PostGISTable(db, 'name with "quotes" and spaces')
205    
206     self.assertEquals(table.NumColumns(), 1)
207     self.assertEquals(table.Column(0).name, "gid")
208    
209     def test_column_name_quoting(self):
210     """Test whether PostGISTable quotes column names properly"""
211     stmt = '''CREATE TABLE unusual_column_names (
212     gid integer,
213     "with space" float,
214     "with "" quote" integer);
215     INSERT INTO unusual_column_names VALUES (1, 1.0, 0);
216     INSERT INTO unusual_column_names VALUES (2, 2.0, 1);
217     INSERT INTO unusual_column_names VALUES (3, 3.0, 1);
218     GRANT SELECT ON unusual_column_names TO PUBLIC;'''
219     self.server.execute_sql(self.dbname, "admin", stmt)
220    
221     db = PostGISConnection(dbname = self.dbname,
222     **self.server.connection_params("user"))
223     table = PostGISTable(db, 'unusual_column_names')
224    
225     self.assertEquals(table.NumColumns(), 3)
226     self.assertEquals(table.Column(0).name, "gid")
227     self.assertEquals(table.Column(1).name, "with space")
228     self.assertEquals(table.Column(2).name, "with \" quote")
229    
230     # do some queries where the names have to be quoted
231     self.assertEquals(table.ReadRowAsDict(1),
232     {"gid": 1, "with space": 1.0, "with \" quote": 0})
233     self.assertEquals(table.ReadValue(2, 1, row_is_ordinal = True), 3.0)
234     self.assertEquals(table.ReadValue(2, 1, row_is_ordinal = False), 2.0)
235     self.assertEquals(table.ValueRange("with space"), (1.0, 3.0))
236 bh 2471
237     # The return value of UniqueValues is unsorted, so we need to
238     # sort it for comparison.
239     unique_values = table.UniqueValues("with \" quote")
240     unique_values.sort()
241     self.assertEquals(unique_values, [0, 1])
242 bh 1948 self.assertEquals(table.SimpleQuery(table.Columns()[2], "==", 1),
243     [2, 3])
244     self.assertEquals(table.SimpleQuery(table.Columns()[0], "==",
245     table.Columns()[1]), [1, 2, 3])
246    
247     def test_shapestore_name_quoting(self):
248     """Test whether PostGISShapeStore quotes table names properly"""
249     postgissupport.skip_if_addgeometrycolumn_does_not_use_quote_ident()
250    
251     # Create a table with a name that needs quoting and a geometry
252     # column whose name has to be quoted
253     stmt = '''CREATE TABLE "table "" name" (gid integer);
254     GRANT SELECT ON "table "" name" TO PUBLIC;'''
255     self.server.execute_sql(self.dbname, "admin", stmt)
256     stmt = """select AddGeometryColumn('%s', 'table \" name',
257     'the \" geom', '-1', 'POINT', 2);"""
258     self.server.execute_sql(self.dbname, "admin", stmt % self.dbname)
259     stmt = '''INSERT INTO "table "" name" VALUES (0,
260     GeometryFromText('POINT(0 0)', -1));'''
261     self.server.execute_sql(self.dbname, "admin", stmt)
262    
263     # Instantiate the table
264     db = PostGISConnection(dbname = self.dbname,
265     **self.server.connection_params("user"))
266     store = PostGISShapeStore(db, "table \" name")
267    
268     # do some queries where the names have to be quoted
269     self.assertEquals(store.NumShapes(), 1)
270     self.assertEquals(store.ShapeType(), SHAPETYPE_POINT)
271     self.assertEquals(store.BoundingBox(), (0, 0, 0, 0))
272     self.assertEquals(store.Shape(0).ShapeID(), 0)
273     self.assertEquals([s.ShapeID() for s in store.AllShapes()], [0])
274     self.assertEquals([s.ShapeID()
275     for s in store.ShapesInRegion((-1, -1, 1, 1))], [0])
276    
277 bh 2057 def test_shapestore_empty_table(self):
278     """Test PostGISShapeStore with emtpy table"""
279     conn = psycopg.connect("dbname=%s " % self.dbname
280     + self.server.connection_string("admin"))
281     cursor = conn.cursor()
282     cursor.execute("CREATE TABLE test (A INT);")
283     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'test',"
284     " 'geometry', -1, 'POINT', 2);",
285     {"dbname": self.dbname})
286     cursor.execute("GRANT SELECT ON test TO PUBLIC;")
287     conn.commit()
288    
289     db = PostGISConnection(dbname = self.dbname,
290     **self.server.connection_params("user"))
291     store = PostGISShapeStore(db, "test")
292     self.assertEquals(store.BoundingBox(), None)
293    
294 bh 2059 def test_shapestore_two_geom_cols(self):
295     """Test PostGISShapeStore with two geometry columns"""
296     conn = psycopg.connect("dbname=%s " % self.dbname
297     + self.server.connection_string("admin"))
298     cursor = conn.cursor()
299     cursor.execute("INSERT INTO spatial_ref_sys VALUES"
300     " (1, '', 1, '', 'proj=longlat datum=WGS84')")
301     cursor.execute("INSERT INTO spatial_ref_sys VALUES"
302     " (2, '', 2, '', 'proj=longlat datum=WGS84')")
303 bh 2057
304 bh 2059 cursor.execute("CREATE TABLE two_geom_cols"
305     " (gid INTEGER PRIMARY KEY);")
306     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'two_geom_cols',"
307     " 'point', 1, 'POINT', 2);",
308     {"dbname": self.dbname})
309     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'two_geom_cols',"
310     " 'poly', 2, 'POLYGON', 2);",
311     {"dbname": self.dbname})
312     cursor.execute("INSERT INTO two_geom_cols(gid, point, poly) VALUES (1,"
313     " GeometryFromText('POINT(1 1)', 1),"
314     " GeometryFromText('POLYGON((1 1, 1 2, 2 2,1 1))',2));")
315     cursor.execute("GRANT SELECT ON two_geom_cols TO PUBLIC;")
316     conn.commit()
317    
318     db = PostGISConnection(dbname = self.dbname,
319     **self.server.connection_params("user"))
320    
321     # The table has two geometry columns, and will raise a TypeError
322     # when instantiated without specifying which one to use.
323     self.assertRaises(TypeError,
324     PostGISShapeStore, db, "two_geom_cols")
325    
326     # If the geometry_column is not really a geometry column, we get
327     # a TypeError
328     self.assertRaises(TypeError,
329     PostGISShapeStore, db, "two_geom_cols",
330     geometry_column = "gid")
331    
332     # Instantiate two shape stores, one for each of the geometry
333     # columns, and test whether they determine the right shape types
334     # and srids (getting the srid wrong would lead to an exception
335     # in ShapesInRegion).
336     store = PostGISShapeStore(db, "two_geom_cols",
337     geometry_column = "point")
338     self.assertEquals(store.ShapeType(), SHAPETYPE_POINT)
339     self.assertEquals([s.ShapeID()
340     for s in store.ShapesInRegion((0, 0, 100,100))],
341     [1])
342    
343     store = PostGISShapeStore(db, "two_geom_cols",
344     geometry_column = "poly")
345     self.assertEquals(store.ShapeType(), SHAPETYPE_POLYGON)
346     self.assertEquals([s.ShapeID()
347     for s in store.ShapesInRegion((0, 0, 100,100))],
348     [1])
349    
350    
351 bh 1605 class PostGISStaticTests(unittest.TestCase, support.FloatComparisonMixin):
352    
353     """Base class for PostGIS tests with static data."""
354    
355     def setUp(self):
356     """Start the server and create a database with static data
357    
358     This method sets the following instance attributes:
359    
360     dbname -- the name of the database
361    
362     server -- The server object
363    
364     db -- the PostGISConnection object
365     """
366     postgissupport.skip_if_no_postgis()
367     self.server = postgissupport.get_test_server()
368     self.postgisdb = self.server.get_default_static_data_db()
369     self.db = PostGISConnection(dbname = self.postgisdb.dbname,
370 bh 1634 **self.server.connection_params("user"))
371 bh 1605
372     def tearDown(self):
373     """Close the database connection"""
374     self.db.Close()
375    
376    
377 bh 2096 class TableTests:
378 bh 1605
379 bh 2096 """Mix-in class for the PostGISTable tests
380 bh 1605
381 bh 2096 The tests defined here make some assumptions about the table and the
382     data in it:
383    
384     self.table should be the PostGISTable instance to test. Derived
385     classes should set this up in setUp.
386    
387     self.db should be the DB connection object used by self.table.
388    
389     self.table_name should be the name of the table in the database.
390     The tests assume that e.g. the title of self.table can be
391     derived from this.
392    
393     self.gid_column should be the name of the gid column used when
394     self.table was instantiated.
395    
396     The data in the table should be the data of the
397     cultural_landmark-point shapefile with the shape ids used to get
398     the contents of the gid column by adding 1000.
399     """
400    
401 bh 1638 def test_dbconn(self):
402     """Test PostGISTable.DBConnection()"""
403     self.failUnless(self.table.DBConnection() is self.db)
404    
405     def test_dbname(self):
406     """Test PostGISTable.TableName()"""
407 bh 2096 self.assertEquals(self.table.TableName(), self.table_name)
408 bh 1638
409 bh 1658 def test_title(self):
410     """test PostGISTable.Title()"""
411     # The title is currently equal to the tablename
412 bh 2096 self.assertEquals(self.table.Title(), self.table_name)
413 bh 1658
414 bh 1605 def test_dependencies(self):
415     """Test PostGISTable.Dependencies()"""
416     # A PostGISTable depends on no other data container
417     self.assertEquals(self.table.Dependencies(), ())
418    
419     def test_num_rows(self):
420     """Test PostGISTable.NumRows()"""
421     self.assertEquals(self.table.NumRows(), 34)
422    
423     def test_num_columns(self):
424     """Test PostGISTable.NumColumns()"""
425     # The table in the postgis db has one additional column, "gid",
426     # so there's one more column in the PostGISTable than in the DBF
427     self.assertEquals(self.table.NumColumns(), 7)
428    
429     def test_columns(self):
430     """Test PostGISTable.Columns()"""
431     self.assertEquals(len(self.table.Columns()), 7)
432 bh 2096 self.assertEquals(self.table.Columns()[0].name, self.gid_column)
433 bh 1605 self.assertEquals(self.table.Columns()[0].type, FIELDTYPE_INT)
434     self.assertEquals(self.table.Columns()[0].index, 0)
435     self.assertEquals(self.table.Columns()[1].name, "area")
436     self.assertEquals(self.table.Columns()[1].type, FIELDTYPE_DOUBLE)
437     self.assertEquals(self.table.Columns()[1].index, 1)
438     self.assertEquals(self.table.Columns()[5].name, "clptlabel")
439     self.assertEquals(self.table.Columns()[5].type, FIELDTYPE_STRING)
440     self.assertEquals(self.table.Columns()[5].index, 5)
441    
442     def test_column(self):
443     """Test PostGISTable.Column()"""
444     self.assertEquals(self.table.Column("area").name, "area")
445     self.assertEquals(self.table.Column("area").type, FIELDTYPE_DOUBLE)
446     self.assertEquals(self.table.Column("area").index, 1)
447    
448     def test_has_column(self):
449     """Test PostGISTable.HasColumn()"""
450     self.assert_(self.table.HasColumn("area"))
451     self.failIf(self.table.HasColumn("foo"))
452    
453     def test_read_row_as_dict(self):
454     """Test PostGISTable.ReadRowAsDict()"""
455 bh 1662 self.assertEquals(self.table.ReadRowAsDict(1003),
456 bh 2096 {self.gid_column: 1003,
457 bh 1605 "area": 0.0,
458     "perimeter": 0.0,
459     "clpoint_": 4,
460     "clpoint_id": 24,
461     "clptlabel": "RUINS",
462     "clptflag": 0})
463    
464 bh 1662 def test_read_row_as_dict_row_count_mode(self):
465     """Test PostGISTable.ReadRowAsDict() row count address mode"""
466     self.assertEquals(self.table.ReadRowAsDict(3, row_is_ordinal = 1),
467 bh 2096 {self.gid_column: 1003,
468 bh 1662 "area": 0.0,
469     "perimeter": 0.0,
470     "clpoint_": 4,
471     "clpoint_id": 24,
472     "clptlabel": "RUINS",
473     "clptflag": 0})
474    
475 bh 1605 def test_read_value(self):
476     """Test PostGISTable.ReadValue()"""
477 bh 1662 self.assertEquals(self.table.ReadValue(1003, 4), 24)
478     self.assertEquals(self.table.ReadValue(1003, "clpoint_id"), 24)
479 bh 1605
480 bh 1662 def test_read_value_row_count_mode(self):
481     """Test PostGISTable.ReadValue() row count address mode"""
482     self.assertEquals(self.table.ReadValue(3, 4, row_is_ordinal = 1), 24)
483     self.assertEquals(self.table.ReadValue(3, "clpoint_id",
484     row_is_ordinal = 1),
485     24)
486    
487     def test_row_id_to_ordinal(self):
488     """Test PostGISTable.RowIdToOrdinal()"""
489     self.assertEquals(self.table.RowIdToOrdinal(1005), 5)
490    
491     def test_row_oridnal_to_id(self):
492     """Test PostGISTable.RowOrdinalToId()"""
493     self.assertEquals(self.table.RowOrdinalToId(5), 1005)
494    
495 bh 1605 def test_value_range(self):
496     """Test PostGISTable.ValueRange()"""
497     self.assertEquals(self.table.ValueRange("clpoint_id"), (21, 74))
498    
499     def test_unique_values(self):
500     """Test PostGISTable.UniqueValues()"""
501     values = self.table.UniqueValues("clptlabel")
502     values.sort()
503     self.assertEquals(values, ["BUILDING", "FARM", "HUT","LIGHTHOUSE",
504     "OTHER/UNKNOWN", "RUINS"])
505    
506     def test_simple_query(self):
507     """Test PostGISTable.SimpleQuery()"""
508     table = self.table
509     self.assertEquals(table.SimpleQuery(table.Column("clptlabel"),
510     "==", "FARM"),
511 bh 1662 [1006])
512 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
513     ">", 70),
514 bh 1662 [1024, 1025, 1026])
515 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
516     "<", table.Column("clpoint_")),
517 bh 1662 [1028, 1029, 1030, 1031, 1032, 1033])
518 bh 1605
519    
520 bh 2096 class TestPostGISTable(TableTests, PostGISStaticTests):
521    
522     def setUp(self):
523     """Extend inherited method to set self.table to a PostGISTable"""
524     PostGISStaticTests.setUp(self)
525     self.table_name = "landmarks"
526     self.gid_column = "gid"
527    
528     # Note that omit the gid column here to the backwards compatible
529     # interface of the constructor where the gid_column defaults to
530     # "gid"
531     self.table = PostGISTable(self.db, self.table_name)
532    
533    
534     class TestPostGISTableExplicitGIDColumn(TableTests, PostGISStaticTests):
535    
536     def setUp(self):
537     """Extend inherited method to set self.table to a PostGISTable"""
538     PostGISStaticTests.setUp(self)
539     self.table_name = "landmarks_point_id"
540     self.gid_column = "point_id"
541     self.table = PostGISTable(self.db, self.table_name,
542     id_column = self.gid_column)
543    
544    
545 bh 2057 class PointTests:
546 bh 1605
547 bh 2096 """Mix-in class for the tests on POINT tables
548 bh 1605
549 bh 2096 The methods in this class expect self.store to be the shapestore
550     used for testing. Derived classes should initialize self.store with
551     PostGISShapeStore in setUp. Another assumption is that the data in
552     self.store is effectively the cultural_landmark-point shapefile with
553     shape ids increased by 1000.
554     """
555    
556 bh 1605 #
557     # First, some tests that should be independend of the shapetype, so
558     # it shouldn't be necessary to repeat them for other shapetypes
559     #
560    
561     def test_dependencies(self):
562     """Test PostGISShapeStore.Dependencies()"""
563     # A PostGISShapeStore depends on no other data container
564     self.assertEquals(self.store.Dependencies(), ())
565    
566     def test_table(self):
567     """Test PostGISShapeStore.Table() with POINT shapes"""
568     # A PostGISShapeStore is its own table
569     self.assert_(self.store.Table() is self.store)
570    
571     def test_orig_shapestore(self):
572     """Test PostGISShapeStore.OrigShapeStore() with POINT shapes"""
573     # A PostGISShapeStore is not derived from another shape store
574     self.assert_(self.store.OrigShapeStore() is None)
575    
576     def test_raw_format(self):
577     """Test PostGISShapeStore.RawShapeFormat() with POINT shapes"""
578     self.assertEquals(self.store.RawShapeFormat(), RAW_WKT)
579    
580 bh 1658 def test_all_shapes(self):
581     """Test PostGISShapeStore.AllShapes()"""
582     self.assertEquals([s.ShapeID() for s in self.store.AllShapes()],
583 bh 1662 range(1000, 1000 + self.store.NumShapes()))
584 bh 1658
585 bh 2102 def test_id_column(self):
586     self.assertEquals(self.store.IDColumn().name, self.id_column)
587    
588     def test_geometry_column(self):
589     self.assertEquals(self.store.GeometryColumn().name,
590     self.geometry_column)
591    
592 bh 1605 #
593     # Shapetype specific tests
594     #
595    
596     def test_shape_type(self):
597     """Test PostGISShapeStore.ShapeType() with POINT shapes"""
598     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POINT)
599    
600     def test_num_shapes(self):
601     """Test PostGISShapeStore.NumShapes() with POINT shapes"""
602     self.assertEquals(self.store.NumShapes(), 34)
603    
604     def test_bounding_box(self):
605     """Test PostGISShapeStore.BoundingBox() with POINT shapes"""
606     self.assertFloatSeqEqual(self.store.BoundingBox(),
607     [-23.806047439575195, 63.405960083007812,
608     -15.12291431427002, 66.36572265625])
609    
610     def test_shape_shapeid(self):
611     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
612 bh 1662 self.assertEquals(self.store.Shape(1005).ShapeID(), 1005)
613 bh 1605
614     def test_shape_points(self):
615     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
616 bh 1662 self.assertPointListEquals(self.store.Shape(1000).Points(),
617 bh 1605 [[(-22.711074829101562, 66.36572265625)]])
618    
619     def test_shape_raw_data(self):
620     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
621 bh 1662 self.assertEquals(self.store.Shape(1000).RawData(),
622 bh 1605 'POINT(-22.7110748291016 66.36572265625)')
623    
624     def test_shapes_in_region(self):
625     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
626     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
627     self.assertEquals([s.ShapeID() for s in shapes],
628 bh 1662 [1000, 1001, 1002, 1003, 1004, 1005, 1027])
629 bh 1605
630    
631 bh 2057 class TestPostGISShapestorePoint(PointTests, PostGISStaticTests):
632    
633     """Tests for PostGISShapeStore objects with POINT data an no SRID"""
634    
635     def setUp(self):
636     """Extend inherited method to set self.table to a PostGISShapeStore"""
637     PostGISStaticTests.setUp(self)
638 bh 2102 self.id_column = "gid"
639     self.geometry_column = "the_geom"
640 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks")
641    
642    
643    
644     class TestPostGISShapestorePointSRID(PointTests, PostGISStaticTests):
645    
646     """Tests for PostGISShapeStore objects with POINT data and an SRID"""
647    
648     def setUp(self):
649     """Extend inherited method to set self.table to a PostGISShapeStore"""
650     PostGISStaticTests.setUp(self)
651 bh 2102 self.id_column = "gid"
652     self.geometry_column = "the_geom"
653 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks_srid")
654    
655    
656 bh 2096 class TestPostGISShapestorePointExplicitGIDColumn(PointTests,
657     PostGISStaticTests):
658 bh 2057
659 bh 2096 """Tests for PostGISShapeStores with POINT data and explicit gid column"""
660    
661     def setUp(self):
662     """Extend inherited method to set self.table to a PostGISShapeStore"""
663     PostGISStaticTests.setUp(self)
664 bh 2102 self.id_column = "point_id"
665     self.geometry_column = "the_geom"
666 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
667     id_column = "point_id")
668    
669    
670     class TestPostGISShapestorePointOIDAsGIDColumn(PointTests, PostGISStaticTests):
671    
672     """Tests for PostGISShapeStores with POINT data using OID as gid column"""
673    
674     def setUp(self):
675     """Extend inherited method to set self.table to a PostGISShapeStore"""
676     PostGISStaticTests.setUp(self)
677 bh 2102 self.id_column = "oid"
678     self.geometry_column = "the_geom"
679 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
680 bh 2106 id_column = self.id_column,
681     geometry_column = self.geometry_column)
682 bh 2096
683     def find_test_shape_id(self):
684     """Return the id of an interesting shape for some test cases.
685    
686     This test uses OIDs so we can't easily hard wire ids in the test
687     cases
688     """
689     # get the id of an interesting shape
690     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
691     return list(shapes)[0].ShapeID()
692    
693    
694     # Override a few tests that won't work with this table because they
695     # require knowledge of specific IDs
696    
697     def test_shape_shapeid(self):
698     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
699     gid = self.find_test_shape_id()
700     self.assertEquals(self.store.Shape(gid).ShapeID(), gid)
701    
702     def test_shape_points(self):
703     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
704     gid = self.find_test_shape_id()
705     self.assertPointListEquals(self.store.Shape(gid).Points(),
706     [[(-22.711074829101562, 66.36572265625)]])
707    
708     def test_shape_raw_data(self):
709     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
710     gid = self.find_test_shape_id()
711     self.assertEquals(self.store.Shape(gid).RawData(),
712     'POINT(-22.7110748291016 66.36572265625)')
713    
714     def test_shapes_in_region(self):
715     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
716     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
717     self.assertEquals(len(list(shapes)), 7)
718    
719     def test_all_shapes(self):
720     """Test PostGISShapeStore.AllShapes()"""
721     self.assertEquals(len(list(self.store.AllShapes())), 34)
722    
723    
724 bh 2106 class TestPostGISShapestorePointFromViews(PointTests, PostGISStaticTests):
725 bh 2096
726 bh 2106 """Tests for PostGISShapeStores with POINT data in a view"""
727    
728     def setUp(self):
729     """Extend inherited method to set self.table to a PostGISShapeStore"""
730     PostGISStaticTests.setUp(self)
731     self.id_column = "point_id"
732     self.geometry_column = "the_geom"
733     self.store = PostGISShapeStore(self.db, "v_landmarks",
734     id_column = "point_id")
735    
736    
737 bh 2472 class LineStringTests:
738 bh 1605
739 bh 2472 """Tests shared by the LINESTRING and MULTILINESTRING tests.
740 bh 1605
741 bh 2472 The tests are the same because they are based on the same data.
742     """
743 bh 1605
744     def test_shape_type(self):
745     """Test PostGISShapeStore.ShapeType() with ARC shapes"""
746     self.assertEquals(self.store.ShapeType(), SHAPETYPE_ARC)
747    
748     def test_num_shapes(self):
749     """Test PostGISShapeStore.NumShapes() with ARC shapes"""
750     self.assertEquals(self.store.NumShapes(), 839)
751    
752     def test_bounding_box(self):
753     """Test PostGISShapeStore.BoundingBox() with ARC shapes"""
754     self.assertFloatSeqEqual(self.store.BoundingBox(),
755     [-24.450359344482422, 63.426830291748047,
756     -13.55668830871582, 66.520111083984375])
757    
758     def test_shape_shapeid(self):
759     """Test PostGISShapeStore.Shape(i).ShapeID() with ARC shapes"""
760     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
761    
762     def test_shape_points(self):
763     """Test PostGISShapeStore.Shape(i).Points() with ARC shapes"""
764     self.assertPointListEquals(self.store.Shape(32).Points(),
765     [[(-15.0821743011474, 66.2773818969726),
766     (-15.0263500213623, 66.2733917236328)]])
767    
768 bh 2472 def test_shapes_in_region(self):
769     """Test PostGISShapeStore.ShapesInRegion() with ARC shapes"""
770     shapes = self.store.ShapesInRegion((-24.0, 64.5, -23.5, 65.0))
771     self.assertEquals([s.ShapeID() for s in shapes], [573, 581, 613])
772    
773    
774     class TestPostGISShapestoreLineString(LineStringTests, PostGISStaticTests):
775    
776     """Tests for PostGISShapeStore objects with LINESTRING data"""
777    
778     def setUp(self):
779     """Extend inherited method to set self.table to a PostGISShapeStore"""
780     PostGISStaticTests.setUp(self)
781     self.store = PostGISShapeStore(self.db, "roads")
782    
783 bh 1605 def test_shape_raw_data(self):
784     """Test PostGISShapeStore.Shape(i).RawData() with ARC shapes"""
785     self.assertEquals(self.store.Shape(32).RawData(),
786 bh 2472 "LINESTRING(-15.0821743011475 66.2773818969727,"
787     "-15.0263500213623 66.2733917236328)")
788    
789    
790     class TestPostGISShapestoreMultiLineString(LineStringTests,
791     PostGISStaticTests):
792    
793     """Tests for PostGISShapeStore objects with MULTILINESTRING data"""
794    
795     def setUp(self):
796     """Extend inherited method to set self.table to a PostGISShapeStore"""
797     PostGISStaticTests.setUp(self)
798     self.store = PostGISShapeStore(self.db, "roads_multi")
799    
800     def test_shape_raw_data(self):
801     """Test PostGISShapeStore.Shape(i).RawData() with ARC shapes"""
802     self.assertEquals(self.store.Shape(32).RawData(),
803 bh 1605 "MULTILINESTRING((-15.0821743011475 66.2773818969727,"
804     "-15.0263500213623 66.2733917236328))")
805    
806    
807 bh 1656 class PolygonTests:
808 bh 1605
809 bh 2057 """Test shared by the POLYGON and MULTIPOLYGON tests
810 bh 1605
811 bh 1656 The tests are the same because they are based on the same data.
812     """
813    
814 bh 1605 def test_shape_type(self):
815     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
816     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
817    
818     def test_num_shapes(self):
819     """Test PostGISShapeStore.NumShapes() with POLYGON shapes"""
820     self.assertEquals(self.store.NumShapes(), 156)
821    
822     def test_bounding_box(self):
823     """Test PostGISShapeStore.BoundingBox() with POLYGON shapes"""
824     self.assertFloatSeqEqual(self.store.BoundingBox(),
825     [-24.546524047851562, 63.286754608154297,
826     -13.495815277099609, 66.563774108886719])
827    
828     def test_shape_shapeid(self):
829     """Test PostGISShapeStore.Shape(i).ShapeID() with POLYGON shapes"""
830     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
831    
832     def test_shape_points(self):
833     """Test PostGISShapeStore.Shape(i).Points() with POLYGON shapes"""
834     self.assertPointListEquals(self.store.Shape(4).Points(),
835     [[(-22.40639114379882, 64.714111328125),
836     (-22.41621208190918, 64.716003417968),
837     (-22.40605163574218, 64.719200134277),
838     (-22.40639114379882, 64.714111328125)]])
839    
840 bh 1656 def test_shapes_in_region(self):
841     """Test PostGISShapeStore.ShapesInRegion() with POLYGON shapes"""
842     shapes = self.store.ShapesInRegion((-23.0, 65.5, -22.8, 65.25))
843     self.assertEquals([s.ShapeID() for s in shapes],
844     [47, 56, 59, 61, 62, 71, 144])
845    
846    
847     class TestPostGISShapestorePolygon(PolygonTests, PostGISStaticTests):
848    
849     """Tests for PostGISShapeStore objects with POLYGON data"""
850    
851     def setUp(self):
852     """Extend inherited method to set self.table to a PostGISShapeStore"""
853     PostGISStaticTests.setUp(self)
854     self.store = PostGISShapeStore(self.db, "political")
855    
856     def test_shape_type(self):
857     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
858     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
859    
860    
861 bh 1605 def test_shape_raw_data(self):
862     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
863     self.assertEquals(self.store.Shape(4).RawData(),
864     "POLYGON((-22.4063911437988 64.714111328125,"
865     "-22.4162120819092 64.7160034179688,"
866     "-22.4060516357422 64.7192001342773,"
867     "-22.4063911437988 64.714111328125))")
868    
869    
870 bh 1656 class TestPostGISShapestoreMultiPolygon(PolygonTests, PostGISStaticTests):
871 bh 1605
872 bh 1656 """Tests for PostGISShapeStore objects with MUTLIPOLYGON data"""
873    
874     def setUp(self):
875     """Extend inherited method to set self.table to a PostGISShapeStore"""
876     PostGISStaticTests.setUp(self)
877     self.store = PostGISShapeStore(self.db, "political_multi")
878    
879     def test_shape_raw_data(self):
880     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
881     self.assertEquals(self.store.Shape(4).RawData(),
882     "MULTIPOLYGON(((-22.4063911437988 64.714111328125,"
883     "-22.4162120819092 64.7160034179688,"
884     "-22.4060516357422 64.7192001342773,"
885     "-22.4063911437988 64.714111328125)))")
886    
887 bh 1693
888    
889 bh 1605 if __name__ == "__main__":
890     support.run_tests()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26