/[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 2717 - (hide annotations)
Mon Jan 1 21:44:05 2007 UTC (18 years, 2 months ago) by bernhard
Original Path: trunk/thuban/test/test_postgis_db.py
File MIME type: text/x-python
File size: 38976 byte(s)
Adding an explicit WITH OIDS to the create table commands. This fixes tests
that rely on an oid column to be present for postgresql >=8.0.

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