mongoid-geospatial 4.0.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/README.md +126 -242
- data/bench/bench +11 -10
- data/lib/mongoid/geospatial.rb +14 -17
- data/lib/mongoid/geospatial/fields/point.rb +42 -10
- data/lib/mongoid/geospatial/geometry_field.rb +25 -2
- data/lib/mongoid/geospatial/helpers/delegate.rb +6 -2
- data/lib/mongoid/geospatial/version.rb +1 -1
- data/lib/mongoid/geospatial/wrappers/georuby.rb +4 -0
- data/lib/mongoid/geospatial/wrappers/rgeo.rb +4 -1
- data/mongoid-geospatial.gemspec +2 -2
- data/spec/models/bar.rb +1 -1
- data/spec/models/farm.rb +1 -1
- data/spec/models/person.rb +2 -1
- data/spec/models/river.rb +7 -7
- data/spec/mongoid/geospatial/fields/line_string_spec.rb +44 -8
- data/spec/mongoid/geospatial/fields/point_spec.rb +30 -28
- data/spec/mongoid/geospatial/fields/polygon_spec.rb +25 -18
- data/spec/mongoid/geospatial/geospatial_spec.rb +65 -49
- data/spec/mongoid/geospatial/helpers/core_spec.rb +8 -3
- data/spec/mongoid/geospatial/helpers/delegate_spec.rb +18 -1
- data/spec/mongoid/geospatial/helpers/spatial_spec.rb +9 -1
- data/spec/mongoid/geospatial/helpers/sphere_spec.rb +10 -1
- data/spec/mongoid/geospatial/wrappers/rgeo_spec.rb +4 -2
- data/spec/spec_helper.rb +7 -3
- metadata +5 -5
@@ -15,29 +15,65 @@ describe Mongoid::Geospatial::LineString do
|
|
15
15
|
expect(River.first.course).to eq(river.course)
|
16
16
|
end
|
17
17
|
|
18
|
+
it 'should line_string += point nicely' do
|
19
|
+
river = River.create!(name: 'Amazonas', course: [[1, 1], [9, 9]])
|
20
|
+
river.course += [[10, 10]]
|
21
|
+
river.save
|
22
|
+
expect(River.first.course).to eq([[1, 1], [9, 9], [10, 10]])
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should parent.line_string << point nicely' do
|
26
|
+
pending 'Mongoid Issue #...'
|
27
|
+
river = River.create!(name: 'Amazonas', course: [[1, 1], [9, 9]])
|
28
|
+
river.course.push [10, 10]
|
29
|
+
river.save
|
30
|
+
expect(River.first.course).to eq([[1, 1], [9, 9], [10, 10]])
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should have same obj id' do
|
34
|
+
pending 'Mongoid Issue #...'
|
35
|
+
river = River.create!(name: 'Amazonas', course: [[1, 1], [9, 9]])
|
36
|
+
expect(river.course.object_id).to eq(river.course.object_id)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should have same obj id ary' do
|
40
|
+
river = River.create!(name: 'Amazonas', mouth_array: [[1, 1], [9, 9]])
|
41
|
+
expect(river.mouth_array.object_id).to eq(river.mouth_array.object_id)
|
42
|
+
end
|
43
|
+
|
18
44
|
it 'should support a field mapped as linestring' do
|
19
45
|
River.create!(course: [[5, 5], [6, 5], [6, 6], [5, 6]])
|
20
46
|
expect(River.first.course).to eq([[5, 5], [6, 5], [6, 6], [5, 6]])
|
21
47
|
end
|
22
48
|
|
23
49
|
it 'should have a bounding box' do
|
24
|
-
|
25
|
-
expect(
|
50
|
+
l = Mongoid::Geospatial::LineString.new [[1, 5], [6, 5], [6, 6], [5, 6]]
|
51
|
+
expect(l.bbox).to eq([[1, 5], [6, 6]])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have a geom box' do
|
55
|
+
l = Mongoid::Geospatial::LineString.new [[1, 1], [5, 5]]
|
56
|
+
expect(l.geom_box).to eq([[1, 1], [1, 5], [5, 5], [5, 1], [1, 1]])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should have a geom box' do
|
60
|
+
l = Mongoid::Geospatial::LineString.new [[1, 1], [2, 2], [3, 4], [5, 5]]
|
61
|
+
expect(l.geom_box).to eq([[1, 1], [1, 5], [5, 5], [5, 1], [1, 1]])
|
26
62
|
end
|
27
63
|
|
28
64
|
it 'should have a center point' do
|
29
|
-
|
30
|
-
expect(
|
65
|
+
l = Mongoid::Geospatial::LineString.new [[1, 1], [1, 1], [9, 9], [9, 9]]
|
66
|
+
expect(l.center).to eq([5.0, 5.0])
|
31
67
|
end
|
32
68
|
|
33
69
|
it 'should have a radius helper' do
|
34
|
-
|
35
|
-
expect(
|
70
|
+
l = Mongoid::Geospatial::LineString.new [[1, 1], [1, 1], [9, 9], [9, 9]]
|
71
|
+
expect(l.radius(10)).to eq([[5.0, 5.0], 10])
|
36
72
|
end
|
37
73
|
|
38
74
|
it 'should have a radius sphere' do
|
39
|
-
|
40
|
-
expect(
|
75
|
+
l = Mongoid::Geospatial::LineString.new [[1, 1], [1, 1], [9, 9], [9, 9]]
|
76
|
+
expect(l.radius_sphere(10)[1]).to be_within(0.001).of(0.001569)
|
41
77
|
end
|
42
78
|
end
|
43
79
|
end
|
@@ -13,9 +13,10 @@ describe Mongoid::Geospatial::Point do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should set point methodically' do
|
16
|
-
bar.location = Mongoid::Geospatial::Point.new(8,
|
16
|
+
bar.location = Mongoid::Geospatial::Point.new(8, 9)
|
17
17
|
expect(bar.save).to be_truthy
|
18
18
|
expect(Bar.first.location.x).to eq(8)
|
19
|
+
expect(Bar.first.location.y).to eq(9)
|
19
20
|
end
|
20
21
|
|
21
22
|
it 'should set point with comma separated text' do
|
@@ -34,6 +35,11 @@ describe Mongoid::Geospatial::Point do
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
38
|
+
it 'should have #reverse to get lat, lon' do
|
39
|
+
bar = Bar.create!(name: "Moe's", location: [1, 2])
|
40
|
+
expect(bar.location.reverse).to eq([2, 1])
|
41
|
+
end
|
42
|
+
|
37
43
|
it 'should set point to nil' do
|
38
44
|
bar = Bar.create!(name: "Moe's", location: [1, 1])
|
39
45
|
bar.location = nil
|
@@ -42,6 +48,13 @@ describe Mongoid::Geospatial::Point do
|
|
42
48
|
expect(Bar.where(location: nil).first).to eq(bar)
|
43
49
|
end
|
44
50
|
|
51
|
+
it 'should update point x' do
|
52
|
+
bar = Bar.create!(name: "Moe's", location: [1, 1])
|
53
|
+
bar.location = [2, 3]
|
54
|
+
expect(bar.save).to be_truthy
|
55
|
+
expect(Bar.first.location.to_a).to eq([2, 3])
|
56
|
+
end
|
57
|
+
|
45
58
|
it 'should set point empty string to nil' do
|
46
59
|
bar = Bar.create!(name: "Moe's", location: [1, 1])
|
47
60
|
bar.location = ''
|
@@ -78,15 +91,18 @@ describe Mongoid::Geospatial::Point do
|
|
78
91
|
end
|
79
92
|
|
80
93
|
it 'should have a radius sphere helper' do
|
81
|
-
expect(bar.location.radius_sphere[1])
|
94
|
+
expect(bar.location.radius_sphere[1])
|
95
|
+
.to be_within(0.0001).of(0.00015)
|
82
96
|
end
|
83
97
|
|
84
98
|
it 'should have a radius sphere helper in meters' do
|
85
|
-
expect(bar.location.radius_sphere(1000, :m)[1])
|
99
|
+
expect(bar.location.radius_sphere(1000, :m)[1])
|
100
|
+
.to be_within(0.0001).of(0.00015)
|
86
101
|
end
|
87
102
|
|
88
103
|
it 'should have a radius sphere helper in miles' do
|
89
|
-
expect(bar.location.radius_sphere(1, :mi)[1])
|
104
|
+
expect(bar.location.radius_sphere(1, :mi)[1])
|
105
|
+
.to be_within(0.0001).of(0.00025)
|
90
106
|
end
|
91
107
|
end
|
92
108
|
|
@@ -162,43 +178,29 @@ describe Mongoid::Geospatial::Point do
|
|
162
178
|
end
|
163
179
|
|
164
180
|
it 'returns the documents within a circle' do
|
165
|
-
pending '
|
166
|
-
|
167
|
-
|
168
|
-
Mongoid::Geospatial::EARTH_RADIUS_KM]).to_a)
|
169
|
-
.to eq([mile1])
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'returns the documents within a circle' do
|
173
|
-
pending 'Moped'
|
174
|
-
expect(Bar.where(:location.within_circle => [elvis.location,
|
175
|
-
500.0 / Mongoid::Geospatial::EARTH_RADIUS_KM])
|
176
|
-
.to_a).to include(mile3)
|
181
|
+
pending 'Circle'
|
182
|
+
l = [elvis.location, 500.0 / Mongoid::Geospatial::EARTH_RADIUS_KM]
|
183
|
+
expect(Bar.where(:location.within_circle => l).to_a).to include(mile3)
|
177
184
|
end
|
178
185
|
|
179
186
|
it 'returns the documents within a spherical circle' do
|
180
|
-
pending '
|
187
|
+
pending 'Circle'
|
181
188
|
expect(Bar.where(:location.within_spherical_circle =>
|
182
189
|
[elvis.location, 0.0005]).to_a).to eq([mile1])
|
183
190
|
end
|
184
191
|
|
185
|
-
it 'returns the documents within a spherical circle 2' do
|
186
|
-
pending 'Moped'
|
187
|
-
expect(Bar.where(:location.within_spherical_circle =>
|
188
|
-
[elvis.location, 0.5]).to_a).to include(mile9)
|
189
|
-
end
|
190
|
-
|
191
192
|
it 'returns the documents within a center circle' do
|
192
|
-
pending '
|
193
|
+
pending 'Circle'
|
193
194
|
expect(Bar.where(:location.within_center_circle =>
|
194
195
|
[elvis.location, 0.0005]).to_a).to eq([mile1])
|
195
196
|
end
|
196
197
|
|
197
198
|
it 'returns the documents within a box' do
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
199
|
+
poly = Mongoid::Geospatial::LineString.new(
|
200
|
+
[elvis.location.map { |c| c + 1 },
|
201
|
+
elvis.location.map { |c| c - 1 }])
|
202
|
+
expect(Bar.where(:location.within_polygon => [poly.geom_box]).to_a)
|
203
|
+
.to include(mile3)
|
202
204
|
end
|
203
205
|
end
|
204
206
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mongoid::Geospatial::Polygon do
|
4
|
+
it 'should have correct indexes on farm' do
|
5
|
+
Farm.create_indexes
|
6
|
+
expect(Farm.collection.indexes.get(geom: '2dsphere')).not_to be_nil
|
7
|
+
end
|
8
|
+
|
4
9
|
describe '(de)mongoize' do
|
5
10
|
it 'should support a field mapped as polygon' do
|
6
11
|
farm = Farm.new(area: [[5, 5], [6, 5], [6, 6], [5, 6]])
|
@@ -45,36 +50,38 @@ describe Mongoid::Geospatial::Polygon do
|
|
45
50
|
end
|
46
51
|
|
47
52
|
let!(:ranch) do
|
48
|
-
Farm.create(name: 'Ranch',
|
53
|
+
Farm.create!(name: 'Ranch',
|
54
|
+
area: [[1, 1], [3, 3], [3, 1], [1, 1]],
|
55
|
+
geom: [2, 2])
|
49
56
|
end
|
50
57
|
|
51
58
|
let!(:farm) do
|
52
|
-
Farm.create(name: 'Farm',
|
59
|
+
Farm.create!(name: 'Farm',
|
60
|
+
area: [[47, 1], [48, 1.5], [49, 3], [49, 1], [47, 1]],
|
61
|
+
geom: [48, 1.28])
|
53
62
|
end
|
54
63
|
|
55
64
|
it 'returns the documents within a box' do
|
56
|
-
|
57
|
-
expect(
|
58
|
-
ranch.area).to_a).to eq([ranch])
|
65
|
+
query = Farm.geo_spacial(:geom.within_polygon => [ranch.area])
|
66
|
+
expect(query.to_a).to eq([ranch])
|
59
67
|
end
|
60
68
|
|
61
69
|
it 'returns the documents within a polygon' do
|
62
|
-
|
63
|
-
expect(
|
64
|
-
farm.area).to_a).to eq([farm])
|
70
|
+
query = Farm.where(:geom.within_polygon => [farm.area])
|
71
|
+
expect(query.to_a).to eq([farm])
|
65
72
|
end
|
66
73
|
|
67
|
-
it 'returns the documents within a center' do
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
74
|
+
# it 'returns the documents within a center' do
|
75
|
+
# pending 'Moped'
|
76
|
+
# expect(Farm.where(:geom.within_circle =>
|
77
|
+
# [ranch.geom, 0.4]).first).to eq(ranch)
|
78
|
+
# end
|
72
79
|
|
73
|
-
it 'returns the documents within a center_sphere' do
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
80
|
+
# it 'returns the documents within a center_sphere' do
|
81
|
+
# pending 'Moped'
|
82
|
+
# expect(Farm.where(:geom.within_spherical_circle =>
|
83
|
+
# [ranch.geom, 0.1]).first).to eq(ranch)
|
84
|
+
# end
|
78
85
|
end
|
79
86
|
end
|
80
87
|
end
|
@@ -16,12 +16,12 @@ describe Mongoid::Geospatial do
|
|
16
16
|
context 'Creating indexes' do
|
17
17
|
it 'should create a 2d index' do
|
18
18
|
Bar.create_indexes
|
19
|
-
expect(Bar.collection.indexes
|
19
|
+
expect(Bar.collection.indexes.get(location: '2d')).not_to be_nil
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should create a 2dsphere index' do
|
23
23
|
Alarm.create_indexes
|
24
|
-
expect(Alarm.collection.indexes
|
24
|
+
expect(Alarm.collection.indexes.get(spot: '2dsphere')).not_to be_nil
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -56,79 +56,95 @@ describe Mongoid::Geospatial do
|
|
56
56
|
Alarm.create(name: 'lax', spot: [-118.40, 33.94])
|
57
57
|
end
|
58
58
|
|
59
|
-
it 'should work with
|
59
|
+
it 'should work with specific center and different spot attribute' do
|
60
60
|
expect(Alarm.nearby(lax.spot)).to eq([lax, jfk])
|
61
61
|
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# end
|
63
|
+
it 'should work with default origin' do
|
64
|
+
expect(Alarm.near_sphere(spot: lax.spot)).to eq([lax, jfk])
|
65
|
+
end
|
67
66
|
|
68
|
-
|
67
|
+
it 'should work with default origin key' do
|
68
|
+
expect(Alarm.where(:spot.near_sphere => lax.spot)).to eq([lax, jfk])
|
69
|
+
end
|
70
|
+
|
71
|
+
context ':paginate' do
|
72
|
+
before do
|
73
|
+
Alarm.create_indexes
|
74
|
+
50.times do
|
75
|
+
Alarm.create(spot: [rand(10) + 1, rand(10) + 1])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'limits fine with 25' do
|
80
|
+
expect(Alarm.near_sphere(spot: [5, 5])
|
81
|
+
.limit(25).to_a.size).to eq 25
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'limits fine with 25 and skips' do
|
85
|
+
expect(Alarm.near_sphere(spot: [5, 5])
|
86
|
+
.skip(25).limit(25).to_a.size).to eq 25
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'paginates 50' do
|
90
|
+
page1 = Alarm.near_sphere(spot: [5, 5]).limit(25)
|
91
|
+
page2 = Alarm.near_sphere(spot: [5, 5]).skip(25).limit(25)
|
92
|
+
expect((page1 + page2).uniq.size).to eq(50)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context ':query' do
|
97
|
+
before do
|
98
|
+
Alarm.create_indexes
|
99
|
+
3.times do
|
100
|
+
Alarm.create(spot: [jfk.spot.x + rand(0), jfk.spot.y + rand(0)])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should filter using extra query option' do
|
105
|
+
query = Alarm.near_sphere(spot: jfk.spot).where(name: jfk.name)
|
106
|
+
expect(query.to_a).to eq [jfk]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context ':maxDistance' do
|
111
|
+
it 'should get 1 item' do
|
112
|
+
spot = 2465 / Mongoid::Geospatial.earth_radius[:mi]
|
113
|
+
query = Alarm.near_sphere(spot: lax.spot).max_distance(spot: spot)
|
114
|
+
expect(query.to_a.size).to eq 1
|
115
|
+
end
|
116
|
+
end
|
69
117
|
|
70
118
|
# context ':distance_multiplier' do
|
71
119
|
# it "should multiply returned distance with multiplier" do
|
72
|
-
# Bar.geo_near(lax.location,
|
120
|
+
# Bar.geo_near(lax.location,
|
121
|
+
# ::distance_multiplier=> Mongoid::Geospatial.earth_radius[:mi])
|
122
|
+
# .second.geo[:distance].to_i.should be_within(1).of(2469)
|
73
123
|
# end
|
74
124
|
# end
|
75
125
|
|
76
126
|
# context ':unit' do
|
77
127
|
# it "should multiply returned distance with multiplier" do
|
78
|
-
# Bar.geo_near(lax.location, :spherical => true, :unit => :mi)
|
128
|
+
# Bar.geo_near(lax.location, :spherical => true, :unit => :mi)
|
129
|
+
# .second.geo[:distance].to_i.should be_within(1).of(2469)
|
79
130
|
# end
|
80
131
|
|
81
132
|
# it "should convert max_distance to radians with unit" do
|
82
|
-
# Bar.geo_near(lax.location, :spherical => true,
|
133
|
+
# Bar.geo_near(lax.location, :spherical => true,
|
134
|
+
# :max_distance => 2465, :unit => :mi).size.should == 1
|
83
135
|
# end
|
84
136
|
|
85
137
|
# end
|
86
138
|
|
87
|
-
# context ':query' do
|
88
|
-
# it "should filter using extra query option" do
|
89
|
-
# # two record in the collection, only one's name is Munich
|
90
|
-
# Bar.geo_near(jfk.location, :query => {:name => jfk.name}).should == [jfk]
|
91
|
-
# end
|
92
|
-
# end
|
93
|
-
|
94
139
|
# end
|
95
140
|
|
96
141
|
# context 'criteria chaining' do
|
97
142
|
# it "should filter by where" do
|
98
143
|
# Bar.where(:name => jfk.name).geo_near(jfk.location).should == [jfk]
|
99
|
-
# Bar.any_of({:name => jfk.name},{:name => lax.name})
|
100
|
-
#
|
101
|
-
|
102
|
-
# it 'should skip 1' do
|
103
|
-
# Bar.skip(1).geo_near(jfk.location).size.should == 1
|
104
|
-
# end
|
105
|
-
|
106
|
-
# it 'should limit 1' do
|
107
|
-
# Bar.limit(1).geo_near(jfk.location).size.should == 1
|
144
|
+
# Bar.any_of({:name => jfk.name},{:name => lax.name})
|
145
|
+
# .geo_near(jfk.location).should == [jfk,lax]
|
108
146
|
# end
|
109
147
|
# end
|
110
148
|
# end
|
111
|
-
|
112
|
-
# context ':paginate' do
|
113
|
-
# before do
|
114
|
-
# Bar.create_indexes
|
115
|
-
# 50.times do
|
116
|
-
# Bar.create({:location => [rand(360)-180,rand(360)-180]})
|
117
|
-
# end
|
118
|
-
# end
|
119
|
-
|
120
|
-
# [nil,1,2].each do |page|
|
121
|
-
# it "page=#{page} should have 25" do
|
122
|
-
# Bar.geo_near([1,1], :page => page).size.should == 25
|
123
|
-
# end
|
124
|
-
# end
|
125
|
-
|
126
|
-
# it "page=3 should have 0" do
|
127
|
-
# Bar.geo_near([1,1], :page => 20).size.should == 0
|
128
|
-
# end
|
129
|
-
|
130
|
-
# it "per_page=5" do
|
131
|
-
# Bar.geo_near([1,1], :page => 1, :per_page => 5).size.should == 5
|
132
|
-
# end
|
133
149
|
end
|
134
150
|
end
|
@@ -12,15 +12,20 @@ module Mongoid
|
|
12
12
|
def self.from_hash_y(hsh)
|
13
13
|
v = (Mongoid::Geospatial.lat_symbols & hsh.keys).first
|
14
14
|
return hsh[v].to_f if !v.nil? && hsh[v]
|
15
|
-
|
16
|
-
|
15
|
+
if Mongoid::Geospatial.lng_symbols.index(hsh.keys[1])
|
16
|
+
fail "Hash cannot contain #{Mongoid::Geospatial.lng_symbols.inspect} "\
|
17
|
+
"as second arg without #{Mongoid::Geospatial.lat_symbols.inspect}"
|
18
|
+
end
|
17
19
|
hsh.values[1].to_f
|
18
20
|
end
|
19
21
|
|
20
22
|
def self.from_hash_x(hsh)
|
21
23
|
v = (Mongoid::Geospatial.lng_symbols & hsh.keys).first
|
22
24
|
return hsh[v].to_f if !v.nil? && hsh[v]
|
23
|
-
|
25
|
+
if Mongoid::Geospatial.lat_symbols.index(keys[0])
|
26
|
+
fail "Hash cannot contain #{Mongoid::Geospatial.lat_symbols.inspect} "\
|
27
|
+
"as first arg without #{Mongoid::Geospatial.lng_symbols.inspect}"
|
28
|
+
end
|
24
29
|
values[0].to_f
|
25
30
|
end
|
26
31
|
end
|
@@ -44,7 +44,24 @@ describe Mongoid::Fields do
|
|
44
44
|
|
45
45
|
it 'should not work fine with nils' do
|
46
46
|
bus = Bus.create!(name: 'B', location: nil)
|
47
|
-
expect
|
47
|
+
expect do
|
48
|
+
bus.x = 9
|
49
|
+
bus.y = 9
|
50
|
+
end.to raise_error(NoMethodError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should update point x' do
|
54
|
+
bus = Bus.create!(name: '0789', location: [1, 1])
|
55
|
+
bus.x = 2
|
56
|
+
expect(bus.save).to be_truthy
|
57
|
+
expect(Bus.first.location.to_a).to eq([2, 1])
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should update point y' do
|
61
|
+
bus = Bus.create!(name: '0987', location: [1, 1])
|
62
|
+
bus.y = 2
|
63
|
+
expect(bus.save).to be_truthy
|
64
|
+
expect(Bus.first.location.to_a).to eq([1.0, 2.0])
|
48
65
|
end
|
49
66
|
end
|
50
67
|
end
|