aryll 1.0.0.rc1
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 +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +5 -0
- data/LICENSE +25 -0
- data/README.md +51 -0
- data/Rakefile +23 -0
- data/aryll.gemspec +30 -0
- data/lib/aryll/international_uri.rb +29 -0
- data/lib/aryll/link_checker.rb +89 -0
- data/lib/aryll/status_message.rb +36 -0
- data/lib/aryll/version.rb +3 -0
- data/lib/aryll.rb +18 -0
- data/test/aryll_test.rb +30 -0
- data/test/link_checker_test.rb +209 -0
- data/test/test_helper.rb +31 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7149f50c4b8078d740e2afd666aadf0f46bf23f2
|
4
|
+
data.tar.gz: 550cf05fba224bea0787e8d5b888bc8cfbab4863
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e5227678705900c94e75e91291f27900745173d174eae5b2a3d5c11785df0e199198cc9edf983b1f7b94e15c1dbecc3e99f4337dfbd9f5060cd3d7ef62d739e5
|
7
|
+
data.tar.gz: a18baced3db9580c7f2f224ea89d9e6b0667d6b040001db0e75960edd7e5a0687e897fc236d7a791ecb4fc2bca24f16768d0ccb11f719c016bf002e4130ae53d
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
aryll
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2011, kaupert media gmbh
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the original author / copyright holder nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Aryll [](https://travis-ci.org/kaupertmedia/kauperts_link_checker)
|
2
|
+
|
3
|
+
**Aryll** is a simple library to check for the well-being of URLs. It supports HTTPS and IDN URIs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
```
|
9
|
+
gem 'aryll'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
```
|
14
|
+
$ bundle
|
15
|
+
```
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
```
|
19
|
+
$ gem install aryll
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
It will check any object that responds to `url`:
|
24
|
+
```ruby
|
25
|
+
status = Aryll.check!(my_url)
|
26
|
+
unless status.ok?
|
27
|
+
puts status
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
You can ignore 301 permanent redirect that only add a trailing slash like this:
|
32
|
+
```ruby
|
33
|
+
status = Aryll::LinkChecker.check!(url, ignore_trailing_slash_redirects: true)
|
34
|
+
unless status.ok?
|
35
|
+
# A redirect from http://example.com/foo to http://example.com/foo/ will be considered ok
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
## I18n
|
40
|
+
The following keys are used to translate error messages using the I18n gem:
|
41
|
+
|
42
|
+
* `kauperts.link_checker.errors.timeout`: message when rescueing from Timeout::Error
|
43
|
+
* `kauperts.link_checker.errors.generic_network`: message when (currently) rescueing from all other exceptions
|
44
|
+
|
45
|
+
## Credits
|
46
|
+
**Aryll** is extracted from a maintenance task made for
|
47
|
+
[berlin.kauperts.de](https://berlin.kauperts.de) by [kaupert media gmbh](http://kaupertmedia.de).
|
48
|
+
|
49
|
+
## License
|
50
|
+
**Aryll** is released under a 3-clause BSD-licence. See the LICENSE file for details.
|
51
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rdoc/task'
|
6
|
+
|
7
|
+
desc "Default: run unit tests."
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.libs << 'test'
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'Aryll'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README*')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
data/aryll.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aryll/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "aryll"
|
8
|
+
s.version = Aryll::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Wolfgang Vogl", "Carsten Zimmermann", "Matthias Viehweger"]
|
11
|
+
s.email = ["cz@aegisnet.de"]
|
12
|
+
s.homepage = ""
|
13
|
+
s.summary = "A simple library to check for the well-being of an URL"
|
14
|
+
s.description = "A simple library to check for the well-being of an URL"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.required_ruby_version = '>= 2.2'
|
20
|
+
|
21
|
+
s.add_dependency "i18n"
|
22
|
+
s.add_dependency "simpleidn"
|
23
|
+
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'rdoc'
|
26
|
+
s.add_development_dependency 'bundler'
|
27
|
+
s.add_development_dependency 'minitest', '>= 5.0'
|
28
|
+
s.add_development_dependency 'webmock'
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Aryll
|
2
|
+
class LinkChecker
|
3
|
+
|
4
|
+
class InternationalURI < Struct.new(:url)
|
5
|
+
def domain
|
6
|
+
@domain ||= url_without_protocol.split('/', 2)[0]
|
7
|
+
end
|
8
|
+
|
9
|
+
def idn_domain
|
10
|
+
@idn_domain ||= SimpleIDN.to_ascii domain
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_uri
|
14
|
+
URI.parse(url.gsub(domain, idn_domain))
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def url_without_protocol
|
20
|
+
@url_without_protocol ||= /^http[s]?:\/\/(.+)/.match(url)[1]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def InternationalURI(url)
|
25
|
+
InternationalURI.new(url).to_uri
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Aryll
|
2
|
+
# Checks the status of a web address. The returned status can be accessed via
|
3
|
+
# +status+. It contains either a string representation of a numeric http
|
4
|
+
# status code or an error message.
|
5
|
+
#
|
6
|
+
# Supports HTTPS and IDN-domains.
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# The following keys are used to translate error messages using the I18n gem:
|
10
|
+
# * <tt>kauperts.link_checker.errors.timeout</tt>: rescues from Timeout::Error
|
11
|
+
# * <tt>kauperts.link_checker.errors.generic_network</tt>: (currently) rescues from all other exceptions
|
12
|
+
# * <tt>kauperts.link_checker.status.redirect_permanently</tt>: translation for 301 permanent redirects
|
13
|
+
class LinkChecker
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :ignore_trailing_slash_redirects, :ignore_302_redirects
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :url, :status, :ignore_trailing_slash_redirects, :ignore_302_redirects,
|
25
|
+
:open_timeout, :read_timeout, :user_agent
|
26
|
+
|
27
|
+
# === Parameters
|
28
|
+
# * +url+: URL, complete with protocol scheme
|
29
|
+
# * +options+: optional configuration parameters, see below.
|
30
|
+
#
|
31
|
+
# === Available Options
|
32
|
+
# * +ignore_trailing_slash_redirects+: ignores redirects to the same URI but only with an added trailing slash (default: false)
|
33
|
+
# * +ignore_302_redirects+: ignores temporary redirects (default: false)
|
34
|
+
# * +open_timeout+: Passed to Net::HTTP#open_timeout
|
35
|
+
# * +read_timeout+: Passed to Net::HTTP#read_timeout
|
36
|
+
def initialize(url, ignore_trailing_slash_redirects: false, ignore_302_redirects: false, open_timeout: 5, read_timeout: 10, user_agent: "Aryll Spider v#{Aryll::VERSION} (https://github.com/kaupertmedia/aryll)".freeze)
|
37
|
+
@url = url
|
38
|
+
|
39
|
+
@ignore_trailing_slash_redirects = ignore_trailing_slash_redirects || self.class.ignore_trailing_slash_redirects
|
40
|
+
@ignore_302_redirects = ignore_302_redirects || self.class.ignore_302_redirects
|
41
|
+
@open_timeout, @read_timeout = open_timeout, read_timeout
|
42
|
+
@user_agent = user_agent
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks the associated url. Sets and returns +status+
|
46
|
+
def check!
|
47
|
+
@status = begin
|
48
|
+
if response.code == '301'
|
49
|
+
@redirect_with_trailing_slash_only = "#{uri}/" == response['location']
|
50
|
+
StatusMessage.moved_permanently response['location']
|
51
|
+
else
|
52
|
+
response.code
|
53
|
+
end
|
54
|
+
rescue Timeout::Error => e
|
55
|
+
StatusMessage.timeout e.message
|
56
|
+
rescue Exception => e
|
57
|
+
StatusMessage.generic e.message
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns if a check has been run and the return code was '200 OK'
|
62
|
+
# or if a 301 permanent redirect only added a trailing slash
|
63
|
+
# while +ignore_trailing_slash_redirects+ has been set to true
|
64
|
+
def ok?
|
65
|
+
(status == '200') ||
|
66
|
+
(status == '302' && ignore_302_redirects) ||
|
67
|
+
[@redirect_with_trailing_slash_only, ignore_trailing_slash_redirects].all?
|
68
|
+
end
|
69
|
+
|
70
|
+
def uri
|
71
|
+
@uri ||= InternationalURI(url)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def response
|
77
|
+
@response ||= begin
|
78
|
+
https_opts = { use_ssl: uri.scheme == 'https', verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
79
|
+
Net::HTTP.start(uri.host, uri.port, https_opts) do |http|
|
80
|
+
request = Net::HTTP::Get.new uri, 'User-Agent' => user_agent
|
81
|
+
http.open_timeout = open_timeout
|
82
|
+
http.read_timeout = read_timeout
|
83
|
+
http.request request
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module Aryll
|
4
|
+
class LinkChecker
|
5
|
+
|
6
|
+
class StatusMessage
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def moved_permanently(message)
|
11
|
+
t 'status.redirect_permanently', 'Moved permanently', message
|
12
|
+
end
|
13
|
+
|
14
|
+
def generic(message)
|
15
|
+
t 'errors.generic_network', 'Generic network error', message
|
16
|
+
end
|
17
|
+
|
18
|
+
def timeout(message)
|
19
|
+
t 'errors.timeout', 'Timeout', message
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def t(key, default, message)
|
25
|
+
[
|
26
|
+
I18n.t("kauperts.link_checker.#{key}", default: default),
|
27
|
+
"(#{message})"
|
28
|
+
].join ' '
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/aryll.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "net/https"
|
2
|
+
require "simpleidn"
|
3
|
+
require 'aryll/link_checker'
|
4
|
+
require 'aryll/international_uri'
|
5
|
+
require 'aryll/status_message'
|
6
|
+
|
7
|
+
module Aryll
|
8
|
+
|
9
|
+
# Immediately checks +url+ and returns the LinkChecker instance
|
10
|
+
def check!(url, **options)
|
11
|
+
checker = LinkChecker.new(url, **options)
|
12
|
+
checker.check!
|
13
|
+
checker
|
14
|
+
end
|
15
|
+
|
16
|
+
module_function :check!
|
17
|
+
|
18
|
+
end
|
data/test/aryll_test.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Aryll do
|
4
|
+
|
5
|
+
let(:url) do
|
6
|
+
'http://www.example.com'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.check!' do
|
10
|
+
it { described_class.method(:check!).arity.must_equal(-2) }
|
11
|
+
|
12
|
+
let(:request_stub) { stub_net_http! }
|
13
|
+
|
14
|
+
before { request_stub }
|
15
|
+
|
16
|
+
it 'returns a link checker instance' do
|
17
|
+
subject = described_class.check!(url)
|
18
|
+
subject.must_be_instance_of Aryll::LinkChecker
|
19
|
+
assert_requested request_stub
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def described_class
|
24
|
+
Aryll
|
25
|
+
end
|
26
|
+
|
27
|
+
def stub_net_http!(return_code = "200", host: 'www.example.com', path: '/', protocol: 'http')
|
28
|
+
stub_request(:get, "#{protocol}://#{host}#{path}").to_return(status: return_code.to_i)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Aryll::LinkChecker do
|
4
|
+
|
5
|
+
let(:url) do
|
6
|
+
'http://www.example.com'
|
7
|
+
end
|
8
|
+
|
9
|
+
subject { described_class.new url }
|
10
|
+
|
11
|
+
let(:translation) { {} }
|
12
|
+
|
13
|
+
before do
|
14
|
+
I18n.backend.store_translations I18n.locale, translation
|
15
|
+
end
|
16
|
+
|
17
|
+
after { I18n.backend.reload! }
|
18
|
+
|
19
|
+
describe 'the class-level configuration defaults' do
|
20
|
+
|
21
|
+
[:ignore_trailing_slash_redirects, :ignore_302_redirects].each do |configuration|
|
22
|
+
describe ".#{configuration}" do
|
23
|
+
it "has a getter and setter" do
|
24
|
+
described_class.must_respond_to configuration
|
25
|
+
described_class.must_respond_to "#{configuration}="
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.configure' do
|
31
|
+
[:ignore_trailing_slash_redirects, :ignore_302_redirects].each do |configuration|
|
32
|
+
it "changes the value for #{configuration}" do
|
33
|
+
config_val = described_class.send configuration
|
34
|
+
proc {
|
35
|
+
described_class.configure do |config|
|
36
|
+
config.send "#{configuration}=", 'foo'
|
37
|
+
end
|
38
|
+
}.must_change -> { described_class.send(configuration) }
|
39
|
+
described_class.send "#{configuration}=", config_val
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'its constructor' do
|
47
|
+
it 'sets the url object' do
|
48
|
+
subject.url.must_equal url
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#check!' do
|
53
|
+
it "returns a '200' status" do
|
54
|
+
stub_net_http!
|
55
|
+
subject.check!.must_equal '200'
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns a '404' status" do
|
59
|
+
stub_net_http!("404")
|
60
|
+
subject.check!.must_equal '404'
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'with SSL' do
|
64
|
+
let(:url) do
|
65
|
+
'https://www.example.com/'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns a '200' status" do
|
69
|
+
stub_net_http! protocol: 'https'
|
70
|
+
subject.check!.must_equal '200'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'with configuration options' do
|
75
|
+
describe 'for trailing slashes' do
|
76
|
+
before { stub_net_http_redirect!("301", location: url + '/') }
|
77
|
+
|
78
|
+
it 'considers trailing slashes for redirects not ok by default' do
|
79
|
+
subject.check!
|
80
|
+
subject.ok?.must_equal false
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'ignores permanent redirects with trailing slash' do
|
84
|
+
subject = described_class.new(url, ignore_trailing_slash_redirects: true )
|
85
|
+
subject.check!
|
86
|
+
subject.ok?.must_equal true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'for temporary redirects (302)' do
|
91
|
+
before do
|
92
|
+
stub_net_http_redirect!("302")
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'considers temporary redirects not ok by default' do
|
96
|
+
subject.check!
|
97
|
+
subject.ok?.must_equal false
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'ignores temporary redirects' do
|
101
|
+
subject = described_class.new(url, ignore_302_redirects: true)
|
102
|
+
subject.check!
|
103
|
+
subject.ok?.must_equal true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'with timeout errors' do
|
109
|
+
before do
|
110
|
+
stub_request(:any, 'www.example.com').to_timeout
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'handles timeouts' do
|
114
|
+
subject.check!
|
115
|
+
subject.status.must_match(/Timeout .+/)
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'with I18n' do
|
119
|
+
let(:translation) do
|
120
|
+
{ kauperts: { link_checker: { errors: { timeout: "Zeitüberschreitung" } } } }
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'translates the error message' do
|
124
|
+
subject.check!
|
125
|
+
subject.status.must_match(/Zeitüberschreitung .+/)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'with a unrecognized network error' do
|
131
|
+
let(:generic_error) { Class.new(StandardError) }
|
132
|
+
|
133
|
+
before do
|
134
|
+
stub_request(:any, 'www.example.com').to_raise generic_error
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'handles generic network problem' do
|
138
|
+
subject.check!
|
139
|
+
subject.status.must_match(/Generic network error .+/)
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'with I18n' do
|
143
|
+
let(:translation) do
|
144
|
+
{ kauperts: { link_checker: { errors: { generic_network: "Netzwerkfehler" } } } }
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'translates the error message' do
|
148
|
+
subject.check!
|
149
|
+
subject.status.must_match(/Netzwerkfehler .+/)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'with IDN domains' do
|
155
|
+
let(:url) do
|
156
|
+
'http://www.trotzköpfchen.de'
|
157
|
+
end
|
158
|
+
|
159
|
+
before do
|
160
|
+
stub_net_http!(host: 'www.xn--trotzkpfchen-9ib.de')
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'handles domain with umlauts' do
|
164
|
+
subject.check!.must_equal '200'
|
165
|
+
subject.ok?.must_equal true
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '#status' do
|
172
|
+
describe 'with a permanent redirect' do
|
173
|
+
before do
|
174
|
+
stub_net_http_redirect!("301")
|
175
|
+
subject.check!
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'returns the redirection url' do
|
179
|
+
subject.status.must_equal 'Moved permanently (http://auenland.de)'
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'with I18n' do
|
183
|
+
let(:translation) do
|
184
|
+
{ kauperts: { link_checker: { status: { redirect_permanently: "Umgezogen" } } } }
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'translates the status' do
|
188
|
+
subject.status.must_match(/Umgezogen \(http:.+/)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
def described_class
|
196
|
+
Aryll::LinkChecker
|
197
|
+
end
|
198
|
+
|
199
|
+
def stub_net_http!(return_code = "200", host: 'www.example.com', path: '/', protocol: 'http')
|
200
|
+
stub_request(:get, "#{protocol}://#{host}#{path}").to_return(status: return_code.to_i)
|
201
|
+
end
|
202
|
+
|
203
|
+
def stub_net_http_redirect!(return_code = '301', location: "http://auenland.de")
|
204
|
+
stub_request(:get, "http://www.example.com").to_return(
|
205
|
+
status: return_code.to_i,
|
206
|
+
headers: { 'Location' => location }
|
207
|
+
)
|
208
|
+
end
|
209
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
if ENV['COVERAGE']
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
|
8
|
+
require 'minitest/autorun'
|
9
|
+
require 'minitest/pride'
|
10
|
+
require 'webmock/minitest'
|
11
|
+
|
12
|
+
require 'aryll'
|
13
|
+
|
14
|
+
I18n.available_locales = :en
|
15
|
+
|
16
|
+
module MiniTest
|
17
|
+
module Assertions
|
18
|
+
|
19
|
+
def assert_change(change_proc)
|
20
|
+
before = change_proc.call
|
21
|
+
yield
|
22
|
+
after = change_proc.call
|
23
|
+
refute_equal before, after
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
module Expectations
|
29
|
+
infect_an_assertion :assert_change, :must_change, :block
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aryll
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.rc1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wolfgang Vogl
|
8
|
+
- Carsten Zimmermann
|
9
|
+
- Matthias Viehweger
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: i18n
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: simpleidn
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rake
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: rdoc
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: bundler
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: minitest
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '5.0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '5.0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: webmock
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
description: A simple library to check for the well-being of an URL
|
114
|
+
email:
|
115
|
+
- cz@aegisnet.de
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".ruby-gemset"
|
122
|
+
- ".ruby-version"
|
123
|
+
- ".travis.yml"
|
124
|
+
- Gemfile
|
125
|
+
- LICENSE
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- aryll.gemspec
|
129
|
+
- lib/aryll.rb
|
130
|
+
- lib/aryll/international_uri.rb
|
131
|
+
- lib/aryll/link_checker.rb
|
132
|
+
- lib/aryll/status_message.rb
|
133
|
+
- lib/aryll/version.rb
|
134
|
+
- test/aryll_test.rb
|
135
|
+
- test/link_checker_test.rb
|
136
|
+
- test/test_helper.rb
|
137
|
+
homepage: ''
|
138
|
+
licenses: []
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '2.2'
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: 1.3.1
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.5.1
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: A simple library to check for the well-being of an URL
|
160
|
+
test_files:
|
161
|
+
- test/aryll_test.rb
|
162
|
+
- test/link_checker_test.rb
|
163
|
+
- test/test_helper.rb
|