/[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 2102 - (hide annotations)
Thu Mar 11 21:04:30 2004 UTC (20 years, 11 months ago) by bh
Original Path: trunk/thuban/test/test_postgis_db.py
File MIME type: text/x-python
File size: 35471 byte(s)
* Thuban/UI/dbdialog.py (ChooseDBTableDialog.__init__): Rework how
the dialog is constructed. Add combo boxes to select id and
geometry column.  Rename some instance variables.
(ChooseDBTableDialog.GetTable): Return id and geometry column
names
(ChooseDBTableDialog.OnTableSelect): New. Event handler for
selections in the table list

* Thuban/UI/mainwindow.py (MainWindow.AddDBLayer): Use id_column
and geometry_column

* Thuban/Model/session.py (Session.OpenDBShapeStore): Add the new
parameters for id_column and geometry column of PostGISShapeStore
here as well.

* Thuban/Model/postgisdb.py (type_map): Add ROWID psycog type.
(_raw_type_map): New. Map raw PostgreSQL type ints to thuban types
(PostGISConnection.GeometryTables): Use a better query to
determine which relations in the database might be usable for
shapestores.  Now supports views as well but is more PostgreSQL
specific
(PostGISConnection.table_columns): New. Somewhat experimental
method to let the db dialogs provide lists of columns to users so
that they can select id and geometry columns.
(PostGISTable.__init__): The default value of the id_column
parameter is now None it still means "gid" effectively, though.
(PostGISTable.IDColumn): New introspection method to return a
column object for the id column
(PostGISShapeStore.GeometryColumn): New introspection method to
return a column object for the geometry column

* test/test_postgis_db.py
(TestPostGISConnection.test_gis_tables_non_empty):
Removed. Subsumed by the new:
(TestPostGISConnection.test_gis_tables_with_views_and_tables):
New. Tes the GeometryTables and table_columns methods with actual
tables and views.
(PointTests.test_id_column, PointTests.test_geometry_column):
New. tests for the new methods.
(TestPostGISShapestorePoint.setUp)
(TestPostGISShapestorePointSRID.setUp)
(TestPostGISShapestorePointExplicitGIDColumn.setUp): Fill the
instance variables needed by the new tests

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     self.assertEquals(table.UniqueValues("with \" quote"), [0, 1])
237     self.assertEquals(table.SimpleQuery(table.Columns()[2], "==", 1),
238     [2, 3])
239     self.assertEquals(table.SimpleQuery(table.Columns()[0], "==",
240     table.Columns()[1]), [1, 2, 3])
241    
242     def test_shapestore_name_quoting(self):
243     """Test whether PostGISShapeStore quotes table names properly"""
244     postgissupport.skip_if_addgeometrycolumn_does_not_use_quote_ident()
245    
246     # Create a table with a name that needs quoting and a geometry
247     # column whose name has to be quoted
248     stmt = '''CREATE TABLE "table "" name" (gid integer);
249     GRANT SELECT ON "table "" name" TO PUBLIC;'''
250     self.server.execute_sql(self.dbname, "admin", stmt)
251     stmt = """select AddGeometryColumn('%s', 'table \" name',
252     'the \" geom', '-1', 'POINT', 2);"""
253     self.server.execute_sql(self.dbname, "admin", stmt % self.dbname)
254     stmt = '''INSERT INTO "table "" name" VALUES (0,
255     GeometryFromText('POINT(0 0)', -1));'''
256     self.server.execute_sql(self.dbname, "admin", stmt)
257    
258     # Instantiate the table
259     db = PostGISConnection(dbname = self.dbname,
260     **self.server.connection_params("user"))
261     store = PostGISShapeStore(db, "table \" name")
262    
263     # do some queries where the names have to be quoted
264     self.assertEquals(store.NumShapes(), 1)
265     self.assertEquals(store.ShapeType(), SHAPETYPE_POINT)
266     self.assertEquals(store.BoundingBox(), (0, 0, 0, 0))
267     self.assertEquals(store.Shape(0).ShapeID(), 0)
268     self.assertEquals([s.ShapeID() for s in store.AllShapes()], [0])
269     self.assertEquals([s.ShapeID()
270     for s in store.ShapesInRegion((-1, -1, 1, 1))], [0])
271    
272 bh 2057 def test_shapestore_empty_table(self):
273     """Test PostGISShapeStore with emtpy table"""
274     conn = psycopg.connect("dbname=%s " % self.dbname
275     + self.server.connection_string("admin"))
276     cursor = conn.cursor()
277     cursor.execute("CREATE TABLE test (A INT);")
278     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'test',"
279     " 'geometry', -1, 'POINT', 2);",
280     {"dbname": self.dbname})
281     cursor.execute("GRANT SELECT ON test TO PUBLIC;")
282     conn.commit()
283    
284     db = PostGISConnection(dbname = self.dbname,
285     **self.server.connection_params("user"))
286     store = PostGISShapeStore(db, "test")
287     self.assertEquals(store.BoundingBox(), None)
288    
289 bh 2059 def test_shapestore_two_geom_cols(self):
290     """Test PostGISShapeStore with two geometry columns"""
291     conn = psycopg.connect("dbname=%s " % self.dbname
292     + self.server.connection_string("admin"))
293     cursor = conn.cursor()
294     cursor.execute("INSERT INTO spatial_ref_sys VALUES"
295     " (1, '', 1, '', 'proj=longlat datum=WGS84')")
296     cursor.execute("INSERT INTO spatial_ref_sys VALUES"
297     " (2, '', 2, '', 'proj=longlat datum=WGS84')")
298 bh 2057
299 bh 2059 cursor.execute("CREATE TABLE two_geom_cols"
300     " (gid INTEGER PRIMARY KEY);")
301     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'two_geom_cols',"
302     " 'point', 1, 'POINT', 2);",
303     {"dbname": self.dbname})
304     cursor.execute("SELECT AddGeometryColumn(%(dbname)s, 'two_geom_cols',"
305     " 'poly', 2, 'POLYGON', 2);",
306     {"dbname": self.dbname})
307     cursor.execute("INSERT INTO two_geom_cols(gid, point, poly) VALUES (1,"
308     " GeometryFromText('POINT(1 1)', 1),"
309     " GeometryFromText('POLYGON((1 1, 1 2, 2 2,1 1))',2));")
310     cursor.execute("GRANT SELECT ON two_geom_cols TO PUBLIC;")
311     conn.commit()
312    
313     db = PostGISConnection(dbname = self.dbname,
314     **self.server.connection_params("user"))
315    
316     # The table has two geometry columns, and will raise a TypeError
317     # when instantiated without specifying which one to use.
318     self.assertRaises(TypeError,
319     PostGISShapeStore, db, "two_geom_cols")
320    
321     # If the geometry_column is not really a geometry column, we get
322     # a TypeError
323     self.assertRaises(TypeError,
324     PostGISShapeStore, db, "two_geom_cols",
325     geometry_column = "gid")
326    
327     # Instantiate two shape stores, one for each of the geometry
328     # columns, and test whether they determine the right shape types
329     # and srids (getting the srid wrong would lead to an exception
330     # in ShapesInRegion).
331     store = PostGISShapeStore(db, "two_geom_cols",
332     geometry_column = "point")
333     self.assertEquals(store.ShapeType(), SHAPETYPE_POINT)
334     self.assertEquals([s.ShapeID()
335     for s in store.ShapesInRegion((0, 0, 100,100))],
336     [1])
337    
338     store = PostGISShapeStore(db, "two_geom_cols",
339     geometry_column = "poly")
340     self.assertEquals(store.ShapeType(), SHAPETYPE_POLYGON)
341     self.assertEquals([s.ShapeID()
342     for s in store.ShapesInRegion((0, 0, 100,100))],
343     [1])
344    
345    
346 bh 1605 class PostGISStaticTests(unittest.TestCase, support.FloatComparisonMixin):
347    
348     """Base class for PostGIS tests with static data."""
349    
350     def setUp(self):
351     """Start the server and create a database with static data
352    
353     This method sets the following instance attributes:
354    
355     dbname -- the name of the database
356    
357     server -- The server object
358    
359     db -- the PostGISConnection object
360     """
361     postgissupport.skip_if_no_postgis()
362     self.server = postgissupport.get_test_server()
363     self.postgisdb = self.server.get_default_static_data_db()
364     self.db = PostGISConnection(dbname = self.postgisdb.dbname,
365 bh 1634 **self.server.connection_params("user"))
366 bh 1605
367     def tearDown(self):
368     """Close the database connection"""
369     self.db.Close()
370    
371    
372 bh 2096 class TableTests:
373 bh 1605
374 bh 2096 """Mix-in class for the PostGISTable tests
375 bh 1605
376 bh 2096 The tests defined here make some assumptions about the table and the
377     data in it:
378    
379     self.table should be the PostGISTable instance to test. Derived
380     classes should set this up in setUp.
381    
382     self.db should be the DB connection object used by self.table.
383    
384     self.table_name should be the name of the table in the database.
385     The tests assume that e.g. the title of self.table can be
386     derived from this.
387    
388     self.gid_column should be the name of the gid column used when
389     self.table was instantiated.
390    
391     The data in the table should be the data of the
392     cultural_landmark-point shapefile with the shape ids used to get
393     the contents of the gid column by adding 1000.
394     """
395    
396 bh 1638 def test_dbconn(self):
397     """Test PostGISTable.DBConnection()"""
398     self.failUnless(self.table.DBConnection() is self.db)
399    
400     def test_dbname(self):
401     """Test PostGISTable.TableName()"""
402 bh 2096 self.assertEquals(self.table.TableName(), self.table_name)
403 bh 1638
404 bh 1658 def test_title(self):
405     """test PostGISTable.Title()"""
406     # The title is currently equal to the tablename
407 bh 2096 self.assertEquals(self.table.Title(), self.table_name)
408 bh 1658
409 bh 1605 def test_dependencies(self):
410     """Test PostGISTable.Dependencies()"""
411     # A PostGISTable depends on no other data container
412     self.assertEquals(self.table.Dependencies(), ())
413    
414     def test_num_rows(self):
415     """Test PostGISTable.NumRows()"""
416     self.assertEquals(self.table.NumRows(), 34)
417    
418     def test_num_columns(self):
419     """Test PostGISTable.NumColumns()"""
420     # The table in the postgis db has one additional column, "gid",
421     # so there's one more column in the PostGISTable than in the DBF
422     self.assertEquals(self.table.NumColumns(), 7)
423    
424     def test_columns(self):
425     """Test PostGISTable.Columns()"""
426     self.assertEquals(len(self.table.Columns()), 7)
427 bh 2096 self.assertEquals(self.table.Columns()[0].name, self.gid_column)
428 bh 1605 self.assertEquals(self.table.Columns()[0].type, FIELDTYPE_INT)
429     self.assertEquals(self.table.Columns()[0].index, 0)
430     self.assertEquals(self.table.Columns()[1].name, "area")
431     self.assertEquals(self.table.Columns()[1].type, FIELDTYPE_DOUBLE)
432     self.assertEquals(self.table.Columns()[1].index, 1)
433     self.assertEquals(self.table.Columns()[5].name, "clptlabel")
434     self.assertEquals(self.table.Columns()[5].type, FIELDTYPE_STRING)
435     self.assertEquals(self.table.Columns()[5].index, 5)
436    
437     def test_column(self):
438     """Test PostGISTable.Column()"""
439     self.assertEquals(self.table.Column("area").name, "area")
440     self.assertEquals(self.table.Column("area").type, FIELDTYPE_DOUBLE)
441     self.assertEquals(self.table.Column("area").index, 1)
442    
443     def test_has_column(self):
444     """Test PostGISTable.HasColumn()"""
445     self.assert_(self.table.HasColumn("area"))
446     self.failIf(self.table.HasColumn("foo"))
447    
448     def test_read_row_as_dict(self):
449     """Test PostGISTable.ReadRowAsDict()"""
450 bh 1662 self.assertEquals(self.table.ReadRowAsDict(1003),
451 bh 2096 {self.gid_column: 1003,
452 bh 1605 "area": 0.0,
453     "perimeter": 0.0,
454     "clpoint_": 4,
455     "clpoint_id": 24,
456     "clptlabel": "RUINS",
457     "clptflag": 0})
458    
459 bh 1662 def test_read_row_as_dict_row_count_mode(self):
460     """Test PostGISTable.ReadRowAsDict() row count address mode"""
461     self.assertEquals(self.table.ReadRowAsDict(3, row_is_ordinal = 1),
462 bh 2096 {self.gid_column: 1003,
463 bh 1662 "area": 0.0,
464     "perimeter": 0.0,
465     "clpoint_": 4,
466     "clpoint_id": 24,
467     "clptlabel": "RUINS",
468     "clptflag": 0})
469    
470 bh 1605 def test_read_value(self):
471     """Test PostGISTable.ReadValue()"""
472 bh 1662 self.assertEquals(self.table.ReadValue(1003, 4), 24)
473     self.assertEquals(self.table.ReadValue(1003, "clpoint_id"), 24)
474 bh 1605
475 bh 1662 def test_read_value_row_count_mode(self):
476     """Test PostGISTable.ReadValue() row count address mode"""
477     self.assertEquals(self.table.ReadValue(3, 4, row_is_ordinal = 1), 24)
478     self.assertEquals(self.table.ReadValue(3, "clpoint_id",
479     row_is_ordinal = 1),
480     24)
481    
482     def test_row_id_to_ordinal(self):
483     """Test PostGISTable.RowIdToOrdinal()"""
484     self.assertEquals(self.table.RowIdToOrdinal(1005), 5)
485    
486     def test_row_oridnal_to_id(self):
487     """Test PostGISTable.RowOrdinalToId()"""
488     self.assertEquals(self.table.RowOrdinalToId(5), 1005)
489    
490 bh 1605 def test_value_range(self):
491     """Test PostGISTable.ValueRange()"""
492     self.assertEquals(self.table.ValueRange("clpoint_id"), (21, 74))
493    
494     def test_unique_values(self):
495     """Test PostGISTable.UniqueValues()"""
496     values = self.table.UniqueValues("clptlabel")
497     values.sort()
498     self.assertEquals(values, ["BUILDING", "FARM", "HUT","LIGHTHOUSE",
499     "OTHER/UNKNOWN", "RUINS"])
500    
501     def test_simple_query(self):
502     """Test PostGISTable.SimpleQuery()"""
503     table = self.table
504     self.assertEquals(table.SimpleQuery(table.Column("clptlabel"),
505     "==", "FARM"),
506 bh 1662 [1006])
507 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
508     ">", 70),
509 bh 1662 [1024, 1025, 1026])
510 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
511     "<", table.Column("clpoint_")),
512 bh 1662 [1028, 1029, 1030, 1031, 1032, 1033])
513 bh 1605
514    
515 bh 2096 class TestPostGISTable(TableTests, PostGISStaticTests):
516    
517     def setUp(self):
518     """Extend inherited method to set self.table to a PostGISTable"""
519     PostGISStaticTests.setUp(self)
520     self.table_name = "landmarks"
521     self.gid_column = "gid"
522    
523     # Note that omit the gid column here to the backwards compatible
524     # interface of the constructor where the gid_column defaults to
525     # "gid"
526     self.table = PostGISTable(self.db, self.table_name)
527    
528    
529     class TestPostGISTableExplicitGIDColumn(TableTests, PostGISStaticTests):
530    
531     def setUp(self):
532     """Extend inherited method to set self.table to a PostGISTable"""
533     PostGISStaticTests.setUp(self)
534     self.table_name = "landmarks_point_id"
535     self.gid_column = "point_id"
536     self.table = PostGISTable(self.db, self.table_name,
537     id_column = self.gid_column)
538    
539    
540 bh 2057 class PointTests:
541 bh 1605
542 bh 2096 """Mix-in class for the tests on POINT tables
543 bh 1605
544 bh 2096 The methods in this class expect self.store to be the shapestore
545     used for testing. Derived classes should initialize self.store with
546     PostGISShapeStore in setUp. Another assumption is that the data in
547     self.store is effectively the cultural_landmark-point shapefile with
548     shape ids increased by 1000.
549     """
550    
551 bh 1605 #
552     # First, some tests that should be independend of the shapetype, so
553     # it shouldn't be necessary to repeat them for other shapetypes
554     #
555    
556     def test_dependencies(self):
557     """Test PostGISShapeStore.Dependencies()"""
558     # A PostGISShapeStore depends on no other data container
559     self.assertEquals(self.store.Dependencies(), ())
560    
561     def test_table(self):
562     """Test PostGISShapeStore.Table() with POINT shapes"""
563     # A PostGISShapeStore is its own table
564     self.assert_(self.store.Table() is self.store)
565    
566     def test_orig_shapestore(self):
567     """Test PostGISShapeStore.OrigShapeStore() with POINT shapes"""
568     # A PostGISShapeStore is not derived from another shape store
569     self.assert_(self.store.OrigShapeStore() is None)
570    
571     def test_raw_format(self):
572     """Test PostGISShapeStore.RawShapeFormat() with POINT shapes"""
573     self.assertEquals(self.store.RawShapeFormat(), RAW_WKT)
574    
575 bh 1658 def test_all_shapes(self):
576     """Test PostGISShapeStore.AllShapes()"""
577     self.assertEquals([s.ShapeID() for s in self.store.AllShapes()],
578 bh 1662 range(1000, 1000 + self.store.NumShapes()))
579 bh 1658
580 bh 2102 def test_id_column(self):
581     self.assertEquals(self.store.IDColumn().name, self.id_column)
582    
583     def test_geometry_column(self):
584     self.assertEquals(self.store.GeometryColumn().name,
585     self.geometry_column)
586    
587 bh 1605 #
588     # Shapetype specific tests
589     #
590    
591     def test_shape_type(self):
592     """Test PostGISShapeStore.ShapeType() with POINT shapes"""
593     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POINT)
594    
595     def test_num_shapes(self):
596     """Test PostGISShapeStore.NumShapes() with POINT shapes"""
597     self.assertEquals(self.store.NumShapes(), 34)
598    
599     def test_bounding_box(self):
600     """Test PostGISShapeStore.BoundingBox() with POINT shapes"""
601     self.assertFloatSeqEqual(self.store.BoundingBox(),
602     [-23.806047439575195, 63.405960083007812,
603     -15.12291431427002, 66.36572265625])
604    
605     def test_shape_shapeid(self):
606     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
607 bh 1662 self.assertEquals(self.store.Shape(1005).ShapeID(), 1005)
608 bh 1605
609     def test_shape_points(self):
610     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
611 bh 1662 self.assertPointListEquals(self.store.Shape(1000).Points(),
612 bh 1605 [[(-22.711074829101562, 66.36572265625)]])
613    
614     def test_shape_raw_data(self):
615     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
616 bh 1662 self.assertEquals(self.store.Shape(1000).RawData(),
617 bh 1605 'POINT(-22.7110748291016 66.36572265625)')
618    
619     def test_shapes_in_region(self):
620     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
621     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
622     self.assertEquals([s.ShapeID() for s in shapes],
623 bh 1662 [1000, 1001, 1002, 1003, 1004, 1005, 1027])
624 bh 1605
625    
626 bh 2057 class TestPostGISShapestorePoint(PointTests, PostGISStaticTests):
627    
628     """Tests for PostGISShapeStore objects with POINT data an no SRID"""
629    
630     def setUp(self):
631     """Extend inherited method to set self.table to a PostGISShapeStore"""
632     PostGISStaticTests.setUp(self)
633 bh 2102 self.id_column = "gid"
634     self.geometry_column = "the_geom"
635 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks")
636    
637    
638    
639     class TestPostGISShapestorePointSRID(PointTests, PostGISStaticTests):
640    
641     """Tests for PostGISShapeStore objects with POINT data and an SRID"""
642    
643     def setUp(self):
644     """Extend inherited method to set self.table to a PostGISShapeStore"""
645     PostGISStaticTests.setUp(self)
646 bh 2102 self.id_column = "gid"
647     self.geometry_column = "the_geom"
648 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks_srid")
649    
650    
651 bh 2096 class TestPostGISShapestorePointExplicitGIDColumn(PointTests,
652     PostGISStaticTests):
653 bh 2057
654 bh 2096 """Tests for PostGISShapeStores with POINT data and explicit gid column"""
655    
656     def setUp(self):
657     """Extend inherited method to set self.table to a PostGISShapeStore"""
658     PostGISStaticTests.setUp(self)
659 bh 2102 self.id_column = "point_id"
660     self.geometry_column = "the_geom"
661 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
662     id_column = "point_id")
663    
664    
665     class TestPostGISShapestorePointOIDAsGIDColumn(PointTests, PostGISStaticTests):
666    
667     """Tests for PostGISShapeStores with POINT data using OID as gid column"""
668    
669     def setUp(self):
670     """Extend inherited method to set self.table to a PostGISShapeStore"""
671     PostGISStaticTests.setUp(self)
672 bh 2102 self.id_column = "oid"
673     self.geometry_column = "the_geom"
674 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
675     id_column = "oid")
676    
677     def find_test_shape_id(self):
678     """Return the id of an interesting shape for some test cases.
679    
680     This test uses OIDs so we can't easily hard wire ids in the test
681     cases
682     """
683     # get the id of an interesting shape
684     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
685     return list(shapes)[0].ShapeID()
686    
687    
688     # Override a few tests that won't work with this table because they
689     # require knowledge of specific IDs
690    
691     def test_shape_shapeid(self):
692     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
693     gid = self.find_test_shape_id()
694     self.assertEquals(self.store.Shape(gid).ShapeID(), gid)
695    
696     def test_shape_points(self):
697     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
698     gid = self.find_test_shape_id()
699     self.assertPointListEquals(self.store.Shape(gid).Points(),
700     [[(-22.711074829101562, 66.36572265625)]])
701    
702     def test_shape_raw_data(self):
703     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
704     gid = self.find_test_shape_id()
705     self.assertEquals(self.store.Shape(gid).RawData(),
706     'POINT(-22.7110748291016 66.36572265625)')
707    
708     def test_shapes_in_region(self):
709     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
710     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
711     self.assertEquals(len(list(shapes)), 7)
712    
713     def test_all_shapes(self):
714     """Test PostGISShapeStore.AllShapes()"""
715     self.assertEquals(len(list(self.store.AllShapes())), 34)
716    
717    
718    
719 bh 1605 class TestPostGISShapestoreArc(PostGISStaticTests):
720    
721     """Tests for PostGISShapeStore objects with MULTILINESTRING data"""
722    
723     def setUp(self):
724     """Extend inherited method to set self.table to a PostGISShapeStore"""
725     PostGISStaticTests.setUp(self)
726     self.store = PostGISShapeStore(self.db, "roads")
727    
728     def test_shape_type(self):
729     """Test PostGISShapeStore.ShapeType() with ARC shapes"""
730     self.assertEquals(self.store.ShapeType(), SHAPETYPE_ARC)
731    
732     def test_num_shapes(self):
733     """Test PostGISShapeStore.NumShapes() with ARC shapes"""
734     self.assertEquals(self.store.NumShapes(), 839)
735    
736     def test_bounding_box(self):
737     """Test PostGISShapeStore.BoundingBox() with ARC shapes"""
738     self.assertFloatSeqEqual(self.store.BoundingBox(),
739     [-24.450359344482422, 63.426830291748047,
740     -13.55668830871582, 66.520111083984375])
741    
742     def test_shape_shapeid(self):
743     """Test PostGISShapeStore.Shape(i).ShapeID() with ARC shapes"""
744     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
745    
746     def test_shape_points(self):
747     """Test PostGISShapeStore.Shape(i).Points() with ARC shapes"""
748     self.assertPointListEquals(self.store.Shape(32).Points(),
749     [[(-15.0821743011474, 66.2773818969726),
750     (-15.0263500213623, 66.2733917236328)]])
751    
752     def test_shape_raw_data(self):
753     """Test PostGISShapeStore.Shape(i).RawData() with ARC shapes"""
754     self.assertEquals(self.store.Shape(32).RawData(),
755     "MULTILINESTRING((-15.0821743011475 66.2773818969727,"
756     "-15.0263500213623 66.2733917236328))")
757    
758     def test_shapes_in_region(self):
759     """Test PostGISShapeStore.ShapesInRegion() with ARC shapes"""
760     shapes = self.store.ShapesInRegion((-24.0, 64.5, -23.5, 65.0))
761     self.assertEquals([s.ShapeID() for s in shapes], [573, 581, 613])
762    
763    
764    
765 bh 1656 class PolygonTests:
766 bh 1605
767 bh 2057 """Test shared by the POLYGON and MULTIPOLYGON tests
768 bh 1605
769 bh 1656 The tests are the same because they are based on the same data.
770     """
771    
772 bh 1605 def test_shape_type(self):
773     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
774     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
775    
776     def test_num_shapes(self):
777     """Test PostGISShapeStore.NumShapes() with POLYGON shapes"""
778     self.assertEquals(self.store.NumShapes(), 156)
779    
780     def test_bounding_box(self):
781     """Test PostGISShapeStore.BoundingBox() with POLYGON shapes"""
782     self.assertFloatSeqEqual(self.store.BoundingBox(),
783     [-24.546524047851562, 63.286754608154297,
784     -13.495815277099609, 66.563774108886719])
785    
786     def test_shape_shapeid(self):
787     """Test PostGISShapeStore.Shape(i).ShapeID() with POLYGON shapes"""
788     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
789    
790     def test_shape_points(self):
791     """Test PostGISShapeStore.Shape(i).Points() with POLYGON shapes"""
792     self.assertPointListEquals(self.store.Shape(4).Points(),
793     [[(-22.40639114379882, 64.714111328125),
794     (-22.41621208190918, 64.716003417968),
795     (-22.40605163574218, 64.719200134277),
796     (-22.40639114379882, 64.714111328125)]])
797    
798 bh 1656 def test_shapes_in_region(self):
799     """Test PostGISShapeStore.ShapesInRegion() with POLYGON shapes"""
800     shapes = self.store.ShapesInRegion((-23.0, 65.5, -22.8, 65.25))
801     self.assertEquals([s.ShapeID() for s in shapes],
802     [47, 56, 59, 61, 62, 71, 144])
803    
804    
805     class TestPostGISShapestorePolygon(PolygonTests, PostGISStaticTests):
806    
807     """Tests for PostGISShapeStore objects with POLYGON data"""
808    
809     def setUp(self):
810     """Extend inherited method to set self.table to a PostGISShapeStore"""
811     PostGISStaticTests.setUp(self)
812     self.store = PostGISShapeStore(self.db, "political")
813    
814     def test_shape_type(self):
815     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
816     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
817    
818    
819 bh 1605 def test_shape_raw_data(self):
820     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
821     self.assertEquals(self.store.Shape(4).RawData(),
822     "POLYGON((-22.4063911437988 64.714111328125,"
823     "-22.4162120819092 64.7160034179688,"
824     "-22.4060516357422 64.7192001342773,"
825     "-22.4063911437988 64.714111328125))")
826    
827    
828 bh 1656 class TestPostGISShapestoreMultiPolygon(PolygonTests, PostGISStaticTests):
829 bh 1605
830 bh 1656 """Tests for PostGISShapeStore objects with MUTLIPOLYGON data"""
831    
832     def setUp(self):
833     """Extend inherited method to set self.table to a PostGISShapeStore"""
834     PostGISStaticTests.setUp(self)
835     self.store = PostGISShapeStore(self.db, "political_multi")
836    
837     def test_shape_raw_data(self):
838     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
839     self.assertEquals(self.store.Shape(4).RawData(),
840     "MULTIPOLYGON(((-22.4063911437988 64.714111328125,"
841     "-22.4162120819092 64.7160034179688,"
842     "-22.4060516357422 64.7192001342773,"
843     "-22.4063911437988 64.714111328125)))")
844    
845 bh 1693
846    
847 bh 1605 if __name__ == "__main__":
848     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