loqate 0.2.0 → 0.3.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 +4 -4
- data/.yardstick.yml +9 -6
- data/CHANGELOG.md +17 -1
- data/README.md +39 -13
- data/ROADMAP.md +1 -0
- data/lib/loqate/address_gateway.rb +61 -15
- data/lib/loqate/error.rb +3 -1
- data/lib/loqate/mappers/error_mapper.rb +11 -5
- data/lib/loqate/mappers/generic_mapper.rb +13 -4
- data/lib/loqate/result.rb +43 -4
- data/lib/loqate/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fff6b4e7b798fed1a00eb2acfa53ffd3997820f815e1ef780ab46d4e8efbb68b
|
4
|
+
data.tar.gz: d442998133eaafc167db8a823b87703021bbf72c061237cac7a0dbb659d9a271
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d57781e89b7743e9c315d97e821cb31d56b0a1b2458cf1d2a640908e9d6e9bd45f8d64f155b63ccd2b704fa1b1b9b71bf700acd7c10ac08afcdf3c1e99e62020
|
7
|
+
data.tar.gz: 794e2d39014cc609fb708989785c74c551ad895bff4565b2f00cc67351353587b2bf3974c91fec54b53e02a7fb44668529c79058318444e8f5bbd00ba1985edd
|
data/.yardstick.yml
CHANGED
@@ -47,6 +47,7 @@ rules:
|
|
47
47
|
- Loqate::Result::Failure#failure?
|
48
48
|
- Loqate::Result#code
|
49
49
|
- Loqate::Result#value
|
50
|
+
- Loqate::Result::Failure#error
|
50
51
|
ReturnTag:
|
51
52
|
enabled: true
|
52
53
|
exclude:
|
@@ -60,9 +61,9 @@ rules:
|
|
60
61
|
- Loqate::AddressGateway#client
|
61
62
|
- Loqate::AddressGateway#mapper
|
62
63
|
- Loqate::AddressGateway#error_mapper
|
63
|
-
- Loqate::AddressGateway#
|
64
|
-
- Loqate::AddressGateway#
|
65
|
-
- Loqate::AddressGateway#
|
64
|
+
- Loqate::AddressGateway#build_error_from
|
65
|
+
- Loqate::AddressGateway#build_addresses_from
|
66
|
+
- Loqate::AddressGateway#build_detailed_address_from
|
66
67
|
- Loqate::Client#configuration
|
67
68
|
- Loqate::Client#authenticate_params
|
68
69
|
- Loqate::Client#format_params
|
@@ -73,6 +74,7 @@ rules:
|
|
73
74
|
- Loqate::Util#underscore
|
74
75
|
- Loqate::Error#attributes
|
75
76
|
- Loqate::Gateway#client
|
77
|
+
- Loqate::Result::Failure#error
|
76
78
|
Summary::Presence:
|
77
79
|
enabled: true
|
78
80
|
exclude:
|
@@ -86,9 +88,9 @@ rules:
|
|
86
88
|
- Loqate::AddressGateway#client
|
87
89
|
- Loqate::AddressGateway#mapper
|
88
90
|
- Loqate::AddressGateway#error_mapper
|
89
|
-
- Loqate::AddressGateway#
|
90
|
-
- Loqate::AddressGateway#
|
91
|
-
- Loqate::AddressGateway#
|
91
|
+
- Loqate::AddressGateway#build_error_from
|
92
|
+
- Loqate::AddressGateway#build_addresses_from
|
93
|
+
- Loqate::AddressGateway#build_detailed_address_from
|
92
94
|
- Loqate::Client#configuration
|
93
95
|
- Loqate::Client#authenticate_params
|
94
96
|
- Loqate::Client#format_params
|
@@ -96,6 +98,7 @@ rules:
|
|
96
98
|
- Loqate::DetailedAddress#==
|
97
99
|
- Loqate::Error#attributes
|
98
100
|
- Loqate::Gateway#client
|
101
|
+
- Loqate::Result::Failure#error
|
99
102
|
Summary::Length:
|
100
103
|
enabled: false
|
101
104
|
Summary::Delimiter:
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.3.0] - 2018-11-10
|
8
|
+
### Changed
|
9
|
+
- `address.retrieve` and `address.find` return a single error, not an array with a single item
|
10
|
+
- `address.retrieve` returns a single address, not an array of addresses
|
11
|
+
- `Loqate::Error` inherits from `StandardError` so that it can be raised as an exception
|
12
|
+
- Improved the documentation of `Success` and `Failure`
|
13
|
+
|
14
|
+
## Added
|
15
|
+
- `find!` to find an address or raise an exception
|
16
|
+
- `retrieve!` to retrieve the details of an address or raise an exception
|
17
|
+
- Aliased `Failure#value` to `Failure#error`
|
18
|
+
|
19
|
+
## Fixed
|
20
|
+
- Fixed the documentation of `AddressGateway`
|
21
|
+
|
7
22
|
## [0.2.0] - 2018-10-31
|
8
23
|
### Added
|
9
24
|
- VCR and WebMock to record HTTP interactions
|
@@ -20,4 +35,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
20
35
|
- Initial core functionality
|
21
36
|
- Codebase maintenance tools
|
22
37
|
|
23
|
-
[0.
|
38
|
+
[0.3.0]: https://github.com/wilsonsilva/loqate/compare/v0.2.0...v0.3.0
|
39
|
+
[0.2.0]: https://github.com/wilsonsilva/loqate/compare/v0.1.0...v0.2.0
|
data/README.md
CHANGED
@@ -38,7 +38,41 @@ To get started, initialize an API gateway with [your API key](https://account.lo
|
|
38
38
|
gateway = Loqate::Gateway.new(api_key: '<YOUR_API_KEY>')
|
39
39
|
```
|
40
40
|
|
41
|
-
|
41
|
+
### Bang Methods
|
42
|
+
|
43
|
+
Most methods have a bang and a non-bang version (e.g. `gateway.address.find` and `gateway.address.find!`).
|
44
|
+
The non-bang version will either return a `Loqate::Success` or an `Loqate::Failure`. The bang version will
|
45
|
+
either return the desired resource, or it will raise an exception.
|
46
|
+
|
47
|
+
#### Example of using non-bang method
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
result = gateway.address.find(text: 'EC1Y 8AF', country: 'GB', limit: 5)
|
51
|
+
|
52
|
+
if result.success?
|
53
|
+
addresses = result.value
|
54
|
+
addresses.first.id # => 'GB|RM|B|8144611'
|
55
|
+
else
|
56
|
+
error = result.error
|
57
|
+
puts "Error retrieving the address: #{error.description}. Resolution: #{error.resolution}"
|
58
|
+
end
|
59
|
+
|
60
|
+
result.failure? # => false
|
61
|
+
```
|
62
|
+
|
63
|
+
#### Example of using bang method
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
begin
|
67
|
+
addresses = gateway.address.find!(text: 'EC1Y 8AF', country: 'GB', limit: 5)
|
68
|
+
addresses.first.id # => 'GB|RM|B|8144611'
|
69
|
+
rescue Loqate::Error => e
|
70
|
+
puts "Error retrieving the address: #{e.description}. Resolution: #{e.resolution}"
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
It is recommended that you use the bang methods when you assume that the data is valid and do not expect validations
|
75
|
+
to fail. Otherwise, use the non-bang methods.
|
42
76
|
|
43
77
|
### Address API
|
44
78
|
|
@@ -56,9 +90,6 @@ selection.
|
|
56
90
|
```ruby
|
57
91
|
result = gateway.address.find(text: 'EC1Y 8AF', country: 'GB', limit: 5)
|
58
92
|
|
59
|
-
result.success? # => true
|
60
|
-
result.failure? # => false
|
61
|
-
|
62
93
|
addresses = result.value
|
63
94
|
addresses.first.id # => 'GB|RM|B|8144611'
|
64
95
|
```
|
@@ -68,15 +99,10 @@ addresses.first.id # => 'GB|RM|B|8144611'
|
|
68
99
|
```ruby
|
69
100
|
result = gateway.address.retrieve(id: 'GB|RM|B|8144611')
|
70
101
|
|
71
|
-
result.
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
address = addresses.first
|
76
|
-
|
77
|
-
address.city # 'London'
|
78
|
-
address.line1 # '148 Warner Road'
|
79
|
-
address.postal_code # 'E17 7EA'
|
102
|
+
address = result.value
|
103
|
+
address.city # 'London'
|
104
|
+
address.line1 # '148 Warner Road'
|
105
|
+
address.postal_code # 'E17 7EA'
|
80
106
|
```
|
81
107
|
|
82
108
|
## Development
|
data/ROADMAP.md
CHANGED
@@ -46,33 +46,79 @@ module Loqate
|
|
46
46
|
# @example Retrieving an address in the UK
|
47
47
|
# address = address_gateway.find(countries: 'GB', text: 'Scrubs Lane')
|
48
48
|
#
|
49
|
-
# @return [
|
49
|
+
# @return [Result] A result wrapping a list of addresses
|
50
50
|
#
|
51
51
|
def find(options)
|
52
52
|
response = client.get(FIND_ENDPOINT, options)
|
53
53
|
|
54
|
-
response.errors? &&
|
54
|
+
response.errors? && build_error_from(response.items.first) || build_addresses_from(response.items)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Returns the full address details based on the id.
|
58
58
|
#
|
59
59
|
# @param [Hash] options The options to retrieve the address.
|
60
60
|
# @option options [String] :id The Id from a Find method to retrieve the details for.
|
61
|
-
# @option options [String] :field_1_format a.
|
62
|
-
# @option options [String] :field_2_format
|
63
|
-
# @option options [String] :field_3_format
|
64
|
-
# @option options [String] :field_4_format
|
65
|
-
# @option options [String] :field_5_format
|
61
|
+
# @option options [String] :field_1_format Format of a custom address field.
|
62
|
+
# @option options [String] :field_2_format Format of a custom address field.
|
63
|
+
# @option options [String] :field_3_format Format of a custom address field.
|
64
|
+
# @option options [String] :field_4_format Format of a custom address field.
|
65
|
+
# @option options [String] :field_5_format Format of a custom address field.
|
66
66
|
#
|
67
67
|
# @example Retrieving the details of an address
|
68
68
|
# detailed_address = gateway.retrieve(id: 'GB|RM|ENG|6RB-NW10')
|
69
69
|
#
|
70
|
-
# @return [
|
70
|
+
# @return [Result] A result wrapping a detailed address
|
71
71
|
#
|
72
72
|
def retrieve(options)
|
73
73
|
response = client.get(RETRIEVE_ENDPOINT, options)
|
74
74
|
|
75
|
-
response.errors? &&
|
75
|
+
response.errors? && build_error_from(response.items.first) || build_detailed_address_from(response.items.first)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Find addresses and places.
|
79
|
+
#
|
80
|
+
# @param [Hash] options The options to find an address or a list of addresses.
|
81
|
+
# @option options [String] :text The search text to find. Ideally a postcode or the start of the address.
|
82
|
+
# @option options [String] countries A comma separated list of ISO 2 or 3 character country codes to limit
|
83
|
+
# the search within.
|
84
|
+
# @option options [String] origin A starting location for the search. This can be the name or ISO 2 or 3 character
|
85
|
+
# code of a country, WGS84 coordinates (comma separated) or IP address to search from.
|
86
|
+
# @option options [String] container A container for the search. This should only be another Id previously returned
|
87
|
+
# from this service when the Type of the result was not 'Address'.
|
88
|
+
# @option options [Integer] limit The maximum number of results to return.
|
89
|
+
# @option options [String] language The preferred language for results. This should be a 2 or 4 character language
|
90
|
+
# code e.g. (en, fr, en-gb, en-us etc).
|
91
|
+
#
|
92
|
+
# @example Retrieving addresses in the UK
|
93
|
+
# addresses = address_gateway.find!(countries: 'GB', text: 'Scrubs Lane')
|
94
|
+
#
|
95
|
+
# @raise [Error] If the result is not a success
|
96
|
+
#
|
97
|
+
# @return [Array<Address>] A list of addresses
|
98
|
+
#
|
99
|
+
def find!(options)
|
100
|
+
unwrap_result_or_raise { find(options) }
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the full address details based on the id.
|
104
|
+
#
|
105
|
+
# @param [Hash] options The options to retrieve the address.
|
106
|
+
# @option options [String] :id The Id from a Find method to retrieve the details for.
|
107
|
+
# @option options [String] :field_1_format Format of a custom address field.
|
108
|
+
# @option options [String] :field_2_format Format of a custom address field.
|
109
|
+
# @option options [String] :field_3_format Format of a custom address field.
|
110
|
+
# @option options [String] :field_4_format Format of a custom address field.
|
111
|
+
# @option options [String] :field_5_format Format of a custom address field.
|
112
|
+
#
|
113
|
+
# @example Retrieving the details of an address
|
114
|
+
# detailed_address = gateway.retrieve!(id: 'GB|RM|ENG|6RB-NW10')
|
115
|
+
#
|
116
|
+
# @raise [Error] If the result is not a success
|
117
|
+
#
|
118
|
+
# @return [DetailedAddress] A detailed address
|
119
|
+
#
|
120
|
+
def retrieve!(options)
|
121
|
+
unwrap_result_or_raise { retrieve(options) }
|
76
122
|
end
|
77
123
|
|
78
124
|
private
|
@@ -81,20 +127,20 @@ module Loqate
|
|
81
127
|
attr_reader :client, :mapper, :error_mapper
|
82
128
|
|
83
129
|
# @api private
|
84
|
-
def
|
85
|
-
|
86
|
-
Failure(
|
130
|
+
def build_error_from(item)
|
131
|
+
error = error_mapper.map_one(item)
|
132
|
+
Failure(error)
|
87
133
|
end
|
88
134
|
|
89
135
|
# @api private
|
90
|
-
def
|
136
|
+
def build_addresses_from(items)
|
91
137
|
address = mapper.map(items, Address)
|
92
138
|
Success(address)
|
93
139
|
end
|
94
140
|
|
95
141
|
# @api private
|
96
|
-
def
|
97
|
-
detailed_address = mapper.
|
142
|
+
def build_detailed_address_from(item)
|
143
|
+
detailed_address = mapper.map_one(item, DetailedAddress)
|
98
144
|
Success(detailed_address)
|
99
145
|
end
|
100
146
|
end
|
data/lib/loqate/error.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Loqate
|
2
2
|
# Generic error returned from an API call
|
3
|
-
class Error
|
3
|
+
class Error < StandardError
|
4
4
|
# Unique identifier for the error
|
5
5
|
#
|
6
6
|
# @return [Integer]
|
@@ -33,6 +33,8 @@ module Loqate
|
|
33
33
|
# @param [String] resolution How to solve the error
|
34
34
|
#
|
35
35
|
def initialize(id:, description:, cause:, resolution:)
|
36
|
+
super(description)
|
37
|
+
|
36
38
|
@id = id
|
37
39
|
@cause = cause
|
38
40
|
@resolution = resolution
|
@@ -14,12 +14,18 @@ module Loqate
|
|
14
14
|
# @return [Array<Error>] An array of errors
|
15
15
|
#
|
16
16
|
def map(items)
|
17
|
-
items.map
|
18
|
-
|
19
|
-
|
17
|
+
items.map { |item| map_one(item) }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Creates an error from an API response
|
21
|
+
#
|
22
|
+
# @return [Error] A concrete instance of Error
|
23
|
+
#
|
24
|
+
def map_one(item)
|
25
|
+
attributes = item.transform_keys { |attribute| Util.underscore(attribute) }
|
26
|
+
attributes[:id] = attributes.delete(:error).to_i
|
20
27
|
|
21
|
-
|
22
|
-
end
|
28
|
+
Loqate::Error.new(attributes)
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -15,10 +15,19 @@ module Loqate
|
|
15
15
|
# @return An array of objects of the given class
|
16
16
|
#
|
17
17
|
def map(items, object_class)
|
18
|
-
items.map
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
items.map { |item| map_one(item, object_class) }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a single object from an API response. The object will be an instance of +object_class+.
|
22
|
+
#
|
23
|
+
# @param [Class] object_class Class of the final object
|
24
|
+
# @param [Hash] item Attributes to instantiate the final object
|
25
|
+
#
|
26
|
+
# @return An object of the given class
|
27
|
+
#
|
28
|
+
def map_one(item, object_class)
|
29
|
+
attributes = item.transform_keys { |attribute| Util.underscore(attribute) }
|
30
|
+
object_class.new(attributes)
|
22
31
|
end
|
23
32
|
end
|
24
33
|
end
|
data/lib/loqate/result.rb
CHANGED
@@ -31,7 +31,7 @@ module Loqate
|
|
31
31
|
class Success < Result
|
32
32
|
# Always true
|
33
33
|
#
|
34
|
-
# @return [
|
34
|
+
# @return [TrueClass]
|
35
35
|
#
|
36
36
|
def success?
|
37
37
|
true
|
@@ -39,7 +39,7 @@ module Loqate
|
|
39
39
|
|
40
40
|
# Always false
|
41
41
|
#
|
42
|
-
# @return [
|
42
|
+
# @return [FalseClass]
|
43
43
|
#
|
44
44
|
def failure?
|
45
45
|
false
|
@@ -50,7 +50,7 @@ module Loqate
|
|
50
50
|
class Failure < Result
|
51
51
|
# Always false
|
52
52
|
#
|
53
|
-
# @return [
|
53
|
+
# @return [FalseClass]
|
54
54
|
#
|
55
55
|
def success?
|
56
56
|
false
|
@@ -58,11 +58,13 @@ module Loqate
|
|
58
58
|
|
59
59
|
# Always true
|
60
60
|
#
|
61
|
-
# @return [
|
61
|
+
# @return [TrueClass]
|
62
62
|
#
|
63
63
|
def failure?
|
64
64
|
true
|
65
65
|
end
|
66
|
+
|
67
|
+
alias error value
|
66
68
|
end
|
67
69
|
|
68
70
|
# Utility methods to conveniently return +Success+ or +Failure+ results.
|
@@ -97,6 +99,43 @@ module Loqate
|
|
97
99
|
def Failure(value, code: nil)
|
98
100
|
Failure.new(value: value, code: code)
|
99
101
|
end
|
102
|
+
|
103
|
+
# Unwraps a Result object. Returns the unwrapped value if the result is successful or raise
|
104
|
+
# an exception otherwise.
|
105
|
+
#
|
106
|
+
# @example When the given block returns a success
|
107
|
+
# class Action
|
108
|
+
# include Loqate::Result::Mixin
|
109
|
+
#
|
110
|
+
# def call
|
111
|
+
# Success('the value')
|
112
|
+
# end
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# operation.unwrap_result_or_raise { call } # => 'the value'
|
116
|
+
#
|
117
|
+
# @example When the given block returns a failure
|
118
|
+
# class Action
|
119
|
+
# include Loqate::Result::Mixin
|
120
|
+
#
|
121
|
+
# def call
|
122
|
+
# Failure(StandardError.new)
|
123
|
+
# end
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# operation.unwrap_result_or_raise { call } # => raises StandardError
|
127
|
+
#
|
128
|
+
# @raise [Object] If the result is not a success.
|
129
|
+
#
|
130
|
+
# @return [Object] The unwrapped object.
|
131
|
+
#
|
132
|
+
def unwrap_result_or_raise
|
133
|
+
result = yield
|
134
|
+
|
135
|
+
raise result.error if result.failure?
|
136
|
+
|
137
|
+
result.value
|
138
|
+
end
|
100
139
|
end
|
101
140
|
end
|
102
141
|
end
|
data/lib/loqate/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loqate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wilson Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10
|
11
|
+
date: 2018-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|