activerecord-spatial 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +21 -0
  4. data/Guardfile +17 -0
  5. data/MIT-LICENSE +23 -0
  6. data/README.rdoc +169 -0
  7. data/Rakefile +28 -0
  8. data/activerecord-spatial.gemspec +26 -0
  9. data/lib/activerecord-spatial.rb +32 -0
  10. data/lib/activerecord-spatial/active_record.rb +14 -0
  11. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions.rb +36 -0
  12. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/postgis.rb +24 -0
  13. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid.rb +21 -0
  14. data/lib/activerecord-spatial/active_record/models/geography_column.rb +17 -0
  15. data/lib/activerecord-spatial/active_record/models/geometry_column.rb +17 -0
  16. data/lib/activerecord-spatial/active_record/models/spatial_column.rb +22 -0
  17. data/lib/activerecord-spatial/active_record/models/spatial_ref_sys.rb +20 -0
  18. data/lib/activerecord-spatial/associations.rb +292 -0
  19. data/lib/activerecord-spatial/spatial_columns.rb +345 -0
  20. data/lib/activerecord-spatial/spatial_function.rb +201 -0
  21. data/lib/activerecord-spatial/spatial_scope_constants.rb +114 -0
  22. data/lib/activerecord-spatial/spatial_scopes.rb +297 -0
  23. data/lib/activerecord-spatial/version.rb +5 -0
  24. data/lib/tasks/test.rake +45 -0
  25. data/test/accessors_geographies_tests.rb +149 -0
  26. data/test/accessors_geometries_tests.rb +151 -0
  27. data/test/adapter_tests.rb +44 -0
  28. data/test/associations_tests.rb +656 -0
  29. data/test/database.yml +17 -0
  30. data/test/fixtures/bars.yml +16 -0
  31. data/test/fixtures/blorts.yml +37 -0
  32. data/test/fixtures/foo3ds.yml +17 -0
  33. data/test/fixtures/foo_geographies.yml +16 -0
  34. data/test/fixtures/foos.yml +16 -0
  35. data/test/fixtures/zortables.yml +36 -0
  36. data/test/geography_column_tests.rb +40 -0
  37. data/test/geometry_column_tests.rb +40 -0
  38. data/test/models/bar.rb +17 -0
  39. data/test/models/blort.rb +12 -0
  40. data/test/models/foo.rb +17 -0
  41. data/test/models/foo3d.rb +17 -0
  42. data/test/models/foo_geography.rb +16 -0
  43. data/test/models/zortable.rb +17 -0
  44. data/test/spatial_scopes_geographies_tests.rb +106 -0
  45. data/test/spatial_scopes_tests.rb +444 -0
  46. data/test/test_helper.rb +272 -0
  47. metadata +138 -0
@@ -0,0 +1,444 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class SpatialScopesTests < ActiveRecordSpatialTestCase
6
+ def self.before_suite
7
+ load_models(:foo, :foo3d)
8
+ end
9
+
10
+ def ids_tester(method, args, ids = [], klass = Foo)
11
+ geoms = klass.send(method, *Array.wrap(args)).all
12
+ assert_equal(ids.sort, geoms.collect(&:id).sort)
13
+ end
14
+
15
+ def test_contains
16
+ ids_tester(:st_contains, 'POINT(3 3)', [ 3 ])
17
+ end
18
+
19
+ def test_containsproperly
20
+ ids_tester(:st_containsproperly, 'LINESTRING(-4 -4, 4 4)', [ 3 ])
21
+ end
22
+
23
+ def test_covers
24
+ ids_tester(:st_covers, 'LINESTRING(-4 -4, 4 4)', [ 3 ])
25
+ end
26
+
27
+ def test_coveredby
28
+ ids_tester(:st_coveredby, 'POLYGON((-6 -6, -6 6, 6 6, 6 -6, -6 -6))', [ 1, 3 ])
29
+ end
30
+
31
+ def test_crosses
32
+ ids_tester(:st_crosses, 'LINESTRING(-6 -6, 4 4)', [ 3 ])
33
+ end
34
+
35
+ def test_disjoint
36
+ ids_tester(:st_disjoint, 'POINT(100 100)', [ 1, 2, 3 ])
37
+ end
38
+
39
+ def test_equal
40
+ ids_tester(:st_equals, 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5))', [ 3 ])
41
+ end
42
+
43
+ def test_intersects
44
+ ids_tester(:st_intersects, 'LINESTRING(-5 -5, 10 10)', [ 1, 2, 3 ])
45
+ end
46
+
47
+ def test_orderingequals
48
+ ids_tester(:st_orderingequals, 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5))', [ 3 ])
49
+ end
50
+
51
+ def test_overlaps
52
+ ids_tester(:st_overlaps, 'POLYGON((-6 -6, -5 0, 0 0, 0 -5, -6 -6))', [ 3 ])
53
+ end
54
+
55
+ def test_touches
56
+ ids_tester(:st_touches, 'POLYGON((-5 -5, -5 -10, -10 -10, -10 -5, -5 -5))', [ 3 ])
57
+ end
58
+
59
+ def test_within
60
+ ids_tester(:st_within, 'POLYGON((-5 -5, 5 10, 20 20, 10 5, -5 -5))', [ 1, 2 ])
61
+ end
62
+
63
+ def test_dwithin
64
+ ids_tester(:st_dwithin, [ 'POINT(5 5)', 10 ], [ 1, 2, 3 ])
65
+ end
66
+
67
+ def test_dfullywithin
68
+ ids_tester(:st_dfullywithin, [ 'POINT(5 5)', 10 ], [ 1, 2 ])
69
+ end
70
+
71
+ def test_geometry_type
72
+ ids_tester(:st_geometry_type, 'ST_Point', [ 1, 2 ])
73
+ ids_tester(:st_geometry_type, [ 'ST_Point', 'ST_Polygon' ], [ 1, 2, 3 ])
74
+ ids_tester(:st_geometry_type, [ 'ST_MultiLineString' ], [])
75
+ end
76
+
77
+ def test_allow_null
78
+ begin
79
+ foo = Foo.create(:name => 'four')
80
+ ids_tester(:st_contains, [ 'POINT(3 3)', { :allow_null => true } ], [ 3, foo.id ])
81
+ ensure
82
+ Foo.find_by_name('four').destroy
83
+ end
84
+ end
85
+
86
+ def test_nil_relationship
87
+ assert_equal([ 1, 2, 3 ], Foo.st_within(nil).all.collect(&:id).sort)
88
+ end
89
+
90
+ def test_with_column
91
+ assert_equal([1, 2, 3], Foo.st_disjoint('POINT(100 100)', :column => :the_other_geom).all.collect(&:id).sort)
92
+ end
93
+
94
+ def test_with_srid_switching
95
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=4326; POINT(100 100)').all.collect(&:id).sort)
96
+ end
97
+
98
+ def test_with_srid_default
99
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=default; POINT(100 100)').all.collect(&:id).sort)
100
+ assert_equal([3], Foo.st_contains('SRID=default; POINT(-3 -3)').all.collect(&:id).sort)
101
+ end
102
+
103
+ def test_with_srid_transform
104
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=4269; POINT(100 100)', :column => :the_other_geom).all.collect(&:id).sort)
105
+ assert_equal([3], Foo.st_contains('SRID=4269; POINT(7 7)', :column => :the_other_geom).all.collect(&:id).sort)
106
+ end
107
+
108
+ def test_order_by_st_distance
109
+ assert_equal([3, 1, 2], Foo.order_by_st_distance('POINT(1 1)').all.collect(&:id))
110
+ end
111
+
112
+ def test_order_by_st_distance_desc
113
+ assert_equal([2, 1, 3], Foo.order_by_st_distance('POINT(1 1)', :desc => true).all.collect(&:id))
114
+ end
115
+
116
+ def test_order_by_st_distance_sphere
117
+ assert_equal([3, 1, 2], Foo.order_by_st_distance_sphere('POINT(1 1)').all.collect(&:id))
118
+ end
119
+
120
+ def test_order_by_st_distance_sphere_desc
121
+ assert_equal([2, 1, 3], Foo.order_by_st_distance_sphere('POINT(1 1)', :desc => true).all.collect(&:id))
122
+ end
123
+
124
+ def test_order_by_st_max_distance
125
+ assert_equal([1, 3, 2], Foo.order_by_st_maxdistance('POINT(1 1)').all.collect(&:id))
126
+ end
127
+
128
+ def test_order_by_st_max_distance_desc
129
+ assert_equal([2, 3, 1], Foo.order_by_st_maxdistance('POINT(1 1)', :desc => true).all.collect(&:id))
130
+ end
131
+
132
+ def test_order_by_st_area
133
+ assert_equal([1, 2, 3], Foo.order_by_st_area.order('id').all.collect(&:id))
134
+ end
135
+
136
+ def test_order_by_st_area_desc
137
+ assert_equal([3, 1, 2], Foo.order_by_st_area(:desc => true).order('id').all.collect(&:id))
138
+ end
139
+
140
+ def test_order_by_st_ndims
141
+ assert_equal([1, 2, 3], Foo.order_by_st_ndims.order('id').all.collect(&:id))
142
+ end
143
+
144
+ def test_order_by_st_ndims_desc
145
+ assert_equal([1, 2, 3], Foo.order_by_st_ndims(:desc => true).order('id').all.collect(&:id))
146
+ end
147
+
148
+ def test_order_by_st_npoints
149
+ assert_equal([1, 2, 3], Foo.order_by_st_npoints.order('id').all.collect(&:id))
150
+ end
151
+
152
+ def test_order_by_st_npoints_desc
153
+ assert_equal([3, 1, 2], Foo.order_by_st_npoints(:desc => true).order('id').all.collect(&:id))
154
+ end
155
+
156
+ def test_order_by_st_nrings
157
+ assert_equal([1, 2, 3], Foo.order_by_st_nrings.order('id').all.collect(&:id))
158
+ end
159
+
160
+ def test_order_by_st_nrings_desc
161
+ assert_equal([3, 1, 2], Foo.order_by_st_nrings(:desc => true).order('id').all.collect(&:id))
162
+ end
163
+
164
+ def test_order_by_st_numgeometries
165
+ assert_equal([1, 2, 3], Foo.order_by_st_numgeometries.order('id').all.collect(&:id))
166
+ end
167
+
168
+ def test_order_by_st_numgeometries_desc
169
+ assert_equal([1, 2, 3], Foo.order_by_st_numgeometries(:desc => true).order('id').all.collect(&:id))
170
+ end
171
+
172
+ def test_order_by_st_numinteriorring
173
+ assert_equal([3, 1, 2], Foo.order_by_st_numinteriorring.order('id').all.collect(&:id))
174
+ end
175
+
176
+ def test_order_by_st_numinteriorring_desc
177
+ assert_equal([1, 2, 3], Foo.order_by_st_numinteriorring(:desc => true).order('id').all.collect(&:id))
178
+ end
179
+
180
+ def test_order_by_st_numinteriorrings
181
+ assert_equal([3, 1, 2], Foo.order_by_st_numinteriorrings.order('id').all.collect(&:id))
182
+ end
183
+
184
+ def test_order_by_st_numinteriorrings_desc
185
+ assert_equal([1, 2, 3], Foo.order_by_st_numinteriorrings(:desc => true).order('id').all.collect(&:id))
186
+ end
187
+
188
+ def test_order_by_st_numpoints
189
+ assert_equal([1, 2, 3], Foo.order_by_st_numpoints.order('id').all.collect(&:id))
190
+ end
191
+
192
+ def test_order_by_st_numpoints_desc
193
+ assert_equal([1, 2, 3], Foo.order_by_st_numpoints(:desc => true).order('id').all.collect(&:id))
194
+ end
195
+
196
+ def test_order_by_st_length3d
197
+ assert_equal([1, 2, 3], Foo.order_by_st_length3d.order('id').all.collect(&:id))
198
+ end
199
+
200
+ def test_order_by_st_length3d_desc
201
+ assert_equal([1, 2, 3], Foo.order_by_st_length3d(:desc => true).order('id').all.collect(&:id))
202
+ end
203
+
204
+ def test_order_by_st_length
205
+ assert_equal([1, 2, 3], Foo.order_by_st_length.order('id').all.collect(&:id))
206
+ end
207
+
208
+ def test_order_by_st_length_desc
209
+ assert_equal([1, 2, 3], Foo.order_by_st_length(:desc => true).order('id').all.collect(&:id))
210
+ end
211
+
212
+ def test_order_by_st_length2d
213
+ assert_equal([1, 2, 3], Foo.order_by_st_length2d.order('id').all.collect(&:id))
214
+ end
215
+
216
+ def test_order_by_st_length2d_desc
217
+ assert_equal([1, 2, 3], Foo.order_by_st_length2d(:desc => true).order('id').all.collect(&:id))
218
+ end
219
+
220
+ def test_order_by_st_length3d_spheroid
221
+ assert_equal([1, 2, 3], Foo.order_by_st_length3d_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]').order('id').all.collect(&:id))
222
+ end
223
+
224
+ def test_order_by_st_length3d_spheroid_desc
225
+ expected = if ActiveRecordSpatial::POSTGIS[:lib] >= '2.0'
226
+ [3, 1, 2]
227
+ else
228
+ [1, 2, 3]
229
+ end
230
+
231
+ assert_equal(expected, Foo.order_by_st_length3d_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]', :desc => true).order('id').all.collect(&:id))
232
+ end
233
+
234
+ def test_order_by_st_length2d_spheroid
235
+ assert_equal([1, 2, 3], Foo.order_by_st_length2d_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]').order('id').all.collect(&:id))
236
+ end
237
+
238
+ def test_order_by_st_length2d_spheroid_desc
239
+ assert_equal([3, 1, 2], Foo.order_by_st_length2d_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]', :desc => true).order('id').all.collect(&:id))
240
+ end
241
+
242
+ def test_order_by_st_length_spheroid
243
+ assert_equal([1, 2, 3], Foo.order_by_st_length_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]').order('id').all.collect(&:id))
244
+ end
245
+
246
+ def test_order_by_st_length_spheroid_desc
247
+ expected = if ActiveRecordSpatial::POSTGIS[:lib] >= '2.0'
248
+ [3, 1, 2]
249
+ else
250
+ [1, 2, 3]
251
+ end
252
+
253
+ assert_equal(expected, Foo.order_by_st_length_spheroid('SPHEROID["WGS 84", 6378137, 298.257223563]', :desc => true).order('id').all.collect(&:id))
254
+ end
255
+
256
+ def test_order_by_st_perimeter
257
+ assert_equal([1, 2, 3], Foo.order_by_st_perimeter.order('id').all.collect(&:id))
258
+ end
259
+
260
+ def test_order_by_st_perimeter_desc
261
+ assert_equal([3, 1, 2], Foo.order_by_st_perimeter(:desc => true).order('id').all.collect(&:id))
262
+ end
263
+
264
+ def test_order_by_st_perimeter2d
265
+ assert_equal([1, 2, 3], Foo.order_by_st_perimeter2d.order('id').all.collect(&:id))
266
+ end
267
+
268
+ def test_order_by_st_perimeter2d_desc
269
+ assert_equal([3, 1, 2], Foo.order_by_st_perimeter2d(:desc => true).order('id').all.collect(&:id))
270
+ end
271
+
272
+ def test_order_by_st_perimeter3d
273
+ assert_equal([1, 2, 3], Foo.order_by_st_perimeter3d.order('id').all.collect(&:id))
274
+ end
275
+
276
+ def test_order_by_st_perimeter3d_desc
277
+ assert_equal([3, 1, 2], Foo.order_by_st_perimeter3d(:desc => true).order('id').all.collect(&:id))
278
+ end
279
+
280
+ def test_order_by_st_hausdorffdistance
281
+ assert_equal([1, 3, 2], Foo.order_by_st_hausdorffdistance('POINT(1 1)').all.collect(&:id))
282
+ end
283
+
284
+ def test_order_by_st_hausdorffdistance_desc
285
+ assert_equal([2, 3, 1], Foo.order_by_st_hausdorffdistance('POINT(1 1)', :desc => true).all.collect(&:id))
286
+ end
287
+
288
+ def test_order_by_st_hausdorffdistance_with_densify_frac
289
+ assert_equal([1, 3, 2], Foo.order_by_st_hausdorffdistance('POINT(1 1)', 0.314).all.collect(&:id))
290
+ end
291
+
292
+ def test_order_by_st_distance_spheroid
293
+ assert_equal([2, 3, 1], Foo.order_by_st_distance_spheroid('POINT(10 10)', 'SPHEROID["WGS 84", 6378137, 298.257223563]').order('id').all.collect(&:id))
294
+ end
295
+
296
+ def test_order_by_st_distance_spheroid_desc
297
+ assert_equal([1, 3, 2], Foo.order_by_st_distance_spheroid('POINT(10 10)', 'SPHEROID["WGS 84", 6378137, 298.257223563]', :desc => true).order('id').all.collect(&:id))
298
+ end
299
+
300
+ def test_order_by_st_area_with_desc_symbol
301
+ assert_equal([3, 1, 2], Foo.order_by_st_area(:desc).order('id').all.collect(&:id))
302
+ end
303
+
304
+ def test_3dintersects
305
+ skip('ST_3dintersects is unavailable') unless Foo3d.respond_to?(:st_3dintersects)
306
+
307
+ ids_tester(:st_3dintersects, 'LINESTRING(-5 -5 -5, 10 10 10)', [ 1, 3 ], Foo3d)
308
+ end
309
+
310
+ def test_3ddistance
311
+ skip('ST_3ddistance is unavailable') unless Foo3d.respond_to?(:order_by_st_3ddistance)
312
+
313
+ assert_equal([3, 2, 1], Foo3d.order_by_st_3ddistance('POINT(10 10)').order('id').all.collect(&:id))
314
+ end
315
+
316
+ def test_3dmaxdistance
317
+ skip('ST_3dmaxdistance is unavailable') unless Foo3d.respond_to?(:order_by_st_3dmaxdistance)
318
+
319
+ assert_equal([2, 1, 3], Foo3d.order_by_st_3dmaxdistance('POINT(10 10)').order('id').all.collect(&:id))
320
+ end
321
+
322
+ def test_3ddwithin
323
+ skip('ST_3ddwithin is unavailable') unless Foo3d.respond_to?(:st_3ddwithin)
324
+
325
+ ids_tester(:st_3ddwithin, [ 'LINESTRING(-5 -5 -5, 10 10 10)', 10 ], [ 1, 2, 3 ], Foo3d)
326
+ end
327
+
328
+ def test_3ddfullywithin
329
+ skip('ST_3ddfullywithin is unavilable') unless Foo3d.respond_to?(:st_3ddfullywithin)
330
+
331
+ ids_tester(:st_3ddfullywithin, [ 'LINESTRING(-10 -10 -10, 10 10 10)', 100 ], [ 1, 2, 3 ], Foo3d)
332
+ end
333
+
334
+ def test_order_by_with_column_wrapper
335
+ values = nil
336
+
337
+ assert_sql(/ST_envelope\("foos"."the_geom"\)/) do
338
+ values = Foo.
339
+ order_by_st_perimeter(
340
+ :desc => true,
341
+ :column => {
342
+ :wrapper => :envelope
343
+ }
344
+ ).order('id').all.collect(&:id)
345
+ end
346
+
347
+ assert_equal([3, 1, 2], values)
348
+ end
349
+
350
+ def test_order_by_with_column_wrapper_and_an_option
351
+ values = nil
352
+
353
+ assert_sql(/ST_geometryn\("foos"."the_geom", 1\)/) do
354
+ values = Foo.
355
+ order_by_st_perimeter(
356
+ :desc => true,
357
+ :column => {
358
+ :wrapper => {
359
+ :geometryn => 1
360
+ }
361
+ }
362
+ ).order('id').all.collect(&:id)
363
+ end
364
+
365
+ assert_equal([3, 1, 2], values)
366
+ end
367
+
368
+ def test_order_by_with_column_wrapper_and_options
369
+ values = nil
370
+
371
+ assert_sql(/ST_snap\("foos"."the_geom", 'POINT \(0 0\)', 1.0\)/) do
372
+ values = Foo.
373
+ order_by_st_perimeter(
374
+ :desc => true,
375
+ :column => {
376
+ :wrapper => {
377
+ :snap => [
378
+ 'POINT (0 0)',
379
+ 1.0
380
+ ]
381
+ }
382
+ }
383
+ ).order('id').all.collect(&:id)
384
+ end
385
+
386
+ assert_equal([3, 1, 2], values)
387
+ end
388
+
389
+ def test_relationship_with_column_wrapper
390
+ values = nil
391
+
392
+ assert_sql(/ST_centroid\("foos"."the_geom"\)/) do
393
+ values = Foo.
394
+ st_within(
395
+ 'POLYGON((-5 -5, 5 10, 20 20, 10 5, -5 -5))',
396
+ :column => {
397
+ :wrapper => :centroid
398
+ }
399
+ ).order('id').all.collect(&:id)
400
+ end
401
+
402
+ assert_equal([1, 2, 3], values)
403
+ end
404
+
405
+ def test_relationship_with_column_wrapper_and_option
406
+ values = nil
407
+
408
+ assert_sql(/ST_geometryn\("foos"."the_geom", 1\)/) do
409
+ values = Foo.
410
+ st_within(
411
+ 'POLYGON((-5 -5, 5 10, 20 20, 10 5, -5 -5))',
412
+ :column => {
413
+ :wrapper => {
414
+ :geometryn => 1
415
+ }
416
+ }
417
+ ).order('id').all.collect(&:id)
418
+ end
419
+
420
+ assert_equal([1, 2], values)
421
+ end
422
+
423
+ def test_relationship_with_column_wrapper_and_options
424
+ values = nil
425
+
426
+ assert_sql(/ST_snap\("foos"."the_geom", 'POINT \(0 0\)', 1.0\)/) do
427
+ values = Foo.
428
+ st_within(
429
+ 'POLYGON((-5 -5, 5 10, 20 20, 10 5, -5 -5))',
430
+ :column => {
431
+ :wrapper => {
432
+ :snap => [
433
+ 'POINT (0 0)',
434
+ 1.0
435
+ ]
436
+ }
437
+ }
438
+ ).order('id').all.collect(&:id)
439
+ end
440
+
441
+ assert_equal([1, 2], values)
442
+ end
443
+ end
444
+
@@ -0,0 +1,272 @@
1
+
2
+ require 'simplecov'
3
+
4
+ SimpleCov.command_name('Unit Tests')
5
+ SimpleCov.start do
6
+ add_filter '/test/'
7
+ end
8
+
9
+ require 'rubygems'
10
+ require 'minitest/autorun'
11
+ require 'minitest/reporters'
12
+ require 'active_support'
13
+ require 'active_support/core_ext/module/aliasing'
14
+ require 'active_support/dependencies'
15
+ require 'active_record'
16
+ require 'active_record/fixtures'
17
+ require 'logger'
18
+
19
+ require File.join(File.dirname(__FILE__), %w{ .. lib activerecord-spatial })
20
+
21
+ POSTGIS_PATHS = [
22
+ ENV['POSTGIS_PATH'],
23
+ '/opt/local/share/postgresql*/contrib/postgis-*',
24
+ '/usr/share/postgresql*/contrib/postgis-*',
25
+ '/usr/pgsql-*/share/contrib/postgis-*',
26
+ ].compact
27
+
28
+ puts "Testing against ActiveRecord #{Gem.loaded_specs['activerecord'].version.to_s}"
29
+ puts "Ruby version #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} - #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}"
30
+ puts "Geos library version #{Geos::VERSION}" if defined?(Geos::VERSION)
31
+ puts "GEOS version #{Geos::GEOS_VERSION}"
32
+ puts "GEOS extensions version #{Geos::GEOS_EXTENSIONS_VERSION}"
33
+ if defined?(Geos::FFIGeos)
34
+ puts "Using #{Geos::FFIGeos.geos_library_paths.join(', ')}"
35
+ end
36
+
37
+ ActiveRecord::Base.logger = Logger.new("debug.log") if ENV['ENABLE_LOGGER']
38
+ ActiveRecord::Base.configurations = {
39
+ 'arunit' => {}
40
+ }
41
+
42
+ %w{
43
+ database.yml
44
+ local_database.yml
45
+ }.each do |file|
46
+ file = File.join('test', file)
47
+
48
+ next unless File.exists?(file)
49
+
50
+ configuration = YAML.load(File.read(file))
51
+
52
+ if configuration['arunit']
53
+ ActiveRecord::Base.configurations['arunit'].merge!(configuration['arunit'])
54
+ end
55
+
56
+ if defined?(JRUBY_VERSION) && configuration['jdbc']
57
+ ActiveRecord::Base.configurations['arunit'].merge!(configuration['jdbc'])
58
+ end
59
+ end
60
+
61
+ ActiveRecord::Base.establish_connection 'arunit'
62
+ ARBC = ActiveRecord::Base.connection
63
+
64
+ if postgresql_version = ARBC.select_rows('SELECT version()').first.first
65
+ puts "PostgreSQL info from version(): #{postgresql_version}"
66
+ end
67
+
68
+ puts "Checking for PostGIS install"
69
+ 2.times do
70
+ begin
71
+ if postgis_version = ActiveRecordSpatial::POSTGIS[:lib]
72
+ puts "PostGIS info from postgis_full_version(): #{postgis_version}"
73
+ break
74
+ end
75
+ rescue ActiveRecord::StatementInvalid
76
+ puts "Trying to install PostGIS. If this doesn't work, you'll have to do this manually!"
77
+
78
+ plpgsql = ARBC.select_rows(%{SELECT count(*) FROM pg_language WHERE lanname = 'plpgsql'}).first.first.to_i
79
+ if plpgsql == 0
80
+ ARBC.execute(%{CREATE LANGUAGE plpgsql})
81
+ end
82
+
83
+ %w{
84
+ postgis.sql
85
+ spatial_ref_sys.sql
86
+ }.each do |file|
87
+ if !(found = Dir.glob(POSTGIS_PATHS).collect { |path|
88
+ File.join(path, file)
89
+ }.first)
90
+ puts "ERROR: Couldn't find #{file}. Try setting the POSTGIS_PATH to give us a hint!"
91
+ exit
92
+ else
93
+ ARBC.execute(File.read(found))
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
100
+ BASE_PATH = Pathname.new(File.dirname(__FILE__))
101
+
102
+ include ActiveRecord::TestFixtures
103
+ self.fixture_path = BASE_PATH.join('fixtures')
104
+
105
+ REGEXP_WKB_HEX = /[A-Fa-f0-9\s]+/
106
+
107
+ POINT_WKT = 'POINT(10 10.01)'
108
+ POINT_EWKT = 'SRID=4326; POINT(10 10.01)'
109
+ POINT_EWKT_WITH_DEFAULT = 'SRID=default; POINT(10 10.01)'
110
+ POINT_WKB = "0101000000000000000000244085EB51B81E052440"
111
+ POINT_WKB_BIN = "\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
112
+ POINT_EWKB = "0101000020E6100000000000000000244085EB51B81E052440"
113
+ POINT_EWKB_BIN = "\x01\x01\x00\x00\x20\xE6\x10\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
114
+ POINT_G_LAT_LNG = "(10.01, 10)"
115
+ POINT_G_LAT_LNG_URL_VALUE = "10.01,10"
116
+
117
+ POLYGON_WKT = 'POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
118
+ POLYGON_EWKT = 'SRID=4326; POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
119
+ POLYGON_WKB = "
120
+ 0103000000010000000500000000000000000000000000000000000000000000000000F
121
+ 03F000000000000F03F0000000000000440000000000000044000000000000014400000
122
+ 00000000144000000000000000000000000000000000
123
+ ".gsub(/\s/, '')
124
+ POLYGON_WKB_BIN = [
125
+ "\x01\x03\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00",
126
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF0\x3F\x00",
127
+ "\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00",
128
+ "\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14",
129
+ "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
130
+ ].join
131
+ POLYGON_EWKB = "
132
+ 0103000020E610000001000000050000000000000000000000000000000000000000000
133
+ 0000000F03F000000000000F03F00000000000004400000000000000440000000000000
134
+ 1440000000000000144000000000000000000000000000000000
135
+ ".gsub(/\s/, '')
136
+ POLYGON_EWKB_BIN = [
137
+ "\x01\x03\x00\x00\x20\xE6\x10\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00",
138
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
139
+ "\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\xF0\x3F\x00\x00",
140
+ "\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00",
141
+ "\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00",
142
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
143
+ ].join
144
+
145
+ POLYGON_WITH_INTERIOR_RING = "POLYGON((0 0, 5 0, 5 5, 0 5, 0 0),(4 4, 4 1, 1 1, 1 4, 4 4))"
146
+
147
+ LINESTRING_WKT = "LINESTRING (0 0, 5 5, 5 10, 10 10)"
148
+
149
+ GEOMETRYCOLLECTION_WKT = 'GEOMETRYCOLLECTION (
150
+ MULTIPOLYGON (
151
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
152
+ (
153
+ (10 10, 10 14, 14 14, 14 10, 10 10),
154
+ (11 11, 11 12, 12 12, 12 11, 11 11)
155
+ )
156
+ ),
157
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
158
+ POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0), (4 4, 4 1, 1 1, 1 4, 4 4)),
159
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
160
+ LINESTRING (0 0, 2 3),
161
+ MULTIPOINT ((0 0), (2 3)),
162
+ POINT (9 0)
163
+ )'
164
+
165
+ BOUNDS_G_LAT_LNG = "((0.1, 0.1), (5.2, 5.2))"
166
+ BOUNDS_G_LAT_LNG_URL_VALUE = '0.1,0.1,5.2,5.2'
167
+
168
+ class << self
169
+ def load_models(*args)
170
+ options = args.extract_options!
171
+
172
+ args.each do |model|
173
+ model = model.to_s
174
+ klass = model.classify
175
+
176
+ ActiveSupport::Dependencies.load_file(BASE_PATH.join("models/#{model}.rb"), [ klass ])
177
+
178
+ ActiveRecord::Base.silence do
179
+ fixtures model.pluralize
180
+ end
181
+ end
182
+ end
183
+
184
+ def load_default_models
185
+ load_models(:foo, :bar)
186
+
187
+ Foo.class_eval do
188
+ has_many_spatially :foos
189
+ has_many_spatially :bars
190
+ end
191
+
192
+ Bar.class_eval do
193
+ has_many_spatially :foos
194
+ has_many_spatially :bars
195
+ end
196
+ end
197
+
198
+ def after_suite
199
+ ActiveSupport::Dependencies.clear
200
+ end
201
+ end
202
+
203
+ def setup
204
+ if ActiveRecord::Base.logger
205
+ ActiveRecord::Base.logger.debug("Beginning tests for #{self.class.name}##{self.method_name}")
206
+ end
207
+ end
208
+
209
+ def assert_saneness_of_point(point)
210
+ assert_kind_of(Geos::Point, point)
211
+ assert_equal(10.01, point.lat)
212
+ assert_equal(10, point.lng)
213
+ end
214
+
215
+ def assert_saneness_of_polygon(polygon)
216
+ assert_kind_of(Geos::Polygon, polygon)
217
+ cs = polygon.exterior_ring.coord_seq
218
+ assert_equal([
219
+ [ 0, 0 ],
220
+ [ 1, 1 ],
221
+ [ 2.5, 2.5 ],
222
+ [ 5, 5 ],
223
+ [ 0, 0 ]
224
+ ], cs.to_a)
225
+ end
226
+ end
227
+
228
+ module ActiveRecord
229
+ class SQLCounter
230
+ cattr_accessor :ignored_sql
231
+ self.ignored_sql = [
232
+ /^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/,
233
+ /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/,
234
+ /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/, /^ROLLBACK/, /\WFROM pg_/
235
+ ]
236
+
237
+ cattr_accessor :log
238
+ self.log = []
239
+
240
+ attr_reader :ignore
241
+
242
+ def initialize(ignore = self.class.ignored_sql)
243
+ @ignore = ignore
244
+ end
245
+
246
+ def call(name, start, finish, message_id, values)
247
+ sql = values[:sql]
248
+
249
+ # FIXME: this seems bad. we should probably have a better way to indicate
250
+ # the query was cached
251
+ return if 'CACHE' == values[:name] || ignore.any? { |x| x =~ sql }
252
+ self.class.log << sql
253
+ end
254
+ end
255
+
256
+ ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
257
+ end
258
+
259
+ class SpatialTestRunner < MiniTest::Reporters::SpecReporter
260
+ def before_suite(suite)
261
+ super(suite)
262
+ suite.before_suite if suite.respond_to?(:before_suite)
263
+ end
264
+
265
+ def after_suite(suite)
266
+ super(suite)
267
+ suite.after_suite if suite.respond_to?(:after_suite)
268
+ end
269
+ end
270
+
271
+ MiniTest::Reporters.use!(SpatialTestRunner.new)
272
+