locations_ng 1.0.2 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fa049b1575ec78e58249287f6d569e18f89d4142
4
- data.tar.gz: b5cf8f333940cef919906c7d58a04a04233e45f0
2
+ SHA256:
3
+ metadata.gz: e0f6ef8d982bcd1d492e7581ef5c430288f0dddb4c7315ea8e74aa1e4903d4c2
4
+ data.tar.gz: 37a3806fb1fabb9a1110ac68a4d6b62b3c309f6cc7b9002841477dd32b20ef70
5
5
  SHA512:
6
- metadata.gz: ab36708ef06d4666f7f2e3eae7534454c5ce2b03fbbea09da34e55e36071a5888a1b7b26ea4ca5605ae2cf59f6bae09724677e45103bf59a32881134bafe5b71
7
- data.tar.gz: d96f563f5709afb642b657595f6f8bfcf5d569bd8021c2c9eb97ec556eb9526d946f8a6a060ac3996781355cd13d7b73a89bb2411c535db3fab0bc0ff917e750
6
+ metadata.gz: bbd2abace362b8cd43c63591cfef75635c58fce637b67e87bd9ed3e6760d27ae76dad748229a22f247d1efb4a0d314034e2a5582e331b9c129370ae9b6bc507a
7
+ data.tar.gz: c16215a75822cdba38f8cc92821bf40b7f0c43827e70fb5c4768b3a16021cf05d02676d9933e61e23635217ffc5ce242fdf324fe6a246696bc048e492a745b35
data/lib/locations_ng.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'yaml'
2
- require 'active_support/core_ext/hash/indifferent_access'
2
+ require 'locations_ng/load_file'
3
3
  require 'locations_ng/state'
4
4
  require 'locations_ng/city'
5
5
  require 'locations_ng/lga'
@@ -1,35 +1,27 @@
1
1
  module LocationsNg
2
2
  class City
3
+ @all_cities = LoadFile.read('cities')
4
+
3
5
  class << self
4
6
  def all
5
- load_cities
7
+ @all_cities
6
8
  end
7
9
 
8
10
  def cities(state)
9
- state_query = state.downcase.gsub(' ', '_')
10
- all_cities = load_cities
11
+ state_query = state_query(state.downcase.tr(' ', '_'))
12
+ city_index = @all_cities.index{ |c| c['alias'] == state_query }
11
13
 
12
- if state_query == 'federal_capital_territory'
13
- state_query = 'fct'
14
+ unless city_index.nil?
15
+ return @all_cities[city_index]['cities']
14
16
  end
15
17
 
16
- city_index = all_cities.index{|c| c['alias'] == state_query}
17
-
18
- if city_index.nil?
19
- {message: "No cities found for '#{state}'", status: 404}
20
- else
21
- all_cities[city_index]['cities']
22
- end
18
+ {message: "No cities found for '#{state}'", status: 404}
23
19
  end
24
20
 
25
21
  private
26
22
 
27
- def load_cities
28
- YAML.load(File.read(files_location 'cities'))
29
- end
30
-
31
- def files_location(file)
32
- File.expand_path("../locations/#{file}.yml", __FILE__)
23
+ def state_query(state)
24
+ state == 'federal_capital_territory' ? 'fct' : state
33
25
  end
34
26
  end
35
27
  end
@@ -1,57 +1,44 @@
1
1
  module LocationsNg
2
2
  class Lga
3
+ @all_lgas = LoadFile.read('lgas')
4
+
3
5
  class << self
4
6
  def all
5
- load_lgas
7
+ @all_lgas
6
8
  end
7
9
 
8
10
  def lgas(state)
9
- query = format_query(state)
10
- all_lgas = load_lgas
11
-
12
- lga_index = all_lgas.index{|l| l['state_alias'] == query}
11
+ lga_index = @all_lgas.index{ |l| l['state_alias'] == format_query(state) }
13
12
 
14
- if lga_index.nil?
15
- {message: "No lgas found for '#{state}'", status: 404}
16
- else
17
- all_lgas[lga_index]['lgas']
13
+ unless lga_index.nil?
14
+ return @all_lgas[lga_index]['lgas']
18
15
  end
16
+
17
+ {message: "No lgas found for '#{state}'", status: 404}
19
18
  end
20
19
 
21
20
  def localities(state, lga)
22
21
  return {message: 'You must enter a state and lga.', status: 500} unless state && lga
23
22
 
24
- state_query = format_query(state)
25
- lga_query = format_query(lga)
26
- all_lgas = load_lgas
23
+ state_index = @all_lgas.index{ |s| s['state_alias'] == format_query(state) }
27
24
 
28
- state_index = all_lgas.index{|s| s['state_alias'] == state_query}
25
+ unless state_index
26
+ return {message: "'#{state}' state not found.", status: 404}
27
+ end
29
28
 
30
- if state_index
31
- lga_index = all_lgas[state_index]['locality'].index{|l| l['lga_alias'] == lga_query}
29
+ lga_index = @all_lgas[state_index]['locality'].index{ |l| l['lga_alias'] == format_query(lga) }
32
30
 
33
- if lga_index
34
- all_lgas[state_index]['locality'][lga_index]['localities']
35
- else
36
- {message: "'#{lga}' LGA not found for '#{state}' state.", status: 404}
37
- end
38
- else
39
- {message: "'#{state}' state not found.", status: 404}
31
+ unless lga_index
32
+ return {message: "'#{lga}' LGA not found for '#{state}' state.", status: 404}
40
33
  end
41
- end
42
34
 
43
- private
44
-
45
- def load_lgas
46
- YAML.load(File.read(files_location 'lgas'))
35
+ @all_lgas[state_index]['locality'][lga_index]['localities']
47
36
  end
48
37
 
49
- def files_location(file)
50
- File.expand_path("../locations/#{file}.yml", __FILE__)
51
- end
38
+ private
52
39
 
53
40
  def format_query(query)
54
- query ? query.downcase.gsub(' ', '_') : query
41
+ query ? query.downcase.tr(' ', '_') : query
55
42
  end
56
43
  end
57
44
  end
@@ -0,0 +1,13 @@
1
+ module LocationsNg
2
+ class LoadFile
3
+ class << self
4
+ def read(file_name)
5
+ YAML.load(File.read(files_location file_name))
6
+ end
7
+
8
+ def files_location(file)
9
+ File.expand_path("../locations/#{file}.yml", __FILE__)
10
+ end
11
+ end
12
+ end
13
+ end
File without changes
@@ -676,7 +676,7 @@
676
676
  - NGURORE
677
677
  - TOUNGO
678
678
  - YOLDE KOHI
679
- - state: Akwa-ibom
679
+ - state: Akwa Ibom
680
680
  state_alias: akwa-ibom
681
681
  lgas:
682
682
  - Abak
@@ -4758,7 +4758,7 @@
4758
4758
  - Ukpata
4759
4759
  - Umulokpa
4760
4760
  - Uvuru
4761
- - state: Fct
4761
+ - state: Federal Capital Territory
4762
4762
  state_alias: fct
4763
4763
  lgas:
4764
4764
  - Abaji
@@ -8,6 +8,7 @@
8
8
  longitude: 7.524724300000001
9
9
  maxLong: 7.9630091
10
10
  alias: abia
11
+ area: 6320
11
12
  - minLat: 7.452592
12
13
  name: Adamawa
13
14
  capital: Yola
@@ -17,6 +18,7 @@
17
18
  longitude: 12.4380581
18
19
  maxLong: 13.6924919
19
20
  alias: adamawa
21
+ area: 36917
20
22
  - minLat: 4.4780049
21
23
  name: Akwa Ibom
22
24
  capital: Uyo
@@ -26,6 +28,7 @@
26
28
  longitude: 7.872159999999999
27
29
  maxLong: 8.340371
28
30
  alias: akwa_ibom
31
+ area: 7081
29
32
  - minLat: 5.692615000000001
30
33
  name: Anambra
31
34
  capital: Awka
@@ -35,6 +38,7 @@
35
38
  longitude: 7.0068393
36
39
  maxLong: 7.355934
37
40
  alias: anambra
41
+ area: 4844
38
42
  - minLat: 10.255381
39
43
  name: Bauchi
40
44
  capital: Bauchi
@@ -44,6 +48,7 @@
44
48
  longitude: 9.844166999999999
45
49
  maxLong: 9.864006
46
50
  alias: bauchi
51
+ area: 45837
47
52
  - minLat: 6.4427789
48
53
  name: Benue
49
54
  capital: Makurdi
@@ -53,6 +58,7 @@
53
58
  longitude: 8.8362755
54
59
  maxLong: 9.918301
55
60
  alias: benue
61
+ area: 34059
56
62
  - minLat: 10.0291549
57
63
  name: Borno
58
64
  capital: Maiduguri
@@ -62,6 +68,7 @@
62
68
  longitude: 12.9789121
63
69
  maxLong: 14.680073
64
70
  alias: borno
71
+ area: 70898
65
72
  - minLat: 4.2771439
66
73
  name: Bayelsa
67
74
  capital: Yenagoa
@@ -71,6 +78,7 @@
71
78
  longitude: 5.898713900000001
72
79
  maxLong: 6.724865899999999
73
80
  alias: bayelsa
81
+ area: 10773
74
82
  - minLat: 4.690596000000001
75
83
  name: Cross River
76
84
  capital: Calabar
@@ -80,6 +88,7 @@
80
88
  longitude: 8.6600586
81
89
  maxLong: 9.472486
82
90
  alias: cross_river
91
+ area: 20156
83
92
  - minLat: 5.024351999999999
84
93
  name: Delta
85
94
  capital: Asaba
@@ -89,6 +98,7 @@
89
98
  longitude: 5.898713900000001
90
99
  maxLong: 6.7653911
91
100
  alias: delta
101
+ area: 17698
92
102
  - minLat: 5.6873539
93
103
  name: Ebonyi
94
104
  capital: Abakaliki
@@ -98,6 +108,7 @@
98
108
  longitude: 7.959286299999999
99
109
  maxLong: 8.4470269
100
110
  alias: ebonyi
111
+ area: 5670
101
112
  - minLat: 5.7386799
102
113
  name: Edo
103
114
  capital: Benin
@@ -107,6 +118,7 @@
107
118
  longitude: 5.898713900000001
108
119
  maxLong: 6.707891000000001
109
120
  alias: edo
121
+ area: 17802
110
122
  - minLat: 7.272215999999999
111
123
  name: Ekiti
112
124
  capital: Ado-Ekiti
@@ -116,6 +128,7 @@
116
128
  longitude: 5.3102505
117
129
  maxLong: 5.8048959
118
130
  alias: ekiti
131
+ area: 6353
119
132
  - minLat: 6.360852
120
133
  name: Enugu
121
134
  capital: Enugu
@@ -125,6 +138,7 @@
125
138
  longitude: 7.510332999999998
126
139
  maxLong: 7.618160199999999
127
140
  alias: enugu
141
+ area: 7161
128
142
  - minLat: 8.396675
129
143
  name: Federal Capital Territory
130
144
  capital: Abuja
@@ -134,6 +148,7 @@
134
148
  longitude: 7.179025999999999
135
149
  maxLong: 7.617400000000001
136
150
  alias: fct
151
+ area: 7315
137
152
  - minLat: 10.264117
138
153
  name: Gombe
139
154
  capital: Gombe
@@ -143,6 +158,7 @@
143
158
  longitude: 11.166667
144
159
  maxLong: 11.2147019
145
160
  alias: gombe
161
+ area: 18768
146
162
  - minLat: 12.5688205
147
163
  name: Jigawa
148
164
  capital: Dutse
@@ -152,6 +168,7 @@
152
168
  longitude: 8.9400589
153
169
  maxLong: 8.9410364
154
170
  alias: jigawa
171
+ area: 23154
155
172
  - minLat: 5.179824000000001
156
173
  name: Imo
157
174
  capital: Owerri
@@ -161,6 +178,7 @@
161
178
  longitude: 6.920913499999999
162
179
  maxLong: 7.404109
163
180
  alias: imo
181
+ area: 5530
164
182
  - minLat: 10.3971566
165
183
  name: Kaduna
166
184
  capital: Kaduna
@@ -170,6 +188,7 @@
170
188
  longitude: 7.433332999999999
171
189
  maxLong: 7.508812000000001
172
190
  alias: kaduna
191
+ area: 46053
173
192
  - minLat: 10.0931591
174
193
  name: Kebbi
175
194
  capital: Birnin Kebbi
@@ -179,6 +198,7 @@
179
198
  longitude: 4.0695454
180
199
  maxLong: 6.027123
181
200
  alias: kebbi
201
+ area: 36800
182
202
  - minLat: 11.912873
183
203
  name: Kano
184
204
  capital: Kano
@@ -188,6 +208,7 @@
188
208
  longitude: 8.591956099999999
189
209
  maxLong: 8.6704765
190
210
  alias: kano
211
+ area: 20131
191
212
  - minLat: 6.528274199999999
192
213
  name: Kogi
193
214
  capital: Lokoja
@@ -197,6 +218,7 @@
197
218
  longitude: 6.5783387
198
219
  maxLong: 7.8822179
199
220
  alias: kogi
221
+ area: 29833
200
222
  - minLat: 6.3936419
201
223
  name: Lagos
202
224
  capital: Ikeja
@@ -205,6 +227,7 @@
205
227
  maxLat: 6.7027984
206
228
  longitude: 3.3792057
207
229
  maxLong: 3.696727799999999
230
+ area: 3345
208
231
  alias: lagos
209
232
  - minLat: 12.934095
210
233
  name: Katsina
@@ -215,6 +238,7 @@
215
238
  longitude: 7.6
216
239
  maxLong: 7.676266000000001
217
240
  alias: katsina
241
+ area: 24192
218
242
  - minLat: 7.966079000000001
219
243
  name: Kwara
220
244
  capital: Ilorin
@@ -224,6 +248,7 @@
224
248
  longitude: 4.5624426
225
249
  maxLong: 6.2142591
226
250
  alias: kwara
251
+ area: 36825
227
252
  - minLat: 7.769181
228
253
  name: Nasarawa
229
254
  capital: Lafia
@@ -233,6 +258,7 @@
233
258
  longitude: 8.3088441
234
259
  maxLong: 9.605724
235
260
  alias: nasarawa
261
+ area: 27117
236
262
  - minLat: 4.269857099999999
237
263
  name: Niger
238
264
  capital: Minna
@@ -242,6 +268,7 @@
242
268
  longitude: 8.675277
243
269
  maxLong: 14.677982
244
270
  alias: niger
271
+ area: 76363
245
272
  - minLat: 6.315346099999999
246
273
  name: Ogun
247
274
  capital: Abeokuta
@@ -251,6 +278,7 @@
251
278
  longitude: 3.2583626
252
279
  maxLong: 4.5990951
253
280
  alias: ogun
281
+ area: 16762
254
282
  - minLat: 7.0529381
255
283
  name: Ondo
256
284
  capital: Akure
@@ -260,6 +288,7 @@
260
288
  longitude: 4.833333
261
289
  maxLong: 4.871921599999999
262
290
  alias: ondo
291
+ area: 15500
263
292
  - minLat: 4.347035099999999
264
293
  name: Rivers
265
294
  capital: Port Harcourt
@@ -269,6 +298,7 @@
269
298
  longitude: 6.920913499999999
270
299
  maxLong: 7.591592899999998
271
300
  alias: rivers
301
+ area: 11077
272
302
  - minLat: 7.790425099999999
273
303
  name: Oyo
274
304
  capital: Ibadan
@@ -278,6 +308,7 @@
278
308
  longitude: 3.933
279
309
  maxLong: 3.9751624
280
310
  alias: oyo
311
+ area: 28454
281
312
  - minLat: 6.969976
282
313
  name: Osun
283
314
  capital: Osogbo
@@ -287,6 +318,7 @@
287
318
  longitude: 4.5624426
288
319
  maxLong: 5.0647019
289
320
  alias: osun
321
+ area: 9251
290
322
  - minLat: 12.9764148
291
323
  name: Sokoto
292
324
  capital: Sokoto
@@ -296,6 +328,7 @@
296
328
  longitude: 5.233333
297
329
  maxLong: 5.2881144
298
330
  alias: sokoto
331
+ area: 25973
299
332
  - minLat: 8.350639
300
333
  name: Plateau
301
334
  capital: Jos
@@ -305,6 +338,7 @@
305
338
  longitude: 9.7232673
306
339
  maxLong: 10.6606639
307
340
  alias: plateau
341
+ area: 30913
308
342
  - minLat: 6.502453999999999
309
343
  name: Taraba
310
344
  capital: Jalingo
@@ -314,6 +348,7 @@
314
348
  longitude: 10.9807003
315
349
  maxLong: 11.981274
316
350
  alias: taraba
351
+ area: 54473
317
352
  - minLat: 10.5932052
318
353
  name: Yobe
319
354
  capital: Damaturu
@@ -323,6 +358,7 @@
323
358
  longitude: 11.7068294
324
359
  maxLong: 12.494047
325
360
  alias: yobe
361
+ area: 45502
326
362
  - minLat: 10.854616
327
363
  name: Zamfara
328
364
  capital: Gusau
@@ -332,3 +368,4 @@
332
368
  longitude: 6.2375947
333
369
  maxLong: 7.245729999999999
334
370
  alias: zamfara
371
+ area: 39762
@@ -1,20 +1,19 @@
1
1
  module LocationsNg
2
2
  class State
3
+ @all_states = LocationsNg::LoadFile.read('states')
4
+
3
5
  class << self
4
6
  def all
5
- load_states.map{ |s| {name: s['name'], capital: s['capital']} }
7
+ @all_states.map{ |s| {name: s['name'], capital: s['capital']} }
6
8
  end
7
9
 
8
10
  def details(state)
9
- state_query = format_query(state)
10
- all_states = load_states
11
-
12
- state_index = all_states.index{|s| s['alias'] == state_query}
11
+ state_index = @all_states.index{ |s| s['alias'] == format_query(state) }
13
12
 
14
13
  if state_index.nil?
15
14
  {message: "No state found for '#{state}'", status: 404}
16
15
  else
17
- res = all_states[state_index].with_indifferent_access
16
+ res = @all_states[state_index]
18
17
  res['cities'] = LocationsNg::City.cities(state)
19
18
  res['lgas'] = LocationsNg::Lga.lgas(state)
20
19
  res
@@ -22,30 +21,19 @@ module LocationsNg
22
21
  end
23
22
 
24
23
  def capital(state)
25
- state_query = format_query(state)
26
- all_states = load_states
27
-
28
- state_index = all_states.index{|s| s['alias'] == state_query}
24
+ state_index = @all_states.index{ |s| s['alias'] == format_query(state) }
29
25
 
30
- if state_index.nil?
31
- {message: "No state found for '#{state}'", status: 404}
32
- else
33
- all_states[state_index]['capital']
26
+ unless state_index.nil?
27
+ return @all_states[state_index]['capital']
34
28
  end
35
- end
36
-
37
- private
38
29
 
39
- def load_states
40
- YAML.load(File.read(files_location 'states'))
30
+ {message: "No state found for '#{state}'", status: 404}
41
31
  end
42
32
 
43
- def files_location(file)
44
- File.expand_path("../locations/#{file}.yml", __FILE__)
45
- end
33
+ private
46
34
 
47
35
  def format_query(query)
48
- query ? query.downcase.gsub(' ', '_') : query
36
+ query ? query.downcase.tr(' ', '_') : query
49
37
  end
50
38
  end
51
39
  end
@@ -1,3 +1,3 @@
1
1
  module LocationsNg
2
- VERSION = '1.0.2'
2
+ VERSION = '1.1.1'
3
3
  end
File without changes
File without changes
@@ -26,21 +26,22 @@ module LocationsNg
26
26
  context 'when state is found' do
27
27
  it 'returns detailed data for the state' do
28
28
  expect(state.details('Lagos')).to eq({'minLat'=>6.3936419,
29
- 'name'=>'Lagos',
30
- 'capital'=>'Ikeja',
31
- 'latitude'=>6.5243793,
32
- 'minLong'=>3.0982732,
33
- 'maxLat'=>6.7027984,
34
- 'longitude'=>3.3792057,
35
- 'maxLong'=>3.696727799999999,
36
- 'alias'=>'lagos',
37
- 'cities'=>%w(Agege Ikeja),
38
- 'lgas'=>['Agege', 'Ajeromi/ifelodun', 'Alimosho',
39
- 'Amuwo-odofin', 'Apapa', 'Badagry', 'Epe',
40
- 'Eti-osa', 'Ibeju/lekki', 'Ifako/ijaiye',
41
- 'Ikeja', 'Ikorodu', 'Kosofe', 'Lagos Island',
42
- 'Lagos Mainland', 'Mushin', 'Ojo', 'Oshodi/isolo',
43
- 'Shomolu', 'Surulere']
29
+ 'name'=>'Lagos',
30
+ 'capital'=>'Ikeja',
31
+ 'latitude'=>6.5243793,
32
+ 'minLong'=>3.0982732,
33
+ 'maxLat'=>6.7027984,
34
+ 'longitude'=>3.3792057,
35
+ 'maxLong'=>3.696727799999999,
36
+ 'area'=>3345,
37
+ 'alias'=>'lagos',
38
+ 'cities'=>%w(Agege Ikeja),
39
+ 'lgas'=>['Agege', 'Ajeromi/ifelodun', 'Alimosho',
40
+ 'Amuwo-odofin', 'Apapa', 'Badagry', 'Epe',
41
+ 'Eti-osa', 'Ibeju/lekki', 'Ifako/ijaiye',
42
+ 'Ikeja', 'Ikorodu', 'Kosofe', 'Lagos Island',
43
+ 'Lagos Mainland', 'Mushin', 'Ojo', 'Oshodi/isolo',
44
+ 'Shomolu', 'Surulere']
44
45
  })
45
46
  end
46
47
  end
File without changes
File without changes
File without changes
data/spec/spec_helper.rb CHANGED
File without changes
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locations_ng
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fiyin Adebayo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-01 00:00:00.000000000 Z
11
+ date: 2021-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.2.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.6
27
27
  - !ruby/object:Gem::Dependency
@@ -47,6 +47,7 @@ files:
47
47
  - lib/locations_ng.rb
48
48
  - lib/locations_ng/city.rb
49
49
  - lib/locations_ng/lga.rb
50
+ - lib/locations_ng/load_file.rb
50
51
  - lib/locations_ng/locations/cities.yml
51
52
  - lib/locations_ng/locations/lgas.yml
52
53
  - lib/locations_ng/locations/states.yml
@@ -78,16 +79,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
79
  - !ruby/object:Gem::Version
79
80
  version: '0'
80
81
  requirements: []
81
- rubyforge_project:
82
- rubygems_version: 2.5.1
82
+ rubygems_version: 3.0.3
83
83
  signing_key:
84
84
  specification_version: 4
85
85
  summary: States, Cities and LGAs in Nigeria.
86
86
  test_files:
87
- - spec/locations_ng/city_spec.rb
88
- - spec/locations_ng/lga_spec.rb
89
- - spec/locations_ng/state_spec.rb
87
+ - spec/spec_helper.rb
88
+ - spec/responses/lgas.json
90
89
  - spec/responses/canonical_states.json
91
90
  - spec/responses/cities.json
92
- - spec/responses/lgas.json
93
- - spec/spec_helper.rb
91
+ - spec/locations_ng/state_spec.rb
92
+ - spec/locations_ng/lga_spec.rb
93
+ - spec/locations_ng/city_spec.rb