html-proofer 1.6.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +74 -56
  4. data/Rakefile +4 -6
  5. data/bin/htmlproof +46 -36
  6. data/html-proofer.gemspec +22 -22
  7. data/lib/html/proofer/check_runner/issue.rb +62 -0
  8. data/lib/html/proofer/{check.rb → check_runner.rb} +11 -19
  9. data/lib/html/proofer/checkable.rb +42 -28
  10. data/lib/html/proofer/checks/favicon.rb +6 -6
  11. data/lib/html/proofer/checks/html.rb +11 -12
  12. data/lib/html/proofer/checks/images.rb +11 -11
  13. data/lib/html/proofer/checks/links.rb +30 -28
  14. data/lib/html/proofer/checks/scripts.rb +7 -8
  15. data/lib/html/proofer/log.rb +38 -0
  16. data/lib/html/proofer/url_validator.rb +135 -0
  17. data/lib/html/proofer/utils.rb +24 -0
  18. data/lib/html/proofer/version.rb +1 -1
  19. data/lib/html/proofer.rb +95 -199
  20. data/spec/html/proofer/command_spec.rb +82 -0
  21. data/spec/html/proofer/favicon_spec.rb +20 -20
  22. data/spec/html/proofer/fixtures/images/srcSetCheck.html +7 -0
  23. data/spec/html/proofer/fixtures/images/srcSetIgnorable.html +13 -0
  24. data/spec/html/proofer/fixtures/images/srcSetMissingAlt.html +7 -0
  25. data/spec/html/proofer/fixtures/images/srcSetMissingImage.html +7 -0
  26. data/spec/html/proofer/fixtures/links/erstiebegru/314/210/303/237ung.html +1 -0
  27. data/spec/html/proofer/fixtures/links/erstiebegr/303/274/303/237ung.html +1 -0
  28. data/spec/html/proofer/fixtures/links/file.foo +11 -0
  29. data/spec/html/proofer/fixtures/links/folder/multiples/catalog/file.html +8 -0
  30. data/spec/html/proofer/fixtures/links/folder/multiples/javadoc/file.html +8 -0
  31. data/spec/html/proofer/fixtures/links/nodupe.html +1 -1
  32. data/spec/html/proofer/fixtures/links/redirected_error.html +1 -0
  33. data/spec/html/proofer/fixtures/links/rootLink/rootLink.html +0 -1
  34. data/spec/html/proofer/fixtures/links/urlencoded-href.html +2 -0
  35. data/spec/html/proofer/fixtures/links/utf8Link.html +2 -0
  36. data/spec/html/proofer/fixtures/utils/lang-jp.html +1 -0
  37. data/spec/html/proofer/html_spec.rb +25 -25
  38. data/spec/html/proofer/images_spec.rb +59 -35
  39. data/spec/html/proofer/links_spec.rb +152 -109
  40. data/spec/html/proofer/scripts_spec.rb +17 -17
  41. data/spec/html/proofer/utils_spec.rb +14 -0
  42. data/spec/html/proofer_spec.rb +58 -38
  43. data/spec/spec_helper.rb +13 -6
  44. metadata +39 -7
  45. data/lib/html/proofer/checks.rb +0 -15
  46. data/lib/html/proofer/issue.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8328f696789f830910e2bee17b2b015e8ffc0b0d
4
- data.tar.gz: f051884d9787841d70dfdaf2ebedc5bb7818a6e2
3
+ metadata.gz: 2e94fed7b3cb30e272c5de25511ad9604e2a9663
4
+ data.tar.gz: d2ba44ef2943e993d69906089e374ae51013ff4b
5
5
  SHA512:
6
- metadata.gz: cf0bfd4a6060c0eebe58be4caad40cbada074241ed378ced25236f52e594b1ff1f1d528c4bb757fac11fe4bb3a68dce072950ccbe5eb965652179660fda19285
7
- data.tar.gz: 53fe8b4b33e7d6507da659f18e54279c85bf741d9bb84439430147584ac1928ff085b31cd61576313098e1e383b216bdff0f844fb9e4fb0f3156c11176a2195a
6
+ metadata.gz: 9f65536fcc74006b51ca34ecc77b048ea59608a2a055c4961afaa086d92c3fe09cc2056de5b7d2a5546f37ec0d6586bec29d1fd7fd05607aaaae3c777cf60172
7
+ data.tar.gz: ca131c1f0a7d06da44a40a7e714ece99821102153c158f130d909d226a86347ce10745d87b62954cdf71657188459fffef8b7410a949a5134b0ee9236ead3ec9
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
data/README.md CHANGED
@@ -22,6 +22,47 @@ Or install it yourself as:
22
22
 
23
23
  **NOTE:** When installation speed matters, set `NOKOGIRI_USE_SYSTEM_LIBRARIES` to `true` in your environment. This is useful for increasing the speed of your Continuous Integration builds.
24
24
 
25
+ ### Real-life examples
26
+
27
+ Project | Repository
28
+ :--- | :---
29
+ [Raspberry Pi documentation](http://www.raspberrypi.org/documentation/) | [raspberrypi/documentation]( https://github.com/raspberrypi/documentation)
30
+ [Open Whisper Systems website](https://whispersystems.org/) | [WhisperSystems/whispersystems.org](https://github.com/WhisperSystems/whispersystems.org)
31
+ [Jekyll website](http://jekyllrb.com/) | [jekyll/jekyll](https://github.com/jekyll/jekyll)
32
+
33
+ ## What's Tested?
34
+
35
+ ### Images
36
+
37
+ `img` elements:
38
+
39
+ * Whether all your images have alt tags
40
+ * Whether your internal image references are not broken
41
+ * Whether external images are showing
42
+
43
+ ### Links
44
+
45
+ `a`, `link` elements:
46
+
47
+ * Whether your internal links are not broken; this includes hash references (`#linkToMe`)
48
+ * Whether external links are working
49
+
50
+ ### Scripts
51
+
52
+ `script` elements:
53
+
54
+ * Whether your internal script references are not broken
55
+ * Whether external scripts are loading
56
+
57
+ ### Favicon
58
+
59
+ Checks if your favicons are valid. This is an optional feature, set the `check_favicon` option to turn it on.
60
+
61
+ ### HTML
62
+
63
+ Nokogiri looks at the markup and [provides errors](http://www.nokogiri.org/tutorials/ensuring_well_formed_markup.html) when parsing your document.
64
+ This is an optional feature, set the `check_html` option to enable validation errors from Nokogiri.
65
+
25
66
  ## Usage
26
67
 
27
68
  ### Using in a script
@@ -35,7 +76,7 @@ require 'html/pipeline'
35
76
  require 'find'
36
77
 
37
78
  # make an out dir
38
- Dir.mkdir("out") unless File.exists?("out")
79
+ Dir.mkdir("out") unless File.exist?("out")
39
80
 
40
81
  pipeline = HTML::Pipeline.new [
41
82
  HTML::Pipeline::MarkdownFilter,
@@ -90,79 +131,47 @@ Don't have or want a `Rakefile`? You _could_ also do something like the followin
90
131
  htmlproof ./_site
91
132
  ```
92
133
 
93
- ### Real-life examples
94
-
95
- Project | Repository
96
- :--- | :---
97
- [Raspberry Pi documentation](http://www.raspberrypi.org/documentation/) | [raspberrypi/documentation]( https://github.com/raspberrypi/documentation)
98
- [Open Whisper Systems website](https://whispersystems.org/) | [WhisperSystems/whispersystems.org](https://github.com/WhisperSystems/whispersystems.org)
99
- [Jekyll website](http://jekyllrb.com/) | [jekyll/jekyll](https://github.com/jekyll/jekyll)
100
-
101
- ## What's Tested?
102
-
103
- ### Images
104
-
105
- `img` elements:
106
-
107
- * Whether all your images have alt tags
108
- * Whether your internal image references are not broken
109
- * Whether external images are showing
110
-
111
- ### Links
112
-
113
- `a`, `link` elements:
114
-
115
- * Whether your internal links are not broken; this includes hash references (`#linkToMe`)
116
- * Whether external links are working
117
-
118
- ### Scripts
119
-
120
- `script` elements:
121
-
122
- * Whether your internal script references are not broken
123
- * Whether external scripts are loading
124
-
125
- ### HTML
126
-
127
- Nokogiri looks at the markup and [provides errors](http://www.nokogiri.org/tutorials/ensuring_well_formed_markup.html) when parsing your document.
128
- This is an optional feature, set the `validate_html` option to enable validation errors from Nokogiri.
129
-
130
134
  ## Configuration
131
135
 
132
136
  The `HTML::Proofer` constructor takes an optional hash of additional options:
133
137
 
134
138
  | Option | Description | Default |
135
139
  | :----- | :---------- | :------ |
140
+ | `alt_ignore` | An array of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore. | `[]` |
141
+ | `check_external_hash` | Checks whether external hashes exist (even if the website exists). This slows the checker down. | `false` |
142
+ |`checks_to_ignore`| An array of Strings indicating which checks you'd like to not perform. | `[]`
143
+ | `directory_index_file` | Sets the file to look for when a link refers to a directory. | `index.html` |
136
144
  | `disable_external` | If `true`, does not run the external link checker, which can take a lot of time. | `false` |
145
+ | `error_sort` | Defines the sort order for error output. Can be `:path`, `:desc`, or `:status`. | `:path`
137
146
  | `ext` | The extension of your HTML files including the dot. | `.html`
138
- | `favicon` | Enables the favicon checker. | `false` |
139
- | `followlocation` | Follows external redirections. Amends missing trailing slashes to internal directories. | `true` |
140
- | `directory_index_file` | Sets the file to look for when a link refers to a directory. | `index.html` |
141
- | `href_ignore` | An array of Strings or RegExps containing `href`s that are safe to ignore. Note that non-HTTP(S) URIs are always ignored. | `[]` |
142
- | `alt_ignore` | An array of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore. | `[]` |
143
147
  | `file_ignore` | An array of Strings or RegExps containing file paths that are safe to ignore. | `[]` |
148
+ | `href_ignore` | An array of Strings or RegExps containing `href`s that are safe to ignore. Note that non-HTTP(S) URIs are always ignored. | `[]` |
144
149
  | `href_swap` | A hash containing key-value pairs of `RegExp => String`. It transforms links that match `RegExp` into `String` via `gsub`. | `{}` |
145
- | `verbose` | If `true`, outputs extra information as the checking happens. Useful for debugging. | `false` |
146
150
  | `only_4xx` | Only reports errors for links that fall within the 4xx status code range. | `false` |
147
- | `validate_html` | Enables HTML validation errors from Nokogiri | `false` |
148
- | `check_external_hash` | Checks whether external hashes exist (even if the website exists). This slows the checker down. | `false` |
151
+ | `check_favicon` | Enables the favicon checker. | `false` |
152
+ | `check_html` | Enables HTML validation errors from Nokogiri | `false` |
153
+ | `verbose` | If `true`, outputs extra information as the checking happens. Useful for debugging. | `false` |
149
154
 
150
- ### Configuring Typhoeus
155
+ ### Configuring Typhoeus and Hydra
151
156
 
152
- You can also pass in any of Typhoeus' options for the external link check. For example:
157
+ [Typhoeus](https://github.com/typhoeus/typhoeus) is used to make fast, parallel requests to external URLs. You can pass in any of Typhoeus' options for the external link checks with the options namespace of `:typhoeus`. For example:
153
158
 
154
159
  ``` ruby
155
- HTML::Proofer.new("out/", {:ext => ".htm", :verbose => true, :ssl_verifyhost => 2 })
160
+ HTML::Proofer.new("out/", {:ext => ".htm", :typhoeus => { :verbose => true, :ssl_verifyhost => 2 } })
156
161
  ```
157
162
 
158
163
  This sets `HTML::Proofer`'s extensions to use _.htm_, and gives Typhoeus a configuration for it to be verbose, and use specific SSL settings. Check [the Typhoeus documentation](https://github.com/typhoeus/typhoeus#other-curl-options) for more information on what options it can receive.
159
164
 
165
+ You can similarly pass in a `:hydra` option with a hash configuration for Hydra.
166
+
167
+ The default value is `typhoeus => { :followlocation => true }`.
168
+
160
169
  ### Configuring Parallel
161
170
 
162
- [Parallel](https://github.com/grosser/parallel) is being used to speed things up a bit. You can pass in any of its options with the options "namespace" `:parallel`. For example:
171
+ [Parallel](https://github.com/grosser/parallel) is being used to speed internal file checks. You can pass in any of its options with the options "namespace" `:parallel`. For example:
163
172
 
164
173
  ``` ruby
165
- HTML::Proofer.new("out/", {:ext => ".htm", :verbose => true, :ssl_verifyhost => 2, :parallel => { :in_processes => 3} })
174
+ HTML::Proofer.new("out/", {:ext => ".htm", :parallel => { :in_processes => 3} })
166
175
  ```
167
176
 
168
177
  `:in_processes => 3` will be passed into Parallel as a configuration option.
@@ -185,14 +194,23 @@ bin/htmlproof www.google.com,www.github.com --as-links
185
194
 
186
195
  Add the `data-proofer-ignore` attribute to any tag to ignore it from the checks.
187
196
 
197
+
198
+ ``` html
199
+ <a href="http://notareallink" data-proofer-ignore>Not checked.</a>
200
+ ```
201
+
188
202
  ## Custom tests
189
203
 
190
- Want to write your own test? Sure! Just create two classes--one that inherits from `HTML::Proofer::Checkable`, and another that inherits from `HTML::Proofer::Checks::Check`. `Checkable` defines various helper methods for your test, while `Checks::Check` actually runs across your content. `Checks::Check` should call `self.add_issue` on failures, to add them to the list.
204
+ Want to write your own test? Sure! Just create two classes--one that inherits from `HTML::Proofer::CheckRunner`, and another that inherits from `HTML::Proofer::Checkable`.
205
+
206
+ The `CheckRunner` subclass must define one method called `run`. This is called on your content, and is responsible for performing the validation on whatever elements you like. When you catch a broken issue, call `add_issue(message)` to explain the error.
207
+
208
+ The `Checkable` subclass defines various helper methods you can use as part of your test. Usually, you'll want to instantiate it within `run`. You have access to all of your element's attributes.
191
209
 
192
210
  Here's an example custom test that protects against `mailto` links that point to `octocat@github.com`:
193
211
 
194
212
  ``` ruby
195
- class OctocatLink < ::HTML::Proofer::Checkable
213
+ class OctocatLinkCheck < ::HTML::Proofer::Checkable
196
214
 
197
215
  def mailto?
198
216
  return false if @data_ignore_proofer || @href.nil? || @href.empty?
@@ -205,14 +223,14 @@ class OctocatLink < ::HTML::Proofer::Checkable
205
223
 
206
224
  end
207
225
 
208
- class MailToOctocat < ::HTML::Proofer::Checks::Check
226
+ class MailToOctocat < ::HTML::Proofer::CheckRunner
209
227
 
210
228
  def run
211
229
  @html.css('a').each do |l|
212
- link = OctocatLink.new l, "octocat_link", self
230
+ link = OctocatLinkCheck.new l, "octocat_link", self
213
231
 
214
232
  if link.mailto? && link.octocat?
215
- return self.add_issue("Don't email the Octocat directly!")
233
+ return add_issue("Don't email the Octocat directly!")
216
234
  end
217
235
  end
218
236
  end
data/Rakefile CHANGED
@@ -12,12 +12,10 @@ task :proof_readme do
12
12
  require 'redcarpet'
13
13
 
14
14
  redcarpet = Redcarpet::Markdown.new Redcarpet::Render::HTML.new({}), {}
15
- html = redcarpet.render File.open("README.md").read
15
+ html = redcarpet.render File.read('README.md')
16
16
 
17
- mkdir_p "out"
18
- File.open "out/README.html", File::CREAT|File::WRONLY do |file|
19
- file.puts html
20
- end
17
+ mkdir_p 'out'
18
+ File.write('out/README.html', html)
21
19
 
22
- HTML::Proofer.new("./out").run
20
+ HTML::Proofer.new('./out').run
23
21
  end
data/bin/htmlproof CHANGED
@@ -1,59 +1,69 @@
1
1
  #!/usr/bin/env ruby
2
2
  STDOUT.sync = true
3
3
 
4
- $:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
5
5
 
6
6
  require 'html/proofer'
7
7
  require 'mercenary'
8
- require "rubygems"
8
+ require 'rubygems'
9
+
10
+ def to_regex?(item)
11
+ if item.start_with? '/' and item.end_with? '/'
12
+ Regexp.new item[1...-1]
13
+ else
14
+ item
15
+ end
16
+ end
9
17
 
10
18
  Mercenary.program(:htmlproof) do |p|
11
- p.version Gem::Specification::load(File.join(File.dirname(__FILE__), "..", "html-proofer.gemspec")).version
12
- p.description "Test your rendered HTML files to make sure they're accurate."
19
+ p.version Gem::Specification.load(File.join(File.dirname(__FILE__), '..', 'html-proofer.gemspec')).version
20
+ p.description %(Test your rendered HTML files to make sure they're accurate.)
13
21
  p.syntax 'htmlproof PATH [options]'
14
22
 
15
- p.description "Runs the HTML-Proofer suite on the files in PATH"
16
-
17
- p.option 'ext', '--ext EXT', 'The extension of your HTML files (default: `.html`)'
18
- p.option 'favicon', '--favicon', 'Enables the favicon checker (default: `false`).'
19
- p.option 'as-links', '--as-links', 'Assumes that `PATH` is a comma-separated array of links to check.'
20
- p.option 'swap', '--swap regex:string,[regex:string,...]', Array, 'Array containing key-value pairs of `RegExp:String`. It transforms links that match `RegExp` into `String`'
21
- p.option 'href_ignore', '--href_ignore link1,[link2,...]', Array, 'Array of Strings or RegExps containing `href`s that are safe to ignore. Note that non-HTTP(S) URIs are always ignored.'
22
- p.option 'alt_ignore', '--alt_ignore image1,[image2,...]', Array, 'Array of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore'
23
- p.option 'file_ignore', '--file_ignore file1,[file2,...]', Array, 'Array of Strings or RegExps containing file paths that are safe to ignore'
24
- p.option 'disable_external', '--disable_external', 'Disables the external link checker (default: `false`)'
25
- p.option 'only_4xx', '--only_4xx', 'Only reports errors for links that fall within the 4x status code range.'
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 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, ' An array of Strings indicating which checks you\'d like to not perform.'
28
+ 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`).'
29
+ 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`)'
30
+ p.option 'disable_external', '--disable-external', 'Disables the external link checker (default: `false`)'
31
+ p.option 'error_sort', '--error-sort SORT', 'Defines the sort order for error output. Can be `path`, `desc`, or `status` (default: `path`).'
32
+ p.option 'ext', '--ext EXT', String, 'The extension of your HTML files (default: `.html`)'
33
+ p.option 'file_ignore', '--file-ignore file1,[file2,...]', Array, 'Comma-separated list of Strings or RegExps containing file paths that are safe to ignore'
34
+ p.option 'href_ignore', '--href-ignore link1,[link2,...]', Array, 'Comma-separated list of Strings or RegExps containing `href`s that are safe to ignore.'
35
+ 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`'
36
+ p.option 'only_4xx', '--only-4xx', 'Only reports errors for links that fall within the 4x status code range.'
37
+ p.option 'check_favicon', '--check-favicon', 'Enables the favicon checker (default: `false`).'
38
+ p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
26
39
  p.option 'verbose', '--verbose', 'Enables more verbose logging.'
27
- p.option 'directory_index_file', '--directory_index_file', 'Sets the file to look for when a link refers to a directory.'
28
- p.option 'validate_html', '--validate_html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
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
40
 
31
41
  p.action do |args, opts|
32
- args = ["."] if args.empty?
42
+ args = ['.'] if args.empty?
33
43
  path = args.first
34
44
 
35
45
  options = {}
36
- options[:ext] = opts["ext"] unless opts["ext"].nil?
37
- unless opts["swap"].nil?
46
+
47
+ # prepare every to go to proofer
48
+ p.options.select { |o| !opts[o.config_key].nil? }.each do |option|
49
+ if option.return_type.to_s == 'Array' # TODO: is_a? doesn't work here?
50
+ opts[option.config_key] = opts[option.config_key].map { |i| to_regex?(i) }
51
+ end
52
+ options[option.config_key.to_sym] = opts[option.config_key]
53
+ end
54
+
55
+ # some minor manipulation of a special option
56
+ unless opts['href_swap'].nil?
38
57
  options[:href_swap] = {}
39
- opts["swap"].each do |s|
40
- pair = s.split(":")
41
- options[:href_swap][%r{#{pair[0]}}] = pair[1]
58
+ opts['href_swap'].each do |s|
59
+ pair = s.split(':')
60
+ options[:href_swap][Regexp.new(pair[0])] = pair[1]
42
61
  end
43
62
  end
44
63
 
45
- options[:href_ignore] = opts["href_ignore"] unless opts["href_ignore"].nil?
46
- options[:alt_ignore] = opts["alt_ignore"] unless opts["alt_ignore"].nil?
47
- options[:file_ignore] = opts["file_ignore"] unless opts["file_ignore"].nil?
48
- options[:disable_external] = opts["disable_external"] unless opts["disable_external"].nil?
49
- options[:only_4xx] = opts["only_4xx"] unless opts["only_4xx"].nil?
50
- options[:favicon] = opts["favicon"] unless opts["favicon"].nil?
51
- options[:verbose] = opts["verbose"] unless opts["verbose"].nil?
52
- options[:directory_index_file] = opts["directory_index_file"] unless opts["directory_index_file"].nil?
53
- options[:validate_html] = opts["validate_html"] unless opts["validate_html"].nil?
54
- options[:check_external_hash] = opts["check_external_hash"] unless opts["check_external_hash"].nil?
55
-
56
- path = path.delete(' ').split(",") if opts["as-links"]
64
+ options[:error_sort] = opts['error-sort'].to_sym unless opts['error-sort'].nil?
65
+
66
+ path = path.delete(' ').split(',') if opts['as_links']
57
67
 
58
68
  HTML::Proofer.new(path, options).run
59
69
  end
data/html-proofer.gemspec CHANGED
@@ -1,31 +1,31 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
3
  require 'html/proofer/version'
4
4
 
5
5
  Gem::Specification.new do |gem|
6
- gem.name = "html-proofer"
6
+ gem.name = 'html-proofer'
7
7
  gem.version = HTML::Proofer::VERSION
8
- gem.authors = ["Garen Torikian"]
9
- gem.email = ["gjtorikian@gmail.com"]
10
- gem.description = %q{Test your rendered HTML files to make sure they're accurate.}
11
- gem.summary = %q{A set of tests to validate your HTML output. These tests check if your image references are legitimate, if they have alt tags, if your internal links are working, and so on. It's intended to be an all-in-one checker for your documentation output.}
12
- gem.homepage = "https://github.com/gjtorikian/html-proofer"
13
- gem.license = "MIT"
14
- gem.executables = ["htmlproof"]
15
- gem.files = `git ls-files`.split($/)
8
+ gem.authors = ['Garen Torikian']
9
+ gem.email = ['gjtorikian@gmail.com']
10
+ gem.description = %(Test your rendered HTML files to make sure they're accurate.)
11
+ gem.summary = %(A set of tests to validate your HTML output. These tests check if your image references are legitimate, if they have alt tags, if your internal links are working, and so on. It's intended to be an all-in-one checker for your documentation output.)
12
+ gem.homepage = 'https://github.com/gjtorikian/html-proofer'
13
+ gem.license = 'MIT'
14
+ gem.executables = ['htmlproof']
15
+ gem.files = `git ls-files -z`.split("\x0")
16
16
  gem.test_files = gem.files.grep(%r{^(spec)/})
17
- gem.require_paths = ["lib"]
17
+ gem.require_paths = ['lib']
18
18
 
19
- gem.add_dependency "mercenary", "~> 0.3.2"
20
- gem.add_dependency "nokogiri", "~> 1.5"
21
- gem.add_dependency "colored", "~> 1.2"
22
- gem.add_dependency "typhoeus", "~> 0.6.7"
23
- gem.add_dependency "yell", "~> 2.0"
24
- gem.add_dependency "parallel", "~> 1.3"
25
- gem.add_dependency "addressable", "~> 2.3"
19
+ gem.add_dependency 'mercenary', '~> 0.3.2'
20
+ gem.add_dependency 'nokogiri', '~> 1.5'
21
+ gem.add_dependency 'colored', '~> 1.2'
22
+ gem.add_dependency 'typhoeus', '~> 0.6.7'
23
+ gem.add_dependency 'yell', '~> 2.0'
24
+ gem.add_dependency 'parallel', '~> 1.3'
25
+ gem.add_dependency 'addressable', '~> 2.3'
26
26
 
27
- gem.add_development_dependency "redcarpet"
28
- gem.add_development_dependency "rspec", "~> 3.1.0"
29
- gem.add_development_dependency "rake"
30
- gem.add_development_dependency "awesome_print"
27
+ gem.add_development_dependency 'redcarpet'
28
+ gem.add_development_dependency 'rspec', '~> 3.1'
29
+ gem.add_development_dependency 'rake'
30
+ gem.add_development_dependency 'awesome_print'
31
31
  end
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ class HTML::Proofer::CheckRunner
3
+
4
+ class Issue
5
+ attr_reader :path, :desc, :status, :line_number
6
+
7
+ def initialize(path, desc, line_number = nil, status = -1)
8
+ @line_number = line_number.nil? ? '' : " (line #{line_number})"
9
+ @path = path
10
+ @desc = desc
11
+ @status = status
12
+ end
13
+
14
+ def to_s
15
+ "#{@path}: #{@desc}#{@line_number}"
16
+ end
17
+ end
18
+
19
+ class SortedIssues
20
+ attr_reader :issues
21
+
22
+ def initialize(issues, error_sort, logger)
23
+ @issues = issues
24
+ @error_sort = error_sort
25
+ @logger = logger
26
+ end
27
+
28
+ def sort_and_report
29
+ case @error_sort
30
+ when :path
31
+ sorted_issues = sort(:path, :desc)
32
+ report(sorted_issues, :path, :desc)
33
+ when :desc
34
+ sorted_issues = sort(:desc, :path)
35
+ report(sorted_issues, :desc, :path)
36
+ when :status
37
+ sorted_issues = sort(:status, :path)
38
+ report(sorted_issues, :status, :path)
39
+ end
40
+ end
41
+
42
+ def sort(first_sort, second_sort)
43
+ issues.sort_by { |t| [t.send(first_sort), t.send(second_sort)] }
44
+ end
45
+
46
+ def report(sorted_issues, first_report, second_report)
47
+ matcher = nil
48
+
49
+ sorted_issues.each do |issue|
50
+ if matcher != issue.send(first_report)
51
+ @logger.log :error, :red, "- #{issue.send(first_report)}"
52
+ matcher = issue.send(first_report)
53
+ end
54
+ if first_report == :status
55
+ @logger.log :error, :red, " * #{issue}"
56
+ else
57
+ @logger.log :error, :red, " * #{issue.send(second_report)}#{issue.line_number}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,15 +1,11 @@
1
1
  # encoding: utf-8
2
- require 'net/http'
3
- require 'net/https'
4
- require 'timeout'
5
- require 'uri'
6
- require 'typhoeus'
7
2
 
8
- class HTML::Proofer::Checks
3
+ class HTML::Proofer
9
4
 
10
- class Check
5
+ # Mostly handles issue management and collecting of external URLs.
6
+ class CheckRunner
11
7
 
12
- attr_reader :issues, :src, :path, :options, :external_urls, :additional_href_ignores, :additional_alt_ignores
8
+ attr_reader :issues, :src, :path, :options, :external_urls, :href_ignores, :alt_ignores
13
9
 
14
10
  def initialize(src, path, html, opts={})
15
11
  @src = src
@@ -17,21 +13,17 @@ class HTML::Proofer::Checks
17
13
  @html = remove_ignored(html)
18
14
  @options = opts
19
15
  @issues = []
20
- @additional_href_ignores = @options[:href_ignore]
21
- @additional_alt_ignores = @options[:alt_ignore]
16
+ @href_ignores = @options[:href_ignore]
17
+ @alt_ignores = @options[:alt_ignore]
22
18
  @external_urls = {}
23
19
  end
24
20
 
25
21
  def run
26
- raise NotImplementedError.new("HTML::Proofer::Check subclasses must implement #run")
22
+ fail NotImplementedError, 'HTML::Proofer::CheckRunner subclasses must implement #run'
27
23
  end
28
24
 
29
- def add_issue(desc, status = -1)
30
- @issues << Issue.new(@path, desc, status)
31
- end
32
-
33
- def output_filenames
34
- Dir[@site.config[:output_dir] + '/**/*'].select{ |f| File.file?(f) }
25
+ def add_issue(desc, line_number = nil, status = -1)
26
+ @issues << Issue.new(@path, desc, line_number, status)
35
27
  end
36
28
 
37
29
  def add_to_external_urls(href)
@@ -42,7 +34,7 @@ class HTML::Proofer::Checks
42
34
  end
43
35
  end
44
36
 
45
- def self.subclasses
37
+ def self.checks
46
38
  classes = []
47
39
 
48
40
  ObjectSpace.each_object(Class) do |c|
@@ -56,7 +48,7 @@ class HTML::Proofer::Checks
56
48
  private
57
49
 
58
50
  def remove_ignored(html)
59
- html.css("code, pre").each { |node| node.unlink }
51
+ html.css('code, pre').each(&:unlink)
60
52
  html
61
53
  end
62
54