ideal_postcodes 0.1.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.
- data/Gemfile +2 -0
- data/README.md +49 -0
- data/Rakefile +8 -0
- data/ideal-postcodes-ruby.gemspec +25 -0
- data/lib/ideal_postcodes.rb +2 -0
- data/lib/idealpostcodes.rb +91 -0
- data/lib/idealpostcodes/errors.rb +33 -0
- data/lib/idealpostcodes/postcode.rb +35 -0
- data/lib/idealpostcodes/util.rb +29 -0
- data/lib/idealpostcodes/version.rb +3 -0
- data/test/test_helper.rb +77 -0
- data/test/test_ideal_postcodes.rb +78 -0
- metadata +156 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Ideal-Postcodes.co.uk API Wrapper
|
2
|
+
|
3
|
+
Get a full list of addresses for any given UK postcode using the Ideal-Postcodes.co.uk API. We use the most accurate addressing database in the UK, Royal Mail's Postcode Address File.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
__Install it__
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install ideal_postcodes
|
11
|
+
```
|
12
|
+
|
13
|
+
__Get an API Key__
|
14
|
+
|
15
|
+
Get a key [Ideal-Postcodes.co.uk](https://ideal-postcodes.co.uk). Try out the service with the test postcode 'ID1 1QD'
|
16
|
+
|
17
|
+
__Use it__
|
18
|
+
|
19
|
+
Do address lookups with a few lines of Ruby
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'ideal_postcodes'
|
23
|
+
|
24
|
+
IdealPostcodes.api_key = "your_key_goes_here"
|
25
|
+
|
26
|
+
postcode = IdealPostcodes::Postcode.lookup "ID1 1QD"
|
27
|
+
|
28
|
+
# postcode.addresses =>
|
29
|
+
#
|
30
|
+
# [
|
31
|
+
# {
|
32
|
+
# :postcode=>"ID1 1QD",
|
33
|
+
# :post_town=>"LONDON",
|
34
|
+
# :line_1=>"Kingsley Hall",
|
35
|
+
# :line_2=>"Powis Road",
|
36
|
+
# :line_3=>""
|
37
|
+
# },
|
38
|
+
# ... and so on
|
39
|
+
```
|
40
|
+
|
41
|
+
## Registering
|
42
|
+
|
43
|
+
PAF is licensed from the Royal Mail and is, unfortunately, not free to use. Ideal Postcodes aims to be simple to use and fairly priced to use for web and mobile developers.
|
44
|
+
|
45
|
+
We charge _2p_ per [external](https://ideal-postcodes.co.uk/termsandconditions#external) lookup.
|
46
|
+
|
47
|
+
## Documentation
|
48
|
+
|
49
|
+
More documentation can be found [here](https://ideal-postcodes.co.uk/documentation/ruby-wrapper)
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
|
+
|
3
|
+
require 'idealpostcodes/version'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
s.name = 'ideal_postcodes'
|
7
|
+
s.version = IdealPostcodes::VERSION
|
8
|
+
s.summary = 'Wrapper for the Ideal-Postcodes.co.uk API'
|
9
|
+
s.description = 'Ideal Postcodes is a simple postcode lookup API for UK addresses. See https://ideal-postcodes.co.uk'
|
10
|
+
s.authors = ['Chris Blanchard']
|
11
|
+
s.email = ['cablanchard@gmail.com']
|
12
|
+
s.homepage = 'https://ideal-postcodes.co.uk/documentation'
|
13
|
+
|
14
|
+
s.add_dependency('rest-client', '~> 1.6')
|
15
|
+
s.add_dependency('multi_json', '~> 1.7.9')
|
16
|
+
|
17
|
+
s.add_development_dependency('mocha', '~> 0.14.0')
|
18
|
+
s.add_development_dependency('test-unit')
|
19
|
+
s.add_development_dependency('shoulda', '~> 3.5.0')
|
20
|
+
s.add_development_dependency('rake')
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
24
|
+
s.require_paths = ['lib']
|
25
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'uri'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'cgi'
|
5
|
+
require 'idealpostcodes/version'
|
6
|
+
require 'idealpostcodes/postcode'
|
7
|
+
require 'idealpostcodes/util'
|
8
|
+
require 'idealpostcodes/errors'
|
9
|
+
|
10
|
+
module IdealPostcodes
|
11
|
+
@base_url = 'https://api.ideal-postcodes.co.uk'
|
12
|
+
@version = '1'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :api_key, :base_url, :version
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.request(method, path, params = {})
|
19
|
+
unless @api_key
|
20
|
+
raise IdealPostcodes::AuthenticationError.new('No API Key provided. ' +
|
21
|
+
'Set your key with IdealPostcodes.api_key = #your_key')
|
22
|
+
end
|
23
|
+
|
24
|
+
url = URI.parse(resource_url(path))
|
25
|
+
params.merge! api_key: @api_key
|
26
|
+
url.query = Util.merge_params(params)
|
27
|
+
request_options = {
|
28
|
+
method: method.downcase.to_sym,
|
29
|
+
url: url.to_s
|
30
|
+
}
|
31
|
+
|
32
|
+
begin
|
33
|
+
response = generate_request(request_options)
|
34
|
+
rescue RestClient::ExceptionWithResponse => error
|
35
|
+
if rcode = error.http_code && rbody = error.http_body
|
36
|
+
handle_error(rcode, rbody)
|
37
|
+
else
|
38
|
+
handle_client_error(error)
|
39
|
+
end
|
40
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => error
|
41
|
+
handle_client_error(e)
|
42
|
+
end
|
43
|
+
parse response.body
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def self.resource_url(path='')
|
49
|
+
URI.escape "#{@base_url}/v#{@version}/#{path}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.generate_request(options)
|
53
|
+
RestClient::Request.execute(options)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.parse(response)
|
57
|
+
begin
|
58
|
+
Util.keys_to_sym MultiJson.load(response)
|
59
|
+
rescue MultiJson::DecodeError => e
|
60
|
+
raise handle_client_error(e)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.handle_error(http_code, http_body)
|
65
|
+
error = parse http_body
|
66
|
+
|
67
|
+
ideal_code, ideal_message = error[:code], error[:message]
|
68
|
+
|
69
|
+
case ideal_code
|
70
|
+
when 4010
|
71
|
+
raise AuthenticationError.new ideal_message, http_code, http_body, ideal_code
|
72
|
+
when 4020
|
73
|
+
raise TokenExhaustedError.new ideal_message, http_code, http_body, ideal_code
|
74
|
+
when 4021
|
75
|
+
raise LimitReachedError.new ideal_message, http_code, http_body, ideal_code
|
76
|
+
when 4040
|
77
|
+
raise ResourceNotFoundError.new ideal_message, http_code, http_body, ideal_code
|
78
|
+
else
|
79
|
+
raise IdealPostcodesError.new ideal_message, http_code, http_body, ideal_code
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.handle_client_error(error)
|
84
|
+
raise IdealPostcodesError.new("An unexpected error occured: #{error.message})")
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.general_error(response_code, response_body)
|
88
|
+
IdealPostcodesError.new "Invalid response object", response_code, response_body
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module IdealPostcodes
|
2
|
+
class IdealPostcodesError < StandardError
|
3
|
+
attr_reader :message
|
4
|
+
attr_reader :http_code
|
5
|
+
attr_reader :http_body
|
6
|
+
attr_reader :response_code
|
7
|
+
|
8
|
+
def initialize(message = nil, http_code = nil, http_body = nil, response_code = nil)
|
9
|
+
@message = message
|
10
|
+
@http_code = http_code
|
11
|
+
@http_body = http_body
|
12
|
+
@response_code = response_code
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
status = @http_code.nil? ? "" : "#{@http_code} error."
|
17
|
+
ideal_code = @response_code.nil ? "" : "(#{@response_code})"
|
18
|
+
"#{status} error. (#{ideal_code}) #{message}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class AuthenticationError< IdealPostcodesError
|
23
|
+
end
|
24
|
+
|
25
|
+
class TokenExhaustedError < IdealPostcodesError
|
26
|
+
end
|
27
|
+
|
28
|
+
class LimitReachedError < IdealPostcodesError
|
29
|
+
end
|
30
|
+
|
31
|
+
class ResourceNotFoundError < IdealPostcodesError
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module IdealPostcodes
|
2
|
+
class Postcode
|
3
|
+
|
4
|
+
attr_reader :postcode_data, :postcode, :addresses
|
5
|
+
|
6
|
+
def initialize(postcode = nil, postcode_data = nil)
|
7
|
+
@raw = postcode_data
|
8
|
+
@addresses = (postcode_data.nil? || postcode_data[:result].nil?) ? [] : postcode_data[:result]
|
9
|
+
@postcode = postcode
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.lookup(postcode)
|
13
|
+
begin
|
14
|
+
response = IdealPostcodes.request :get, "postcodes/#{postcode}"
|
15
|
+
rescue IdealPostcodes::ResourceNotFoundError => error
|
16
|
+
raise error unless error.response_code == 4040
|
17
|
+
response = nil
|
18
|
+
end
|
19
|
+
new postcode, response
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
@raw.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def addresses
|
27
|
+
@addresses
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
addresses.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module IdealPostcodes
|
2
|
+
class Util
|
3
|
+
|
4
|
+
def self.merge_params(hash)
|
5
|
+
result = []
|
6
|
+
hash.each do |key, value|
|
7
|
+
result << "#{CGI.escape(key.to_s)}=#{CGI.escape(value)}"
|
8
|
+
end
|
9
|
+
result.join("&")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.keys_to_sym(object)
|
13
|
+
case object
|
14
|
+
when Hash
|
15
|
+
temp = {}
|
16
|
+
object.each do |key, value|
|
17
|
+
key = (key.to_sym rescue key) || key
|
18
|
+
temp[key] = keys_to_sym(value)
|
19
|
+
end
|
20
|
+
temp
|
21
|
+
when Array
|
22
|
+
object.map { |elem| keys_to_sym(elem) }
|
23
|
+
else
|
24
|
+
object
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'mocha/setup'
|
3
|
+
require 'ideal_postcodes'
|
4
|
+
require 'shoulda'
|
5
|
+
|
6
|
+
module IdealPostcodes
|
7
|
+
|
8
|
+
attr_accessor :mock
|
9
|
+
|
10
|
+
def self.mock=(mock)
|
11
|
+
@mock = mock
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.generate_request(options)
|
15
|
+
method = options[:method]
|
16
|
+
url = options[:url]
|
17
|
+
@mock.execute method, url
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_response(body, status=200)
|
23
|
+
body = MultiJson.dump(body)
|
24
|
+
m = mock
|
25
|
+
m.instance_variable_set('@instance_vals', {code: status, body: body})
|
26
|
+
def m.body; @instance_vals[:body]; end
|
27
|
+
def m.code; @instance_vals[:code]; end
|
28
|
+
m
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_postcode
|
32
|
+
"ID11QD"
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_postcode(params={})
|
36
|
+
{
|
37
|
+
result: [
|
38
|
+
{
|
39
|
+
postcode: "ID1 1QD",
|
40
|
+
post_town: "LONDON",
|
41
|
+
line_1: "Kingsley Hall",
|
42
|
+
line_2: "Powis Road",
|
43
|
+
line_3: ""
|
44
|
+
}
|
45
|
+
],
|
46
|
+
message: "Success",
|
47
|
+
code: 2000
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def invalid_postcode
|
52
|
+
{
|
53
|
+
message: "Postcode not found",
|
54
|
+
code: 4040
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def invalid_token
|
59
|
+
{
|
60
|
+
message: "Invalid key",
|
61
|
+
code: 4010
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def limit_reached
|
66
|
+
{
|
67
|
+
code: 4021,
|
68
|
+
message: "Lookup Limit Reached"
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def token_exhausted
|
73
|
+
{
|
74
|
+
code: 4020,
|
75
|
+
message: "Token exhausted"
|
76
|
+
}
|
77
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class TestIdealPostcodes < Test::Unit::TestCase
|
4
|
+
include Mocha
|
5
|
+
|
6
|
+
context "API" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@mock = mock
|
10
|
+
IdealPostcodes.mock = @mock
|
11
|
+
end
|
12
|
+
|
13
|
+
teardown do
|
14
|
+
IdealPostcodes.mock = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
should "raise an exception if no API key set" do
|
18
|
+
IdealPostcodes.api_key = nil
|
19
|
+
assert_raises IdealPostcodes::AuthenticationError do
|
20
|
+
postcode = IdealPostcodes::Postcode.lookup(test_postcode)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
should "raise an exception if authentication failed" do
|
25
|
+
IdealPostcodes.api_key = "BOGUS"
|
26
|
+
response = test_response invalid_token
|
27
|
+
assert_raises IdealPostcodes::AuthenticationError do
|
28
|
+
@mock.expects(:execute).raises(RestClient::ExceptionWithResponse.new(response, 401))
|
29
|
+
IdealPostcodes::Postcode.lookup(test_postcode)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "Valid API key" do
|
34
|
+
|
35
|
+
setup do
|
36
|
+
IdealPostcodes.api_key = "correctkey"
|
37
|
+
end
|
38
|
+
|
39
|
+
teardown do
|
40
|
+
IdealPostcodes.api_key = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
should "raise an exception if tokens exhausted" do
|
44
|
+
response = test_response token_exhausted
|
45
|
+
assert_raises IdealPostcodes::TokenExhaustedError do
|
46
|
+
@mock.expects(:execute).raises(RestClient::ExceptionWithResponse.new(response, 402))
|
47
|
+
IdealPostcodes::Postcode.lookup(test_postcode)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise an exception if limit has been breached" do
|
52
|
+
response = test_response limit_reached
|
53
|
+
assert_raises IdealPostcodes::LimitReachedError do
|
54
|
+
@mock.expects(:execute).raises(RestClient::ExceptionWithResponse.new(response, 402))
|
55
|
+
IdealPostcodes::Postcode.lookup(test_postcode)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
should "return postcode object with addresses for valid postcode" do
|
60
|
+
response = test_response valid_postcode
|
61
|
+
@mock.expects(:execute).returns(response)
|
62
|
+
postcode = IdealPostcodes::Postcode.lookup(test_postcode)
|
63
|
+
assert_equal postcode.empty?, false
|
64
|
+
assert_equal postcode.addresses, valid_postcode[:result]
|
65
|
+
end
|
66
|
+
|
67
|
+
should "return postcode object with empty array for non-existent postcode" do
|
68
|
+
response = test_response invalid_postcode
|
69
|
+
@mock.expects(:execute).raises(RestClient::ExceptionWithResponse.new(response, 404))
|
70
|
+
postcode = IdealPostcodes::Postcode.lookup(test_postcode)
|
71
|
+
assert_equal postcode.empty?, true
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ideal_postcodes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Blanchard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: multi_json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.7.9
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.7.9
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mocha
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.14.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.14.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: test-unit
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: shoulda
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.5.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.5.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Ideal Postcodes is a simple postcode lookup API for UK addresses. See
|
111
|
+
https://ideal-postcodes.co.uk
|
112
|
+
email:
|
113
|
+
- cablanchard@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- Gemfile
|
119
|
+
- README.md
|
120
|
+
- Rakefile
|
121
|
+
- ideal-postcodes-ruby.gemspec
|
122
|
+
- lib/ideal_postcodes.rb
|
123
|
+
- lib/idealpostcodes.rb
|
124
|
+
- lib/idealpostcodes/errors.rb
|
125
|
+
- lib/idealpostcodes/postcode.rb
|
126
|
+
- lib/idealpostcodes/util.rb
|
127
|
+
- lib/idealpostcodes/version.rb
|
128
|
+
- test/test_helper.rb
|
129
|
+
- test/test_ideal_postcodes.rb
|
130
|
+
homepage: https://ideal-postcodes.co.uk/documentation
|
131
|
+
licenses: []
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.8.24
|
151
|
+
signing_key:
|
152
|
+
specification_version: 3
|
153
|
+
summary: Wrapper for the Ideal-Postcodes.co.uk API
|
154
|
+
test_files:
|
155
|
+
- test/test_helper.rb
|
156
|
+
- test/test_ideal_postcodes.rb
|