html_validation 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ /pkg
2
+ .redcar/*
3
+ spec/.validation/*
4
+ .rspec
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # Add dependencies to develop your gem here.
6
+ # Include everything needed to run rake, tests, features, etc.
7
+ group :development do
8
+ gem "rspec"
9
+ gem "bundler"
10
+ end
11
+
12
+ gem 'rdoc'
13
+ gem 'thor'
14
+
15
+ # Unix Rubies (OSX, Linux)
16
+ platform :ruby do
17
+
18
+ end
19
+
20
+ # Windows Rubies (RubyInstaller)
21
+ platforms :mswin, :mingw do
22
+
23
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ html_validation (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ json (1.7.7)
11
+ rdoc (4.0.0)
12
+ json (~> 1.4)
13
+ rspec (2.11.0)
14
+ rspec-core (~> 2.11.0)
15
+ rspec-expectations (~> 2.11.0)
16
+ rspec-mocks (~> 2.11.0)
17
+ rspec-core (2.11.1)
18
+ rspec-expectations (2.11.2)
19
+ diff-lcs (~> 1.1.3)
20
+ rspec-mocks (2.11.1)
21
+ thor (0.17.0)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler
28
+ html_validation!
29
+ rdoc
30
+ rspec
31
+ thor
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 - 2013 Eric Beland
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,113 @@
1
+ = HTML Validation
2
+
3
+ html_validation helps you validate, track, and fix or accept HTML validation
4
+ issues without depending on an external web service.
5
+ The idea is to take an HTML markup string associated
6
+ with a particular resource (file or URL) and validate it locally.
7
+ No web connection or dependency on a 3rd party web service is involved--just an
8
+ install of HTML Tidy, which is supported by the W3C. An RSPec matcher is included.
9
+
10
+ HTML Validation is intended to be used in acceptance tests, test suites or rake
11
+ tasks to alert you to changes in your html's validity so you can fix them, or
12
+ barring that, review and accept any errors and warnings.
13
+
14
+ == HTML 5
15
+
16
+ The current (as of March 2013) default version of Tidy doesn't support HTML 5.
17
+ To get HTML 5 support, install this fork of tidy: https://github.com/w3c/tidy-html5
18
+ Download the repo as a zip file and extract somewhere, then follow the instructions
19
+ given on the page (using sudo for make commands if on Linux).
20
+
21
+ Be sure to get rid of the old tidy first if you have it already.
22
+
23
+ Redhat/Fedora: sudo yum erase tidy
24
+ Ubuntu: sudo apt-get remove tidy
25
+ OS X: sudo port uninstall tidy
26
+
27
+ On linux/OS X machines, confirm the right installation path shows up with: which tidy
28
+
29
+ == RSpec Setup / Usage:
30
+ Add to spec/spec_helper.rb:
31
+
32
+ require 'html_validation'
33
+ include PageValidations
34
+
35
+ Now, within your Integration Tests, you can do this:
36
+
37
+ page.should have_valid_html
38
+
39
+ It can be convenient to see the html printed in the RSpec failure messages.
40
+ To enable this feature:
41
+
42
+ HaveValidHTML.show_html_in_failures = true
43
+
44
+ == Non-RSpec Usage:
45
+
46
+ require 'html_validation'
47
+
48
+
49
+ h = HTMLValidation.new
50
+ v = h.validation("<html>foo</html>", 'http://somesite.com/index.html')
51
+
52
+ # Note: The second argument (resource) just serves as an identifier used to
53
+ # name our results files, and no data is actually retrieved for you from on the URL!
54
+
55
+ v.valid?
56
+ -> false
57
+
58
+ v.exceptions
59
+ -> line 1 column 1 - Warning: missing <!DOCTYPE> declaration
60
+ -> line 1 column 9 - Warning: plain text isn't allowed in <head> elements
61
+ -> line 1 column 9 - Warning: inserting missing 'title' element
62
+
63
+ v.accept!
64
+
65
+ v.valid?
66
+ -> true
67
+
68
+ # Note: after the exceptions string has been accepted, the exceptions
69
+ # are still available in v.exceptions even though valid? will return true.
70
+
71
+ # The exception string is treated and matched as a whole. The current
72
+ # implementation does not allow partial acceptance of individual
73
+ # results in a result string.
74
+
75
+ == Accepting Errors
76
+
77
+ The HTML Validation gem stores failure data per-resource. The results are stored
78
+ in the data_folder. Typically this is the default folder: spec/.validation.
79
+ After a validation fails, run the thor task to accept or reject validation exceptions.
80
+
81
+ From your project's root folder, run: thor validation:review
82
+
83
+ Note, if you configure an alternate data_folder, you may pass it as an option
84
+ to the Thor task.
85
+
86
+
87
+ == NOTES
88
+
89
+ This is untested on Windows as I don't have access to a Windows machine at the moment.
90
+ It is written so it could (probably) work on Windows. Pull requests in this area would
91
+ be welcomed.
92
+
93
+ == Requirements
94
+
95
+ HTML Tidy needs to be either installed at /usr/bin/tidy or on the PATH.
96
+
97
+
98
+ == Contributing to html_validation
99
+
100
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
101
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
102
+ * Fork the project
103
+ * Start a feature/bugfix branch
104
+ * Commit and push until you are happy with your contribution
105
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
106
+
107
+
108
+ === Running the tests
109
+
110
+ After tidy has been installed, in the gem folder, run: rspec spec
111
+
112
+ Copyright (c) 2012 Eric Beland. See LICENSE.txt for further details.
113
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/html_validation/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Eric Beland"]
6
+ gem.email = ["ebeland@gmail.com"]
7
+ gem.description = %q{HTML Validation lets you validate html locally. Lets you build html validation into your test suite, but break the rules if you must.}
8
+ gem.summary = %q{Local HTML validation for tests and RSpec. }
9
+ gem.homepage = "https://github.com/ericbeland/html_validation"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "html_validation"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = PageValidations::HTML_VALIDATOR_VERSION
17
+ end
@@ -0,0 +1,44 @@
1
+ require 'html_validation'
2
+
3
+ # This is a sample matcher for use with Rspec and Capybara.
4
+ # https://github.com/jnicklas/capybara
5
+ # keep this in spec/support/matchers
6
+ module PageValidations
7
+
8
+ class HaveValidHTML
9
+
10
+ # This is the matching method called by RSpec
11
+ # The response is passed in as an argument when you do this:
12
+ # page.should have_valid_html
13
+
14
+ @@show_html_in_failures = false
15
+
16
+ def self.show_html_in_failures=(val)
17
+ @@show_html_in_failures = val
18
+ end
19
+
20
+ def matches?(page)
21
+ h = HTMLValidation.new
22
+ @v = h.validation(page.body, page.current_url)
23
+ @v.valid?
24
+ end
25
+
26
+ def description
27
+ "Have valid html"
28
+ end
29
+
30
+ def failure_message_for_should
31
+ "#{@v.resource} Invalid html (fix or run rake html_validation task to add exceptions)\n#{@v.resource} exceptions:\n #{@v.exceptions}\n\n #{@v.html if @@show_html_in_failures}"
32
+ end
33
+
34
+ def failure_message_for_should_not
35
+ "#{@v.resource} Expected valid? to fail but didn't. Did you accidentally accept these html validation errors? \n#{@v.resource} exceptions:\n #{@v.exceptions}\n\n #{@v.html if @@show_html_in_failures}"
36
+ end
37
+
38
+ end
39
+
40
+ def have_valid_html
41
+ HaveValidHTML.new
42
+ end
43
+
44
+ end
@@ -0,0 +1,21 @@
1
+ # the item to include to get the RSPec matcher(s)
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), 'have_valid_html'))
4
+
5
+ module HTMLValidationMatcher
6
+ @@data_path = nil
7
+
8
+ def self.included(base)
9
+ # get path of including file, which should be in the /spec folder
10
+ @@data_path, = File.expand_path(File.dirname(caller[0].partition(":")[0]))
11
+ end
12
+
13
+ def self.data_path
14
+ @@data_path
15
+ end
16
+
17
+ def self.data_path=(path)
18
+ @@data_path = path
19
+ end
20
+
21
+ end
@@ -0,0 +1,93 @@
1
+ require 'open3'
2
+
3
+ class HTMLValidationResult
4
+ attr_accessor :resource, :html, :exceptions
5
+
6
+ include PageValidations
7
+ # valid options[:tidy_opts]
8
+ def initialize(resource, html, datapath, options={})
9
+ @resource = resource
10
+ @html = html
11
+ @exceptions = ''
12
+ @datapath = datapath
13
+ @tidyopts = options[:tidy_opts] || "-qi"
14
+ @ignore_proprietary = options[:ignore_proprietary]
15
+ valid?
16
+ end
17
+
18
+ # takes a .url and loads the data into this object
19
+ def self.load_from_files(filepath)
20
+ resource = File.open("#{filepath}.resource.txt", 'r').read
21
+ html = File.open("#{filepath}.html.txt", 'r').read
22
+ HTMLValidationResult.new(resource, html, filepath)
23
+ end
24
+
25
+ # Validates an html string using html tidy. If there are no warnings or exceptions, or
26
+ # there is a previously accepted exception string that matches exactly, valid? returns true
27
+ # Line numbers of exceptions are likely to change with any edit, so our validation
28
+ # compares the exception strings with the lines and columns removed. Name can be a filename,
29
+ # file system path, or url, so long it is uniquely associated with the passed in html.
30
+ def valid?
31
+ @exceptions = validate
32
+ File.delete(data_path("accepted")) if File.exists?(data_path("accepted")) if @exceptions == ''
33
+ valid = (filter(@exceptions) == '' or accepted?(@exceptions))
34
+ save_html_and_exceptions
35
+ valid
36
+ end
37
+
38
+ # Saves the exception string for the given url or file path. When next run, if the exception
39
+ # string is identical, valid? will return true. Note that #exceptions will still list the
40
+ # exception string, though, even if it is an accepted exception string.
41
+ def accept!
42
+ File.open(data_path("accepted"), 'w') {|f| f.write(@exceptions) }
43
+ end
44
+
45
+ private
46
+ # We specifically prefer /usr/bin/tidy by default on *nix as there is another "tidy" programs
47
+ # that could end up earlier on the path. On snow leopard, tidy was installed at this location
48
+ # for me by default.
49
+ def tidy_command
50
+ is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
51
+ bin = (is_windows or !File.exists?("/usr/bin/tidy")) ? 'tidy' : '/usr/bin/tidy'
52
+ "#{bin} #{@tidyopts}"
53
+ end
54
+
55
+ # get the filename for storing a type of data
56
+ def data_path(filetype)
57
+ "#{@datapath}.#{filetype}.txt"
58
+ end
59
+
60
+ def save_html_and_exceptions
61
+ File.open(data_path("html"), 'w') {|f| f.write(@html) }
62
+ File.open(data_path("resource"), 'w') {|f| f.write(@resource) }
63
+ File.open(data_path("exceptions"), 'w') {|f| f.write(@exceptions) }
64
+ end
65
+
66
+ # have we previously accepted this exact string for this path?
67
+ def accepted?(exception_str)
68
+ exception_str = filter(exception_str)
69
+ File.exists?(data_path('accepted')) ? filter(File.open(data_path('accepted'),"r").read) == exception_str : false
70
+ end
71
+
72
+ # Line numbers of exceptions are likely to change with any minor edit, so our validation
73
+ # compares the result strings with the lines and columns removed. This means that
74
+ # if the errors change position in the file (up or down b/c you add or remove code),
75
+ # accepted exception strings will remain valid.
76
+ def filter(str)
77
+ str.gsub!(/^line.*trimming empty.*\n/, '') # the messages about empty are overzealous, and not invalid
78
+ str.gsub!(/^line.*proprietary.*\n/, '') if @ignore_proprietary # if you use IE only attributes like wrap, or spellcheck or things not in standard
79
+ str.gsub(/line [0-9]+ column [0-9]+ -/, '')
80
+ # /line [0-9]+ column [0-9]+ - / + =~ "line 1 column 1 - Warning: missing <!DOCTYPE> declaration"
81
+ end
82
+
83
+ def validate
84
+ stdin, stdout, stderr = Open3.popen3(tidy_command)
85
+ stdin.puts @html
86
+ stdin.close
87
+ stdout.close
88
+ result = stderr.read
89
+ stderr.close
90
+ result
91
+ end
92
+
93
+ end
@@ -0,0 +1,3 @@
1
+ module PageValidations
2
+ HTML_VALIDATOR_VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,82 @@
1
+ # == HTML Validation
2
+ # HTLM Acceptance helps you watch and come to terms with your HTML's validity, or lack thereof.
3
+ # The idea is to take an html markup string associated with a particular path (file or URL),
4
+ # and validate it. It is intended to be used in acceptance tests, test suites or a rake task
5
+ # to alert you to changes in your html's validity so you can fix them, or barring that, review and accept
6
+ # errors and warnings.
7
+
8
+ # ==Resource paths
9
+ # When calling the validation routine, a path, or URL is passed. This is used internally to name
10
+ # the resulting validation output files.
11
+
12
+ # NOTE: HTMLValidation never retreives html or reads in files *for* you. It doesn't read files, or call
13
+ # passed URL's. The purpose of passing a resource path is to give the test a name which saved exceptions
14
+ # can be stored against and compared to. In theory, the resource could be any distinct string, meaningful or not.
15
+
16
+ # If the resource (URL or file) has a saved exception string and it matches, the validation passes.
17
+ # The user can use a rake task can run this manually and upd ate the accepted exception string.
18
+
19
+ require 'rbconfig'
20
+
21
+ require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/html_validation_result'))
22
+ require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/html_validation_matcher'))
23
+
24
+ module PageValidations
25
+
26
+ class HTMLValidation
27
+
28
+ # The data_folder is where we store our output. options[:tidyopts], which defaults to "-qi"
29
+ # can be used to override the command line options to html tidy. On *nix, man tidy to see
30
+ # what else you might use for this string instead of "-qi", however "-qi" is probably what
31
+ # you want 95% of the time.
32
+
33
+ # You may also pass :ignore_proprietary => true as an option to suppress messages like:
34
+ # line 1 column 176 - Warning: <textarea> proprietary attribute "wrap"
35
+ # line 1 column 176 - Warning: <textarea> proprietary attribute "spellcheck"
36
+
37
+ # It may be useful to pass a subfolder in your project as the data_folder, so your
38
+ # HTML Validation status and validation results are stored along with your source.
39
+ def initialize(folder_for_data = nil, options = {})
40
+ self.data_folder = folder_for_data || default_result_file_path
41
+ @options = options
42
+ end
43
+
44
+ # For each stored exception, yield an HTMLValidationResult object to allow the user to
45
+ # call .accept! on the exception if it is OK.
46
+ def each_exception
47
+ Dir.chdir(@data_folder)
48
+ Dir.glob("*.exceptions.txt").each do |file|
49
+ if File.open(File.join(@data_folder, file), 'r').read != ''
50
+ yield HTMLValidationResult.load_from_files(file.gsub('.exceptions.txt',''))
51
+ end
52
+ end
53
+ end
54
+
55
+ def validation(html, resource)
56
+ resource_data_path = File.join(@data_folder, filenameize(resource))
57
+ HTMLValidationResult.new(resource, html, resource_data_path, @options)
58
+ end
59
+
60
+ def data_folder=(path)
61
+ FileUtils.mkdir_p(path)
62
+ @data_folder = path
63
+ end
64
+
65
+ def default_result_file_path
66
+ posix = RbConfig::CONFIG['host_os'] =~ /(darwin|linux)/
67
+ rootpath = Rails.root if defined?(Rails)
68
+ rootpath ||= HTMLValidationMatcher.data_path if HTMLValidationMatcher.data_path
69
+ rootpath ||= posix ? '/tmp/' : "c:\\tmp\\"
70
+ File.join(rootpath, '.validation')
71
+ end
72
+
73
+ private
74
+
75
+ # Takes a url or filepath qne trims and sanitizes it for use as a filename.
76
+ def filenameize(path)
77
+ path.gsub!(/www.|^(http:\/\/|\/|C:\\)/, '')
78
+ path.gsub(/[^0-9A-Za-z.]/, '_')
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env thor
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'html_validation'))
3
+
4
+ class Validation < Thor
5
+ include PageValidations
6
+ desc "review", "Review and Accept (or fix and rerun) HTML Validation errors"
7
+
8
+ method_option :data_path, :aliases => "-d", :desc => "Optional custom data path (if not default of /spec/.validate)"
9
+ def review
10
+ data_path = options[:data_path] || File.join(Dir.getwd, 'spec', '.validation')
11
+ $stdout.puts "Reviewing validation results in: #{data_path}"
12
+
13
+ HTMLValidation.new(data_path).each_exception do |result|
14
+ $stdout.puts "Validation exceptions for: #{result.resource}:\n#{result.exceptions}"
15
+ $stdout.puts "Accept (y)es (n)o or (q)uit"
16
+ sin = $stdin.gets
17
+ if sin[0].downcase == 'y'
18
+ result.accept!
19
+ $stdout.puts "Accepted!"
20
+ else
21
+ $stdout.puts "Rejected!"
22
+ end
23
+ exit if sin.downcase == 'exit' or sin.downcase == 'quit' or sin.downcase == 'q'
24
+ end
25
+ $stdout.puts "HTML Validation Acceptance completed"
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'html_validation/have_valid_html'
4
+
5
+ describe "HTMLValidationRSpecMatcher" do
6
+
7
+ before(:each) do
8
+ @page = double("page")
9
+ end
10
+
11
+ it "should check page object with the matcher for valid HTML and pass valid html" do
12
+ @page.stub :html => good_html
13
+ @page.stub :body => good_html
14
+ @page.stub :current_url => 'http://www.fake.com/good_page'
15
+ @page.should have_valid_html
16
+ end
17
+
18
+ it "should check page object with the matcher for valid HTML and fail bad HTML" do
19
+ @page.stub :html => bad_html
20
+ @page.stub :body => bad_html
21
+ @page.stub :current_url => 'http://www.fake.com/bad_page'
22
+ @page.should_not have_valid_html
23
+ end
24
+
25
+
26
+ private
27
+
28
+ def bad_html
29
+ '<html><title>the title<title></head><body><p>blah blah</body></html>'
30
+ end
31
+
32
+ def good_html
33
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><title>the title</title></head><body><p>a paragraph</p></body></html>'
34
+ end
35
+
36
+ def tmp_path
37
+ is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
38
+ is_windows ? 'c:\temp\validation' : '/tmp/validation'
39
+ end
40
+
41
+ # clean our temp dir without killing it
42
+ def clean_dir(dir)
43
+ Dir.chdir(dir)
44
+ Dir.glob('*').each {|f| FileUtils.rm f }
45
+ end
46
+
47
+ end
@@ -0,0 +1,133 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+ describe "HTMLValidation" do
5
+
6
+ before(:each) do
7
+ FileUtils.mkdir tmp_path if !File.exists?('/tmp/validation')
8
+ @h = HTMLValidation.new('/tmp/validation')
9
+ end
10
+
11
+ it "should return false for invalid xml" do
12
+ result = @h.validation(bad_html, "http://myothersite.com").valid?.should be_false
13
+ end
14
+
15
+ it "should return true for valid html" do
16
+ result = @h.validation(good_html, "http://mysite.com").valid?.should be_true
17
+ end
18
+
19
+ it "should have an exception string for invalid xml" do
20
+ result = @h.validation(bad_html, "http://myfavoritesite.com")
21
+ (result.exceptions.empty?).should be_false
22
+ end
23
+
24
+ it "should return true for valid? if exceptions are accepted" do
25
+ result = @h.validation(bad_html, "http://mynewsite.com")
26
+ result.accept!
27
+ result = @h.validation(bad_html, "http://mynewsite.com").valid?.should be_true
28
+ end
29
+
30
+ it "should show no exceptions for a truly valid file" do
31
+ result = @h.validation(good_html, "http://mybestsite.com")
32
+ (result.exceptions == '').should be_true
33
+ end
34
+
35
+ it "should still show exceptions when returning valid for an accepted exception string" do
36
+ result = @h.validation(bad_html, "http://myworstsite.com")
37
+ result.accept!
38
+ result = @h.validation(bad_html, "http://myworstsite.com")
39
+ result.valid?.should be_true
40
+ (result.exceptions.length == 0).should be_false
41
+ end
42
+
43
+ it "should reset exceptions after each call to valid?" do
44
+ result = @h.validation(bad_html, "http://myuglysite.com")
45
+ result = @h.validation(good_html, "http://myuglysite.com")
46
+ (result.exceptions.length == 0).should be_true
47
+ result.valid?.should be_true
48
+ end
49
+
50
+ it "should reset accepted exceptions string after seeing valid html for a path" do
51
+ result = @h.validation(bad_html, "http://notmysite.com")
52
+ result.accept!
53
+ result = @h.validation(bad_html, "http://notmysite.com").valid?.should be_true
54
+ # now we see valid, so we should reset
55
+ result = @h.validation(good_html, "http://notmysite.com").valid?.should be_true
56
+ result = @h.validation(bad_html, "http://notmysite.com").valid?.should be_false
57
+ end
58
+
59
+ it "should not pass a different non-accepted exception" do
60
+ result = @h.validation(bad_html, "http://mycoolsite.com")
61
+ result.accept!
62
+ result = @h.validation("<html></body></html>", "http://mycoolsite.com").valid?.should be_false
63
+ end
64
+
65
+ it "should ignore proprietary tags when ignore_proprietary is passed" do
66
+ html_with_proprietary=good_html.gsub('<body>','<body><textarea wrap="true" spellcheck="true">hi</textarea>')
67
+ result = @h.validation(html_with_proprietary, "http://mycrosoft.com")
68
+ result.valid?.should be_false
69
+ @h = HTMLValidation.new('/tmp/validation', :ignore_proprietary=>true)
70
+ result = @h.validation(html_with_proprietary, "http://mycrosoft.com")
71
+ result.valid?.should be_true
72
+ end
73
+
74
+ it "should work without a data path being manually set" do
75
+ h = HTMLValidation.new()
76
+ result = h.validation(good_html, "http://mybestsite.com")
77
+ (result.exceptions == '').should be_true
78
+ end
79
+
80
+
81
+ describe "when launching HTML Tidy" do
82
+
83
+ it "should let me pass different Tidy command line options" do
84
+ @h = HTMLValidation.new('/tmp/validation', :tidy_opts=>"-e")
85
+ result = @h.validation("<html>foo", 'c:\mycoolapp\somesite.html')
86
+ result.exceptions.include?("were found!").should be_true
87
+ @h = HTMLValidation.new('/tmp/validation')
88
+ result = @h.validation("<html>foo", 'c:\mycoolapp\somesite.html')
89
+ result.exceptions.include?("were found!").should be_false
90
+ end
91
+
92
+ end
93
+
94
+ describe "when walking exception results" do
95
+
96
+ it "should yield loaded exception results" do
97
+ @h = HTMLValidation.new('/tmp/validation')
98
+ result = @h.validation("<html>foo", 'c:\evencooler.com\somesite.html')
99
+ had_exceptions = false
100
+ @h.each_exception do |e|
101
+ had_exceptions = true
102
+ e.is_a?(HTMLValidationResult).should be_true
103
+ (e.resource.length > 0).should be_true
104
+ (e.html.length > 0).should be_true
105
+ end
106
+ had_exceptions.should be_true
107
+ end
108
+
109
+ end
110
+
111
+
112
+ private
113
+
114
+ def bad_html
115
+ '<html><title>the title<title></head><body><p>blah blah</body></html>'
116
+ end
117
+
118
+ def good_html
119
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><title>the title</title></head><body><p>a paragraph</p></body></html>'
120
+ end
121
+
122
+ def tmp_path
123
+ is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
124
+ is_windows ? 'c:\temp\validation' : '/tmp/validation'
125
+ end
126
+
127
+ # clean our temp dir without killing it
128
+ def clean_dir(dir)
129
+ Dir.chdir(dir)
130
+ Dir.glob('*').each {|f| FileUtils.rm f }
131
+ end
132
+
133
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'html_validation'
5
+
6
+ include PageValidations
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
11
+
12
+ RSpec.configure do |config|
13
+
14
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html_validation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Beland
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: HTML Validation lets you validate html locally. Lets you build html validation
15
+ into your test suite, but break the rules if you must.
16
+ email:
17
+ - ebeland@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .document
23
+ - .gitignore
24
+ - .rspec
25
+ - Gemfile
26
+ - Gemfile.lock
27
+ - LICENSE.txt
28
+ - README.rdoc
29
+ - Rakefile
30
+ - VERSION
31
+ - html_validation.gemspec
32
+ - lib/html_validation.rb
33
+ - lib/html_validation/have_valid_html.rb
34
+ - lib/html_validation/html_validation_matcher.rb
35
+ - lib/html_validation/html_validation_result.rb
36
+ - lib/html_validation/version.rb
37
+ - lib/tasks/validation.thor
38
+ - spec/html_validator_matcher_spec.rb
39
+ - spec/html_validator_spec.rb
40
+ - spec/spec_helper.rb
41
+ homepage: https://github.com/ericbeland/html_validation
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.25
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Local HTML validation for tests and RSpec.
65
+ test_files:
66
+ - spec/html_validator_matcher_spec.rb
67
+ - spec/html_validator_spec.rb
68
+ - spec/spec_helper.rb