ideal_postcodes 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/README.md +295 -42
  4. data/Rakefile +13 -6
  5. data/ideal-postcodes-ruby.gemspec +9 -10
  6. data/lib/idealpostcodes.rb +30 -9
  7. data/lib/idealpostcodes/address.rb +31 -0
  8. data/lib/idealpostcodes/key.rb +13 -0
  9. data/lib/idealpostcodes/postcode.rb +11 -24
  10. data/lib/idealpostcodes/util.rb +2 -2
  11. data/lib/idealpostcodes/version.rb +1 -1
  12. data/spec/addresses_spec.rb +68 -0
  13. data/spec/idealpostcodes_spec.rb +56 -0
  14. data/spec/keys_spec.rb +25 -0
  15. data/spec/postcodes_spec.rb +66 -0
  16. data/spec/spec_helper.rb +65 -0
  17. data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_invalid_key.yml +42 -0
  18. data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_limit_breached.yml +42 -0
  19. data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_no_lookups_remaining.yml +42 -0
  20. data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_returns_an_address_for_a_valid_UDPRN.yml +74 -0
  21. data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_returns_nil_for_an_invalid_UDPRN.yml +42 -0
  22. data/spec/vcr_cassettes/IdealPostcodes_Address_search_is_sensitive_to_limit.yml +81 -0
  23. data/spec/vcr_cassettes/IdealPostcodes_Address_search_is_sensitive_to_page.yml +369 -0
  24. data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_invalid_key.yml +42 -0
  25. data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_limit_breached.yml +42 -0
  26. data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_no_lookups_remaining.yml +42 -0
  27. data/spec/vcr_cassettes/IdealPostcodes_Address_search_returns_results_in_a_SearchResult_object.yml +273 -0
  28. data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_details_returns_key_details.yml +62 -0
  29. data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_returns_the_availability_status_of_a_key_false_key_.yml +45 -0
  30. data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_returns_the_availability_status_of_a_key_true_key_.yml +45 -0
  31. data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_is_sensitive_to_limit_parameter.yml +52 -0
  32. data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_is_sensitive_to_radius_parament.yml +133 -0
  33. data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_returns_an_array_of_postcodes_and_locations.yml +84 -0
  34. data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_returns_an_empty_array_if_no_results_are_found.yml +43 -0
  35. data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_invalid_key.yml +42 -0
  36. data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_key_has_run_out_of_balance.yml +42 -0
  37. data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_limit_has_been_reached.yml +42 -0
  38. data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_returns_a_list_of_addresses_for_a_postcode.yml +268 -0
  39. data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_returns_an_empty_array_if_postcode_does_not_exist.yml +42 -0
  40. data/spec/vcr_cassettes/IdealPostcodes_key_available_returns_false_if_key_is_unavailable.yml +45 -0
  41. data/spec/vcr_cassettes/IdealPostcodes_key_available_returns_true_if_key_is_available.yml +45 -0
  42. data/spec/vcr_cassettes/IdealPostcodes_key_details_raises_an_exception_if_no_secret_is_provided.yml +45 -0
  43. data/spec/vcr_cassettes/IdealPostcodes_key_details_returns_key_information.yml +62 -0
  44. data/spec/vcr_cassettes/IdealPostcodes_request_generates_a_HTTP_request.yml +268 -0
  45. data/spec/vcr_cassettes/IdealPostcodes_request_raises_authentication_error_if_invalid_key_is_provided.yml +42 -0
  46. data/spec/vcr_cassettes/IdealPostcodes_request_raises_limit_reached_error_if_a_limit_has_been_breached.yml +42 -0
  47. data/spec/vcr_cassettes/IdealPostcodes_request_raises_token_exhausted_error_if_key_balance_is_depleted.yml +42 -0
  48. metadata +96 -39
  49. data/test/test_helper.rb +0 -77
  50. data/test/test_ideal_postcodes.rb +0 -78
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c34b866375b1eb59033c3c9f4139ed49e1f91bd1
4
- data.tar.gz: 48da9070ca6d8cb2af643879f1837d697c3a89af
3
+ metadata.gz: be3239f59167b00d3b406e3c6a45365dc7e646b4
4
+ data.tar.gz: 285c68271eb9fb98011e575d1bc8446c3b892e40
5
5
  SHA512:
6
- metadata.gz: 11b659c4e56fb6188874468b2c2e8363eb7088ca13672540ced297f762f5a096f53f49f51d6b2144bc6af0a3006596e2be9e550291aff14ef15d28e6ea2e04ce
7
- data.tar.gz: b64a4e49837cfad1410b382600f2af5eff9ee1fbea7a833689f1b34c021c10a75154f445e6363c0e6cc9f50ce79e2082af292f3c995b084b670301b9b12b3195
6
+ metadata.gz: bd635f4ad102fc61785c3d8d7637f2d7c5f11bd348e2ad9a14ad2f8d3222e4bd44914e6b784512ff819f8c97ec8e87df6151f7c0ba63d6c1d5bceeb6fdf71ab7
7
+ data.tar.gz: b596444fc91dea8b680a9681950f0c2a7f0ca712f0a879290b37c4f3a8ae2c1d7c86e2a883dcc9bd120f5cb2ecf561b8f8c721cd3ccc640984be274a0e3bd32c
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - jruby-19mode
data/README.md CHANGED
@@ -1,57 +1,93 @@
1
- # Ideal-Postcodes.co.uk API Wrapper
1
+ # Ideal Postcodes Ruby Library [![Build Status](https://travis-ci.org/ideal-postcodes/ideal-postcodes-ruby.png)](https://travis-ci.org/ideal-postcodes/ideal-postcodes-ruby)
2
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.
3
+ Ideal Postcodes is a simple JSON API to query UK postcodes and addresses. Find out more at [Ideal-Postcodes.co.uk](https://ideal-postcodes.co.uk/)
4
+
5
+ Our API uses Royal Mail's Postcode Address File and is updated daily. Each method incurs a small charge (typically 2p) - free methods are labelled as such and are based on open data sources.
4
6
 
5
7
  ## Getting Started
6
8
 
7
- __Install it__
9
+ **Install**
8
10
 
9
11
  ```bash
10
12
  gem install ideal_postcodes
11
13
  ```
12
14
 
13
- Alternatively for rails, include this in your gemfile and bundle install
15
+ Alternatively, include this in your gemfile and bundle install
14
16
 
15
17
  ```ruby
16
18
  gem 'ideal_postcodes'
17
19
  ```
18
20
 
19
- __Get an API Key__
21
+ **Create a Key**
20
22
 
21
- Get a key at [Ideal-Postcodes.co.uk](https://ideal-postcodes.co.uk). Try out the service with the test postcode 'ID1 1QD'
23
+ Sign up at [Ideal-Postcodes.co.uk](https://ideal-postcodes.co.uk) and create a key.
22
24
 
23
- __Configuration__
25
+ **Configure**
24
26
 
25
- In order to perform lookups, you'll need to configure the gem by passing in your api key by doing the following:
27
+ Drop in your key when using the library.
26
28
 
27
29
  ```ruby
28
- require 'ideal_postcodes'
29
-
30
30
  IdealPostcodes.api_key = "your_key_goes_here"
31
31
  ```
32
32
 
33
- **For Rails**, the best way to do this is create a file in your initializers folder and drop in your key with this line of code:
33
+ ## Error Handling
34
+
35
+ It's important that you lookout for common exceptions when interacting with the API. The most common exceptions can be caught as shown below.
34
36
 
35
37
  ```ruby
36
- IdealPostcodes.api_key = "<your key goes here>"
38
+ begin
39
+ IdealPostcodes::Postcode.lookup "ID1 1QD"
40
+ rescue IdealPostcodes::AuthenticationError => e
41
+ # Invalid API Key
42
+ rescue IdealPostcodes::TokenExhaustedError => e
43
+ # Token has run out of lookups
44
+ rescue IdealPostcodes::LimitReachedError => e
45
+ # One of your predefinied limits has been reached
46
+ rescue IdealPostcodes::IdealPostcodesError => e
47
+ # API Error
48
+ rescue => e
49
+ # An unexpected error
50
+ end
51
+ ```
52
+
53
+ Possible errors to look out for are listed in the [documentation](https://ideal-postcodes.co.uk/documentatpion/response-codes).
54
+
55
+ ## Methods
56
+
57
+ The client provides a number of methods to allow you to get specific jobs done quickly and easily. These methods are listed below.
58
+
59
+
60
+
61
+
62
+ ## Get all addresses for a postcode [(docs)](https://ideal-postcodes.co.uk/documentation/postcodes#postcode)
63
+
64
+ ```
65
+ IdealPostcodes::Postcode.lookup postcode
37
66
  ```
38
67
 
39
- __Usage__
68
+ Returns an array of addresses representing all addresses at the specified postcode.
40
69
 
41
- Simply call #lookup class method on IdealPostcodes::Postcode. This will return a Postcode object containing the complete list of addresses if the postcode exists.
70
+ **Arguments**
71
+
72
+ - `postcode` (string). The postcode you want to lookup, case and space insensitive.
73
+
74
+ **Returns**
75
+
76
+ An array of hashes which represent each address at the postcode. Returns an empty array for an invalid postcode.
77
+
78
+ **Example**
42
79
 
43
80
  ```ruby
44
- postcode = IdealPostcodes::Postcode.lookup "ID1 1QD"
81
+ addresses = IdealPostcodes::Postcode.lookup "ID1 1QD"
45
82
 
46
- if postcode.empty?
83
+ if addresses.empty?
47
84
  puts "Your postcode doesn't have a match"
48
85
  else
49
- postcode.addresses
86
+ puts addresses
50
87
  end
51
88
 
52
- # postcode.addresses =>
53
- #
54
- # [
89
+ # addresses =>
90
+ #[
55
91
  # {
56
92
  # :postcode => "ID1 1QD",
57
93
  # :post_town => "LONDON",
@@ -61,44 +97,261 @@ end
61
97
  # :organisation_name => "",
62
98
  # :building_name => "Kingsley Hall",
63
99
  # :udprn => 12345678
64
- # }, ... and so on
100
+ # ... and so on
65
101
  ```
66
102
 
67
- __Exceptions__
103
+ **Notes**
104
+
105
+ **Data Source:** Royal Mail Postcode Address File. Ordnance Survey.
106
+
107
+ Use the postcode "ID1 1QD" to test this method for free. The complete list of test postcodes is available in the [documentation](https://ideal-postcodes/documentation/postcodes).
108
+
109
+
68
110
 
69
- The wrapper will raise an exception for anything other than a 200 response or an empty 404 response (which means no addresses at postcode).
111
+
112
+ ## Search for an address [(docs)](https://ideal-postcodes.co.uk/documentation/addresses#query)
113
+
114
+ Perform a search for addresses which match your search term.
115
+
116
+ **Arguments**
117
+
118
+ - `search_term` (string). The address you wish to search for
119
+ - `options` (hash, optional). Customise your search.
120
+ - `limit` (number). The maximum number of returned results per page
121
+ - `page` (number). Page of results to return (starts at page 0)
122
+
123
+ **Returns**
124
+
125
+ Returns a search result object with the following attributes.
126
+
127
+ - `addresses` (Array). An array of hashes which represent each address at the postcode. The array is ordered by how close the search term and address match.
128
+ - `limit` (Number). The maximum number of returned results per page.
129
+ - `page` (Number). The returned page of results.
130
+
131
+
132
+ **Example**
70
133
 
71
134
  ```ruby
72
- begin
73
- IdealPostcodes::Postcode.lookup "ID1 1QD"
74
- rescue IdealPostcodes::AuthenticationError => e
75
- # Invalid API Key
76
- rescue IdealPostcodes::TokenExhaustedError => e
77
- # Token has run out of lookups
78
- rescue IdealPostcodes::LimitReachedError => e
79
- # One of your predefinied limits has been reached
80
- rescue IdealPostcodes::IdealPostcodesError => e
81
- # API Error
82
- rescue => e
83
- # An unexpected error
84
- end
135
+ IdealPostcodes::Address.search "10 Downing Street London"
136
+
137
+ r.limit # => 10
138
+ r.page # => 0
139
+ r.addresses
140
+
141
+ #[
142
+ # {
143
+ # :line_1=>"Prime Minister & First Lord Of The Treasury",
144
+ # :line_2=>"10 Downing Street",
145
+ # :line_3=>"",
146
+ # :post_town=>"LONDON",
147
+ # :postcode=>"SW1A 2AA",
148
+ # :organisation_name=>"Prime Minister & First Lord Of The Treasury",
149
+ # :premise=>"10",
150
+ # :latitude=>51.5035398826274
151
+ # :longitude=>-0.127695242183412,
152
+ # :thoroughfare=>"Downing Street",
153
+ # :district=>"Westminster",
154
+ # :ward=>"St James's",
155
+ # :building_number=>"10",
156
+ # :udprn=>23747771,
157
+ # ... and so on
85
158
  ```
86
159
 
87
- ## Registering
160
+ **Notes**
161
+
162
+ Data source: Royal Mail Postcode Address File, Ordnance Survey.
88
163
 
89
- 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.
164
+ Use the address "ID1 1QD" to test integration for free. The complete list of test methods is available in the [documentation](https://ideal-postcodes/documentation/addresses).
165
+
166
+
167
+
168
+
169
+ ## Get nearby postcode for a given geolocation [(docs)](https://ideal-postcodes.co.uk/documentation/postcodes#lonlat)
170
+
171
+ Retrieve the nearest postcodes for a given geolocation. Free to use.
172
+
173
+ ```ruby
174
+ IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat
175
+ ```
90
176
 
91
- We charge _2p_ per [external](https://ideal-postcodes.co.uk/termsandconditions#external) lookup.
177
+ **Arguments**
92
178
 
93
- ## Documentation
179
+ - `location` (Hash)
180
+ - `longitude` (number, required)
181
+ - `latitude` (number, required)
182
+ - `limit` (number, optional) Maximum number of results to return
183
+ - `radius` (number, optional) search radius (in metres)
94
184
 
95
- More documentation can be found [here](https://ideal-postcodes.co.uk/documentation/ruby-wrapper)
185
+ **Returns**
186
+
187
+ An array of hashes which represent the nearest postcodes to the specified location. Ordered by distance from location.
188
+
189
+ **Example**
190
+
191
+ ```ruby
192
+ postcodes = IdealPostcodes::Postcode.find_by_location longitude: 0.629834, latitude: 51.79232
193
+
194
+ # postcodes =>
195
+ #[
196
+ # {
197
+ # :postcode=>"CM8 1EF",
198
+ # :northings=>213679,
199
+ # :eastings=>581461,
200
+ # :longitude=>0.629834723775309,
201
+ # :latitude=>51.7923246977375,
202
+ # :distance=>0.52506633},
203
+ # {
204
+ # :postcode=>"CM8 1EU",
205
+ # :northings=>213650,
206
+ # :eastings=>581507,
207
+ # :longitude=>0.630485817275861,
208
+ # :latitude=>51.7920493205979,
209
+ # :distance=>54.12525282
210
+ # },
211
+ ```
212
+
213
+ **Notes**
214
+
215
+ Data source: Ordnance Survey. Free to use.
216
+
217
+
218
+
219
+ ## Retrieve an address using UDPRN [(docs)](https://ideal-postcodes.co.uk/documentation/addresses#address)
220
+
221
+ Retrieve the specific address for a specific UDPRN.
222
+
223
+ ```ruby
224
+ IdealPostcodes::Address.lookup udprn
225
+ ```
226
+
227
+ **Arguments**
228
+
229
+ - `udprn` (string | number). A number which uniquely identifies the address.
230
+
231
+ **Returns**
232
+
233
+ Returns a hash representing the matching address. Returns `nil` if no matching address is found.
234
+
235
+ **Example**
236
+
237
+ ```ruby
238
+ IdealPostcodes::Address.lookup 23747771
239
+
240
+ #{
241
+ # :line_1=>"Prime Minister & First Lord Of The Treasury",
242
+ # :line_2=>"10 Downing Street",
243
+ # :line_3=>"",
244
+ # :post_town=>"LONDON",
245
+ # :postcode=>"SW1A 2AA",
246
+ # :organisation_name=>"Prime Minister & First Lord Of The Treasury",
247
+ # :premise=>"10",
248
+ # :latitude=>51.5035398826274
249
+ # :longitude=>-0.127695242183412,
250
+ # :thoroughfare=>"Downing Street",
251
+ # :district=>"Westminster",
252
+ # :ward=>"St James's",
253
+ # :building_number=>"10",
254
+ # :udprn=>23747771,
255
+ # ... and so on
256
+ ```
257
+
258
+ **Notes**
259
+
260
+ Data source: Royal Mail Postcode Address File, Ordnance Survey.
261
+
262
+ Use the address `0` to test integration for free. The complete list of test methods is available in the [documentation](https://ideal-postcodes/documentation/addresses).
263
+
264
+ ## Utility Methods
265
+
266
+ Listed below are free utility methods, e.g. finding the status of your key.
267
+
268
+ ### Find out if your key is in a usable state [(docs)](https://ideal-postcodes.co.uk/documentation/keys#key)
269
+
270
+ Find out if your key is in a usable state. E.g. it has a positive balance, it is currently under your defined usage limits, etc.
271
+
272
+ ```
273
+ IdealPostcodes.key_available
274
+ ```
275
+
276
+ **Arguments**
277
+
278
+ None.
279
+
280
+ **Returns**
281
+
282
+ - availability (Boolean). Returns true if key can be used. False if something is preventing the key from making lookups e.g. insufficient balance, reached limits, etc.
283
+
284
+ **Example**
285
+
286
+ ```ruby
287
+ IdealPostcodes.key_available # => true, you're clear to make lookups
288
+ ```
289
+
290
+ ### Find out private key information [(docs)](https://ideal-postcodes.co.uk/documentation/keys#details)
291
+
292
+ This method reveals private information about your key such as the lookup balance, whitelisted URLs, etc. Note: a secret key is required to invoke this method.
293
+
294
+ ```
295
+ IdealPostcodes.key_details
296
+ ```
297
+
298
+ **Arguments**
299
+
300
+ None.
301
+
302
+ **Returns**
303
+
304
+ Returns a hash containing pertinent private information about your key.
305
+
306
+ **Example**
307
+
308
+ ```ruby
309
+ IdealPostcodes.key_details
310
+
311
+ # {
312
+ # :lookups_remaining=>9678,
313
+ # :daily_limit=>{
314
+ # :limit=>100,
315
+ # :consumed=>1
316
+ # },
317
+ # :individual_limit=>{
318
+ # :limit=>15
319
+ # },
320
+ # :allowed_urls=>["foo.com"],
321
+ # :notifications=>{
322
+ # :emails=>["bar@baz.com"],
323
+ # :enabled=>true},
324
+ # :automated_topups=>{
325
+ # :enabled=>true
326
+ # }
327
+ # }
328
+ ```
329
+
330
+ If you intend to use this method, you must pass your secret key (which can be found on your [account page](https://ideal-postcodes.co.uk/account)) along with your API key when instantiating the client. E.g.
331
+
332
+ ```ruby
333
+ IdealPostcodes.apply_secret "your secret key"
334
+ ```
335
+
336
+ Do not share your secret key and avoid commiting this key to your codebase.
337
+
338
+
339
+ ## Changelog
340
+
341
+ *1.0.0*
342
+ - Major rewrite to make way for more resources
343
+ - Breaking change applied to postcode lookup functionality
344
+ - Implemented [addresses resource](https://ideal-postcodes.co.uk/documentation/addresses)
345
+ - Implemented [keys resource](https://ideal-postcodes.co.uk/documentation/keys)
346
+ - Implemented [postcodes resource](https://ideal-postcodes.co.uk/documentation/postcodes). Added location-based postcode searches
347
+ - Swapped out test suite with rspec and vcr
96
348
 
97
349
  ## Testing
98
350
 
99
351
  ```
100
- bundle exec rake test
352
+ bundle exec rake
101
353
  ```
102
354
 
103
355
  ## License
356
+
104
357
  MIT
data/Rakefile CHANGED
@@ -1,8 +1,15 @@
1
- require 'rake'
2
- require 'rake/testtask'
1
+ begin
2
+ require 'rspec/core/rake_task'
3
3
 
4
- Rake::TestTask.new do |t|
5
- t.libs << "test"
6
- t.test_files = FileList['test/test*.rb']
7
- t.verbose = true
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = "--format documentation"
6
+ end
7
+
8
+ task :default => :spec
9
+ rescue LoadError
10
+ # no rspec available
11
+ end
12
+
13
+ task :eject_tapes do
14
+ `rm spec/vcr_cassettes/*.yml`
8
15
  end
@@ -6,20 +6,19 @@ spec = Gem::Specification.new do |s|
6
6
  s.name = 'ideal_postcodes'
7
7
  s.version = IdealPostcodes::VERSION
8
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'
9
+ s.description = 'Ideal Postcodes is a simple postcode lookup API for UK addresses. See https://ideal-postcodes.co.uk'
10
+ s.authors = ['Ideal Postcodes']
11
+ s.email = ['support@ideal-postcodes.co.uk']
12
+ s.homepage = 'https://ideal-postcodes.co.uk/'
13
13
 
14
14
  s.add_dependency('rest-client', '~> 1.6')
15
- s.add_dependency('multi_json', '~> 1.7.9')
16
15
 
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')
16
+ s.add_development_dependency 'rake', '~> 10.1.0'
17
+ s.add_development_dependency 'vcr', '~> 2.9.3'
18
+ s.add_development_dependency 'rspec', '~> 3.1.0'
19
+ s.add_development_dependency 'webmock', '~> 1.20.4'
21
20
 
22
21
  s.files = `git ls-files`.split("\n")
23
- s.test_files = `git ls-files -- test/*`.split("\n")
22
+ s.test_files = `git ls-files -- spec/*`.split("\n")
24
23
  s.require_paths = ['lib']
25
24
  end