html-proofer 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 251947156251aad2dfb34f8f05b24fe387c34b79
4
- data.tar.gz: 0b1ef3155efa7036f09db41e0cd4689002cdf318
3
+ metadata.gz: c5f9520152e65b775e134ac987d42fdeb69a4448
4
+ data.tar.gz: 6fb435127a7de49da70d5b9284d95bbb736bc19b
5
5
  SHA512:
6
- metadata.gz: 9de89df3791ddb7d945fe5e6624fb18db97407364ab070dd5aa0598d9d414baf276f578f2e7aec90db432596da79f4005ff1b9267093921d02c2827cd0ce88fa
7
- data.tar.gz: 49e32043dbe5a4fd60f46da560c47185cb7319f769cde383045df9d91fcfd205a6c56266f59274d18f6c889405a5da5b0371283371a45d5129853924c81c42b2
6
+ metadata.gz: d2e355f14b84c62685a44b01e93109f7d4c6ddad4884c952f4c734c8a473ee22f94a258b09601bac4a648d9d3fa61f0f949d800208296755e5d63be5a4ca6f67
7
+ data.tar.gz: 9e768b2b3920f5bf61fe1bcd257e890315cbe110c08afec49ba0a8e637341eef5c88f546adeeefcfa079a779b06b09f087ec18b00ed1c21f3f06ec038dd5c4c6
data/Gemfile.lock CHANGED
@@ -3,7 +3,8 @@ PATH
3
3
  specs:
4
4
  html-proofer (0.2.3)
5
5
  colored (~> 1.2)
6
- nokogiri (= 1.6.0)
6
+ mercenary (~> 0.2.0)
7
+ nokogiri (~> 1.6.0)
7
8
  typhoeus (~> 0.6.3)
8
9
 
9
10
  GEM
@@ -22,7 +23,7 @@ GEM
22
23
  ethon (0.6.1)
23
24
  ffi (>= 1.3.0)
24
25
  mime-types (~> 1.18)
25
- ffi (1.9.0)
26
+ ffi (1.9.3)
26
27
  gemoji (1.4.0)
27
28
  github-markdown (0.5.5)
28
29
  html-pipeline (0.0.14)
@@ -34,7 +35,8 @@ GEM
34
35
  rinku (~> 1.7)
35
36
  sanitize (~> 2.0)
36
37
  i18n (0.6.5)
37
- mime-types (1.25)
38
+ mercenary (0.2.0)
39
+ mime-types (1.25.1)
38
40
  mini_portile (0.5.1)
39
41
  minitest (4.7.5)
40
42
  multi_json (1.8.1)
@@ -54,7 +56,7 @@ GEM
54
56
  nokogiri (>= 1.4.4)
55
57
  thread_safe (0.1.3)
56
58
  atomic
57
- typhoeus (0.6.5)
59
+ typhoeus (0.6.6)
58
60
  ethon (~> 0.6.1)
59
61
  tzinfo (0.3.38)
60
62
 
data/README.md CHANGED
@@ -22,6 +22,8 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
+ ### In a script
26
+
25
27
  Require the gem; generate some HTML; create a new instance of the `HTML::Proofer` on
26
28
  your output folder; then `run` it. Here's a simple example:
27
29
 
@@ -52,6 +54,19 @@ end
52
54
  HTML::Proofer.new("./out").run
53
55
  ```
54
56
 
57
+ ### Usage on the command-line
58
+
59
+ You'll get a new program called `htmlproof` with this gem. Jawesome!
60
+
61
+ Use it like you'd expect to:
62
+
63
+ ``` bash
64
+ htmlproof run ./out --swap wow:cow,mow:doh --ext .html.erb --ignore www.github.com
65
+ ```
66
+
67
+ Note: since `swap` is a bit special, you'll pass in a pair of `RegEx:String` values.
68
+ `htmlproof` will figure out what you mean.
69
+
55
70
  ## Usage with Jekyll
56
71
 
57
72
  Want to use HTML Proofer with your Jekyll site? Awesome. Simply add `gem 'html-proofer'` to your `Gemfile` as described above, and add the following to your `Rakefile`, using `rake test` to execute:
@@ -65,6 +80,12 @@ task :test do
65
80
  end
66
81
  ```
67
82
 
83
+ Don't have or want a `Rakefile`? You _could_ also do something like the following:
84
+
85
+ ```bash
86
+ htmlproof ./_site
87
+ ```
88
+
68
89
  ## What's Tested?
69
90
 
70
91
  * Whether all your images have alt tags
@@ -75,7 +96,6 @@ end
75
96
 
76
97
  ## Configuration
77
98
 
78
-
79
99
  The `HTML::Proofer` constructor takes an optional hash of additional options:
80
100
 
81
101
  * `:ext`: the extension (including the `.`) of your HTML files (default: `.html`)
data/Rakefile CHANGED
@@ -5,4 +5,4 @@ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- task :default => :spec
8
+ task :default => :spec
data/bin/htmlproof ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ STDOUT.sync = true
3
+
4
+ require './lib/html/proofer'
5
+ require 'mercenary'
6
+
7
+ Mercenary.program(:htmlproof) do |p|
8
+ # p.version HTML::Proofer::VERSION
9
+ p.description "Test your rendered HTML files to make sure they're accurate."
10
+ p.syntax 'htmlproof run PATH [options]'
11
+
12
+ p.command(:run) do |c|
13
+ c.syntax "htmlproof run PATH"
14
+ c.description "Runs the HTML-Proofer suite on the files in PATH"
15
+
16
+ c.option 'ext', '--ext EXT', String, 'The extension of your HTML files (default: `.html`)'
17
+ c.option 'swap', '--swap regex:string,[regex:string,...]', Array, 'Array containing key-value pairs of `RegExp:String`. It transforms links that match `RegExp` into `String`'
18
+ c.option 'ignore', '--ignore link1,[link2,...]', Array, 'Array of Strings containing `href`s that are safe to ignore (default: `mailto`)'
19
+
20
+ c.action do |args, opts|
21
+ raise "`run` requires a PATH indicating a directory of files to check" if args.empty?
22
+ options = {}
23
+ options[:ext] = opts["ext"] unless opts["ext"].nil?
24
+ unless opts["swap"].nil?
25
+ options[:href_swap] = {}
26
+ opts["swap"].each do |s|
27
+ pair = s.split(":")
28
+ options[:href_swap][%r{#{pair[0]}}] = pair[1]
29
+ end
30
+ end
31
+ options[:href_ignore] = opts["ignore"] unless opts["ignore"].nil?
32
+
33
+ HTML::Proofer.new(args[0], options).run
34
+ end
35
+ end
36
+
37
+ p.default_command(:run)
38
+ end
data/html-proofer.gemspec CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/html/proofer/version", __FILE__)
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'html/proofer/version'
3
4
 
4
5
  Gem::Specification.new do |gem|
5
6
  gem.name = "html-proofer"
@@ -14,7 +15,8 @@ Gem::Specification.new do |gem|
14
15
  gem.test_files = gem.files.grep(%r{^(spec)/})
15
16
  gem.require_paths = ["lib"]
16
17
 
17
- gem.add_dependency "nokogiri", "1.6.0"
18
+ gem.add_dependency "mercenary", "~> 0.2.0"
19
+ gem.add_dependency "nokogiri", "~> 1.6.0"
18
20
  gem.add_dependency "colored", "~> 1.2"
19
21
  gem.add_dependency "typhoeus", "~> 0.6.3"
20
22
 
data/lib/html/proofer.rb CHANGED
@@ -1,65 +1,53 @@
1
1
  require 'nokogiri'
2
- require 'find'
3
- require 'html/proofer/checkable'
4
- require 'html/proofer/checks'
2
+ require File.dirname(__FILE__) + '/proofer/checkable'
3
+ require File.dirname(__FILE__) + '/proofer/checks'
5
4
 
6
5
  module HTML
7
6
  class Proofer
8
7
  def initialize(src, opts={})
9
8
  @srcDir = src
10
9
  @options = {:ext => ".html"}.merge(opts)
11
- @failedTests = []
12
10
  end
13
11
 
14
12
  def run
15
- get_checks.each do |klass|
16
- puts "Running #{klass.name.split(/:/).pop()} check... \n\n"
13
+ total_files = 0
14
+ failed_tests = []
17
15
 
18
- Find.find(@srcDir) do |path|
19
- if File.extname(path) == @options[:ext]
20
- html = HTML::Proofer.create_nokogiri(path)
21
- check = klass.new(@srcDir, path, html, @options)
22
- check.run
23
- check.hydra.run
24
- self.print_issues(klass, check.issues)
25
- end
16
+ puts "Running #{get_checks} checks on #{@srcDir}... \n\n"
17
+
18
+ Dir.glob("#{@srcDir}/**/*#{@options[:ext]}") do |path|
19
+ total_files += 1
20
+ html = HTML::Proofer.create_nokogiri(path)
21
+
22
+ get_checks.each do |klass|
23
+ check = klass.new(@srcDir, path, html, @options)
24
+ check.run
25
+ check.hydra.run
26
+ failed_tests.concat(check.issues) if check.issues.length > 0
26
27
  end
27
28
  end
28
29
 
29
- if @failedTests.empty?
30
- puts "Tests executed successfully.".green
30
+ puts "Ran on #{total_files} files!"
31
+
32
+ if failed_tests.empty?
33
+ puts "HTML-Proofer finished successfully.".green
31
34
  exit 0
32
35
  else
33
- # make the hash default to 0 so that += will work correctly
34
- count = Hash.new(0)
35
-
36
- # iterate over the array, counting duplicate entries
37
- @failedTests.each do |v|
38
- count[v] += 1
36
+ failed_tests.each do |issue|
37
+ $stderr.puts issue + "\n\n"
39
38
  end
40
39
 
41
- count.each do |k, v|
42
- $stderr.puts "#{k} failed #{v} times"
43
- end
44
- raise "Tests ran, but found failures!"
40
+ raise "HTML-Proofer found #{failed_tests.length} failures!"
45
41
  end
46
42
  end
47
43
 
48
44
  def self.create_nokogiri(path)
49
- path << "/index.html" if File.directory? path #support for Jekyll-style links
45
+ path << "/index.html" if File.directory? path # support for Jekyll-style links
50
46
  Nokogiri::HTML(File.read(path))
51
47
  end
52
48
 
53
49
  def get_checks
54
50
  HTML::Proofer::Checks::Check.subclasses
55
51
  end
56
-
57
- def print_issues(klass, issues)
58
- return if issues.empty?
59
- @failedTests.push klass
60
- issues.each do |issue|
61
- $stderr.puts issue + "\n\n"
62
- end
63
- end
64
52
  end
65
53
  end
@@ -18,6 +18,7 @@ class HTML::Proofer::Checks
18
18
  @html = html
19
19
  @options = opts
20
20
  @issues = []
21
+ @checked_urls = {}
21
22
 
22
23
  @hydra = Typhoeus::Hydra.hydra
23
24
  @additional_href_ignores = @options[:href_ignore] || []
@@ -36,10 +37,11 @@ class HTML::Proofer::Checks
36
37
  end
37
38
 
38
39
  def validate_url(href, issue_text)
40
+ return @checked_urls[href] if @checked_urls.has_key? href
39
41
  request = Typhoeus::Request.new(href, {:followlocation => true})
40
42
  request.on_complete do |response|
41
43
  if response.success?
42
- # no op
44
+ @checked_urls[href] = true
43
45
  elsif response.timed_out?
44
46
  self.add_issue(issue_text + " got a time out")
45
47
  elsif response.code == 0
@@ -57,6 +59,8 @@ class HTML::Proofer::Checks
57
59
  self.add_issue("#{issue_text} HTTP request failed: #{response_code}")
58
60
  end
59
61
  end
62
+
63
+ @checked_urls[href] = false unless response.success?
60
64
  end
61
65
  hydra.queue(request)
62
66
  end
@@ -10,6 +10,7 @@ module HTML
10
10
  @id = obj['id']
11
11
  @data_ignore_proofer = obj['data-proofer-ignore']
12
12
  @check = check
13
+ @checked_paths = {}
13
14
 
14
15
  if @href && @check.options[:href_swap]
15
16
  @check.options[:href_swap].each do |link, replace|
@@ -73,7 +74,6 @@ module HTML
73
74
  end
74
75
 
75
76
  def file_path
76
-
77
77
  return if path.nil?
78
78
 
79
79
  if path =~ /^\// #path relative to root
@@ -94,7 +94,8 @@ module HTML
94
94
 
95
95
  # checks if a file exists relative to the current pwd
96
96
  def exists?
97
- File.exist? absolute_path
97
+ return @checked_paths[absolute_path] if @checked_paths.has_key? absolute_path
98
+ @checked_paths[absolute_path] = File.exist? absolute_path
98
99
  end
99
100
 
100
101
  def absolute_path
@@ -1,9 +1,9 @@
1
1
  module HTML
2
2
  class Proofer
3
3
  class Checks
4
- require 'html/proofer/check'
5
- require 'html/proofer/checks/images'
6
- require 'html/proofer/checks/links'
4
+ require File.dirname(__FILE__) + '/check'
5
+ require File.dirname(__FILE__) + '/checks/images'
6
+ require File.dirname(__FILE__) + '/checks/links'
7
7
  end
8
8
  end
9
9
  end
@@ -23,7 +23,6 @@ class Image < ::HTML::Proofer::Checkable
23
23
  end
24
24
 
25
25
  class Images < ::HTML::Proofer::Checks::Check
26
-
27
26
  def run
28
27
  @html.css('img').each do |img|
29
28
 
@@ -40,8 +40,12 @@ class Links < ::HTML::Proofer::Checks::Check
40
40
  elsif link.internal?
41
41
  self.add_issue "linking to internal hash ##{link.hash} that does not exist" unless hash_check @html, link.hash
42
42
  elsif link.external?
43
- target_html = HTML::Proofer.create_nokogiri link.absolute_path
44
- self.add_issue "linking to #{link.href}, but #{link.hash} does not exist" unless hash_check target_html, link.hash
43
+ unless link.exists?
44
+ self.add_issue "trying to find hash of #{link.href}, but #{link.absolute_path} does not exist"
45
+ else
46
+ target_html = HTML::Proofer.create_nokogiri link.absolute_path
47
+ self.add_issue "linking to #{link.href}, but #{link.hash} does not exist" unless hash_check target_html, link.hash
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -1,5 +1,5 @@
1
1
  module HTML
2
2
  class Proofer
3
- VERSION = "0.2.3"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -0,0 +1,9 @@
1
+ <html>
2
+
3
+ <body>
4
+
5
+ <a href="/articles/linkToFolder">A real file, but the href should change!</a>
6
+
7
+ </body>
8
+
9
+ </html>
@@ -87,4 +87,11 @@ describe "Links tests" do
87
87
  @linkCheck.run
88
88
  @linkCheck.issues[0].should eq(nil)
89
89
  end
90
+
91
+ it 'translates links via href_swap' do
92
+ translatedLink = "#{FIXTURES_DIR}/linkTranslatedViaHrefSwap.html"
93
+ @linkCheck = Links.new("#{FIXTURES_DIR}", translatedLink, HTML::Proofer.create_nokogiri(translatedLink), {:href_swap => { /\A\/articles\/([\w-]+)/ => "\\1.html" }})
94
+ @linkCheck.run
95
+ @linkCheck.issues[0].should eq(nil)
96
+ end
90
97
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'bundler/setup'
2
- require_relative "../lib/html-proofer"
2
+ require_relative "../lib/html/proofer"
3
3
 
4
4
  require File.expand_path('../../lib/html/proofer/version.rb', __FILE__)
5
5
 
metadata CHANGED
@@ -1,27 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.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: 2013-10-24 00:00:00.000000000 Z
11
+ date: 2013-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mercenary
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: nokogiri
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - '='
31
+ - - ~>
18
32
  - !ruby/object:Gem::Version
19
33
  version: 1.6.0
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - '='
38
+ - - ~>
25
39
  - !ruby/object:Gem::Version
26
40
  version: 1.6.0
27
41
  - !ruby/object:Gem::Dependency
@@ -108,8 +122,8 @@ files:
108
122
  - LICENSE.txt
109
123
  - README.md
110
124
  - Rakefile
125
+ - bin/htmlproof
111
126
  - html-proofer.gemspec
112
- - lib/html-proofer.rb
113
127
  - lib/html/proofer.rb
114
128
  - lib/html/proofer/check.rb
115
129
  - lib/html/proofer/checkable.rb
@@ -132,6 +146,7 @@ files:
132
146
  - spec/html/proofer/fixtures/ignorableLinks.html
133
147
  - spec/html/proofer/fixtures/index.html
134
148
  - spec/html/proofer/fixtures/linkToFolder.html
149
+ - spec/html/proofer/fixtures/linkTranslatedViaHrefSwap.html
135
150
  - spec/html/proofer/fixtures/linkWithHttps.html
136
151
  - spec/html/proofer/fixtures/linkWithRedirect.html
137
152
  - spec/html/proofer/fixtures/missingImageAlt.html
@@ -190,6 +205,7 @@ test_files:
190
205
  - spec/html/proofer/fixtures/ignorableLinks.html
191
206
  - spec/html/proofer/fixtures/index.html
192
207
  - spec/html/proofer/fixtures/linkToFolder.html
208
+ - spec/html/proofer/fixtures/linkTranslatedViaHrefSwap.html
193
209
  - spec/html/proofer/fixtures/linkWithHttps.html
194
210
  - spec/html/proofer/fixtures/linkWithRedirect.html
195
211
  - spec/html/proofer/fixtures/missingImageAlt.html
data/lib/html-proofer.rb DELETED
@@ -1 +0,0 @@
1
- require 'html/proofer'