/[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 2623 - (hide annotations)
Mon May 9 18:12:12 2005 UTC (19 years, 10 months ago) by bh
Original Path: trunk/thuban/test/test_postgis_db.py
File MIME type: text/x-python
File size: 38826 byte(s)
* Thuban/Model/postgisdb.py (PostGISConnection.connect): Set the
connection to autoconnect.  Fixes RT#3148.

* test/test_postgis_db.py
(TestPostGISSpecialCases.test_simple_error_handling): New test
that attempts to reproduce RT#3148.

1 bh 2623 # Copyright (C) 2003, 2004, 2005 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 2623 def test_simple_error_handling(self):
352     """Test some simple error handling.
353    
354     If an error happens in, say the SimpleQuery method, a subsequent
355     ReadValue call should still succeed.
356     """
357     conn = psycopg.connect("dbname=%s " % self.dbname
358     + self.server.connection_string("admin"))
359     cursor = conn.cursor()
360     cursor.execute("CREATE TABLE some_table"
361     " (gid INTEGER PRIMARY KEY, length float);"
362     "INSERT INTO some_table VALUES (1, 3.5);")
363     cursor.execute("GRANT SELECT ON some_table TO PUBLIC;")
364     conn.commit()
365     conn.close()
366    
367     db = PostGISConnection(dbname = self.dbname,
368     **self.server.connection_params("user"))
369     table = PostGISTable(db, "some_table", id_column = "gid")
370    
371     # trying to compare the length to a string should fail with an
372     # exception.
373     self.assertRaises(psycopg.ProgrammingError,
374     table.SimpleQuery,
375     table.Column("length"), "<=", "abc")
376    
377     # After the exception, doing a query on the same table should
378     # work. Since it's the same database connection as before, it
379     # can fail if no rollback has been done or the connection isn't
380     # in autocommit mode. Typical error message is
381     #
382     # ERROR: current transaction is aborted, commands ignored
383     # until end of transaction block
384     try:
385     self.assertEquals(table.ReadValue(1, "length"), 3.5)
386     except psycopg.ProgrammingError, val:
387     self.fail("table didn't handle exception properly (%s)" % val)
388    
389    
390 bh 1605 class PostGISStaticTests(unittest.TestCase, support.FloatComparisonMixin):
391    
392     """Base class for PostGIS tests with static data."""
393    
394     def setUp(self):
395     """Start the server and create a database with static data
396    
397     This method sets the following instance attributes:
398    
399     dbname -- the name of the database
400    
401     server -- The server object
402    
403     db -- the PostGISConnection object
404     """
405     postgissupport.skip_if_no_postgis()
406     self.server = postgissupport.get_test_server()
407     self.postgisdb = self.server.get_default_static_data_db()
408     self.db = PostGISConnection(dbname = self.postgisdb.dbname,
409 bh 1634 **self.server.connection_params("user"))
410 bh 1605
411     def tearDown(self):
412     """Close the database connection"""
413     self.db.Close()
414    
415    
416 bh 2096 class TableTests:
417 bh 1605
418 bh 2096 """Mix-in class for the PostGISTable tests
419 bh 1605
420 bh 2096 The tests defined here make some assumptions about the table and the
421     data in it:
422    
423     self.table should be the PostGISTable instance to test. Derived
424     classes should set this up in setUp.
425    
426     self.db should be the DB connection object used by self.table.
427    
428     self.table_name should be the name of the table in the database.
429     The tests assume that e.g. the title of self.table can be
430     derived from this.
431    
432     self.gid_column should be the name of the gid column used when
433     self.table was instantiated.
434    
435     The data in the table should be the data of the
436     cultural_landmark-point shapefile with the shape ids used to get
437     the contents of the gid column by adding 1000.
438     """
439    
440 bh 1638 def test_dbconn(self):
441     """Test PostGISTable.DBConnection()"""
442     self.failUnless(self.table.DBConnection() is self.db)
443    
444     def test_dbname(self):
445     """Test PostGISTable.TableName()"""
446 bh 2096 self.assertEquals(self.table.TableName(), self.table_name)
447 bh 1638
448 bh 1658 def test_title(self):
449     """test PostGISTable.Title()"""
450     # The title is currently equal to the tablename
451 bh 2096 self.assertEquals(self.table.Title(), self.table_name)
452 bh 1658
453 bh 1605 def test_dependencies(self):
454     """Test PostGISTable.Dependencies()"""
455     # A PostGISTable depends on no other data container
456     self.assertEquals(self.table.Dependencies(), ())
457    
458     def test_num_rows(self):
459     """Test PostGISTable.NumRows()"""
460     self.assertEquals(self.table.NumRows(), 34)
461    
462     def test_num_columns(self):
463     """Test PostGISTable.NumColumns()"""
464     # The table in the postgis db has one additional column, "gid",
465     # so there's one more column in the PostGISTable than in the DBF
466     self.assertEquals(self.table.NumColumns(), 7)
467    
468     def test_columns(self):
469     """Test PostGISTable.Columns()"""
470     self.assertEquals(len(self.table.Columns()), 7)
471 bh 2096 self.assertEquals(self.table.Columns()[0].name, self.gid_column)
472 bh 1605 self.assertEquals(self.table.Columns()[0].type, FIELDTYPE_INT)
473     self.assertEquals(self.table.Columns()[0].index, 0)
474     self.assertEquals(self.table.Columns()[1].name, "area")
475     self.assertEquals(self.table.Columns()[1].type, FIELDTYPE_DOUBLE)
476     self.assertEquals(self.table.Columns()[1].index, 1)
477     self.assertEquals(self.table.Columns()[5].name, "clptlabel")
478     self.assertEquals(self.table.Columns()[5].type, FIELDTYPE_STRING)
479     self.assertEquals(self.table.Columns()[5].index, 5)
480    
481     def test_column(self):
482     """Test PostGISTable.Column()"""
483     self.assertEquals(self.table.Column("area").name, "area")
484     self.assertEquals(self.table.Column("area").type, FIELDTYPE_DOUBLE)
485     self.assertEquals(self.table.Column("area").index, 1)
486    
487     def test_has_column(self):
488     """Test PostGISTable.HasColumn()"""
489     self.assert_(self.table.HasColumn("area"))
490     self.failIf(self.table.HasColumn("foo"))
491    
492     def test_read_row_as_dict(self):
493     """Test PostGISTable.ReadRowAsDict()"""
494 bh 1662 self.assertEquals(self.table.ReadRowAsDict(1003),
495 bh 2096 {self.gid_column: 1003,
496 bh 1605 "area": 0.0,
497     "perimeter": 0.0,
498     "clpoint_": 4,
499     "clpoint_id": 24,
500     "clptlabel": "RUINS",
501     "clptflag": 0})
502    
503 bh 1662 def test_read_row_as_dict_row_count_mode(self):
504     """Test PostGISTable.ReadRowAsDict() row count address mode"""
505     self.assertEquals(self.table.ReadRowAsDict(3, row_is_ordinal = 1),
506 bh 2096 {self.gid_column: 1003,
507 bh 1662 "area": 0.0,
508     "perimeter": 0.0,
509     "clpoint_": 4,
510     "clpoint_id": 24,
511     "clptlabel": "RUINS",
512     "clptflag": 0})
513    
514 bh 1605 def test_read_value(self):
515     """Test PostGISTable.ReadValue()"""
516 bh 1662 self.assertEquals(self.table.ReadValue(1003, 4), 24)
517     self.assertEquals(self.table.ReadValue(1003, "clpoint_id"), 24)
518 bh 1605
519 bh 1662 def test_read_value_row_count_mode(self):
520     """Test PostGISTable.ReadValue() row count address mode"""
521     self.assertEquals(self.table.ReadValue(3, 4, row_is_ordinal = 1), 24)
522     self.assertEquals(self.table.ReadValue(3, "clpoint_id",
523     row_is_ordinal = 1),
524     24)
525    
526     def test_row_id_to_ordinal(self):
527     """Test PostGISTable.RowIdToOrdinal()"""
528     self.assertEquals(self.table.RowIdToOrdinal(1005), 5)
529    
530     def test_row_oridnal_to_id(self):
531     """Test PostGISTable.RowOrdinalToId()"""
532     self.assertEquals(self.table.RowOrdinalToId(5), 1005)
533    
534 bh 1605 def test_value_range(self):
535     """Test PostGISTable.ValueRange()"""
536     self.assertEquals(self.table.ValueRange("clpoint_id"), (21, 74))
537    
538     def test_unique_values(self):
539     """Test PostGISTable.UniqueValues()"""
540     values = self.table.UniqueValues("clptlabel")
541     values.sort()
542     self.assertEquals(values, ["BUILDING", "FARM", "HUT","LIGHTHOUSE",
543     "OTHER/UNKNOWN", "RUINS"])
544    
545     def test_simple_query(self):
546     """Test PostGISTable.SimpleQuery()"""
547     table = self.table
548     self.assertEquals(table.SimpleQuery(table.Column("clptlabel"),
549     "==", "FARM"),
550 bh 1662 [1006])
551 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
552     ">", 70),
553 bh 1662 [1024, 1025, 1026])
554 bh 1605 self.assertEquals(table.SimpleQuery(table.Column("clpoint_id"),
555     "<", table.Column("clpoint_")),
556 bh 1662 [1028, 1029, 1030, 1031, 1032, 1033])
557 bh 1605
558    
559 bh 2096 class TestPostGISTable(TableTests, PostGISStaticTests):
560    
561     def setUp(self):
562     """Extend inherited method to set self.table to a PostGISTable"""
563     PostGISStaticTests.setUp(self)
564     self.table_name = "landmarks"
565     self.gid_column = "gid"
566    
567     # Note that omit the gid column here to the backwards compatible
568     # interface of the constructor where the gid_column defaults to
569     # "gid"
570     self.table = PostGISTable(self.db, self.table_name)
571    
572    
573     class TestPostGISTableExplicitGIDColumn(TableTests, PostGISStaticTests):
574    
575     def setUp(self):
576     """Extend inherited method to set self.table to a PostGISTable"""
577     PostGISStaticTests.setUp(self)
578     self.table_name = "landmarks_point_id"
579     self.gid_column = "point_id"
580     self.table = PostGISTable(self.db, self.table_name,
581     id_column = self.gid_column)
582    
583    
584 bh 2057 class PointTests:
585 bh 1605
586 bh 2096 """Mix-in class for the tests on POINT tables
587 bh 1605
588 bh 2096 The methods in this class expect self.store to be the shapestore
589     used for testing. Derived classes should initialize self.store with
590     PostGISShapeStore in setUp. Another assumption is that the data in
591     self.store is effectively the cultural_landmark-point shapefile with
592     shape ids increased by 1000.
593     """
594    
595 bh 1605 #
596     # First, some tests that should be independend of the shapetype, so
597     # it shouldn't be necessary to repeat them for other shapetypes
598     #
599    
600     def test_dependencies(self):
601     """Test PostGISShapeStore.Dependencies()"""
602     # A PostGISShapeStore depends on no other data container
603     self.assertEquals(self.store.Dependencies(), ())
604    
605     def test_table(self):
606     """Test PostGISShapeStore.Table() with POINT shapes"""
607     # A PostGISShapeStore is its own table
608     self.assert_(self.store.Table() is self.store)
609    
610     def test_orig_shapestore(self):
611     """Test PostGISShapeStore.OrigShapeStore() with POINT shapes"""
612     # A PostGISShapeStore is not derived from another shape store
613     self.assert_(self.store.OrigShapeStore() is None)
614    
615     def test_raw_format(self):
616     """Test PostGISShapeStore.RawShapeFormat() with POINT shapes"""
617     self.assertEquals(self.store.RawShapeFormat(), RAW_WKT)
618    
619 bh 1658 def test_all_shapes(self):
620     """Test PostGISShapeStore.AllShapes()"""
621     self.assertEquals([s.ShapeID() for s in self.store.AllShapes()],
622 bh 1662 range(1000, 1000 + self.store.NumShapes()))
623 bh 1658
624 bh 2102 def test_id_column(self):
625     self.assertEquals(self.store.IDColumn().name, self.id_column)
626    
627     def test_geometry_column(self):
628     self.assertEquals(self.store.GeometryColumn().name,
629     self.geometry_column)
630    
631 bh 1605 #
632     # Shapetype specific tests
633     #
634    
635     def test_shape_type(self):
636     """Test PostGISShapeStore.ShapeType() with POINT shapes"""
637     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POINT)
638    
639     def test_num_shapes(self):
640     """Test PostGISShapeStore.NumShapes() with POINT shapes"""
641     self.assertEquals(self.store.NumShapes(), 34)
642    
643     def test_bounding_box(self):
644     """Test PostGISShapeStore.BoundingBox() with POINT shapes"""
645     self.assertFloatSeqEqual(self.store.BoundingBox(),
646     [-23.806047439575195, 63.405960083007812,
647     -15.12291431427002, 66.36572265625])
648    
649     def test_shape_shapeid(self):
650     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
651 bh 1662 self.assertEquals(self.store.Shape(1005).ShapeID(), 1005)
652 bh 1605
653     def test_shape_points(self):
654     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
655 bh 1662 self.assertPointListEquals(self.store.Shape(1000).Points(),
656 bh 1605 [[(-22.711074829101562, 66.36572265625)]])
657    
658     def test_shape_raw_data(self):
659     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
660 bh 1662 self.assertEquals(self.store.Shape(1000).RawData(),
661 bh 1605 'POINT(-22.7110748291016 66.36572265625)')
662    
663     def test_shapes_in_region(self):
664     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
665     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
666     self.assertEquals([s.ShapeID() for s in shapes],
667 bh 1662 [1000, 1001, 1002, 1003, 1004, 1005, 1027])
668 bh 1605
669    
670 bh 2057 class TestPostGISShapestorePoint(PointTests, PostGISStaticTests):
671    
672     """Tests for PostGISShapeStore objects with POINT data an no SRID"""
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 = "gid"
678     self.geometry_column = "the_geom"
679 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks")
680    
681    
682    
683     class TestPostGISShapestorePointSRID(PointTests, PostGISStaticTests):
684    
685     """Tests for PostGISShapeStore objects with POINT data and an SRID"""
686    
687     def setUp(self):
688     """Extend inherited method to set self.table to a PostGISShapeStore"""
689     PostGISStaticTests.setUp(self)
690 bh 2102 self.id_column = "gid"
691     self.geometry_column = "the_geom"
692 bh 2057 self.store = PostGISShapeStore(self.db, "landmarks_srid")
693    
694    
695 bh 2096 class TestPostGISShapestorePointExplicitGIDColumn(PointTests,
696     PostGISStaticTests):
697 bh 2057
698 bh 2096 """Tests for PostGISShapeStores with POINT data and explicit gid column"""
699    
700     def setUp(self):
701     """Extend inherited method to set self.table to a PostGISShapeStore"""
702     PostGISStaticTests.setUp(self)
703 bh 2102 self.id_column = "point_id"
704     self.geometry_column = "the_geom"
705 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
706     id_column = "point_id")
707    
708    
709     class TestPostGISShapestorePointOIDAsGIDColumn(PointTests, PostGISStaticTests):
710    
711     """Tests for PostGISShapeStores with POINT data using OID as gid column"""
712    
713     def setUp(self):
714     """Extend inherited method to set self.table to a PostGISShapeStore"""
715     PostGISStaticTests.setUp(self)
716 bh 2102 self.id_column = "oid"
717     self.geometry_column = "the_geom"
718 bh 2096 self.store = PostGISShapeStore(self.db, "landmarks_point_id",
719 bh 2106 id_column = self.id_column,
720     geometry_column = self.geometry_column)
721 bh 2096
722     def find_test_shape_id(self):
723     """Return the id of an interesting shape for some test cases.
724    
725     This test uses OIDs so we can't easily hard wire ids in the test
726     cases
727     """
728     # get the id of an interesting shape
729     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
730     return list(shapes)[0].ShapeID()
731    
732    
733     # Override a few tests that won't work with this table because they
734     # require knowledge of specific IDs
735    
736     def test_shape_shapeid(self):
737     """Test PostGISShapeStore.Shape(i).ShapeID() with POINT shapes"""
738     gid = self.find_test_shape_id()
739     self.assertEquals(self.store.Shape(gid).ShapeID(), gid)
740    
741     def test_shape_points(self):
742     """Test PostGISShapeStore.Shape(i).Points() with POINT shapes"""
743     gid = self.find_test_shape_id()
744     self.assertPointListEquals(self.store.Shape(gid).Points(),
745     [[(-22.711074829101562, 66.36572265625)]])
746    
747     def test_shape_raw_data(self):
748     """Test PostGISShapeStore.Shape(i).RawData() with POINT shapes"""
749     gid = self.find_test_shape_id()
750     self.assertEquals(self.store.Shape(gid).RawData(),
751     'POINT(-22.7110748291016 66.36572265625)')
752    
753     def test_shapes_in_region(self):
754     """Test PostGISShapeStore:ShapesInRegion() with POINT shapes"""
755     shapes = self.store.ShapesInRegion((-20.0, 64.0, -24.0, 67))
756     self.assertEquals(len(list(shapes)), 7)
757    
758     def test_all_shapes(self):
759     """Test PostGISShapeStore.AllShapes()"""
760     self.assertEquals(len(list(self.store.AllShapes())), 34)
761    
762    
763 bh 2106 class TestPostGISShapestorePointFromViews(PointTests, PostGISStaticTests):
764 bh 2096
765 bh 2106 """Tests for PostGISShapeStores with POINT data in a view"""
766    
767     def setUp(self):
768     """Extend inherited method to set self.table to a PostGISShapeStore"""
769     PostGISStaticTests.setUp(self)
770     self.id_column = "point_id"
771     self.geometry_column = "the_geom"
772     self.store = PostGISShapeStore(self.db, "v_landmarks",
773     id_column = "point_id")
774    
775    
776 bh 2472 class LineStringTests:
777 bh 1605
778 bh 2472 """Tests shared by the LINESTRING and MULTILINESTRING tests.
779 bh 1605
780 bh 2472 The tests are the same because they are based on the same data.
781     """
782 bh 1605
783     def test_shape_type(self):
784     """Test PostGISShapeStore.ShapeType() with ARC shapes"""
785     self.assertEquals(self.store.ShapeType(), SHAPETYPE_ARC)
786    
787     def test_num_shapes(self):
788     """Test PostGISShapeStore.NumShapes() with ARC shapes"""
789     self.assertEquals(self.store.NumShapes(), 839)
790    
791     def test_bounding_box(self):
792     """Test PostGISShapeStore.BoundingBox() with ARC shapes"""
793     self.assertFloatSeqEqual(self.store.BoundingBox(),
794     [-24.450359344482422, 63.426830291748047,
795     -13.55668830871582, 66.520111083984375])
796    
797     def test_shape_shapeid(self):
798     """Test PostGISShapeStore.Shape(i).ShapeID() with ARC shapes"""
799     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
800    
801     def test_shape_points(self):
802     """Test PostGISShapeStore.Shape(i).Points() with ARC shapes"""
803     self.assertPointListEquals(self.store.Shape(32).Points(),
804     [[(-15.0821743011474, 66.2773818969726),
805     (-15.0263500213623, 66.2733917236328)]])
806    
807 bh 2472 def test_shapes_in_region(self):
808     """Test PostGISShapeStore.ShapesInRegion() with ARC shapes"""
809     shapes = self.store.ShapesInRegion((-24.0, 64.5, -23.5, 65.0))
810     self.assertEquals([s.ShapeID() for s in shapes], [573, 581, 613])
811    
812    
813     class TestPostGISShapestoreLineString(LineStringTests, PostGISStaticTests):
814    
815     """Tests for PostGISShapeStore objects with LINESTRING data"""
816    
817     def setUp(self):
818     """Extend inherited method to set self.table to a PostGISShapeStore"""
819     PostGISStaticTests.setUp(self)
820     self.store = PostGISShapeStore(self.db, "roads")
821    
822 bh 1605 def test_shape_raw_data(self):
823     """Test PostGISShapeStore.Shape(i).RawData() with ARC shapes"""
824     self.assertEquals(self.store.Shape(32).RawData(),
825 bh 2472 "LINESTRING(-15.0821743011475 66.2773818969727,"
826     "-15.0263500213623 66.2733917236328)")
827    
828    
829     class TestPostGISShapestoreMultiLineString(LineStringTests,
830     PostGISStaticTests):
831    
832     """Tests for PostGISShapeStore objects with MULTILINESTRING data"""
833    
834     def setUp(self):
835     """Extend inherited method to set self.table to a PostGISShapeStore"""
836     PostGISStaticTests.setUp(self)
837     self.store = PostGISShapeStore(self.db, "roads_multi")
838    
839     def test_shape_raw_data(self):
840     """Test PostGISShapeStore.Shape(i).RawData() with ARC shapes"""
841     self.assertEquals(self.store.Shape(32).RawData(),
842 bh 1605 "MULTILINESTRING((-15.0821743011475 66.2773818969727,"
843     "-15.0263500213623 66.2733917236328))")
844    
845    
846 bh 1656 class PolygonTests:
847 bh 1605
848 bh 2057 """Test shared by the POLYGON and MULTIPOLYGON tests
849 bh 1605
850 bh 1656 The tests are the same because they are based on the same data.
851     """
852    
853 bh 1605 def test_shape_type(self):
854     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
855     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
856    
857     def test_num_shapes(self):
858     """Test PostGISShapeStore.NumShapes() with POLYGON shapes"""
859     self.assertEquals(self.store.NumShapes(), 156)
860    
861     def test_bounding_box(self):
862     """Test PostGISShapeStore.BoundingBox() with POLYGON shapes"""
863     self.assertFloatSeqEqual(self.store.BoundingBox(),
864     [-24.546524047851562, 63.286754608154297,
865     -13.495815277099609, 66.563774108886719])
866    
867     def test_shape_shapeid(self):
868     """Test PostGISShapeStore.Shape(i).ShapeID() with POLYGON shapes"""
869     self.assertEquals(self.store.Shape(5).ShapeID(), 5)
870    
871     def test_shape_points(self):
872     """Test PostGISShapeStore.Shape(i).Points() with POLYGON shapes"""
873     self.assertPointListEquals(self.store.Shape(4).Points(),
874     [[(-22.40639114379882, 64.714111328125),
875     (-22.41621208190918, 64.716003417968),
876     (-22.40605163574218, 64.719200134277),
877     (-22.40639114379882, 64.714111328125)]])
878    
879 bh 1656 def test_shapes_in_region(self):
880     """Test PostGISShapeStore.ShapesInRegion() with POLYGON shapes"""
881     shapes = self.store.ShapesInRegion((-23.0, 65.5, -22.8, 65.25))
882     self.assertEquals([s.ShapeID() for s in shapes],
883     [47, 56, 59, 61, 62, 71, 144])
884    
885    
886     class TestPostGISShapestorePolygon(PolygonTests, PostGISStaticTests):
887    
888     """Tests for PostGISShapeStore objects with POLYGON data"""
889    
890     def setUp(self):
891     """Extend inherited method to set self.table to a PostGISShapeStore"""
892     PostGISStaticTests.setUp(self)
893     self.store = PostGISShapeStore(self.db, "political")
894    
895     def test_shape_type(self):
896     """Test PostGISShapeStore.ShapeType() with POLYGON shapes"""
897     self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)
898    
899    
900 bh 1605 def test_shape_raw_data(self):
901     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
902     self.assertEquals(self.store.Shape(4).RawData(),
903     "POLYGON((-22.4063911437988 64.714111328125,"
904     "-22.4162120819092 64.7160034179688,"
905     "-22.4060516357422 64.7192001342773,"
906     "-22.4063911437988 64.714111328125))")
907    
908    
909 bh 1656 class TestPostGISShapestoreMultiPolygon(PolygonTests, PostGISStaticTests):
910 bh 1605
911 bh 1656 """Tests for PostGISShapeStore objects with MUTLIPOLYGON data"""
912    
913     def setUp(self):
914     """Extend inherited method to set self.table to a PostGISShapeStore"""
915     PostGISStaticTests.setUp(self)
916     self.store = PostGISShapeStore(self.db, "political_multi")
917    
918     def test_shape_raw_data(self):
919     """Test PostGISShapeStore.Shape(i).RawData() with POLYGON shapes"""
920     self.assertEquals(self.store.Shape(4).RawData(),
921     "MULTIPOLYGON(((-22.4063911437988 64.714111328125,"
922     "-22.4162120819092 64.7160034179688,"
923     "-22.4060516357422 64.7192001342773,"
924     "-22.4063911437988 64.714111328125)))")
925    
926 bh 1693
927    
928 bh 1605 if __name__ == "__main__":
929     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