ndd-url_checker 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe NDD::UrlChecker::ThreadedUrlChecker do
4
+
5
+ before(:all) do
6
+ # Logging.logger.root.level = :debug
7
+ end
8
+
9
+ # TODO
10
+ # it_behaves_like 'a single URL checker'
11
+ # it_behaves_like 'a multiple URL checker', skip_verify = true
12
+
13
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: utf-8
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+
5
+ require 'rubygems'
6
+ require 'spork'
7
+
8
+
9
+ # ----------------------------------------------------------------------------------------------------------------------
10
+ # Spork prefork
11
+ # Loading more in this block will cause your tests to run faster. However, if you change any
12
+ # configuration or code from libraries loaded here, you'll need to restart spork for it take effect.
13
+ # ----------------------------------------------------------------------------------------------------------------------
14
+
15
+ lib_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ spec_dir = File.dirname(__FILE__)
17
+
18
+ Spork.prefork do
19
+
20
+ # ----- load path
21
+
22
+ $LOAD_PATH.unshift(lib_path)
23
+ $LOAD_PATH.unshift(spec_dir)
24
+
25
+ # ----- requirements
26
+
27
+ require 'logging'
28
+ require 'rspec'
29
+ require 'rspec/collection_matchers'
30
+ require 'webmock/rspec'
31
+
32
+ # ----- code coverage
33
+
34
+ if ENV['COVERAGE'] and not ENV['DRB']
35
+ require 'simplecov'
36
+ SimpleCov.start 'test_frameworks'
37
+ end
38
+
39
+ # ----- logging
40
+
41
+ Logging.logger.root.appenders = Logging.appenders.stdout
42
+ Logging.logger.root.level = :off
43
+
44
+ # ----- RSpec configuration
45
+
46
+ RSpec.configure do |config|
47
+
48
+ config.mock_with :rspec
49
+
50
+ # ----- filters
51
+ config.alias_example_to :fit, :focused
52
+ config.filter_run_including :focused
53
+ config.order = 'random'
54
+ config.run_all_when_everything_filtered = true
55
+ config.expect_with :rspec do |c|
56
+ c.syntax = :expect
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+
64
+ # ----------------------------------------------------------------------------------------------------------------------
65
+ # Spork each_run
66
+ # This code will be run each time you run your specs.
67
+ # ----------------------------------------------------------------------------------------------------------------------
68
+
69
+ Spork.each_run do
70
+
71
+ # ----- code coverage
72
+
73
+ # if ENV['COVERAGE'] and not ENV['DRB']
74
+ # require 'simplecov'
75
+ # SimpleCov.start 'test_frameworks'
76
+ # end
77
+
78
+ # ----- files reload
79
+ Dir["#{lib_path}/**/*.rb"].each { |file| require file }
80
+ Dir["#{spec_dir}/support/**/*.rb"].each { |file| require file }
81
+
82
+ require 'ndd/url_checker'
83
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ # @param [Boolean] skip_verify because a forked process cannot be verified
4
+ RSpec.shared_examples 'a multiple URL checker' do |skip_verify|
5
+
6
+ before(:all) do
7
+ WebMock.allow_net_connect!
8
+ end
9
+
10
+ before(:each) do
11
+ WebMock.reset!
12
+ end
13
+
14
+
15
+ # ------------------------------------------------------------------------------------------------- multiple URL -----
16
+ context 'when there are multiple URLs' do
17
+ let!(:stub1) { stub_request(:get, 'http://www.valid.mock/').to_return(status: 200) }
18
+ let!(:stub2) { stub_request(:get, 'http://www.invalid.mock/').to_raise(SocketError) }
19
+
20
+ describe '#validate' do
21
+ it 'returns a map of the results indexed by the URI' do
22
+ results = subject.validate('http://www.valid.mock/', 'http://www.invalid.mock/')
23
+ expect(results).to have(2).items
24
+ expect(results['http://www.valid.mock/']).to be_truthy
25
+ expect(results['http://www.invalid.mock/']).to be_falsey
26
+ end
27
+ end
28
+
29
+ describe '#check' do
30
+ it 'returns a map of the results indexed by the URI' do
31
+ results = subject.check('http://www.valid.mock/', 'http://www.invalid.mock/')
32
+ expect(results).to have(2).items
33
+
34
+ status1 = results['http://www.valid.mock/']
35
+ expect(status1.code).to eq :direct
36
+ expect(status1.uri).to eq 'http://www.valid.mock/'
37
+ expect(status1.error).to be_nil
38
+
39
+ status2 = results['http://www.invalid.mock/']
40
+ expect(status2.code).to eq :failed
41
+ expect(status2.uri).to eq 'http://www.invalid.mock/'
42
+ expect(status2.error).to be_a StandardError
43
+ end
44
+ end
45
+
46
+ after(:each) do
47
+ unless skip_verify
48
+ expect(stub1).to have_been_requested
49
+ expect(stub2).to have_been_requested
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+ # ------------------------------------------------------------------------------------------------------ private -----
56
+ private
57
+
58
+ def stub_redirect(from, to)
59
+ stub_request(:get, from).to_return(status: 301, headers: {Location: to})
60
+ end
61
+ end
62
+
63
+ # expect(subject.valid?('http://www.google.fr')).to be_truthy
64
+ # expect(subject.valid?('http://www.google.fr/')).to be_truthy
65
+ # expect(subject.valid?('http://www.invalid123456789xyz.com')).to be_falsey
66
+ # expect(subject.valid?('http://www.invalid123456789xyz.com/')).to be_falsey
@@ -0,0 +1,207 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.shared_examples 'a single URL checker' do
4
+
5
+ before(:all) do
6
+ WebMock.allow_net_connect!
7
+ end
8
+
9
+ before(:each) do
10
+ WebMock.reset!
11
+ end
12
+
13
+ # ------------------------------------------------------------------------------------------------------- direct -----
14
+ context 'when the URL is valid' do
15
+ let!(:stub) { stub_request(:get, 'http://www.valid.mock/').to_return(status: 200) }
16
+
17
+ describe '#validate' do
18
+ it 'returns true' do
19
+ expect(subject.validate('http://www.valid.mock/')).to be_truthy
20
+ end
21
+ end
22
+
23
+ describe '#check' do
24
+ let (:status) { subject.check('http://www.valid.mock/') }
25
+
26
+ it 'returns a status with a :direct code' do
27
+ expect(status.code).to eq :direct
28
+ end
29
+ it 'returns a status with the requested URI' do
30
+ expect(status.uris).to eq ['http://www.valid.mock/']
31
+ end
32
+ it 'returns a status with no error' do
33
+ expect(status.error).to be_nil
34
+ end
35
+ end
36
+
37
+ after(:each) do
38
+ expect(stub).to have_been_requested
39
+ end
40
+ end
41
+
42
+ # --------------------------------------------------------------------------------------------------- redirected -----
43
+ context 'when there are not too many redirects' do
44
+ let!(:stub1) { stub_redirect('http://www.redirect1.mock/', 'http://www.redirect2.mock/') }
45
+ let!(:stub2) { stub_redirect('http://www.redirect2.mock/', 'http://www.redirect3.mock/') }
46
+ let!(:stub3) { stub_redirect('http://www.redirect3.mock/', 'http://www.redirect4.mock/') }
47
+ let!(:stub4) { stub_request(:get, 'http://www.redirect4.mock/').to_return(status: 200) }
48
+
49
+ describe '#validate' do
50
+ it 'returns true' do
51
+ expect(subject.validate('http://www.redirect1.mock/')).to be_truthy
52
+ end
53
+ end
54
+
55
+ describe '#check' do
56
+ let (:status) { subject.check('http://www.redirect1.mock/') }
57
+
58
+ it 'returns a status with a :direct code' do
59
+ expect(status.code).to eq :redirected
60
+ end
61
+
62
+ it 'returns a status with the requested URI' do
63
+ expect(status.uri).to eq 'http://www.redirect1.mock/'
64
+ end
65
+
66
+ it 'returns a status with the requested URIs' do
67
+ expect(status.uris).to eq (1..4).to_a.map { |i| "http://www.redirect#{i}.mock/" }
68
+ end
69
+ end
70
+
71
+ after(:each) do
72
+ [stub1, stub2, stub3, stub4].each { |stub| expect(stub).to have_been_requested }
73
+ end
74
+ end
75
+
76
+ # ------------------------------------------------------------------------------------------- too_many_redirects -----
77
+ context 'when there are too many redirects' do
78
+ let!(:stub1) { stub_redirect('http://www.redirect1.mock/', 'http://www.redirect2.mock/') }
79
+ let!(:stub2) { stub_redirect('http://www.redirect2.mock/', 'http://www.redirect3.mock/') }
80
+ let!(:stub3) { stub_redirect('http://www.redirect3.mock/', 'http://www.redirect4.mock/') }
81
+ let!(:stub4) { stub_redirect('http://www.redirect4.mock/', 'http://www.redirect5.mock/') }
82
+ let!(:stub5) { stub_redirect('http://www.redirect5.mock/', 'http://www.redirect6.mock/') }
83
+
84
+ describe '#validate' do
85
+ it 'returns false' do
86
+ expect(subject.validate('http://www.redirect1.mock/')).to be_falsey
87
+ end
88
+ end
89
+
90
+ describe '#check' do
91
+ it 'returns UrlChecker::Direct' do
92
+ result = subject.check('http://www.redirect1.mock/')
93
+ expect(result).to be_kind_of NDD::UrlChecker::Status
94
+ # expect(result).to be_kind_of UrlChecker::TooManyRedirect
95
+ expect(result.uri).to eq 'http://www.redirect1.mock/'
96
+ expect(result.uris).to eq (1..6).to_a.map { |i| "http://www.redirect#{i}.mock/" }
97
+ end
98
+ end
99
+
100
+ after(:each) do
101
+ [stub1, stub2, stub3, stub4, stub5].each { |stub| expect(stub).to have_been_requested }
102
+ end
103
+ end
104
+
105
+ # ------------------------------------------------------------------------------------------------- unknown_host -----
106
+ context 'when the URL cannot be resolved' do
107
+ let!(:stub) {
108
+ error = SocketError.new('getaddrinfo: Name or service not known')
109
+ stub_request(:get, 'http://www.invalid.mock/').to_raise(error)
110
+ }
111
+
112
+ describe '#validate' do
113
+ it 'returns false' do
114
+ expect(subject.validate('http://www.invalid.mock/')).to be_falsey
115
+ end
116
+ end
117
+
118
+ describe '#check' do
119
+ let (:status) { subject.check('http://www.invalid.mock/') }
120
+
121
+ it 'returns a status with a :unknown_host code' do
122
+ expect(status.code).to eq :unknown_host
123
+ end
124
+ it 'returns a status with the requested URI' do
125
+ expect(status.uri).to eq 'http://www.invalid.mock/'
126
+ end
127
+ it 'returns a status with no error' do
128
+ expect(status.error).to be_nil
129
+ end
130
+ end
131
+
132
+ after(:each) do
133
+ expect(stub).to have_been_requested
134
+ end
135
+ end
136
+
137
+ # ------------------------------------------------------------------------------------------------- socket error -----
138
+ context 'when there is a socket error' do
139
+ let!(:stub) { stub_request(:get, 'http://www.invalid.mock/').to_raise(SocketError) }
140
+
141
+ describe '#validate' do
142
+ it 'returns false' do
143
+ expect(subject.validate('http://www.invalid.mock/')).to be_falsey
144
+ end
145
+ end
146
+
147
+ describe '#check' do
148
+ let (:status) { subject.check('http://www.invalid.mock/') }
149
+
150
+ it 'returns a status with a :failed code' do
151
+ expect(status.code).to eq :failed
152
+ end
153
+ it 'returns a status with the requested URI' do
154
+ expect(status.uri).to eq 'http://www.invalid.mock/'
155
+ end
156
+ it 'returns a status with the raised error' do
157
+ expect(status.error).to be_a SocketError
158
+ end
159
+ end
160
+
161
+ after(:each) do
162
+ expect(stub).to have_been_requested
163
+ end
164
+ end
165
+
166
+ # -------------------------------------------------------------------------------------------------------- error -----
167
+ context 'when there is an unexpected error' do
168
+ let!(:stub) { stub_request(:get, 'http://www.error.mock/').to_raise('Some error') }
169
+
170
+ describe '#validate' do
171
+ it 'returns false' do
172
+ expect(subject.validate('http://www.error.mock/')).to be_falsey
173
+ end
174
+ end
175
+
176
+ describe '#check' do
177
+ let (:status) { subject.check('http://www.error.mock/') }
178
+
179
+ it 'returns a status with a :failed code' do
180
+ expect(status.code).to eq :failed
181
+ end
182
+ it 'returns a status with the requested URI' do
183
+ expect(status.uri).to eq 'http://www.error.mock/'
184
+ end
185
+ it 'returns a status with the raised error' do
186
+ expect(status.error).to be_a StandardError
187
+ end
188
+ end
189
+
190
+ after(:each) do
191
+ expect(stub).to have_been_requested
192
+ end
193
+ end
194
+
195
+
196
+ # ------------------------------------------------------------------------------------------------------ private -----
197
+ private
198
+
199
+ def stub_redirect(from, to)
200
+ stub_request(:get, from).to_return(status: 301, headers: {Location: to})
201
+ end
202
+ end
203
+
204
+ # expect(subject.valid?('http://www.google.fr')).to be_truthy
205
+ # expect(subject.valid?('http://www.google.fr/')).to be_truthy
206
+ # expect(subject.valid?('http://www.invalid123456789xyz.com')).to be_falsey
207
+ # expect(subject.valid?('http://www.invalid123456789xyz.com/')).to be_falsey
metadata ADDED
@@ -0,0 +1,312 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ndd-url_checker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - David DIDIER
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cod
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: logging
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-spork
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: jeweler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rdoc
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '4.1'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '4.1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '3.1'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '3.1'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec-collection_matchers
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.1'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.1'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.9'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.9'
181
+ - !ruby/object:Gem::Dependency
182
+ name: spork
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.9'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.9'
195
+ - !ruby/object:Gem::Dependency
196
+ name: webmock
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '1.20'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '1.20'
209
+ - !ruby/object:Gem::Dependency
210
+ name: yard
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.8'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '0.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: libnotify
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rb-inotify
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ description: Validate URLs
252
+ email: c_inconnu2@yahoo.fr
253
+ executables: []
254
+ extensions: []
255
+ extra_rdoc_files:
256
+ - LICENSE.txt
257
+ - README.md
258
+ files:
259
+ - ".document"
260
+ - ".rspec"
261
+ - ".ruby-gemset"
262
+ - ".ruby-version"
263
+ - ".travis.yml"
264
+ - CHANGELOG.md
265
+ - Gemfile
266
+ - Gemfile.lock
267
+ - Guardfile
268
+ - LICENSE.txt
269
+ - README.md
270
+ - Rakefile
271
+ - VERSION
272
+ - lib/ndd/url_checker.rb
273
+ - lib/ndd/url_checker/abstract_url_checker.rb
274
+ - lib/ndd/url_checker/blocking_url_checker.rb
275
+ - lib/ndd/url_checker/forked_url_checker.rb
276
+ - lib/ndd/url_checker/parallel_url_checker.rb
277
+ - lib/ndd/url_checker/status.rb
278
+ - lib/ndd/url_checker/threaded_url_checker.rb
279
+ - spec/ndd/url_checker/abstract_url_checker_spec.rb
280
+ - spec/ndd/url_checker/blocking_url_checker_spec.rb
281
+ - spec/ndd/url_checker/forked_url_checker_spec.rb
282
+ - spec/ndd/url_checker/parallel_url_checker_spec.rb
283
+ - spec/ndd/url_checker/status_spec.rb
284
+ - spec/ndd/url_checker/threaded_url_checker_spec.rb
285
+ - spec/spec_helper.rb
286
+ - spec/support/multiple_url_checker_spec.rb
287
+ - spec/support/single_url_checker_spec.rb
288
+ homepage: http://github.com/ddidier/ndd-url_checker
289
+ licenses:
290
+ - MIT
291
+ metadata: {}
292
+ post_install_message:
293
+ rdoc_options: []
294
+ require_paths:
295
+ - lib
296
+ required_ruby_version: !ruby/object:Gem::Requirement
297
+ requirements:
298
+ - - ">="
299
+ - !ruby/object:Gem::Version
300
+ version: '0'
301
+ required_rubygems_version: !ruby/object:Gem::Requirement
302
+ requirements:
303
+ - - ">="
304
+ - !ruby/object:Gem::Version
305
+ version: '0'
306
+ requirements: []
307
+ rubyforge_project:
308
+ rubygems_version: 2.4.4
309
+ signing_key:
310
+ specification_version: 4
311
+ summary: Validate URLs
312
+ test_files: []