postcodes_io 0.1.0 → 0.4.0
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 +5 -5
- data/.github/workflows/gem-push.yml +43 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/LICENSE.txt +1 -1
- data/README.md +44 -6
- data/Rakefile +7 -2
- data/lib/postcodes_io/autocomplete.rb +37 -0
- data/lib/postcodes_io/autocomplete_list.rb +12 -0
- data/lib/postcodes_io/base.rb +10 -0
- data/lib/postcodes_io/lookup.rb +44 -2
- data/lib/postcodes_io/lookup_terminated.rb +33 -0
- data/lib/postcodes_io/postcode.rb +3 -8
- data/lib/postcodes_io/reverse_geocode.rb +20 -0
- data/lib/postcodes_io/version.rb +1 -1
- data/lib/postcodes_io.rb +9 -3
- data/postcodes_io.gemspec +2 -2
- data/spec/autocomplete_spec.rb +36 -0
- data/spec/fixtures/autocomplete_response.json +14 -0
- data/spec/fixtures/lookup_multi_response.json +86 -0
- data/spec/fixtures/lookup_terminated_response.json +10 -0
- data/spec/fixtures/no_results_response.json +1 -0
- data/spec/fixtures/reverse_geocode_response.json +1 -0
- data/spec/lookup_spec.rb +62 -0
- data/spec/lookup_terminated_spec.rb +26 -0
- data/spec/postcode_io_spec.rb +0 -22
- data/spec/reverse_geocode_spec.rb +52 -0
- metadata +47 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2c6a93dd223ae7a6cc8c04b1f7079f955eb4d93d0ebab8bd14f6cffa87f57b82
|
4
|
+
data.tar.gz: 28052e4ba75fa32901fc03b8997cbc67575df1e97c7902fbead915086b88f758
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cb7ab91ceba1f04d2aed32d96a5c4b1c9754c06fef797246311ed340aeaa78cd69157f05f59a9a47d04f6ba3c8d66a537108cd361f00940d30a3189e88b1342
|
7
|
+
data.tar.gz: e91286586e6dd99db43ae487df61d621df6e623877facc54117a132eab964a2f8d506c3c27fb8655d956a771bce39ec0859f3398b3375253b54b2766b678fe2f
|
@@ -0,0 +1,43 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Build + Publish
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
contents: read
|
13
|
+
packages: write
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Set up Ruby 2.6
|
18
|
+
uses: actions/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.6.x
|
21
|
+
|
22
|
+
- name: Publish to GPR
|
23
|
+
run: |
|
24
|
+
mkdir -p $HOME/.gem
|
25
|
+
touch $HOME/.gem/credentials
|
26
|
+
chmod 0600 $HOME/.gem/credentials
|
27
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
28
|
+
gem build *.gemspec
|
29
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
30
|
+
env:
|
31
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
32
|
+
OWNER: ${{ github.repository_owner }}
|
33
|
+
|
34
|
+
- name: Publish to RubyGems
|
35
|
+
run: |
|
36
|
+
mkdir -p $HOME/.gem
|
37
|
+
touch $HOME/.gem/credentials
|
38
|
+
chmod 0600 $HOME/.gem/credentials
|
39
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
40
|
+
gem build *.gemspec
|
41
|
+
gem push *.gem
|
42
|
+
env:
|
43
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
23
|
+
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
# uses: ruby/setup-ruby@v1
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[](https://travis-ci.org/jamesruston/postcodes_io) [](https://badge.fury.io/rb/postcodes_io)
|
1
2
|
# PostcodesIo
|
2
3
|
|
3
4
|
A simple wrapper around [postcodes.io](http://postcodes.io/)
|
@@ -23,16 +24,16 @@ Or install it yourself as:
|
|
23
24
|
Require the gem
|
24
25
|
|
25
26
|
```ruby
|
26
|
-
require '
|
27
|
+
require 'postcodes_io'
|
27
28
|
```
|
28
29
|
|
29
|
-
Create new instance of the
|
30
|
+
Create new instance of the Postcodes::IO
|
30
31
|
|
31
32
|
```ruby
|
32
33
|
pio = Postcodes::IO.new
|
33
34
|
```
|
34
35
|
|
35
|
-
Lookup a postcode
|
36
|
+
### Lookup a postcode
|
36
37
|
```ruby
|
37
38
|
postcode = pio.lookup('NN12 8TN')
|
38
39
|
```
|
@@ -43,7 +44,44 @@ postcode.longitude # -1.02144562675883
|
|
43
44
|
postcode.latitude # 52.0776806788868
|
44
45
|
```
|
45
46
|
|
46
|
-
|
47
|
+
### Make a batch postcode lookup request
|
48
|
+
|
49
|
+
> max 100 postcodes per request
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
postcodes = pio.lookup('NN12 8TN', 'DA3 8NG') # or pio.lookup(['NN12 8TN', 'DA3 8NG'])
|
53
|
+
postcodes.each do |p|
|
54
|
+
puts p.nuts
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
### Autocomplete a postcode
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
postcodes = pio.autocomplete('NN12')
|
62
|
+
puts postcodes.list # ["NN12 6AA", "NN12 6AB", "NN12 6AD", "NN12 6AE", "NN12 6AF", "NN12 6AG", "NN12 6AH", "NN12 6AJ", "NN12 6AL", "NN12 6AN"]
|
63
|
+
```
|
64
|
+
|
65
|
+
|
66
|
+
### Perform a reverse geocode lookup
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
postcodes = pio.reverse_geocode(longitude: 0.629834, latitude: 51.79232)
|
70
|
+
puts postcodes.first.postcode # CM8 1EF
|
71
|
+
```
|
72
|
+
|
73
|
+
### Lookup a terminated postcode
|
74
|
+
```ruby
|
75
|
+
postcode = pio.lookup_terminated('SO23 7SP')
|
76
|
+
```
|
77
|
+
|
78
|
+
Inspect the results!
|
79
|
+
```ruby
|
80
|
+
postcode.longitude # -1.02144562675883
|
81
|
+
postcode.latitude # 52.0776806788868
|
82
|
+
```
|
83
|
+
|
84
|
+
### All available fields
|
47
85
|
|
48
86
|
|name|description|
|
49
87
|
|----|-----------|
|
@@ -64,14 +102,14 @@ postcode.latitude # 52.0776806788868
|
|
64
102
|
|region| [former GORs](http://www.ons.gov.uk/ons/guide-method/geography/beginner-s-guide/administrative/england/government-office-regions/index.html)|
|
65
103
|
|parish| The smallest type of administrative area|
|
66
104
|
|lsoa| [The 2011 Census lower layer SOA code](http://www.ons.gov.uk/ons/guide-method/geography/beginner-s-guide/census/super-output-areas--soas-/index.html)|
|
67
|
-
|msoa| [The 2011 Census middle layer SOA (MSOA) code](
|
105
|
+
|msoa| [The 2011 Census middle layer SOA (MSOA) code](http://www.ons.gov.uk/ons/guide-method/geography/beginner-s-guide/census/super-output-areas--soas-/index.html)|
|
68
106
|
|ccg| Clinical Commissioning Group |
|
69
107
|
|nuts| [see here](http://en.wikipedia.org/wiki/Nomenclature_of_Territorial_Units_for_Statistics)|
|
70
108
|
|
71
109
|
For more details see [the documentation on postcodes.io](http://postcodes.io/docs)
|
72
110
|
## Contributing
|
73
111
|
|
74
|
-
1. Fork it ( https://github.com/
|
112
|
+
1. Fork it ( https://github.com/jamesruston/postcodes_io/fork )
|
75
113
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
114
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
115
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'json'
|
3
|
+
require 'postcodes_io/autocomplete_list'
|
4
|
+
|
5
|
+
module Postcodes
|
6
|
+
module Autocomplete
|
7
|
+
|
8
|
+
def autocomplete(postcode)
|
9
|
+
autocomplete_postcode postcode
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def autocomplete_postcode(postcode)
|
15
|
+
postcode = remove_whitespace postcode
|
16
|
+
response = Excon.get("https://api.postcodes.io/postcodes/#{postcode}/autocomplete")
|
17
|
+
|
18
|
+
unless response.status == 404
|
19
|
+
parsed_response = JSON.parse(response.body)
|
20
|
+
return Postcodes::AutocompleteList.new(parsed_response['result'])
|
21
|
+
end
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_whitespace(string)
|
26
|
+
string.gsub(/\s+/, '')
|
27
|
+
end
|
28
|
+
|
29
|
+
def process_response(response, &block)
|
30
|
+
unless response.status == 404
|
31
|
+
yield JSON.parse(response.body)
|
32
|
+
end
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/postcodes_io/lookup.rb
CHANGED
@@ -4,14 +4,56 @@ require 'postcodes_io/postcode'
|
|
4
4
|
|
5
5
|
module Postcodes
|
6
6
|
module Lookup
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
|
9
|
+
def lookup(*postcodes)
|
10
|
+
postcodes.flatten!
|
11
|
+
if postcodes.count > 1
|
12
|
+
lookup_multiple postcodes
|
13
|
+
else
|
14
|
+
lookup_postcode postcodes.first
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def lookup_postcode(postcode)
|
22
|
+
postcode = remove_whitespace postcode
|
9
23
|
response = Excon.get("https://api.postcodes.io/postcodes/#{postcode}")
|
24
|
+
|
10
25
|
unless response.status == 404
|
11
26
|
parsed_response = JSON.parse(response.body)
|
12
27
|
return Postcodes::Postcode.new(parsed_response['result'])
|
13
28
|
end
|
14
29
|
return nil
|
15
30
|
end
|
31
|
+
|
32
|
+
def lookup_multiple(postcodes)
|
33
|
+
payload = {postcodes: postcodes.map {|p| remove_whitespace p}}
|
34
|
+
response = Excon.post(
|
35
|
+
"https://api.postcodes.io/postcodes",
|
36
|
+
body: payload.to_json,
|
37
|
+
headers: {'Content-Type' => 'application/json'}
|
38
|
+
)
|
39
|
+
|
40
|
+
process_response(response) do |r|
|
41
|
+
return r['result'].map do |result|
|
42
|
+
Postcodes::Postcode.new(result['result'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_whitespace(string)
|
48
|
+
string.gsub(/\s+/, '') # remove any whitespace. m1 1ab => m11ab
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_response(response, &block)
|
52
|
+
unless response.status == 404
|
53
|
+
yield JSON.parse(response.body)
|
54
|
+
end
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
16
58
|
end
|
17
59
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'json'
|
3
|
+
require 'postcodes_io/postcode'
|
4
|
+
|
5
|
+
module Postcodes
|
6
|
+
module LookupTerminated
|
7
|
+
def lookup_terminated(postcode)
|
8
|
+
lookup_terminated_postcode postcode
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def lookup_terminated_postcode(postcode)
|
14
|
+
postcode = remove_whitespace postcode
|
15
|
+
response = Excon.get("https://api.postcodes.io/terminated_postcodes/#{postcode}")
|
16
|
+
|
17
|
+
unless response.status == 404
|
18
|
+
parsed_response = JSON.parse(response.body)
|
19
|
+
return Postcodes::Postcode.new(parsed_response['result'])
|
20
|
+
end
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove_whitespace(string)
|
25
|
+
string.gsub(/\s+/, '') # remove any whitespace. m1 1ab => m11ab
|
26
|
+
end
|
27
|
+
|
28
|
+
def process_response(response)
|
29
|
+
yield JSON.parse(response.body) unless response.status == 404
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,17 +1,12 @@
|
|
1
|
+
require "postcodes_io/base"
|
2
|
+
|
1
3
|
module Postcodes
|
2
|
-
class Postcode
|
4
|
+
class Postcode < Base
|
3
5
|
|
4
6
|
attr_reader :info
|
5
7
|
|
6
8
|
def initialize(info)
|
7
9
|
@info = info
|
8
10
|
end
|
9
|
-
|
10
|
-
# allow accessing info values with dot notation
|
11
|
-
def method_missing(name, *args, &block)
|
12
|
-
return @info[name] if @info.key? name
|
13
|
-
@info.each { |k,v| return v if k.to_s.to_sym == name }
|
14
|
-
super.method_missing name
|
15
|
-
end
|
16
11
|
end
|
17
12
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'json'
|
3
|
+
require 'postcodes_io/postcode'
|
4
|
+
|
5
|
+
module Postcodes
|
6
|
+
module ReverseGeocode
|
7
|
+
def reverse_geocode(longitude:, latitude:, limit: 10, radius: 100, wide_search: false)
|
8
|
+
response = Excon.get(
|
9
|
+
"https://api.postcodes.io/postcodes?lon=#{longitude}&lat=#{latitude}&limit=#{limit}&radius=#{radius}&wideSearch=#{wide_search}")
|
10
|
+
return unless response.status == 200
|
11
|
+
|
12
|
+
json = JSON.parse(response.body)
|
13
|
+
return unless json['result']
|
14
|
+
|
15
|
+
json['result'].map do |result|
|
16
|
+
Postcode.new(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/postcodes_io/version.rb
CHANGED
data/lib/postcodes_io.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'postcodes_io/version'
|
2
|
+
require 'postcodes_io/lookup'
|
3
|
+
require 'postcodes_io/autocomplete'
|
4
|
+
require 'postcodes_io/postcode'
|
5
|
+
require 'postcodes_io/reverse_geocode'
|
6
|
+
require 'postcodes_io/lookup_terminated'
|
4
7
|
|
5
8
|
module Postcodes
|
6
9
|
class IO
|
7
10
|
include Lookup
|
11
|
+
include Autocomplete
|
12
|
+
include ReverseGeocode
|
13
|
+
include LookupTerminated
|
8
14
|
end
|
9
15
|
end
|
data/postcodes_io.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler"
|
22
|
-
spec.add_development_dependency "rake"
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
spec.add_development_dependency "webmock"
|
25
25
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postcodes::IO do
|
4
|
+
|
5
|
+
let(:base_url) {'https://api.postcodes.io'}
|
6
|
+
let(:stub_autocomplete) { File.read('spec/fixtures/autocomplete_response.json') }
|
7
|
+
|
8
|
+
describe '#autocomplete' do
|
9
|
+
|
10
|
+
before :each do
|
11
|
+
stub_request(:get, "#{base_url}/postcodes/NN10/autocomplete")
|
12
|
+
.to_return(status: 200, body: stub_autocomplete)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:input) { 'NN10' }
|
16
|
+
let(:output) { subject.autocomplete(input) }
|
17
|
+
|
18
|
+
it 'requests a postcode' do
|
19
|
+
output
|
20
|
+
WebMock.should have_requested(:get, "#{base_url}/postcodes/NN10/autocomplete")
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns autocompleted array' do
|
24
|
+
expect(output.list).to eq(["NN10 0AA",
|
25
|
+
"NN10 0AD",
|
26
|
+
"NN10 0AE",
|
27
|
+
"NN10 0AF",
|
28
|
+
"NN10 0AG",
|
29
|
+
"NN10 0AH",
|
30
|
+
"NN10 0AJ",
|
31
|
+
"NN10 0AL",
|
32
|
+
"NN10 0AN",
|
33
|
+
"NN10 0AP"])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
{
|
2
|
+
"status": 200,
|
3
|
+
"result": [
|
4
|
+
{
|
5
|
+
"query": "OX49 5NU",
|
6
|
+
"result": {
|
7
|
+
"postcode": "OX49 5NU",
|
8
|
+
"quality": 1,
|
9
|
+
"eastings": 464435,
|
10
|
+
"northings": 195686,
|
11
|
+
"country": "England",
|
12
|
+
"nhs_ha": "South Central",
|
13
|
+
"admin_county": "Oxfordshire",
|
14
|
+
"admin_district": "South Oxfordshire",
|
15
|
+
"admin_ward": "Benson",
|
16
|
+
"longitude": -1.06993881320412,
|
17
|
+
"latitude": 51.6562791294687,
|
18
|
+
"parliamentary_constituency": "Henley",
|
19
|
+
"european_electoral_region": "South East",
|
20
|
+
"primary_care_trust": "Oxfordshire",
|
21
|
+
"region": "South East",
|
22
|
+
"parish": "Brightwell Baldwin",
|
23
|
+
"lsoa": "South Oxfordshire 011B",
|
24
|
+
"msoa": "South Oxfordshire 011",
|
25
|
+
"nuts": "Benson",
|
26
|
+
"incode": "5NU",
|
27
|
+
"outcode": "OX49",
|
28
|
+
"ccg": "NHS Oxfordshire CCG"
|
29
|
+
}
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"query": "M32 0JG",
|
33
|
+
"result": {
|
34
|
+
"postcode": "M32 0JG",
|
35
|
+
"quality": 1,
|
36
|
+
"eastings": 379988,
|
37
|
+
"northings": 395476,
|
38
|
+
"country": "England",
|
39
|
+
"nhs_ha": "North West",
|
40
|
+
"admin_county": null,
|
41
|
+
"admin_district": "Trafford",
|
42
|
+
"admin_ward": "Gorse Hill",
|
43
|
+
"longitude": -2.30283674284007,
|
44
|
+
"latitude": 53.4556572899372,
|
45
|
+
"parliamentary_constituency": "Stretford and Urmston",
|
46
|
+
"european_electoral_region": "North West",
|
47
|
+
"primary_care_trust": "Trafford",
|
48
|
+
"region": "North West",
|
49
|
+
"parish": null,
|
50
|
+
"lsoa": "Trafford 003C",
|
51
|
+
"msoa": "Trafford 003",
|
52
|
+
"nuts": "Gorse Hill",
|
53
|
+
"incode": "0JG",
|
54
|
+
"outcode": "M32",
|
55
|
+
"ccg": "NHS Trafford CCG"
|
56
|
+
}
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"query": "NE30 1DP",
|
60
|
+
"result": {
|
61
|
+
"postcode": "NE30 1DP",
|
62
|
+
"quality": 1,
|
63
|
+
"eastings": 435982,
|
64
|
+
"northings": 568683,
|
65
|
+
"country": "England",
|
66
|
+
"nhs_ha": "North East",
|
67
|
+
"admin_county": null,
|
68
|
+
"admin_district": "North Tyneside",
|
69
|
+
"admin_ward": "Tynemouth",
|
70
|
+
"longitude": -1.43889223951028,
|
71
|
+
"latitude": 55.0114112900573,
|
72
|
+
"parliamentary_constituency": "Tynemouth",
|
73
|
+
"european_electoral_region": "North East",
|
74
|
+
"primary_care_trust": "North Tyneside",
|
75
|
+
"region": "North East",
|
76
|
+
"parish": null,
|
77
|
+
"lsoa": "North Tyneside 016C",
|
78
|
+
"msoa": "North Tyneside 016",
|
79
|
+
"nuts": "Tynemouth",
|
80
|
+
"incode": "1DP",
|
81
|
+
"outcode": "NE30",
|
82
|
+
"ccg": "NHS North Tyneside CCG"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
]
|
86
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"status":200,"result":null}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"status":200,"result":[{"postcode":"PR7 4HF","quality":1,"eastings":360059,"northings":412765,"country":"England","nhs_ha":"North West","longitude":-2.60515477763266,"latitude":53.6099106263766,"european_electoral_region":"North West","primary_care_trust":"Central Lancashire","region":"North West","lsoa":"Chorley 014C","msoa":"Chorley 014","incode":"4HF","outcode":"PR7","distance":0,"parliamentary_constituency":"Chorley","admin_district":"Chorley","parish":"Adlington","admin_county":"Lancashire","admin_ward":"Adlington and Anderton","ccg":"NHS Chorley and South Ribble","nuts":"Chorley and West Lancashire","codes":{"admin_district":"E07000118","admin_county":"E10000017","admin_ward":"E05005165","parish":"E04005139","parliamentary_constituency":"E14000637","ccg":"E38000034","nuts":"UKD47"}},{"postcode":"PR7 4HR","quality":1,"eastings":360038,"northings":412741,"country":"England","nhs_ha":"North West","longitude":-2.60546907187036,"latitude":53.6096933152903,"european_electoral_region":"North West","primary_care_trust":"Central Lancashire","region":"North West","lsoa":"Chorley 014C","msoa":"Chorley 014","incode":"4HR","outcode":"PR7","distance":31.90158431,"parliamentary_constituency":"Chorley","admin_district":"Chorley","parish":"Adlington","admin_county":"Lancashire","admin_ward":"Adlington and Anderton","ccg":"NHS Chorley and South Ribble","nuts":"Chorley and West Lancashire","codes":{"admin_district":"E07000118","admin_county":"E10000017","admin_ward":"E05005165","parish":"E04005139","parliamentary_constituency":"E14000637","ccg":"E38000034","nuts":"UKD47"}},{"postcode":"PR7 4HJ","quality":1,"eastings":360076,"northings":412843,"country":"England","nhs_ha":"North West","longitude":-2.60490787349104,"latitude":53.6106129688375,"european_electoral_region":"North West","primary_care_trust":"Central Lancashire","region":"North West","lsoa":"Chorley 014C","msoa":"Chorley 014","incode":"4HJ","outcode":"PR7","distance":79.85903188,"parliamentary_constituency":"Chorley","admin_district":"Chorley","parish":"Adlington","admin_county":"Lancashire","admin_ward":"Adlington and Anderton","ccg":"NHS Chorley and South Ribble","nuts":"Chorley and West Lancashire","codes":{"admin_district":"E07000118","admin_county":"E10000017","admin_ward":"E05005165","parish":"E04005139","parliamentary_constituency":"E14000637","ccg":"E38000034","nuts":"UKD47"}}]}
|
data/spec/lookup_spec.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postcodes::IO do
|
4
|
+
|
5
|
+
let(:base_url) {'https://api.postcodes.io'}
|
6
|
+
let(:stub_single_response) { File.read('spec/fixtures/lookup_response.json') }
|
7
|
+
let(:stub_multi_response) { File.read('spec/fixtures/lookup_multi_response.json') }
|
8
|
+
|
9
|
+
describe '#lookup' do
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
stub_request(:get, "#{base_url}/postcodes/CM129TR")
|
13
|
+
.to_return(status: 200, body: stub_single_response)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:input) { 'CM12 9TR' }
|
17
|
+
let(:output) { subject.lookup(input) }
|
18
|
+
|
19
|
+
it 'requests a postcode' do
|
20
|
+
output
|
21
|
+
WebMock.should have_requested(:get, "#{base_url}/postcodes/CM129TR")
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns the long and lat' do
|
25
|
+
output.longitude.should == 0.411227930206834
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#lookup with multiple postcodes' do
|
30
|
+
before :each do
|
31
|
+
stub_request(:post, "#{base_url}/postcodes")
|
32
|
+
.with(body: postcode_payload, headers: {'Content-Type' => 'application/json'})
|
33
|
+
.to_return(status: 200, body: stub_multi_response)
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:input) { ['OX495NU', 'M320JG', 'NE301DP'] }
|
37
|
+
let(:output) { subject.lookup(input) }
|
38
|
+
let(:postcode_payload) { {postcodes: input}.to_json }
|
39
|
+
|
40
|
+
it 'makes a request with mutliple postcodes' do
|
41
|
+
output
|
42
|
+
WebMock.should have_requested(:post, "#{base_url}/postcodes")
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns a postcode object for each result' do
|
46
|
+
output.count.should == 3
|
47
|
+
output.each do |o|
|
48
|
+
o.class.should == Postcodes::Postcode
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'as splat' do
|
53
|
+
let(:output) { subject.lookup('OX495NU', 'M320JG', 'NE301DP') }
|
54
|
+
|
55
|
+
it 'allows passing postcodes as multiple arguments' do
|
56
|
+
output
|
57
|
+
WebMock.should have_requested(:post, "#{base_url}/postcodes")
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postcodes::IO do
|
4
|
+
let(:base_url) { 'https://api.postcodes.io' }
|
5
|
+
let(:stub_response) { File.read('spec/fixtures/lookup_terminated_response.json') }
|
6
|
+
|
7
|
+
describe '#lookup_terminated' do
|
8
|
+
before :each do
|
9
|
+
stub_request(:get, "#{base_url}/terminated_postcodes/CM129TR")
|
10
|
+
.to_return(status: 200, body: stub_response)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:input) { 'CM12 9TR' }
|
14
|
+
let(:output) { subject.lookup_terminated(input) }
|
15
|
+
|
16
|
+
it 'requests a terminated postcode' do
|
17
|
+
output
|
18
|
+
WebMock.should have_requested(:get, "#{base_url}/terminated_postcodes/CM129TR")
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the long and lat' do
|
22
|
+
output.longitude.should == -1.316261
|
23
|
+
output.latitude.should == 51.062297
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/postcode_io_spec.rb
CHANGED
@@ -2,26 +2,4 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Postcodes::IO do
|
4
4
|
|
5
|
-
let(:base_url) {'https://api.postcodes.io'}
|
6
|
-
let(:stub_response) { File.read('spec/fixtures/lookup_response.json') }
|
7
|
-
|
8
|
-
before :each do
|
9
|
-
stub_request(:get, "#{base_url}/postcodes/CM129TR")
|
10
|
-
.to_return(status: 200, body: stub_response)
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#lookup' do
|
14
|
-
let(:input) { 'CM12 9TR' }
|
15
|
-
let(:output) { subject.lookup(input) }
|
16
|
-
|
17
|
-
it 'requests a postcode' do
|
18
|
-
output
|
19
|
-
WebMock.should have_requested(:get, "#{base_url}/postcodes/CM129TR")
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns the long and lat' do
|
23
|
-
output.longitude.should == 0.411227930206834
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
5
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Postcodes::IO, '#reverse_geocode' do
|
4
|
+
let(:latitiude) { '53.6099106263766' }
|
5
|
+
let(:longitude) { '2.60515477763266' }
|
6
|
+
let(:base_url) { 'https://api.postcodes.io' }
|
7
|
+
let(:url) { "#{base_url}/postcodes?lon=#{longitude}&lat=#{latitiude}&limit=10&radius=100&wideSearch=false" }
|
8
|
+
let(:no_results_response) do
|
9
|
+
File.read('spec/fixtures/no_results_response.json')
|
10
|
+
end
|
11
|
+
let(:reverse_geocode_response) do
|
12
|
+
File.read('spec/fixtures/reverse_geocode_response.json')
|
13
|
+
end
|
14
|
+
|
15
|
+
subject(:reverse_geocode) do
|
16
|
+
described_class.new.reverse_geocode(
|
17
|
+
longitude: longitude, latitude: latitiude)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when a 400 is returned' do
|
21
|
+
before do
|
22
|
+
stub_request(:get, url).to_return(status: 400)
|
23
|
+
end
|
24
|
+
|
25
|
+
it { is_expected.to be_nil }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when there are no results returned' do
|
29
|
+
before do
|
30
|
+
stub_request(:get, url).to_return(status: 200, body: no_results_response)
|
31
|
+
end
|
32
|
+
|
33
|
+
it { is_expected.to be_nil }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when results are returned' do
|
37
|
+
before do
|
38
|
+
stub_request(:get, url)
|
39
|
+
.to_return(status: 200, body: reverse_geocode_response)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the correct number of postcodes' do
|
43
|
+
expect(reverse_geocode.count).to eq(3)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'instantiates an object for each returned postcode' do
|
47
|
+
reverse_geocode.each do |result|
|
48
|
+
expect(result).to be_a(Postcodes::Postcode)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postcodes_io
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Ruston
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: webmock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: excon
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0.39'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.39'
|
83
83
|
description: Get rich data from postcode lookups. Wraps postcodes.io
|
@@ -87,19 +87,36 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
-
- .
|
91
|
-
- .
|
90
|
+
- ".github/workflows/gem-push.yml"
|
91
|
+
- ".github/workflows/ruby.yml"
|
92
|
+
- ".gitignore"
|
93
|
+
- ".rspec"
|
94
|
+
- ".travis.yml"
|
92
95
|
- Gemfile
|
93
96
|
- LICENSE.txt
|
94
97
|
- README.md
|
95
98
|
- Rakefile
|
96
99
|
- lib/postcodes_io.rb
|
100
|
+
- lib/postcodes_io/autocomplete.rb
|
101
|
+
- lib/postcodes_io/autocomplete_list.rb
|
102
|
+
- lib/postcodes_io/base.rb
|
97
103
|
- lib/postcodes_io/lookup.rb
|
104
|
+
- lib/postcodes_io/lookup_terminated.rb
|
98
105
|
- lib/postcodes_io/postcode.rb
|
106
|
+
- lib/postcodes_io/reverse_geocode.rb
|
99
107
|
- lib/postcodes_io/version.rb
|
100
108
|
- postcodes_io.gemspec
|
109
|
+
- spec/autocomplete_spec.rb
|
110
|
+
- spec/fixtures/autocomplete_response.json
|
111
|
+
- spec/fixtures/lookup_multi_response.json
|
101
112
|
- spec/fixtures/lookup_response.json
|
113
|
+
- spec/fixtures/lookup_terminated_response.json
|
114
|
+
- spec/fixtures/no_results_response.json
|
115
|
+
- spec/fixtures/reverse_geocode_response.json
|
116
|
+
- spec/lookup_spec.rb
|
117
|
+
- spec/lookup_terminated_spec.rb
|
102
118
|
- spec/postcode_io_spec.rb
|
119
|
+
- spec/reverse_geocode_spec.rb
|
103
120
|
- spec/spec_helper.rb
|
104
121
|
homepage: ''
|
105
122
|
licenses:
|
@@ -111,21 +128,29 @@ require_paths:
|
|
111
128
|
- lib
|
112
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
113
130
|
requirements:
|
114
|
-
- -
|
131
|
+
- - ">="
|
115
132
|
- !ruby/object:Gem::Version
|
116
133
|
version: '0'
|
117
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
135
|
requirements:
|
119
|
-
- -
|
136
|
+
- - ">="
|
120
137
|
- !ruby/object:Gem::Version
|
121
138
|
version: '0'
|
122
139
|
requirements: []
|
123
|
-
|
124
|
-
rubygems_version: 2.2.2
|
140
|
+
rubygems_version: 3.0.3.1
|
125
141
|
signing_key:
|
126
142
|
specification_version: 4
|
127
143
|
summary: Lookup postcodes
|
128
144
|
test_files:
|
145
|
+
- spec/autocomplete_spec.rb
|
146
|
+
- spec/fixtures/autocomplete_response.json
|
147
|
+
- spec/fixtures/lookup_multi_response.json
|
129
148
|
- spec/fixtures/lookup_response.json
|
149
|
+
- spec/fixtures/lookup_terminated_response.json
|
150
|
+
- spec/fixtures/no_results_response.json
|
151
|
+
- spec/fixtures/reverse_geocode_response.json
|
152
|
+
- spec/lookup_spec.rb
|
153
|
+
- spec/lookup_terminated_spec.rb
|
130
154
|
- spec/postcode_io_spec.rb
|
155
|
+
- spec/reverse_geocode_spec.rb
|
131
156
|
- spec/spec_helper.rb
|