what3words 0.9.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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +94 -0
- data/Rakefile +9 -0
- data/lib/what3words.rb +4 -0
- data/lib/what3words/api.rb +143 -0
- data/lib/what3words/version.rb +3 -0
- data/spec/config.sample.yaml +4 -0
- data/spec/fixtures/LibertyTech.yaml +30 -0
- data/spec/integration/what3words_api_integration_spec.rb +106 -0
- data/spec/lib/what3words/api_spec.rb +155 -0
- data/spec/spec_helper.rb +15 -0
- data/what3words.gemspec +27 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a6a56c27bd81fb87fa8882399c6f47457bd9338
|
4
|
+
data.tar.gz: 041d1b4b0200929b7a55b924ad156393fb28f64d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef460b5136173a400cc5defda1fd47541c2087387b7be54443b375a3e907a701a7d1f52531980eb4bcd967fc3e66f4ad6e4e05a4f3727b57c5b8007c56d9a648
|
7
|
+
data.tar.gz: 17fd183c73e177e5cd9ba66e5029ce0979cd351009815e88800dfe42ebaeda4c22eb4606f16e0bbb311c2928698adc1c62b510670029d5c23ff50d6cfe26aaaa
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 What3Words Limited
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# What3Words
|
2
|
+
|
3
|
+
Use the What3Words API in your Ruby app (see http://what3words.com/api/reference)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem "what3words"
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install what3words
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Sign up for an API key at http://what3words.com/api/signup
|
22
|
+
|
23
|
+
See http://what3words.com/api/reference for all parameters that can be
|
24
|
+
passed to the API calls
|
25
|
+
|
26
|
+
Then:
|
27
|
+
|
28
|
+
what3words = What3Words::API.new(:key => "<your-api-key>")
|
29
|
+
|
30
|
+
Convert 3 words into GPS coordinates
|
31
|
+
|
32
|
+
what3words.words_to_position ["prom", "cape", "pump"]
|
33
|
+
# => [51.484463, -0.195405]
|
34
|
+
|
35
|
+
Convert OneWord to GPS coordinates
|
36
|
+
|
37
|
+
what3words.words_to_position "LibertyTech"
|
38
|
+
# => [51.512573,-0.144879]
|
39
|
+
|
40
|
+
Convert 3 words into GPS coordinates and return 3 words for the same position in a different language
|
41
|
+
|
42
|
+
what3words.words_to_position ["prom", "cape", "pump"], :full_response => true, :lang => "fr"
|
43
|
+
# => { :type => "3 words", :words => ["concevoir", "époque", "amasser"],
|
44
|
+
:position => [51.484463, -0.195405], :language: "fr" }
|
45
|
+
|
46
|
+
Supported keyword params for `words_to_position` call:
|
47
|
+
|
48
|
+
* `full_response` (default false) - return the original response from the API
|
49
|
+
* `language` (defaults to language of 3 words) - optional language code (only use this if you want to return 3 words in a different language to the language submitted)
|
50
|
+
* `oneword_password` (default nil) - password for OneWord, if private
|
51
|
+
* `corners` (default false) - "true" or "false" to return the coordinates of the w3w square. Will return an array with the southwest coordinates of the square and then the northeast coordinate
|
52
|
+
* `email` (default nil) - user email if required for private OneWord
|
53
|
+
* `password` (default nil) - user password if required for private OneWord
|
54
|
+
|
55
|
+
Convert position information to 3 words
|
56
|
+
|
57
|
+
what3words.position_to_words [51.484463, -0.195405]
|
58
|
+
# => ["prom", "cape", "pump"]
|
59
|
+
|
60
|
+
Convert position information to 3 words in a different language
|
61
|
+
|
62
|
+
what3words.position_to_words [51.484463, -0.195405], :lang => :fr
|
63
|
+
# => ["concevoir", "époque", "amasser"]
|
64
|
+
|
65
|
+
Supported keyword params for `position_to_words` call:
|
66
|
+
|
67
|
+
* `full_response` (default false) - return the original response from the API
|
68
|
+
* `language` (defaults to en) - optional language code
|
69
|
+
* `corners` (default false) - "true" or "false" to return the coordinates of the w3w square. Will return an array with the southwest coordinates of the square and then the northeast coordinate
|
70
|
+
|
71
|
+
Get list of available 3 word languages
|
72
|
+
|
73
|
+
what3words.languages
|
74
|
+
# => [ "en", "fr" ]
|
75
|
+
|
76
|
+
The `get_languages` call also returns the full response from the API
|
77
|
+
|
78
|
+
what3words.languages :full_response => true
|
79
|
+
# => {:languages=>[{:code=>"de", :name_display=>"Deutsch"}, {:code=>"en", :name_display=>"English"}, ... ]}
|
80
|
+
|
81
|
+
See http://what3words.com/api/reference for the original API call documentation
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it ( http://github.com/<my-github-username>/what3words and click "Fork" )
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
90
|
+
|
91
|
+
### Testing
|
92
|
+
|
93
|
+
1. Unit specs require no set up. Look in `spec/what3words`
|
94
|
+
2. Integration specs that hit the API directly are in spec/integration, and need the file spec/config.yaml to be filled in (using spec/config.sample.yaml as a template) with valid details. It is only needed for testing private OneWord functionality
|
data/Rakefile
ADDED
data/lib/what3words.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rest-client"
|
4
|
+
|
5
|
+
module What3Words
|
6
|
+
class API
|
7
|
+
|
8
|
+
class Error < RuntimeError; end
|
9
|
+
class ResponseError < Error; end
|
10
|
+
class WordError < Error; end
|
11
|
+
|
12
|
+
REGEX_3_WORDS = /^\p{L}+\.\p{L}+\.\p{L}+$/u
|
13
|
+
REGEX_ONE_WORD = /^\*[\p{L}\-0-9]{6,31}$/u
|
14
|
+
|
15
|
+
ENDPOINTS = {
|
16
|
+
:words_to_position => "w3w",
|
17
|
+
:position_to_words => "position",
|
18
|
+
:languages => "get-languages"
|
19
|
+
}
|
20
|
+
|
21
|
+
def initialize(params)
|
22
|
+
@key = params.fetch(:key)
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :key
|
26
|
+
|
27
|
+
def words_to_position(words, params = {})
|
28
|
+
words_string = get_words_string words
|
29
|
+
request_params = assemble_w2p_request_params(words_string, params)
|
30
|
+
needs_ssl = needs_ssl?(request_params)
|
31
|
+
response = request! :words_to_position, request_params, needs_ssl
|
32
|
+
make_response(response, :position, params[:full_response])
|
33
|
+
end
|
34
|
+
|
35
|
+
def position_to_words(position, params = {})
|
36
|
+
request_params = assemble_p2w_request_params(position, params)
|
37
|
+
response = request! :position_to_words, request_params
|
38
|
+
make_response(response, :words, params[:full_response])
|
39
|
+
end
|
40
|
+
|
41
|
+
def languages(params = {})
|
42
|
+
request_params = assemble_common_request_params(params)
|
43
|
+
response = request! :languages, request_params
|
44
|
+
if params[:full_response]
|
45
|
+
response
|
46
|
+
else
|
47
|
+
response[:languages].map {|i| i[:code]}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def assemble_common_request_params(params)
|
52
|
+
h = {:key => key}
|
53
|
+
h[:lang] = params[:language] if params[:language]
|
54
|
+
h[:corners] = true if params[:corners]
|
55
|
+
h
|
56
|
+
end
|
57
|
+
private :assemble_common_request_params
|
58
|
+
|
59
|
+
def assemble_w2p_request_params(words_string, params)
|
60
|
+
h = {:string => words_string}
|
61
|
+
h[:"oneword-password"] = params[:oneword_password] if params[:oneword_password]
|
62
|
+
h[:email] = params[:email] if params[:email]
|
63
|
+
h[:password] = params[:password] if params[:password]
|
64
|
+
h.merge(assemble_common_request_params(params))
|
65
|
+
end
|
66
|
+
private :assemble_w2p_request_params
|
67
|
+
|
68
|
+
def assemble_p2w_request_params(position, params)
|
69
|
+
h = {:position => position.join(",")}
|
70
|
+
h.merge(assemble_common_request_params(params))
|
71
|
+
end
|
72
|
+
private :assemble_p2w_request_params
|
73
|
+
|
74
|
+
def make_response(response, part_response_key, need_full_response)
|
75
|
+
if need_full_response
|
76
|
+
response
|
77
|
+
else
|
78
|
+
response[part_response_key]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
private :make_response
|
82
|
+
|
83
|
+
def request!(endpoint_name, params, needs_ssl = false)
|
84
|
+
response = RestClient.post endpoint(endpoint_name, needs_ssl), params
|
85
|
+
response = JSON.parse(response.body)
|
86
|
+
if response["error"].to_s.strip != ""
|
87
|
+
raise ResponseError, "#{response["error"]}: #{response["message"]}"
|
88
|
+
end
|
89
|
+
deep_symbolize_keys(response)
|
90
|
+
end
|
91
|
+
private :request!
|
92
|
+
|
93
|
+
def get_words_string(words)
|
94
|
+
if words.respond_to? :to_str
|
95
|
+
w = words
|
96
|
+
elsif words.respond_to? :join
|
97
|
+
w = words.join(".")
|
98
|
+
else
|
99
|
+
raise Error, "Cannot get words string for #{words.inspect}"
|
100
|
+
end
|
101
|
+
check_words w
|
102
|
+
end
|
103
|
+
private :get_words_string
|
104
|
+
|
105
|
+
def check_words(words)
|
106
|
+
unless REGEX_3_WORDS.match(words) or REGEX_ONE_WORD.match(words)
|
107
|
+
raise WordError, "#{words} is not valid 3 words or OneWord"
|
108
|
+
end
|
109
|
+
return words
|
110
|
+
end
|
111
|
+
private :check_words
|
112
|
+
|
113
|
+
def deep_symbolize_keys(i)
|
114
|
+
if i.kind_of? Hash
|
115
|
+
ni = {}
|
116
|
+
i.each {|k,v| ni[k.respond_to?(:to_sym) ? k.to_sym : k] = deep_symbolize_keys(v) }
|
117
|
+
elsif i.kind_of? Array
|
118
|
+
ni = i.map(&method(:deep_symbolize_keys))
|
119
|
+
else
|
120
|
+
ni = i
|
121
|
+
end
|
122
|
+
|
123
|
+
ni
|
124
|
+
end
|
125
|
+
|
126
|
+
def base_url(needs_ssl = false)
|
127
|
+
protocol = needs_ssl ? "https" : "http"
|
128
|
+
"#{protocol}://api.what3words.com/"
|
129
|
+
end
|
130
|
+
private :base_url
|
131
|
+
|
132
|
+
def endpoint(name, needs_ssl)
|
133
|
+
return base_url(needs_ssl) + ENDPOINTS.fetch(name)
|
134
|
+
end
|
135
|
+
|
136
|
+
def needs_ssl?(params)
|
137
|
+
(params.has_key?(:email) and params.has_key?(:password)) or
|
138
|
+
params.has_key?(:"oneword-password")
|
139
|
+
end
|
140
|
+
private :needs_ssl?
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
:type: OneWord
|
3
|
+
:oneword: "*LibertyTech"
|
4
|
+
:position:
|
5
|
+
- 51.512573
|
6
|
+
- -0.144879
|
7
|
+
:info:
|
8
|
+
:name: Liberty Tech office
|
9
|
+
:address1: 124 New Bond Street
|
10
|
+
:address2: ''
|
11
|
+
:address3: ''
|
12
|
+
:city: London
|
13
|
+
:county: ''
|
14
|
+
:postcode: W1S 1DX
|
15
|
+
:country_id: '0'
|
16
|
+
:website: http://libertytech.com
|
17
|
+
:email: enquiries@libertytech.com
|
18
|
+
:telephone: 0207 493 8140
|
19
|
+
:delivery_notes: Ring bell number 7, we're on the top floor.
|
20
|
+
:notes: Top floor, lots of stairs!
|
21
|
+
:social_facebook: http://www.facebook.com/libertytech
|
22
|
+
:social_twitter: http://www.twitter.com/libertytech
|
23
|
+
:social_google: ''
|
24
|
+
:social_linkedin: ''
|
25
|
+
:social_instagram: ''
|
26
|
+
:words:
|
27
|
+
- boxer
|
28
|
+
- overnight
|
29
|
+
- crate
|
30
|
+
:language: en
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
describe What3Words::API, "integration", :integration => true do
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
WebMock.allow_net_connect!
|
10
|
+
end
|
11
|
+
|
12
|
+
let!(:config) do
|
13
|
+
file = "spec/config.yaml"
|
14
|
+
if ! File.exist? file
|
15
|
+
raise "Add a file #{file} (use spec/config.sample.yaml as a template) with correct values to run integration specs"
|
16
|
+
end
|
17
|
+
YAML.load_file file
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:api_key) { config["api_key"] }
|
21
|
+
let(:private_one_word) { config["private_one_word"] }
|
22
|
+
let(:private_one_word_password) { config["private_one_word_password"] }
|
23
|
+
|
24
|
+
let(:w3w) { described_class.new(:key => api_key) }
|
25
|
+
|
26
|
+
it "returns errors from API" do
|
27
|
+
badw3w = described_class.new(:key => "")
|
28
|
+
expect { badw3w.words_to_position ["prom", "cape", "pump"] }.
|
29
|
+
to raise_error described_class::ResponseError
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "getting position" do
|
33
|
+
|
34
|
+
it "works with 3 words in array" do
|
35
|
+
result = w3w.words_to_position ["prom", "cape", "pump"]
|
36
|
+
expect(result).to eq [51.484463, -0.195405]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "works with string of 3 words separated by '.'" do
|
40
|
+
result = w3w.words_to_position "prom.cape.pump"
|
41
|
+
expect(result).to eq [51.484463, -0.195405]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "gets full response from API" do
|
45
|
+
result = w3w.words_to_position ["prom", "cape", "pump"], :full_response => true
|
46
|
+
expect(result).to eq( :type => "3 words", :words => ["prom", "cape", "pump"],
|
47
|
+
:position => [51.484463, -0.195405], :language => "en" )
|
48
|
+
end
|
49
|
+
|
50
|
+
it "sends all possible parameters for 3 words" do
|
51
|
+
result = w3w.words_to_position ["prom", "cape", "pump"], :full_response => true,
|
52
|
+
:language => "fr", :corners => true
|
53
|
+
expect(result).to eq(
|
54
|
+
:type => "3 words", :words => ["concevoir", "époque", "amasser"],
|
55
|
+
:position => [51.484463, -0.195405], :language => "fr",
|
56
|
+
:corners => [[51.484449, -0.195426], [51.484476, -0.195383]])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "checks 3 words format matches standard regex" do
|
60
|
+
expect { w3w.words_to_position ["1", "cape", "pump"] }.
|
61
|
+
to raise_error described_class::WordError
|
62
|
+
|
63
|
+
expect { w3w.words_to_position "1.cape.pump" }.
|
64
|
+
to raise_error described_class::WordError
|
65
|
+
end
|
66
|
+
|
67
|
+
it "checks OneWord format matches standard regex" do
|
68
|
+
expect { w3w.words_to_position "123foo" }.
|
69
|
+
to raise_error described_class::WordError
|
70
|
+
end
|
71
|
+
|
72
|
+
it "works with a OneWord" do
|
73
|
+
result = w3w.words_to_position "*LibertyTech"
|
74
|
+
expect(result).to eq [51.512573, -0.144879]
|
75
|
+
end
|
76
|
+
|
77
|
+
it "disallows access to protected OneWord" do
|
78
|
+
expect { w3w.words_to_position private_one_word }.
|
79
|
+
to raise_error described_class::ResponseError
|
80
|
+
end
|
81
|
+
|
82
|
+
it "accesses OneWord protected by oneword password" do
|
83
|
+
expect(w3w.words_to_position private_one_word,
|
84
|
+
:oneword_password => private_one_word_password).
|
85
|
+
to eq [29.567043, 106.587865]
|
86
|
+
end
|
87
|
+
|
88
|
+
xit "accesses OneWord protected by user credentials (username & password)"
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "gets 3 words" do
|
92
|
+
it "from position" do
|
93
|
+
expect(w3w.position_to_words [29.567041, 106.587875], :language => "fr").
|
94
|
+
to eq ["courgette", "approbateur", "infrason"]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "gets languages" do
|
99
|
+
expect(w3w.languages).to include "en"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "'s deep_symbolize_keys helper works" do
|
103
|
+
expect(w3w.deep_symbolize_keys("foo" => {"bar" => true})).
|
104
|
+
to eq(:foo => {:bar => true})
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe What3Words::API do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
WebMock.disable_net_connect!
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:api_key) { "APIkey" }
|
12
|
+
|
13
|
+
let(:w3w) { described_class.new(:key => api_key) }
|
14
|
+
|
15
|
+
it "returns errors from API" do
|
16
|
+
stub_request(:post, "http://api.what3words.com/w3w").
|
17
|
+
to_return(:status => 200, :body => '{"error": "XX", "message": "msg"}')
|
18
|
+
|
19
|
+
expect { w3w.words_to_position ["prom", "cape", "pump"] }.
|
20
|
+
to raise_error described_class::ResponseError
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "getting position" do
|
24
|
+
|
25
|
+
def stub!(request_body, response_body = {}, protocol = "http")
|
26
|
+
r = stub_request(:post, "#{protocol}://api.what3words.com/w3w").
|
27
|
+
with(:body => request_body).
|
28
|
+
to_return(:status => 200, :body => response_body.to_json)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sends 3 words given as array" do
|
32
|
+
stub! hash_including(:string => "a.b.c")
|
33
|
+
result = w3w.words_to_position ["a", "b", "c"]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "sends 3 words given as string" do
|
37
|
+
stub! hash_including(:string => "a.b.c")
|
38
|
+
result = w3w.words_to_position "a.b.c"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "extracts position from response" do
|
42
|
+
stub! hash_including(:string => "a.b.c"), {"position" => [1, 2]}
|
43
|
+
result = w3w.words_to_position "a.b.c"
|
44
|
+
expect(result).to eq [1, 2]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns full response instead of just coords" do
|
48
|
+
stub!(hash_including(:string => "a.b.c"),
|
49
|
+
{"full" => true})
|
50
|
+
result = w3w.words_to_position "a.b.c", :full_response => true
|
51
|
+
expect(result).to eq :full => true
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sends lang option" do
|
55
|
+
stub!(hash_including(:string => "a.b.c", :lang => "fr"))
|
56
|
+
w3w.words_to_position "a.b.c", :language => "fr"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "sends corners option" do
|
60
|
+
stub!(hash_including(:string => "a.b.c", :corners => "true"))
|
61
|
+
w3w.words_to_position "a.b.c", :corners => true
|
62
|
+
end
|
63
|
+
|
64
|
+
it "uses https for private OneWord with oneword-password" do
|
65
|
+
stub!(hash_including(:string => "a.b.c", :"oneword-password" => "oopw"),
|
66
|
+
{}, "https")
|
67
|
+
w3w.words_to_position "a.b.c", :oneword_password => "oopw"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "uses https for private OneWord with email / password" do
|
71
|
+
stub!(hash_including(:string => "a.b.c", :email => "em", :password => "pw"),
|
72
|
+
{}, "https")
|
73
|
+
w3w.words_to_position "a.b.c", :email => "em", :password => "pw"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "parses response errors" do
|
77
|
+
stub! hash_including(:string => "a.b.c"), {:error => "xx", :message => "msg"}
|
78
|
+
expect { w3w.words_to_position "a.b.c" }.
|
79
|
+
to raise_error described_class::ResponseError, "xx: msg"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "checks 3 words as array matches standard regex" do
|
83
|
+
stub! anything
|
84
|
+
expect { w3w.words_to_position ["1", "cape", "pump"] }.
|
85
|
+
to raise_error described_class::WordError
|
86
|
+
end
|
87
|
+
|
88
|
+
it "checks 3 words as string matches standard regex" do
|
89
|
+
stub! anything
|
90
|
+
expect { w3w.words_to_position "1.cape.pump" }.
|
91
|
+
to raise_error described_class::WordError
|
92
|
+
end
|
93
|
+
|
94
|
+
it "checks OneWord format matches standard regex" do
|
95
|
+
stub! anything
|
96
|
+
expect { w3w.words_to_position "123foo" }.
|
97
|
+
to raise_error described_class::WordError
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "gets 3 words" do
|
102
|
+
|
103
|
+
def stub!(request_body, response_body = {})
|
104
|
+
r = stub_request(:post, "http://api.what3words.com/position").
|
105
|
+
with(:body => request_body).
|
106
|
+
to_return(:status => 200, :body => response_body.to_json)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "extracts 3 words from response" do
|
110
|
+
stub! hash_including(:position => "1,2"), {:words => ["a", "b", "c"]}
|
111
|
+
expect(w3w.position_to_words([1, 2])).to eq ["a", "b", "c"]
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns full response if asked" do
|
115
|
+
stub! hash_including(:position => "1,2"), {:full => "1"}
|
116
|
+
expect(w3w.position_to_words([1, 2], :full_response => true)).to eq(:full => "1")
|
117
|
+
end
|
118
|
+
|
119
|
+
it "sends lang option" do
|
120
|
+
stub!(hash_including(:position => "1,2", :lang => "fr"))
|
121
|
+
w3w.position_to_words([1, 2], :language => "fr")
|
122
|
+
end
|
123
|
+
|
124
|
+
it "sends corners option" do
|
125
|
+
stub!(hash_including(:position => "1,2", :corners => "true"))
|
126
|
+
w3w.position_to_words([1, 2], :corners => true)
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "getting available languages" do
|
132
|
+
|
133
|
+
def stub!(request_body, response_body = {})
|
134
|
+
r = stub_request(:post, "http://api.what3words.com/get-languages").
|
135
|
+
with(:body => request_body).
|
136
|
+
to_return(:status => 200, :body => response_body.to_json)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "gets list of codes" do
|
140
|
+
stub! anything, {:languages => [{:code => "l1"}, {:code => "l2"}]}
|
141
|
+
expect(w3w.languages). to eq ["l1", "l2"]
|
142
|
+
end
|
143
|
+
|
144
|
+
it "gets full response" do
|
145
|
+
stub! anything, {:languages => [{:code => "l1"}, {:code => "l2"}]}
|
146
|
+
expect(w3w.languages :full_response => true).
|
147
|
+
to eq(:languages => [{:code => "l1"}, {:code => "l2"}])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it "'s deep_symbolize_keys helper works" do
|
152
|
+
expect(w3w.deep_symbolize_keys("foo" => {"bar" => 1, "baz" => [{"quux" => "www"}]})).
|
153
|
+
to eq(:foo => {:bar => 1, :baz => [{:quux => "www"}]})
|
154
|
+
end
|
155
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
require "webmock/rspec"
|
6
|
+
|
7
|
+
require "what3words"
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.filter_run_excluding :integration => true
|
11
|
+
|
12
|
+
config.before(:all) do
|
13
|
+
WebMock.disable_net_connect!
|
14
|
+
end
|
15
|
+
end
|
data/what3words.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "what3words/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "what3words"
|
9
|
+
spec.version = What3Words::VERSION
|
10
|
+
spec.authors = ["Asfand Yar Qazi"]
|
11
|
+
spec.email = ["ayqazi@gmail.com"]
|
12
|
+
spec.summary = "Query the what3words API in Ruby"
|
13
|
+
spec.homepage = "http://rubygems.org/gems/what3words"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rest-client"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "webmock"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: what3words
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Asfand Yar Qazi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- ayqazi@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- lib/what3words.rb
|
96
|
+
- lib/what3words/api.rb
|
97
|
+
- lib/what3words/version.rb
|
98
|
+
- spec/config.sample.yaml
|
99
|
+
- spec/fixtures/LibertyTech.yaml
|
100
|
+
- spec/integration/what3words_api_integration_spec.rb
|
101
|
+
- spec/lib/what3words/api_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- what3words.gemspec
|
104
|
+
homepage: http://rubygems.org/gems/what3words
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.2.2
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Query the what3words API in Ruby
|
128
|
+
test_files:
|
129
|
+
- spec/config.sample.yaml
|
130
|
+
- spec/fixtures/LibertyTech.yaml
|
131
|
+
- spec/integration/what3words_api_integration_spec.rb
|
132
|
+
- spec/lib/what3words/api_spec.rb
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
has_rdoc:
|