html-proofer 2.5.2 → 3.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.
@@ -0,0 +1,47 @@
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 'html-proofer'
9
+ require_all 'html-proofer/check'
10
+
11
+ require 'parallel'
12
+ require 'fileutils'
13
+
14
+ begin
15
+ require 'awesome_print'
16
+ rescue LoadError; end
17
+
18
+ module HTMLProofer
19
+
20
+ def check_file(file, options = {})
21
+ fail ArgumentError unless file.is_a?(String)
22
+ options[:type] = :file
23
+ HTMLProofer::Runner.new(file, options)
24
+ end
25
+ module_function :check_file
26
+
27
+ def check_directory(directory, options = {})
28
+ fail ArgumentError unless directory.is_a?(String)
29
+ options[:type] = :directory
30
+ HTMLProofer::Runner.new([directory], options)
31
+ end
32
+ module_function :check_directory
33
+
34
+ def check_directories(directories, options = {})
35
+ fail ArgumentError unless directories.is_a?(Array)
36
+ options[:type] = :directory
37
+ HTMLProofer::Runner.new(directories, options)
38
+ end
39
+ module_function :check_directories
40
+
41
+ def check_links(links, options = {})
42
+ fail ArgumentError unless links.is_a?(Array)
43
+ options[:type] = :links
44
+ HTMLProofer::Runner.new(links, options)
45
+ end
46
+ module_function :check_links
47
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-06 00:00:00.000000000 Z
11
+ date: 2016-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '4.2'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '4.2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: redcarpet
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -178,30 +192,45 @@ dependencies:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
194
  version: '2.9'
195
+ - !ruby/object:Gem::Dependency
196
+ name: timecop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.8'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.8'
181
209
  description: Test your rendered HTML files to make sure they're accurate.
182
210
  email:
183
211
  - gjtorikian@gmail.com
184
212
  executables:
185
- - htmlproof
213
+ - htmlproofer
186
214
  extensions: []
187
215
  extra_rdoc_files: []
188
216
  files:
189
- - bin/htmlproof
190
- - lib/html/proofer.rb
191
- - lib/html/proofer/cache.rb
192
- - lib/html/proofer/check_runner.rb
193
- - lib/html/proofer/check_runner/issue.rb
194
- - lib/html/proofer/checkable.rb
195
- - lib/html/proofer/checks/favicon.rb
196
- - lib/html/proofer/checks/html.rb
197
- - lib/html/proofer/checks/images.rb
198
- - lib/html/proofer/checks/links.rb
199
- - lib/html/proofer/checks/scripts.rb
200
- - lib/html/proofer/log.rb
201
- - lib/html/proofer/url_validator.rb
202
- - lib/html/proofer/utils.rb
203
- - lib/html/proofer/version.rb
204
- - lib/html/proofer/xpathfunctions.rb
217
+ - bin/htmlproofer
218
+ - lib/html-proofer.rb
219
+ - lib/html-proofer/cache.rb
220
+ - lib/html-proofer/check.rb
221
+ - lib/html-proofer/check/favicon.rb
222
+ - lib/html-proofer/check/html.rb
223
+ - lib/html-proofer/check/images.rb
224
+ - lib/html-proofer/check/links.rb
225
+ - lib/html-proofer/check/scripts.rb
226
+ - lib/html-proofer/configuration.rb
227
+ - lib/html-proofer/element.rb
228
+ - lib/html-proofer/issue.rb
229
+ - lib/html-proofer/log.rb
230
+ - lib/html-proofer/runner.rb
231
+ - lib/html-proofer/url_validator.rb
232
+ - lib/html-proofer/utils.rb
233
+ - lib/html-proofer/version.rb
205
234
  homepage: https://github.com/gjtorikian/html-proofer
206
235
  licenses:
207
236
  - MIT
@@ -222,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
251
  version: '0'
223
252
  requirements: []
224
253
  rubyforge_project:
225
- rubygems_version: 2.4.5
254
+ rubygems_version: 2.4.5.1
226
255
  signing_key:
227
256
  specification_version: 4
228
257
  summary: A set of tests to validate your HTML output. These tests check if your image
data/bin/htmlproof DELETED
@@ -1,85 +0,0 @@
1
- #!/usr/bin/env ruby
2
- STDOUT.sync = true
3
-
4
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
5
-
6
- require 'html/proofer'
7
- require 'mercenary'
8
- require 'rubygems'
9
-
10
- def to_regex?(item)
11
- if item.start_with?('/') && item.end_with?('/')
12
- Regexp.new item[1...-1]
13
- else
14
- item
15
- end
16
- end
17
-
18
- Mercenary.program(:htmlproof) do |p|
19
- p.version HTML::Proofer::VERSION
20
- p.description %(Test your rendered HTML files to make sure they're accurate.)
21
- p.syntax 'htmlproof PATH [options]'
22
-
23
- p.description 'Runs the HTML-Proofer suite on the files in PATH. For more details, see the README.'
24
-
25
- p.option 'as_links', '--as-links', 'Assumes that `PATH` is a comma-separated array of links to check.'
26
- p.option 'alt_ignore', '--alt-ignore image1,[image2,...]', Array, 'Comma-separated list of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore'
27
- p.option 'empty_alt_ignore', '--empty-alt-ignore', 'Ignores images with empty alt tags.'
28
- p.option 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, ' An array of Strings indicating which checks you\'d like to not perform.'
29
- p.option 'check_external_hash', '--check-external-hash', 'Checks whether external hashes exist (even if the website exists). This slows the checker down (default: `false`).'
30
- p.option 'check_favicon', '--check-favicon', 'Enables the favicon checker (default: `false`).'
31
- p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
32
- p.option 'directory_index_file', '--directory-index-file', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
33
- p.option 'disable_external', '--disable-external', 'Disables the external link checker (default: `false`)'
34
- p.option 'error_sort', '--error-sort SORT', 'Defines the sort order for error output. Can be `path`, `desc`, or `status` (default: `path`).'
35
- p.option 'enforce_https', '--enforce-https', 'Fails a link if it\'s not marked as `https` (default: `false`).'
36
- p.option 'ext', '--ext EXT', String, 'The extension of your HTML files (default: `.html`)'
37
- p.option 'file_ignore', '--file-ignore file1,[file2,...]', Array, 'Comma-separated list of Strings or RegExps containing file paths that are safe to ignore'
38
- p.option 'href_ignore', '--href-ignore link1,[link2,...]', Array, 'Comma-separated list of Strings or RegExps containing `href`s that are safe to ignore.'
39
- p.option 'href_swap', '--href-swap re:string,[re:string,...]', Array, 'Comma-separated list of key-value pairs of `RegExp:String`. Transforms links matching `RegExp` into `String`'
40
- p.option 'ignore_script_embeds', '--ignore-script-embeds', 'Ignore `check_html` errors associated with `script`s (default: `false`)'
41
- p.option 'only_4xx', '--only-4xx', 'Only reports errors for links that fall within the 4x status code range.'
42
- p.option 'url_ignore', '--url-ignore link1,[link2,...]', Array, 'Comma-separated list of Strings or RegExps containing URLs that are safe to ignore.'
43
- p.option 'verbose', '--verbose', 'Enables more verbose logging.'
44
- p.option 'verbosity', '--verbosity', String, 'Sets the logging level, as determined by Yell'
45
-
46
- p.action do |args, opts|
47
- args = ['.'] if args.empty?
48
- path = args.first
49
-
50
- options = {}
51
-
52
- # prepare everything to go to proofer
53
- p.options.select { |o| !opts[o.config_key].nil? }.each do |option|
54
- if option.return_type.to_s == 'Array' # TODO: is_a? doesn't work here?
55
- opts[option.config_key] = opts[option.config_key].map { |i| to_regex?(i) }
56
- end
57
- options[option.config_key.to_sym] = opts[option.config_key]
58
- end
59
-
60
- # some minor manipulation of a special option
61
- unless opts['href_swap'].nil?
62
- options[:href_swap] = {}
63
- opts['href_swap'].each do |s|
64
- pair = s.split(':', 2)
65
- options[:href_swap][Regexp.new(pair[0])] = pair[1]
66
- end
67
- end
68
-
69
- # check for ignore_scripts_embeds as it should be set in :validation
70
- unless opts['ignore_script_embeds'].nil?
71
- options[:validation] = { :ignore_script_embeds => true }
72
- end
73
-
74
- options[:error_sort] = opts['error-sort'].to_sym unless opts['error-sort'].nil?
75
- options[:verbosity] = opts['verbosity'].to_sym unless opts['verbosity'].nil?
76
-
77
- # FIXME: this is gross
78
- options[:validation] = {}
79
- options[:validation][:ignore_script_embeds] = opts['ignore_script_embeds']
80
-
81
- path = path.delete(' ').split(',') if opts['as_links']
82
-
83
- HTML::Proofer.new(path, options).run
84
- end
85
- end
@@ -1,16 +0,0 @@
1
- module HTML
2
- class Proofer
3
- module Cache
4
- def create_nokogiri(path)
5
- if File.exist? path
6
- content = File.open(path).read
7
- else
8
- content = path
9
- end
10
-
11
- Nokogiri::HTML(content)
12
- end
13
- module_function :create_nokogiri
14
- end
15
- end
16
- end
@@ -1,69 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module HTML
4
- class Proofer
5
- # Mostly handles issue management and collecting of external URLs.
6
- class CheckRunner
7
-
8
- attr_reader :issues, :src, :path, :options, :typhoeus_opts, :hydra_opts, :parallel_opts, \
9
- :validation_opts, :external_urls, :href_ignores, :url_ignores, :alt_ignores, \
10
- :empty_alt_ignore
11
-
12
- def initialize(src, path, html, options, typhoeus_opts, hydra_opts, parallel_opts, validation_opts)
13
- @src = src
14
- @path = path
15
- @html = remove_ignored(html)
16
- @options = options
17
- @typhoeus_opts = typhoeus_opts
18
- @hydra_opts = hydra_opts
19
- @parallel_opts = parallel_opts
20
- @validation_opts = validation_opts
21
- @issues = []
22
- @href_ignores = @options[:href_ignore]
23
- @url_ignores = @options[:url_ignore]
24
- @alt_ignores = @options[:alt_ignore]
25
- @empty_alt_ignore = @options[:empty_alt_ignore]
26
- @external_urls = {}
27
- end
28
-
29
- def run
30
- fail NotImplementedError, 'HTML::Proofer::CheckRunner subclasses must implement #run'
31
- end
32
-
33
- def add_issue(desc, line_number = nil, status = -1)
34
- @issues << Issue.new(@path, desc, line_number, status)
35
- end
36
-
37
- def add_to_external_urls(url, line)
38
- return if @external_urls[url]
39
- add_path_for_url(url)
40
- end
41
-
42
- def add_path_for_url(url)
43
- if @external_urls[url]
44
- @external_urls[url] << @path
45
- else
46
- @external_urls[url] = [@path]
47
- end
48
- end
49
-
50
- def self.checks
51
- classes = []
52
-
53
- ObjectSpace.each_object(Class) do |c|
54
- next unless c.superclass == self
55
- classes << c
56
- end
57
-
58
- classes
59
- end
60
-
61
- private
62
-
63
- def remove_ignored(html)
64
- html.css('code, pre, tt').each(&:unlink)
65
- html
66
- end
67
- end
68
- end
69
- end
@@ -1,164 +0,0 @@
1
- require 'addressable/uri'
2
- require_relative './utils'
3
-
4
- module HTML
5
- class Proofer
6
- # Represents the superclass from which all checks derive.
7
- class Checkable
8
- include HTML::Proofer::Utils
9
-
10
- attr_reader :line
11
-
12
- def initialize(obj, check)
13
- obj.attributes.each_pair do |attribute, value|
14
- instance_variable_set("@#{attribute.tr('-:.', '_')}".to_sym, value.value)
15
- end
16
-
17
- @text = obj.content
18
- @check = check
19
- @checked_paths = {}
20
- @type = self.class.name
21
- @line = obj.line
22
-
23
- if @href && @check.options[:href_swap]
24
- @href = swap(@href, @check.options[:href_swap])
25
- end
26
-
27
- # fix up missing protocols
28
- @href.insert 0, 'http:' if @href =~ %r{^//}
29
- @src.insert 0, 'http:' if @src =~ %r{^//}
30
- end
31
-
32
- def url
33
- @src || @srcset || @href || ''
34
- end
35
-
36
- def valid?
37
- !parts.nil?
38
- end
39
-
40
- def parts
41
- @parts ||= Addressable::URI.parse url
42
- rescue URI::Error, Addressable::URI::InvalidURIError
43
- @parts = nil
44
- end
45
-
46
- def path
47
- Addressable::URI.unencode parts.path unless parts.nil?
48
- end
49
-
50
- def hash
51
- parts.fragment unless parts.nil?
52
- end
53
-
54
- def scheme
55
- parts.scheme unless parts.nil?
56
- end
57
-
58
- # path is to an external server
59
- def remote?
60
- %w( http https ).include? scheme
61
- end
62
-
63
- def non_http_remote?
64
- !scheme.nil? && !remote?
65
- end
66
-
67
- def ignore?
68
- return true if @data_proofer_ignore
69
-
70
- # ignore base64 encoded images
71
- if %w(ImageCheckable FaviconCheckable).include? @type
72
- return true if url.match(/^data:image/)
73
- end
74
-
75
- # ignore user defined URLs
76
- return true if ignores_pattern_check(@check.url_ignores)
77
-
78
- # ignore user defined hrefs
79
- if 'LinkCheckable' == @type
80
- return true if ignores_pattern_check(@check.href_ignores)
81
- end
82
-
83
- # ignore user defined alts
84
- if 'ImageCheckable' == @type
85
- return true if ignores_pattern_check(@check.alt_ignores)
86
- end
87
- end
88
-
89
- def ignore_empty_alt?
90
- @check.empty_alt_ignore
91
- end
92
-
93
- # path is external to the file
94
- def external?
95
- !internal?
96
- end
97
-
98
- # path is an anchor or a query
99
- def internal?
100
- url.start_with? '#', '?'
101
- end
102
-
103
- def file_path
104
- return if path.nil?
105
-
106
- if path =~ %r{^/} # path relative to root
107
- base = File.directory?(@check.src) ? @check.src : File.dirname(@check.src)
108
- elsif File.exist?(File.expand_path path, @check.src) # relative links, path is a file
109
- base = File.dirname @check.path
110
- elsif File.exist?(File.join(File.dirname(@check.path), path)) # relative links in nested dir, path is a file
111
- base = File.dirname @check.path
112
- else # relative link, path is a directory
113
- base = @check.path
114
- end
115
-
116
- file = File.join base, path
117
-
118
- # implicit index support
119
- if File.directory?(file) && !unslashed_directory?(file)
120
- file = File.join file, @check.options[:directory_index_file]
121
- end
122
-
123
- file
124
- end
125
-
126
- # checks if a file exists relative to the current pwd
127
- def exists?
128
- return @checked_paths[absolute_path] if @checked_paths.key? absolute_path
129
- @checked_paths[absolute_path] = File.exist? absolute_path
130
- end
131
-
132
- def absolute_path
133
- path = file_path || @check.path
134
- File.expand_path path, Dir.pwd
135
- end
136
-
137
- def ignores_pattern_check(links)
138
- links.each do |ignore|
139
- if ignore.is_a? String
140
- return true if ignore == url
141
- elsif ignore.is_a? Regexp
142
- return true if ignore =~ url
143
- end
144
- end
145
-
146
- false
147
- end
148
-
149
- def unslashed_directory?(file)
150
- File.directory?(file) && !file.end_with?(File::SEPARATOR) && !follow_location?
151
- end
152
-
153
- def follow_location?
154
- @check.typhoeus_opts && @check.typhoeus_opts[:followlocation]
155
- end
156
-
157
- private
158
-
159
- def real_attr(attr)
160
- attr.to_s unless attr.nil? || attr.empty?
161
- end
162
- end
163
- end
164
- end
@@ -1,46 +0,0 @@
1
- # encoding: utf-8
2
-
3
- class HtmlCheck < ::HTML::Proofer::CheckRunner
4
- # new html5 tags (source: http://www.w3schools.com/html/html5_new_elements.asp)
5
- # and svg child tags (source: https://developer.mozilla.org/en-US/docs/Web/SVG/Element)
6
- HTML5_TAGS = %w(article aside bdi details dialog figcaption
7
- figure footer header main mark menuitem meter
8
- nav progress rp rt ruby section summary
9
- time wbr datalist keygen output color date
10
- datetime datetime-local email month number
11
- range search tel time url week canvas
12
- svg audio embed source track video
13
- altGlyph altGlyphDef altGlyphItem animate
14
- animateColor animateMotion animateTransform
15
- circle clipPath color-profile cursor defs
16
- desc ellipse feBlend feColorMatrix
17
- feComponentTransfer feComposite feConvolveMatrix
18
- feDiffuseLighting feDisplacementMap feDistantLight
19
- feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
20
- feImage feMerge feMergeNode feMorphology feOffset
21
- fePointLight feSpecularLighting feSpotLight feTile
22
- feTurbulence filter font font-face font-face-format
23
- font-face-name font-face-src font-face-uri
24
- foreignObject g glyph glyphRef hkern image line
25
- linearGradient marker mask metadata missing-glyph
26
- mpath path pattern polygon polyline radialGradient
27
- rect set stop switch symbol text textPath tref tspan use
28
- view vkern)
29
-
30
- SCRIPT_EMBEDS_MSG = /Element script embeds close tag/
31
-
32
- def run
33
- @html.errors.each do |error|
34
- message = error.message
35
- line = error.line
36
- # Nokogiri (or rather libxml2 underhood) only recognizes html4 tags,
37
- # so we need to skip errors caused by the new tags in html5
38
- next if HTML5_TAGS.include? message[/Tag ([\w-]+) invalid/o, 1]
39
-
40
- # tags embedded in scripts are used in templating languages: http://git.io/vOovv
41
- next if @validation_opts[:ignore_script_embeds] && message =~ SCRIPT_EMBEDS_MSG
42
-
43
- add_issue(message, line)
44
- end
45
- end
46
- end
@@ -1,54 +0,0 @@
1
- # encoding: utf-8
2
-
3
- class ImageCheckable < ::HTML::Proofer::Checkable
4
- SCREEN_SHOT_REGEX = /Screen(?: |%20)Shot(?: |%20)\d+-\d+-\d+(?: |%20)at(?: |%20)\d+.\d+.\d+/
5
-
6
- attr_reader :alt
7
-
8
- def empty_alt_tag?
9
- alt.strip.empty?
10
- end
11
-
12
- def terrible_filename?
13
- src =~ SCREEN_SHOT_REGEX
14
- end
15
-
16
- def src
17
- real_attr(@src) || real_attr(@srcset)
18
- end
19
-
20
- def missing_src?
21
- !src
22
- end
23
- end
24
-
25
- class ImageCheck < ::HTML::Proofer::CheckRunner
26
- def run
27
- @html.css('img').each do |node|
28
- img = ImageCheckable.new(node, self)
29
- line = node.line
30
-
31
- next if img.ignore?
32
-
33
- # screenshot filenames should return because of terrible names
34
- next add_issue("image has a terrible filename (#{img.src})", line) if img.terrible_filename?
35
-
36
- # does the image exist?
37
- if img.missing_src?
38
- add_issue('image has no src or srcset attribute', line)
39
- else
40
- if img.remote?
41
- add_to_external_urls(img.src, line)
42
- else
43
- add_issue("internal image #{img.src} does not exist", line) unless img.exists?
44
- end
45
- end
46
-
47
- if img.alt.nil? || (img.empty_alt_tag? && !img.ignore_empty_alt?)
48
- add_issue("image #{img.src} does not have an alt attribute", line)
49
- end
50
- end
51
-
52
- external_urls
53
- end
54
- end