html-proofer 1.6.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +74 -56
- data/Rakefile +4 -6
- data/bin/htmlproof +46 -36
- data/html-proofer.gemspec +22 -22
- data/lib/html/proofer/check_runner/issue.rb +62 -0
- data/lib/html/proofer/{check.rb → check_runner.rb} +11 -19
- data/lib/html/proofer/checkable.rb +42 -28
- data/lib/html/proofer/checks/favicon.rb +6 -6
- data/lib/html/proofer/checks/html.rb +11 -12
- data/lib/html/proofer/checks/images.rb +11 -11
- data/lib/html/proofer/checks/links.rb +30 -28
- data/lib/html/proofer/checks/scripts.rb +7 -8
- data/lib/html/proofer/log.rb +38 -0
- data/lib/html/proofer/url_validator.rb +135 -0
- data/lib/html/proofer/utils.rb +24 -0
- data/lib/html/proofer/version.rb +1 -1
- data/lib/html/proofer.rb +95 -199
- data/spec/html/proofer/command_spec.rb +82 -0
- data/spec/html/proofer/favicon_spec.rb +20 -20
- data/spec/html/proofer/fixtures/images/srcSetCheck.html +7 -0
- data/spec/html/proofer/fixtures/images/srcSetIgnorable.html +13 -0
- data/spec/html/proofer/fixtures/images/srcSetMissingAlt.html +7 -0
- data/spec/html/proofer/fixtures/images/srcSetMissingImage.html +7 -0
- data/spec/html/proofer/fixtures/links/erstiebegru/314/210/303/237ung.html +1 -0
- data/spec/html/proofer/fixtures/links/erstiebegr/303/274/303/237ung.html +1 -0
- data/spec/html/proofer/fixtures/links/file.foo +11 -0
- data/spec/html/proofer/fixtures/links/folder/multiples/catalog/file.html +8 -0
- data/spec/html/proofer/fixtures/links/folder/multiples/javadoc/file.html +8 -0
- data/spec/html/proofer/fixtures/links/nodupe.html +1 -1
- data/spec/html/proofer/fixtures/links/redirected_error.html +1 -0
- data/spec/html/proofer/fixtures/links/rootLink/rootLink.html +0 -1
- data/spec/html/proofer/fixtures/links/urlencoded-href.html +2 -0
- data/spec/html/proofer/fixtures/links/utf8Link.html +2 -0
- data/spec/html/proofer/fixtures/utils/lang-jp.html +1 -0
- data/spec/html/proofer/html_spec.rb +25 -25
- data/spec/html/proofer/images_spec.rb +59 -35
- data/spec/html/proofer/links_spec.rb +152 -109
- data/spec/html/proofer/scripts_spec.rb +17 -17
- data/spec/html/proofer/utils_spec.rb +14 -0
- data/spec/html/proofer_spec.rb +58 -38
- data/spec/spec_helper.rb +13 -6
- metadata +39 -7
- data/lib/html/proofer/checks.rb +0 -15
- data/lib/html/proofer/issue.rb +0 -21
data/lib/html/proofer.rb
CHANGED
@@ -1,40 +1,34 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
def require_all(path)
|
2
|
+
glob = File.join(File.dirname(__FILE__), path, '*.rb')
|
3
|
+
Dir[glob].each do |f|
|
4
|
+
require f
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require_all 'proofer'
|
9
|
+
require_all 'proofer/check_runner'
|
10
|
+
require_all 'proofer/checks'
|
11
|
+
require_relative './proofer/utils'
|
12
|
+
|
3
13
|
require 'parallel'
|
4
|
-
require "addressable/uri"
|
5
14
|
|
6
15
|
begin
|
7
|
-
require
|
16
|
+
require 'awesome_print'
|
8
17
|
rescue LoadError; end
|
9
18
|
|
10
|
-
%w[
|
11
|
-
checkable
|
12
|
-
checks
|
13
|
-
issue
|
14
|
-
version
|
15
|
-
].each { |r| require File.join(File.dirname(__FILE__), "proofer", r) }
|
16
|
-
|
17
19
|
module HTML
|
18
20
|
|
19
|
-
def self.colorize(color, string)
|
20
|
-
if $stdout.isatty && $stderr.isatty
|
21
|
-
Colored.colorize(string, :foreground => color)
|
22
|
-
else
|
23
|
-
string
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
21
|
class Proofer
|
28
|
-
include
|
22
|
+
include Utils
|
29
23
|
|
30
24
|
attr_reader :options, :typhoeus_opts, :parallel_opts
|
31
25
|
|
32
|
-
def initialize(src, opts={})
|
26
|
+
def initialize(src, opts = {})
|
33
27
|
@src = src
|
34
28
|
|
35
29
|
@proofer_opts = {
|
36
|
-
:ext =>
|
37
|
-
:
|
30
|
+
:ext => '.html',
|
31
|
+
:check_favicon => false,
|
38
32
|
:href_swap => [],
|
39
33
|
:href_ignore => [],
|
40
34
|
:file_ignore => [],
|
@@ -43,184 +37,103 @@ module HTML
|
|
43
37
|
:disable_external => false,
|
44
38
|
:verbose => false,
|
45
39
|
:only_4xx => false,
|
46
|
-
:directory_index_file =>
|
47
|
-
:
|
48
|
-
:error_sort => :path
|
40
|
+
:directory_index_file => 'index.html',
|
41
|
+
:check_html => false,
|
42
|
+
:error_sort => :path,
|
43
|
+
:checks_to_ignore => []
|
49
44
|
}
|
50
45
|
|
51
|
-
@typhoeus_opts = {
|
46
|
+
@typhoeus_opts = opts[:typhoeus] || {
|
52
47
|
:followlocation => true
|
53
48
|
}
|
49
|
+
opts.delete(:typhoeus)
|
50
|
+
|
51
|
+
@hydra_opts = opts[:hydra] || {}
|
52
|
+
opts.delete(:hydra)
|
54
53
|
|
55
54
|
# fall back to parallel defaults
|
56
55
|
@parallel_opts = opts[:parallel] || {}
|
57
56
|
opts.delete(:parallel)
|
58
57
|
|
59
|
-
|
60
|
-
# a proofer_opt, it must be for Typhoeus
|
61
|
-
opts.keys.each do |key|
|
62
|
-
if @proofer_opts[key].nil?
|
63
|
-
@typhoeus_opts[key] = opts[key]
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
@options = @proofer_opts.merge(@typhoeus_opts).merge(opts)
|
58
|
+
@options = @proofer_opts.merge(opts)
|
68
59
|
|
69
60
|
@failed_tests = []
|
61
|
+
end
|
70
62
|
|
71
|
-
|
72
|
-
|
73
|
-
l.adapter :stderr, level: [:error, :fatal]
|
74
|
-
end
|
63
|
+
def logger
|
64
|
+
@logger ||= HTML::Proofer::Log.new(@options[:verbose])
|
75
65
|
end
|
76
66
|
|
77
67
|
def run
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
logger.info HTML::colorize :white, "Running #{get_checks} checks on #{@src} on *#{@options[:ext]}... \n\n"
|
82
|
-
|
83
|
-
results = Parallel.map(files, @parallel_opts) do |path|
|
84
|
-
html = HTML::Proofer.create_nokogiri(path)
|
85
|
-
result = {:external_urls => {}, :failed_tests => []}
|
86
|
-
|
87
|
-
get_checks.each do |klass|
|
88
|
-
logger.debug HTML::colorize :blue, "Checking #{klass.to_s.downcase} on #{path} ..."
|
89
|
-
check = Object.const_get(klass).new(@src, path, html, @options)
|
90
|
-
check.run
|
91
|
-
result[:external_urls].merge!(check.external_urls)
|
92
|
-
result[:failed_tests].concat(check.issues) if check.issues.length > 0
|
93
|
-
end
|
94
|
-
result
|
95
|
-
end
|
96
|
-
|
97
|
-
results.each do |item|
|
98
|
-
external_urls.merge!(item[:external_urls])
|
99
|
-
@failed_tests.concat(item[:failed_tests])
|
100
|
-
end
|
101
|
-
|
102
|
-
external_link_checker(external_urls) unless @options[:disable_external]
|
68
|
+
count = checks.length
|
69
|
+
check_text = "#{checks} " << (count == 1 ? 'check' : 'checks')
|
70
|
+
logger.log :info, :blue, "Running #{check_text} on #{@src} on *#{@options[:ext]}... \n\n"
|
103
71
|
|
104
|
-
|
72
|
+
if @src.is_a?(Array) && !@options[:disable_external]
|
73
|
+
check_list_of_links
|
105
74
|
else
|
106
|
-
|
107
|
-
external_link_checker(external_urls) unless @options[:disable_external]
|
75
|
+
check_directory_of_files
|
108
76
|
end
|
109
77
|
|
110
78
|
if @failed_tests.empty?
|
111
|
-
logger.info
|
79
|
+
logger.log :info, :green, 'HTML-Proofer finished successfully.'
|
112
80
|
else
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
@failed_tests = @failed_tests.sort do |a,b|
|
117
|
-
comp = (a.send(@options[:error_sort]) <=> b.send(@options[:error_sort]))
|
118
|
-
comp.zero? ? (a.path <=> b.path) : comp
|
119
|
-
end
|
81
|
+
print_failed_tests
|
82
|
+
end
|
83
|
+
end
|
120
84
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
logger.error HTML::colorize :blue, "- #{issue.path}"
|
126
|
-
matcher = issue.path
|
127
|
-
end
|
128
|
-
logger.error HTML::colorize :red, " * #{issue.desc}"
|
129
|
-
when :desc
|
130
|
-
if matcher != issue.desc
|
131
|
-
logger.error HTML::colorize :blue, "- #{issue.desc}"
|
132
|
-
matcher = issue.desc
|
133
|
-
end
|
134
|
-
logger.error HTML::colorize :red, " * #{issue.path}"
|
135
|
-
when :status
|
136
|
-
if matcher != issue.status
|
137
|
-
logger.error HTML::colorize :blue, "- #{issue.status}"
|
138
|
-
matcher = issue.status
|
139
|
-
end
|
140
|
-
logger.error HTML::colorize :red, " * #{issue.to_s}"
|
141
|
-
end
|
85
|
+
def check_list_of_links
|
86
|
+
if @options[:href_swap]
|
87
|
+
@src = @src.map do |external_url|
|
88
|
+
swap(external_url, @options[:href_swap])
|
142
89
|
end
|
143
|
-
|
144
|
-
raise HTML::colorize :red, "HTML-Proofer found #{@failed_tests.length} failures!"
|
145
90
|
end
|
91
|
+
external_urls = Hash[*@src.map { |s| [s, nil] }.flatten]
|
92
|
+
validate_urls(external_urls)
|
146
93
|
end
|
147
94
|
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# the
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
external_urls = Hash[external_urls.sort]
|
155
|
-
|
156
|
-
logger.info HTML::colorize :yellow, "Checking #{external_urls.length} external links..."
|
95
|
+
# Collects any external URLs found in a directory of files. Also collectes
|
96
|
+
# every failed test from check_files_for_internal_woes.
|
97
|
+
# Sends the external URLs to Typhoeus for batch processing.
|
98
|
+
def check_directory_of_files
|
99
|
+
external_urls = {}
|
100
|
+
results = check_files_for_internal_woes
|
157
101
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if has_hash? href && @options[:check_external_hash]
|
162
|
-
queue_request(:get, href, filenames)
|
163
|
-
else
|
164
|
-
queue_request(:head, href, filenames)
|
165
|
-
end
|
102
|
+
results.each do |item|
|
103
|
+
external_urls.merge!(item[:external_urls])
|
104
|
+
@failed_tests.concat(item[:failed_tests])
|
166
105
|
end
|
167
|
-
logger.debug HTML::colorize :yellow, "Running requests for all #{hydra.queued_requests.size} external URLs..."
|
168
|
-
hydra.run
|
169
|
-
end
|
170
106
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
hydra.queue request
|
107
|
+
validate_urls(external_urls) unless @options[:disable_external]
|
108
|
+
|
109
|
+
logger.log :info, :blue, "Ran on #{files.length} files!\n\n"
|
175
110
|
end
|
176
111
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
return unless @options[:check_external_hash]
|
190
|
-
if hash = has_hash?(href)
|
191
|
-
body_doc = Nokogiri::HTML(response.body)
|
192
|
-
# user-content is a special addition by GitHub.
|
193
|
-
xpath = %$//*[@name="#{hash}"]|//*[@id="#{hash}"]$
|
194
|
-
xpath << %$|//*[@name="user-content-#{hash}"]|//*[@id="user-content-#{hash}"]$ if URI.parse(href).host.match(/github\.com/i)
|
195
|
-
if body_doc.xpath(xpath).empty?
|
196
|
-
add_failed_tests filenames, "External link #{href} failed: #{effective_url} exists, but the hash '#{hash}' does not", response_code
|
197
|
-
end
|
112
|
+
# Walks over each implemented check and runs them on the files, in parallel.
|
113
|
+
def check_files_for_internal_woes
|
114
|
+
Parallel.map(files, @parallel_opts) do |path|
|
115
|
+
html = create_nokogiri(path)
|
116
|
+
result = { :external_urls => {}, :failed_tests => [] }
|
117
|
+
|
118
|
+
checks.each do |klass|
|
119
|
+
logger.log :debug, :yellow, "Checking #{klass.to_s.downcase} on #{path} ..."
|
120
|
+
check = Object.const_get(klass).new(@src, path, html, @options)
|
121
|
+
check.run
|
122
|
+
result[:external_urls].merge!(check.external_urls)
|
123
|
+
result[:failed_tests].concat(check.issues) if check.issues.length > 0
|
198
124
|
end
|
199
|
-
|
200
|
-
return if @options[:only_4xx]
|
201
|
-
add_failed_tests filenames, "External link #{href} failed: got a time out", response_code
|
202
|
-
elsif (response_code == 405 || response_code == 420 || response_code == 503) && method == :head
|
203
|
-
# 420s usually come from rate limiting; let's ignore the query and try just the path with a GET
|
204
|
-
uri = URI(href)
|
205
|
-
queue_request(:get, uri.scheme + "://" + uri.host + uri.path, filenames)
|
206
|
-
# just be lazy; perform an explicit get request. some servers are apparently not configured to
|
207
|
-
# intercept HTTP HEAD
|
208
|
-
elsif method == :head
|
209
|
-
queue_request(:get, effective_url, filenames)
|
210
|
-
else
|
211
|
-
return if @options[:only_4xx] && !response_code.between?(400, 499)
|
212
|
-
# Received a non-successful http response.
|
213
|
-
add_failed_tests filenames, "External link #{href} failed: #{response_code} #{response.return_message}", response_code
|
125
|
+
result
|
214
126
|
end
|
215
127
|
end
|
216
128
|
|
217
|
-
def
|
218
|
-
|
129
|
+
def validate_urls(external_urls)
|
130
|
+
url_validator = HTML::Proofer::UrlValidator.new(logger, external_urls, @options, @typhoeus_opts, @hydra_opts)
|
131
|
+
@failed_tests.concat(url_validator.run)
|
219
132
|
end
|
220
133
|
|
221
134
|
def files
|
222
135
|
if File.directory? @src
|
223
|
-
pattern = File.join
|
136
|
+
pattern = File.join(@src, '**', "*#{@options[:ext]}")
|
224
137
|
files = Dir.glob(pattern).select { |fn| File.file? fn }
|
225
138
|
files.reject { |f| ignore_file?(f) }
|
226
139
|
elsif File.extname(@src) == @options[:ext]
|
@@ -231,49 +144,23 @@ module HTML
|
|
231
144
|
end
|
232
145
|
|
233
146
|
def ignore_file?(file)
|
234
|
-
|
235
|
-
if pattern.is_a?
|
236
|
-
|
237
|
-
elsif pattern.is_a? Regexp
|
238
|
-
return pattern =~ file
|
239
|
-
end
|
147
|
+
options[:file_ignore].each do |pattern|
|
148
|
+
return true if pattern.is_a?(String) && pattern == file
|
149
|
+
return true if pattern.is_a?(Regexp) && pattern =~ file
|
240
150
|
end
|
241
151
|
|
242
152
|
false
|
243
153
|
end
|
244
154
|
|
245
|
-
def
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
checks.delete("Favicons") unless @options[:favicon]
|
253
|
-
checks.delete("Html") unless @options[:validate_html]
|
254
|
-
checks
|
255
|
-
end
|
256
|
-
|
257
|
-
def has_hash?(url)
|
258
|
-
begin
|
259
|
-
URI.parse(url).fragment
|
260
|
-
rescue URI::InvalidURIError
|
261
|
-
nil
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def log_level
|
266
|
-
@options[:verbose] ? :debug : :info
|
267
|
-
end
|
268
|
-
|
269
|
-
def add_failed_tests(filenames, desc, status = nil)
|
270
|
-
if filenames.nil?
|
271
|
-
@failed_tests << Checks::Issue.new("", desc, status)
|
272
|
-
elsif
|
273
|
-
filenames.each { |f|
|
274
|
-
@failed_tests << Checks::Issue.new(f, desc, status)
|
275
|
-
}
|
155
|
+
def checks
|
156
|
+
return @checks unless @checks.nil?
|
157
|
+
@checks = HTML::Proofer::CheckRunner.checks.map(&:name)
|
158
|
+
@checks.delete('FaviconCheck') unless @options[:check_favicon]
|
159
|
+
@checks.delete('HtmlCheck') unless @options[:check_html]
|
160
|
+
@options[:checks_to_ignore].each do |ignored|
|
161
|
+
@checks.delete(ignored)
|
276
162
|
end
|
163
|
+
@checks
|
277
164
|
end
|
278
165
|
|
279
166
|
def failed_tests
|
@@ -282,5 +169,14 @@ module HTML
|
|
282
169
|
@failed_tests.each { |f| result << f.to_s }
|
283
170
|
result
|
284
171
|
end
|
172
|
+
|
173
|
+
def print_failed_tests
|
174
|
+
sorted_failures = HTML::Proofer::CheckRunner::SortedIssues.new(@failed_tests, @options[:error_sort], logger)
|
175
|
+
|
176
|
+
sorted_failures.sort_and_report
|
177
|
+
count = @failed_tests.length
|
178
|
+
failure_text = "#{count} " << (count == 1 ? 'failure' : 'failures')
|
179
|
+
fail logger.colorize :red, "HTML-Proofer found #{failure_text}!"
|
180
|
+
end
|
285
181
|
end
|
286
182
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Command test' do
|
4
|
+
it 'works with as-links' do
|
5
|
+
output = make_bin('--as-links www.github.com,foofoofoo.biz')
|
6
|
+
expect(output).to match('1 failure')
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'works with alt-ignore' do
|
10
|
+
ignorableLinks = "#{FIXTURES_DIR}/images/ignorableAltViaOptions.html"
|
11
|
+
output = make_bin('--alt-ignore /wikimedia/,gpl.png', ignorableLinks)
|
12
|
+
expect(output).to match('successfully')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'works with checks_to_ignore' do
|
16
|
+
external = "#{FIXTURES_DIR}/links/file.foo"
|
17
|
+
output = make_bin('--ext .foo --checks-to-ignore LinkCheck', external)
|
18
|
+
expect(output).to match('successfully')
|
19
|
+
expect(output).to_not match('LinkCheck')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'works with check-external-hash' do
|
23
|
+
brokenHashOnTheWeb = "#{FIXTURES_DIR}/links/brokenHashOnTheWeb.html"
|
24
|
+
output = make_bin('--check-external-hash', brokenHashOnTheWeb)
|
25
|
+
expect(output).to match('1 failure')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'works with directory-index-file' do
|
29
|
+
link_pointing_to_directory = "#{FIXTURES_DIR}/links/link_pointing_to_directory.html"
|
30
|
+
output = make_bin('--directory-index-file index.php', link_pointing_to_directory)
|
31
|
+
expect(output).to match('successfully')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'works with disable-external' do
|
35
|
+
external = "#{FIXTURES_DIR}/links/brokenLinkExternal.html"
|
36
|
+
output = make_bin('--disable-external', external)
|
37
|
+
expect(output).to match('successfully')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'works with ext' do
|
41
|
+
external = "#{FIXTURES_DIR}/links/file.foo"
|
42
|
+
output = make_bin('--ext .foo', external)
|
43
|
+
expect(output).to match('1 failure')
|
44
|
+
expect(output).to match('LinkCheck')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'works with file-ignore' do
|
48
|
+
external = "#{FIXTURES_DIR}/links/brokenHashInternal.html"
|
49
|
+
output = make_bin("--file-ignore #{external}", external)
|
50
|
+
expect(output).to match('successfully')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'works with href-ignore' do
|
54
|
+
ignorableLinks = "#{FIXTURES_DIR}/links/ignorableLinksViaOptions.html"
|
55
|
+
output = make_bin('--href-ignore /^http:\/\//,/sdadsad/,../whaadadt.html', ignorableLinks)
|
56
|
+
expect(output).to match('successfully')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'works with href-swap' do
|
60
|
+
translatedLink = "#{FIXTURES_DIR}/links/linkTranslatedViaHrefSwap.html"
|
61
|
+
output = make_bin('--href-swap "\A/articles/([\w-]+):\1.html"', translatedLink)
|
62
|
+
expect(output).to match('successfully')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'works with only-4xx' do
|
66
|
+
brokenHashOnTheWeb = "#{FIXTURES_DIR}/links/brokenHashOnTheWeb.html"
|
67
|
+
output = make_bin('--only-4xx', brokenHashOnTheWeb)
|
68
|
+
expect(output).to match('successfully')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'works with check-favicon' do
|
72
|
+
broken = "#{FIXTURES_DIR}/favicon/favicon_broken.html"
|
73
|
+
output = make_bin('--check-favicon', broken)
|
74
|
+
expect(output).to match('1 failure')
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'works with check-html' do
|
78
|
+
broken = "#{FIXTURES_DIR}/html/invalid_tag.html"
|
79
|
+
output = make_bin('--check-html', broken)
|
80
|
+
expect(output).to match('1 failure')
|
81
|
+
end
|
82
|
+
end
|
@@ -1,47 +1,47 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
it
|
3
|
+
describe 'Favicons test' do
|
4
|
+
it 'ignores for absent favicon by default' do
|
5
5
|
absent = "#{FIXTURES_DIR}/favicon/favicon_absent.html"
|
6
|
-
expect(
|
6
|
+
expect(run_proofer(absent).failed_tests).to eq []
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
9
|
+
it 'fails for absent favicon' do
|
10
10
|
absent = "#{FIXTURES_DIR}/favicon/favicon_absent.html"
|
11
|
-
proofer =
|
12
|
-
expect(proofer.failed_tests.first).to match
|
11
|
+
proofer = run_proofer(absent, { :check_favicon => true })
|
12
|
+
expect(proofer.failed_tests.first).to match(/no favicon specified/)
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'fails for absent favicon but present apple touch icon' do
|
16
16
|
absent = "#{FIXTURES_DIR}/favicon/favicon_absent_apple.html"
|
17
|
-
proofer =
|
17
|
+
proofer = run_proofer(absent, { :check_favicon => true })
|
18
18
|
# Travis gives a different error message here for some reason
|
19
|
-
expect(proofer.failed_tests.last).to match
|
19
|
+
expect(proofer.failed_tests.last).to match(/(internally linking to gpl.png, which does not exist|no favicon specified)/)
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
22
|
+
it 'fails for broken favicon' do
|
23
23
|
broken = "#{FIXTURES_DIR}/favicon/favicon_broken.html"
|
24
|
-
proofer =
|
24
|
+
proofer = run_proofer(broken, { :check_favicon => true })
|
25
25
|
|
26
|
-
expect(proofer.failed_tests.first).to match
|
26
|
+
expect(proofer.failed_tests.first).to match(/internally linking to asdadaskdalsdk.png/)
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
29
|
+
it 'passes for present favicon' do
|
30
30
|
present = "#{FIXTURES_DIR}/favicon/favicon_present.html"
|
31
|
-
proofer =
|
31
|
+
proofer = run_proofer(present, { :check_favicon => true })
|
32
32
|
expect(proofer.failed_tests).to eq []
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
35
|
+
it 'passes for present favicon with shortcut notation' do
|
36
36
|
present = "#{FIXTURES_DIR}/favicon/favicon_present_shortcut.html"
|
37
|
-
proofer =
|
37
|
+
proofer = run_proofer(present, { :check_favicon => true })
|
38
38
|
expect(proofer.failed_tests).to eq []
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'fails for broken favicon with data-proofer-ignore' do
|
42
42
|
broken_but_ignored = "#{FIXTURES_DIR}/favicon/favicon_broken_but_ignored.html"
|
43
|
-
proofer =
|
44
|
-
expect(proofer.failed_tests.first).to match
|
43
|
+
proofer = run_proofer(broken_but_ignored, { :check_favicon => true })
|
44
|
+
expect(proofer.failed_tests.first).to match(/no favicon specified/)
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<picture>
|
2
|
+
<!--[if IE 9]><video style="display: none;"><![endif]-->
|
3
|
+
<source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
|
4
|
+
<source srcset="examples/images/large.jpg" media="(min-width: 800px)">
|
5
|
+
<!--[if IE 9]></video><![endif]-->
|
6
|
+
<img src="gpl.png" alt="Working">
|
7
|
+
</picture>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<picture>
|
2
|
+
<!--[if IE 9]><video style="display: none;"><![endif]-->
|
3
|
+
<source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
|
4
|
+
<source srcset="examples/images/large.jpg" media="(min-width: 800px)">
|
5
|
+
<!--[if IE 9]></video><![endif]-->
|
6
|
+
<img srcset="gpl.png">
|
7
|
+
</picture>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<picture>
|
2
|
+
<!--[if IE 9]><video style="display: none;"><![endif]-->
|
3
|
+
<source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
|
4
|
+
<source srcset="examples/images/large.jpg" media="(min-width: 800px)">
|
5
|
+
<!--[if IE 9]></video><![endif]-->
|
6
|
+
<img srcset="notreal.png" alt="Missing image">
|
7
|
+
</picture>
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -1 +1 @@
|
|
1
|
-
<a href="https://help.github.com/
|
1
|
+
<a href="https://help.github.com/articlezzz">add ssh</a>
|
@@ -0,0 +1 @@
|
|
1
|
+
<a href="http://asia.cnet.com/blogs/geekonomics/post.htm?id=63009224">not real</a>
|
@@ -0,0 +1 @@
|
|
1
|
+
<html lang="jp">
|