html_validation 0.4.1 → 0.5.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.
- data/README.rdoc +55 -39
- data/lib/html_validation.rb +1 -22
- data/lib/html_validation/have_valid_html.rb +4 -4
- data/lib/html_validation/html_validation_result.rb +44 -31
- data/lib/html_validation/page_validations.rb +65 -29
- data/lib/html_validation/version.rb +1 -1
- data/spec/helpers/html_validation_helpers.rb +23 -0
- data/spec/{html_validator_matcher_spec.rb → html_validation_matcher_spec.rb} +7 -14
- data/spec/{html_validator_spec.rb → html_validation_spec.rb} +62 -57
- data/spec/spec_helper.rb +24 -2
- metadata +8 -6
data/README.rdoc
CHANGED
@@ -1,46 +1,59 @@
|
|
1
1
|
= HTML Validation
|
2
2
|
|
3
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
|
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
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.
|
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
13
|
|
14
14
|
== HTML 5
|
15
15
|
|
16
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
|
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
19
|
given on the page (using sudo for make commands if on Linux).
|
20
20
|
|
21
21
|
Be sure to get rid of the old tidy first if you have it already.
|
22
22
|
|
23
23
|
Redhat/Fedora: sudo yum erase tidy
|
24
|
+
|
24
25
|
Ubuntu: sudo apt-get remove tidy
|
26
|
+
|
25
27
|
OS X: sudo port uninstall tidy
|
26
28
|
|
27
|
-
On linux/OS X machines, confirm the right installation path
|
29
|
+
On linux/OS X machines, confirm the right installation path using: which tidy
|
28
30
|
|
29
31
|
== RSpec Setup / Usage:
|
30
|
-
Add to spec/spec_helper.rb:
|
31
|
-
|
32
|
+
Add to spec/spec_helper.rb:
|
33
|
+
|
32
34
|
require 'html_validation'
|
33
35
|
include PageValidations
|
34
36
|
|
35
|
-
Now, within your Integration Tests, you can do this:
|
37
|
+
Now, within your Integration Tests, you can do this:
|
36
38
|
|
37
39
|
page.should have_valid_html
|
38
40
|
|
39
41
|
It can be convenient to see the html printed in the RSpec failure messages.
|
40
|
-
To enable this feature:
|
42
|
+
To enable this feature (globally for all):
|
41
43
|
|
42
44
|
HaveValidHTML.show_html_in_failures = true
|
43
45
|
|
46
|
+
|
47
|
+
# All tidy flags, including using a config file can be passed.
|
48
|
+
|
49
|
+
# A shortcut to disable Tidy Warning messages (they are on by default)
|
50
|
+
# has been created for your convenience. However, some things that might be
|
51
|
+
# called "errors" show up as warnings, so the recommended approach is
|
52
|
+
# run, then accept the errors / warnings that are noted.
|
53
|
+
HTMLValidation.show_warnings = false
|
54
|
+
|
55
|
+
|
56
|
+
|
44
57
|
== Non-RSpec Usage:
|
45
58
|
|
46
59
|
require 'html_validation'
|
@@ -48,61 +61,64 @@ On linux/OS X machines, confirm the right installation path shows up with: whic
|
|
48
61
|
|
49
62
|
h = HTMLValidation.new
|
50
63
|
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
|
64
|
+
|
65
|
+
# Note: The second argument (resource) just serves as an identifier used to
|
53
66
|
# name our results files, and no data is actually retrieved for you from on the URL!
|
54
67
|
|
55
68
|
v.valid?
|
56
69
|
-> false
|
57
|
-
|
70
|
+
|
58
71
|
v.exceptions
|
59
72
|
-> line 1 column 1 - Warning: missing <!DOCTYPE> declaration
|
60
73
|
-> line 1 column 9 - Warning: plain text isn't allowed in <head> elements
|
61
74
|
-> line 1 column 9 - Warning: inserting missing 'title' element
|
62
|
-
|
75
|
+
|
63
76
|
v.accept!
|
64
|
-
|
77
|
+
|
65
78
|
v.valid?
|
66
79
|
-> true
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
|
81
|
+
Note: after the exceptions string has been accepted, the exceptions
|
82
|
+
are still available in v.exceptions even though valid? will return true.
|
83
|
+
This is so you can print them out, nag yourself, etc.
|
84
|
+
|
85
|
+
The exception string is treated and matched as a whole. The current
|
86
|
+
implementation does not allow partial acceptance of individual
|
87
|
+
results in a result string.
|
88
|
+
|
89
|
+
== Accepting Errors / Warnings
|
90
|
+
|
77
91
|
The HTML Validation gem stores failure data per-resource. The results are stored
|
78
92
|
in the data_folder. Typically this is the default folder: spec/.validation.
|
79
93
|
After a validation fails, run the thor task to accept or reject validation exceptions.
|
80
94
|
|
81
|
-
From your project's root folder, run: validation review
|
82
|
-
|
95
|
+
From your project's root folder, run: validation review
|
96
|
+
|
97
|
+
The result string is checked as a whole, so changes require re-review.
|
98
|
+
|
83
99
|
Note, if you configure an alternate data_folder, you may pass it as an option
|
84
100
|
to the Thor task.
|
85
101
|
|
86
|
-
|
102
|
+
|
87
103
|
== NOTES
|
88
|
-
|
89
|
-
This is untested on Windows as I don't have access to a Windows machine at the moment.
|
104
|
+
|
105
|
+
This is untested on Windows as I don't have access to a Windows machine at the moment.
|
90
106
|
It is written so it could (probably) work on Windows. Pull requests in this area would
|
91
|
-
be welcomed.
|
92
|
-
|
107
|
+
be welcomed.
|
108
|
+
|
93
109
|
== Requirements
|
94
110
|
|
95
111
|
HTML Tidy needs to be either installed at /usr/bin/tidy or on the PATH.
|
96
112
|
|
97
113
|
|
98
114
|
== Contributing to html_validation
|
99
|
-
|
115
|
+
|
100
116
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
101
117
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
102
118
|
* Fork the project
|
103
119
|
* Start a feature/bugfix branch
|
104
120
|
* 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.
|
121
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
106
122
|
|
107
123
|
|
108
124
|
=== Running the tests
|
data/lib/html_validation.rb
CHANGED
@@ -1,25 +1,4 @@
|
|
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
1
|
require 'rbconfig'
|
20
|
-
|
21
|
-
|
22
|
-
|
23
2
|
require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/page_validations'))
|
24
3
|
require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/html_validation_result'))
|
25
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/html_validation_matcher'))
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'html_validation/html_validation_matcher'))
|
@@ -8,10 +8,10 @@ module PageValidations
|
|
8
8
|
# The response is passed in as an argument when you do this:
|
9
9
|
# page.should have_valid_html
|
10
10
|
|
11
|
-
@@
|
11
|
+
@@html_in_failures = false
|
12
12
|
|
13
13
|
def self.show_html_in_failures=(val)
|
14
|
-
@@
|
14
|
+
@@html_in_failures = val
|
15
15
|
end
|
16
16
|
|
17
17
|
def matches?(page)
|
@@ -25,11 +25,11 @@ module PageValidations
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def failure_message_for_should
|
28
|
-
"#{@v.resource} Invalid html (fix or run
|
28
|
+
"#{@v.resource} Invalid html (fix or run 'validation review' to add exceptions)\n#{@v.resource} exceptions:\n #{@v.exceptions}\n\n #{@v.html if @@html_in_failures}"
|
29
29
|
end
|
30
30
|
|
31
31
|
def failure_message_for_should_not
|
32
|
-
"#{@v.resource} Expected valid? to fail but didn't. Did you accidentally accept these
|
32
|
+
"#{@v.resource} Expected valid? to fail but didn't. Did you accidentally accept these validation errors? \n#{@v.resource} exceptions:\n #{@v.exceptions}\n\n #{@v.html if @@html_in_failures}"
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
@@ -4,56 +4,69 @@ require File.join(File.dirname(__FILE__), '..', 'html_validation')
|
|
4
4
|
|
5
5
|
class HTMLValidationResult
|
6
6
|
attr_accessor :resource, :html, :exceptions
|
7
|
-
|
7
|
+
|
8
8
|
include PageValidations
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
# :resource: a label (could be a url) representing the html in question
|
11
|
+
# :html: the actual html
|
12
|
+
# :datapath: where to find results
|
13
|
+
# :options:
|
14
|
+
|
15
|
+
# options ex: options[:tidy_opts] = ['--show-warnings false']
|
16
|
+
def initialize(resource, html, datapath, tidy_flags = [], options = {})
|
11
17
|
@resource = resource
|
12
18
|
@html = html
|
13
19
|
@exceptions = ''
|
14
20
|
@datapath = datapath
|
15
|
-
@
|
16
|
-
@ignore_proprietary = options[:ignore_proprietary]
|
21
|
+
@tidy_flags = (HTMLValidation.default_tidy_flags + tidy_flags).uniq
|
22
|
+
@ignore_proprietary = options[:ignore_proprietary]
|
17
23
|
valid?
|
18
24
|
end
|
19
25
|
|
26
|
+
# An array of strings representing the default command line flags to pass to Tidy.
|
27
|
+
# ex: ['--qi', '--show-warnings false']
|
28
|
+
#
|
29
|
+
# For a list of options (including how to pass a config file flag), see here:
|
30
|
+
# http://w3c.github.com/tidy-html5/
|
31
|
+
|
32
|
+
|
20
33
|
# takes a .url and loads the data into this object
|
21
34
|
def self.load_from_files(filepath)
|
22
35
|
resource = File.open("#{filepath}.resource.txt", 'r').read
|
23
36
|
html = File.open("#{filepath}.html.txt", 'r').read
|
24
37
|
HTMLValidationResult.new(resource, html, filepath)
|
25
38
|
end
|
26
|
-
|
27
|
-
# Validates an html string using html tidy. If there are no warnings or exceptions, or
|
39
|
+
|
40
|
+
# Validates an html string using html tidy. If there are no warnings or exceptions, or
|
28
41
|
# there is a previously accepted exception string that matches exactly, valid? returns true
|
29
|
-
# Line numbers of exceptions are likely to change with any edit, so our validation
|
42
|
+
# Line numbers of exceptions are likely to change with any edit, so our validation
|
30
43
|
# compares the exception strings with the lines and columns removed. Name can be a filename,
|
31
44
|
# file system path, or url, so long it is uniquely associated with the passed in html.
|
32
45
|
def valid?
|
33
|
-
@exceptions = validate
|
34
|
-
File.delete(data_path("accepted")) if File.exists?(data_path("accepted")) if @exceptions == ''
|
35
|
-
valid = (filter(@exceptions) == '' or accepted?(@exceptions))
|
36
|
-
save_html_and_exceptions
|
46
|
+
@exceptions = validate
|
47
|
+
File.delete(data_path("accepted")) if File.exists?(data_path("accepted")) if @exceptions == ''
|
48
|
+
valid = (filter(@exceptions) == '' or accepted?(@exceptions))
|
49
|
+
save_html_and_exceptions
|
37
50
|
valid
|
38
51
|
end
|
39
52
|
|
40
53
|
# Saves the exception string for the given url or file path. When next run, if the exception
|
41
|
-
# string is identical, valid? will return true. Note that #exceptions will still list the
|
54
|
+
# string is identical, valid? will return true. Note that #exceptions will still list the
|
42
55
|
# exception string, though, even if it is an accepted exception string.
|
43
|
-
def accept!
|
56
|
+
def accept!
|
44
57
|
File.open(data_path("accepted"), 'w') {|f| f.write(@exceptions) }
|
45
58
|
end
|
46
|
-
|
59
|
+
|
47
60
|
private
|
48
|
-
# We specifically prefer /usr/bin/tidy by default on *nix as there is another "tidy"
|
49
|
-
# that could end up earlier on the path.
|
50
|
-
# for me by default.
|
61
|
+
# We specifically prefer /usr/bin/tidy by default on *nix as there is another "tidy" program
|
62
|
+
# that could end up earlier on the path. tidy was installed at this location for me by default.
|
51
63
|
def tidy_command
|
52
64
|
is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
53
65
|
bin = (is_windows or !File.exists?("/usr/bin/tidy")) ? 'tidy' : '/usr/bin/tidy'
|
54
|
-
"#{bin} #{@
|
66
|
+
cmd = "#{bin} #{@tidy_flags.join(' ')}"
|
67
|
+
cmd
|
55
68
|
end
|
56
|
-
|
69
|
+
|
57
70
|
# get the filename for storing a type of data
|
58
71
|
def data_path(filetype)
|
59
72
|
"#{@datapath}.#{filetype}.txt"
|
@@ -61,27 +74,27 @@ class HTMLValidationResult
|
|
61
74
|
|
62
75
|
def save_html_and_exceptions
|
63
76
|
File.open(data_path("html"), 'w') {|f| f.write(@html) }
|
64
|
-
File.open(data_path("resource"), 'w') {|f| f.write(@resource) }
|
65
|
-
File.open(data_path("exceptions"), 'w') {|f| f.write(@exceptions) }
|
66
|
-
end
|
77
|
+
File.open(data_path("resource"), 'w') {|f| f.write(@resource) }
|
78
|
+
File.open(data_path("exceptions"), 'w') {|f| f.write(@exceptions) }
|
79
|
+
end
|
67
80
|
|
68
81
|
# have we previously accepted this exact string for this path?
|
69
82
|
def accepted?(exception_str)
|
70
83
|
exception_str = filter(exception_str)
|
71
84
|
File.exists?(data_path('accepted')) ? filter(File.open(data_path('accepted'),"r").read) == exception_str : false
|
72
85
|
end
|
73
|
-
|
74
|
-
# Line numbers of exceptions are likely to change with any minor edit, so our validation
|
75
|
-
# compares the result strings with the lines and columns removed. This means that
|
76
|
-
# if the errors change position in the file (up or down b/c you add or remove code),
|
86
|
+
|
87
|
+
# Line numbers of exceptions are likely to change with any minor edit, so our validation
|
88
|
+
# compares the result strings with the lines and columns removed. This means that
|
89
|
+
# if the errors change position in the file (up or down b/c you add or remove code),
|
77
90
|
# accepted exception strings will remain valid.
|
78
91
|
def filter(str)
|
79
92
|
str.gsub!(/^line.*trimming empty.*\n/, '') # the messages about empty are overzealous, and not invalid
|
80
|
-
str.gsub!(/^line.*proprietary.*\n/, '') if @ignore_proprietary # if you use IE only attributes like wrap, or spellcheck or things not in standard
|
81
|
-
str.gsub(/line [0-9]+ column [0-9]+ -/, '')
|
93
|
+
str.gsub!(/^line.*proprietary.*\n/, '') if @ignore_proprietary # if you use IE only attributes like wrap, or spellcheck or things not in standard
|
94
|
+
str.gsub(/line [0-9]+ column [0-9]+ -/, '')
|
82
95
|
# /line [0-9]+ column [0-9]+ - / + =~ "line 1 column 1 - Warning: missing <!DOCTYPE> declaration"
|
83
96
|
end
|
84
|
-
|
97
|
+
|
85
98
|
def validate
|
86
99
|
stdin, stdout, stderr = Open3.popen3(tidy_command)
|
87
100
|
stdin.puts @html
|
@@ -91,5 +104,5 @@ class HTMLValidationResult
|
|
91
104
|
stderr.close
|
92
105
|
result
|
93
106
|
end
|
94
|
-
|
107
|
+
|
95
108
|
end
|
@@ -1,27 +1,61 @@
|
|
1
|
+
module PageValidations
|
2
|
+
# Namespace planned for future additional validations
|
1
3
|
|
2
4
|
|
3
|
-
module PageValidations
|
4
|
-
|
5
5
|
class HTMLValidation
|
6
|
-
|
6
|
+
|
7
|
+
@@default_tidy_flags = ['-quiet', '-indent']
|
8
|
+
|
7
9
|
# The data_folder is where we store our output. options[:tidyopts], which defaults to "-qi"
|
8
10
|
# can be used to override the command line options to html tidy. On *nix, man tidy to see
|
9
|
-
# what else you might use for this string instead of "-qi", however "-qi" is probably what
|
11
|
+
# what else you might use for this string instead of "-qi", however "-qi" is probably what
|
10
12
|
# you want 95% of the time.
|
11
|
-
|
12
|
-
# You may also pass :ignore_proprietary => true as an option to suppress messages like:
|
13
|
+
|
14
|
+
# You may also pass :ignore_proprietary => true as an option to suppress messages like:
|
13
15
|
# line 1 column 176 - Warning: <textarea> proprietary attribute "wrap"
|
14
16
|
# line 1 column 176 - Warning: <textarea> proprietary attribute "spellcheck"
|
15
|
-
|
17
|
+
|
16
18
|
# It may be useful to pass a subfolder in your project as the data_folder, so your
|
17
|
-
# HTML Validation status and validation results are stored along with your source.
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
# HTML Validation status and validation results are stored along with your source.
|
20
|
+
|
21
|
+
# :folder_for_data: Storage folder path to save, and look for, result files.
|
22
|
+
# :options: hash passed directly to HTMLValidationResult
|
23
|
+
def initialize(folder_for_data = nil, tidy_flags = [], options={})
|
24
|
+
self.data_folder = folder_for_data || default_result_file_path
|
25
|
+
@tidy_flags = tidy_flags
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Default command line flags to pass when tidy is executed.
|
31
|
+
# all tidy flags flags as an array of strings like ['--show-warnings false']
|
32
|
+
# Note: Pass the entire string for each setting, NOT a name value pair
|
33
|
+
# settings are available from: tidy -h
|
34
|
+
def self.default_tidy_flags
|
35
|
+
@@default_tidy_flags
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.default_tidy_flags=(val)
|
39
|
+
@@default_tidy_flags = val
|
40
|
+
end
|
41
|
+
|
42
|
+
# Shortcut to enable/disable whether warnings are checked in Tidy.
|
43
|
+
# Note that changing this setting (or any flag) can change how
|
44
|
+
# the result files are seen in terms of their acceptance.
|
45
|
+
# Meaning, if you have previously accepted a page with warnings either
|
46
|
+
# on or off, you will probably need to re-run the 'validation review' command
|
47
|
+
# following your first run with the new setting.
|
48
|
+
def self.show_warnings=(val)
|
49
|
+
if val
|
50
|
+
@@default_tidy_flags.delete('--show-warnings false') # remove the flag (rely on default: true)
|
51
|
+
else
|
52
|
+
(@@default_tidy_flags << '--show-warnings false').uniq!
|
53
|
+
end
|
21
54
|
end
|
22
55
|
|
23
|
-
|
24
|
-
#
|
56
|
+
|
57
|
+
# For each stored exception, yield an HTMLValidationResult object to allow the user to
|
58
|
+
# call .accept! on the exception if it is OK.
|
25
59
|
def each_exception
|
26
60
|
Dir.chdir(@data_folder)
|
27
61
|
Dir.glob("*.exceptions.txt").each do |file|
|
@@ -30,32 +64,34 @@ module PageValidations
|
|
30
64
|
end
|
31
65
|
end
|
32
66
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
67
|
+
|
68
|
+
# :html: The html to validate
|
69
|
+
# :resource: Used to create a name for the result file, nothing more. Usually a URL.
|
70
|
+
def validation(html, resource_name)
|
71
|
+
resource_data_path = File.join(@data_folder, filenameize(resource_name))
|
72
|
+
HTMLValidationResult.new(resource_name, html, resource_data_path, @tidy_flags, @options)
|
37
73
|
end
|
38
|
-
|
74
|
+
|
39
75
|
def data_folder=(path)
|
40
|
-
FileUtils.mkdir_p(path)
|
41
|
-
@data_folder = path
|
76
|
+
FileUtils.mkdir_p(path)
|
77
|
+
@data_folder = path
|
42
78
|
end
|
43
|
-
|
79
|
+
|
44
80
|
def default_result_file_path
|
45
|
-
posix
|
46
|
-
rootpath
|
47
|
-
rootpath ||= HTMLValidationMatcher.data_path if HTMLValidationMatcher.data_path
|
81
|
+
posix = RbConfig::CONFIG['host_os'] =~ /(darwin|linux)/
|
82
|
+
rootpath = Rails.root if defined?(Rails)
|
83
|
+
rootpath ||= HTMLValidationMatcher.data_path if HTMLValidationMatcher.data_path
|
48
84
|
rootpath ||= posix ? '/tmp/' : "c:\\tmp\\"
|
49
85
|
File.join(rootpath, '.validation')
|
50
86
|
end
|
51
|
-
|
87
|
+
|
52
88
|
private
|
53
|
-
|
89
|
+
|
54
90
|
# Takes a url or filepath qne trims and sanitizes it for use as a filename.
|
55
91
|
def filenameize(path)
|
56
92
|
path.gsub!(/www.|^(http:\/\/|\/|C:\\)/, '')
|
57
|
-
path.gsub(/[^0-9A-Za-z.]/, '_')
|
93
|
+
path.gsub(/[^0-9A-Za-z.]/, '_')
|
58
94
|
end
|
59
|
-
|
95
|
+
|
60
96
|
end
|
61
|
-
end
|
97
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module HTMLValidationHelpers
|
2
|
+
|
3
|
+
def bad_html
|
4
|
+
'<html><title>the title<title></head><body><p>blah blah</body></html>'
|
5
|
+
end
|
6
|
+
|
7
|
+
def good_html
|
8
|
+
html_5_doctype + '<html><title>the title</title></head><body><p>a paragraph</p></body></html>'
|
9
|
+
end
|
10
|
+
|
11
|
+
def dtd
|
12
|
+
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
|
13
|
+
end
|
14
|
+
|
15
|
+
def html_5_doctype
|
16
|
+
'<!DOCTYPE html>'
|
17
|
+
end
|
18
|
+
|
19
|
+
def warning_html
|
20
|
+
html_5_doctype + '<html><title proprietary="1">h</title></head><body><p>a para</p></body></html>'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -3,7 +3,8 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
require 'html_validation/have_valid_html'
|
4
4
|
|
5
5
|
describe "HTMLValidationRSpecMatcher" do
|
6
|
-
|
6
|
+
include HTMLValidationHelpers
|
7
|
+
|
7
8
|
before(:each) do
|
8
9
|
@page = double("page")
|
9
10
|
end
|
@@ -14,34 +15,26 @@ describe "HTMLValidationRSpecMatcher" do
|
|
14
15
|
@page.stub :current_url => 'http://www.fake.com/good_page'
|
15
16
|
@page.should have_valid_html
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
it "should check page object with the matcher for valid HTML and fail bad HTML" do
|
19
20
|
@page.stub :html => bad_html
|
20
21
|
@page.stub :body => bad_html
|
21
22
|
@page.stub :current_url => 'http://www.fake.com/bad_page'
|
22
23
|
@page.should_not have_valid_html
|
23
24
|
end
|
24
|
-
|
25
|
-
|
25
|
+
|
26
|
+
|
26
27
|
private
|
27
28
|
|
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
29
|
def tmp_path
|
37
30
|
is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
38
31
|
is_windows ? 'c:\temp\validation' : '/tmp/validation'
|
39
32
|
end
|
40
|
-
|
33
|
+
|
41
34
|
# clean our temp dir without killing it
|
42
35
|
def clean_dir(dir)
|
43
36
|
Dir.chdir(dir)
|
44
37
|
Dir.glob('*').each {|f| FileUtils.rm f }
|
45
38
|
end
|
46
|
-
|
39
|
+
|
47
40
|
end
|
@@ -1,52 +1,53 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
3
|
+
|
4
4
|
describe "HTMLValidation" do
|
5
|
-
|
5
|
+
include HTMLValidationHelpers
|
6
|
+
|
6
7
|
before(:each) do
|
7
8
|
FileUtils.mkdir tmp_path if !File.exists?('/tmp/validation')
|
8
|
-
@h = HTMLValidation.new('/tmp/validation')
|
9
|
+
@h = HTMLValidation.new('/tmp/validation')
|
9
10
|
end
|
10
|
-
|
11
|
-
it "should return false for invalid
|
11
|
+
|
12
|
+
it "should return false for invalid html" do
|
12
13
|
result = @h.validation(bad_html, "http://myothersite.com").valid?.should be_false
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
it "should return true for valid html" do
|
16
17
|
result = @h.validation(good_html, "http://mysite.com").valid?.should be_true
|
17
18
|
end
|
18
|
-
|
19
|
-
it "should have an exception string for invalid
|
19
|
+
|
20
|
+
it "should have an exception string for invalid html" do
|
20
21
|
result = @h.validation(bad_html, "http://myfavoritesite.com")
|
21
22
|
(result.exceptions.empty?).should be_false
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
it "should return true for valid? if exceptions are accepted" do
|
25
26
|
result = @h.validation(bad_html, "http://mynewsite.com")
|
26
27
|
result.accept!
|
27
28
|
result = @h.validation(bad_html, "http://mynewsite.com").valid?.should be_true
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
it "should show no exceptions for a truly valid file" do
|
31
32
|
result = @h.validation(good_html, "http://mybestsite.com")
|
32
33
|
(result.exceptions == '').should be_true
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
it "should still show exceptions when returning valid for an accepted exception string" do
|
36
37
|
result = @h.validation(bad_html, "http://myworstsite.com")
|
37
38
|
result.accept!
|
38
39
|
result = @h.validation(bad_html, "http://myworstsite.com")
|
39
40
|
result.valid?.should be_true
|
40
|
-
|
41
|
+
result.exceptions.length.should_not be_zero
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
it "should reset exceptions after each call to valid?" do
|
44
45
|
result = @h.validation(bad_html, "http://myuglysite.com")
|
45
46
|
result = @h.validation(good_html, "http://myuglysite.com")
|
46
|
-
|
47
|
+
result.exceptions.length.should be_zero
|
47
48
|
result.valid?.should be_true
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
it "should reset accepted exceptions string after seeing valid html for a path" do
|
51
52
|
result = @h.validation(bad_html, "http://notmysite.com")
|
52
53
|
result.accept!
|
@@ -55,79 +56,83 @@ describe "HTMLValidation" do
|
|
55
56
|
result = @h.validation(good_html, "http://notmysite.com").valid?.should be_true
|
56
57
|
result = @h.validation(bad_html, "http://notmysite.com").valid?.should be_false
|
57
58
|
end
|
58
|
-
|
59
|
+
|
59
60
|
it "should not pass a different non-accepted exception" do
|
60
61
|
result = @h.validation(bad_html, "http://mycoolsite.com")
|
61
62
|
result.accept!
|
62
|
-
result = @h.validation("<html></body></html>", "http://mycoolsite.com").valid?.should be_false
|
63
|
+
result = @h.validation("<html></body></html>", "http://mycoolsite.com").valid?.should be_false
|
63
64
|
end
|
64
|
-
|
65
|
+
|
65
66
|
it "should ignore proprietary tags when ignore_proprietary is passed" do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
67
|
+
html_with_proprietary=good_html.gsub('<body>','<body><textarea wrap="true" spellcheck="true">hi</textarea>')
|
68
|
+
result = @h.validation(html_with_proprietary, "http://mycrosoft.com")
|
69
|
+
result.valid?.should be_false
|
70
|
+
@h = HTMLValidation.new('/tmp/validation', [], :ignore_proprietary => true)
|
71
|
+
result = @h.validation(html_with_proprietary, "http://mycrosoft.com")
|
72
|
+
result.valid?.should be_true
|
73
|
+
end
|
74
|
+
|
74
75
|
it "should work without a data path being manually set" do
|
75
|
-
h = HTMLValidation.new()
|
76
|
+
h = HTMLValidation.new()
|
76
77
|
result = h.validation(good_html, "http://mybestsite.com")
|
77
|
-
|
78
|
+
result.exceptions.should be_empty
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should not show (should ignore) warnings when they are turned off" do
|
82
|
+
HTMLValidation.show_warnings = false
|
83
|
+
h = HTMLValidation.new()
|
84
|
+
result = h.validation(warning_html, "http://mywarningsite.com")
|
85
|
+
result.exceptions.should be_empty
|
86
|
+
HTMLValidation.show_warnings = true
|
87
|
+
h = HTMLValidation.new()
|
88
|
+
result = h.validation(warning_html, "http://myotherwarningsite.com")
|
89
|
+
result.exceptions.should_not be_empty
|
78
90
|
end
|
79
|
-
|
80
|
-
|
91
|
+
|
92
|
+
|
81
93
|
describe "when launching HTML Tidy" do
|
82
|
-
|
94
|
+
|
83
95
|
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
96
|
@h = HTMLValidation.new('/tmp/validation')
|
88
97
|
result = @h.validation("<html>foo", 'c:\mycoolapp\somesite.html')
|
89
|
-
result.exceptions.include?("
|
90
|
-
|
91
|
-
|
98
|
+
result.exceptions.include?("Warning:").should be_true
|
99
|
+
@h = HTMLValidation.new('/tmp/validation', ["--show-warnings false"])
|
100
|
+
result = @h.validation("<html>foo", 'c:\mycoolapp\somesite.html')
|
101
|
+
result.exceptions.include?("Warning:").should be_false
|
102
|
+
end
|
103
|
+
|
92
104
|
end
|
93
|
-
|
105
|
+
|
94
106
|
describe "when walking exception results" do
|
95
|
-
|
96
|
-
it "should yield loaded exception results" do
|
107
|
+
|
108
|
+
it "should yield loaded exception results" do
|
97
109
|
@h = HTMLValidation.new('/tmp/validation')
|
98
|
-
result = @h.validation("<html>foo", 'c:\evencooler.com\somesite.html')
|
110
|
+
result = @h.validation("<html>foo", 'c:\evencooler.com\somesite.html')
|
99
111
|
had_exceptions = false
|
100
112
|
@h.each_exception do |e|
|
101
113
|
had_exceptions = true
|
102
114
|
e.is_a?(HTMLValidationResult).should be_true
|
103
115
|
(e.resource.length > 0).should be_true
|
104
116
|
(e.html.length > 0).should be_true
|
105
|
-
end
|
117
|
+
end
|
106
118
|
had_exceptions.should be_true
|
107
|
-
|
108
|
-
|
119
|
+
end
|
120
|
+
|
109
121
|
end
|
110
|
-
|
111
|
-
|
122
|
+
|
123
|
+
|
112
124
|
private
|
113
|
-
|
114
|
-
|
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
|
-
|
125
|
+
|
126
|
+
|
122
127
|
def tmp_path
|
123
128
|
is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
124
129
|
is_windows ? 'c:\temp\validation' : '/tmp/validation'
|
125
130
|
end
|
126
|
-
|
131
|
+
|
127
132
|
# clean our temp dir without killing it
|
128
133
|
def clean_dir(dir)
|
129
134
|
Dir.chdir(dir)
|
130
135
|
Dir.glob('*').each {|f| FileUtils.rm f }
|
131
136
|
end
|
132
|
-
|
137
|
+
|
133
138
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,8 +7,30 @@ include PageValidations
|
|
7
7
|
|
8
8
|
# Requires supporting files with custom matchers and macros, etc,
|
9
9
|
# in ./support/ and its subdirectories.
|
10
|
-
Dir["#{File.dirname(__FILE__)}/
|
10
|
+
Dir["#{File.dirname(__FILE__)}/helpers/**/*.rb"].each {|f| require f }
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f }
|
11
12
|
|
12
13
|
RSpec.configure do |config|
|
13
|
-
|
14
|
+
|
15
|
+
|
14
16
|
end
|
17
|
+
|
18
|
+
def bad_html
|
19
|
+
'<html><title>the title<title></head><body><p>blah blah</body></html>'
|
20
|
+
end
|
21
|
+
|
22
|
+
def good_html
|
23
|
+
html_5_doctype + '<html><title>the title</title></head><body><p>a paragraph</p></body></html>'
|
24
|
+
end
|
25
|
+
|
26
|
+
def dtd
|
27
|
+
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
|
28
|
+
end
|
29
|
+
|
30
|
+
def html_5_doctype
|
31
|
+
'<!DOCTYPE html>'
|
32
|
+
end
|
33
|
+
|
34
|
+
def warning_html
|
35
|
+
html_5_doctype + '<html><title proprietary="1">h</title></head><body><p>a para</p></body></html>'
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html_validation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: HTML Validation lets you validate html locally. Lets you build html validation
|
15
15
|
into your test suite, but break the rules if you must.
|
@@ -36,8 +36,9 @@ files:
|
|
36
36
|
- lib/html_validation/html_validation_result.rb
|
37
37
|
- lib/html_validation/page_validations.rb
|
38
38
|
- lib/html_validation/version.rb
|
39
|
-
- spec/
|
40
|
-
- spec/
|
39
|
+
- spec/helpers/html_validation_helpers.rb
|
40
|
+
- spec/html_validation_matcher_spec.rb
|
41
|
+
- spec/html_validation_spec.rb
|
41
42
|
- spec/spec_helper.rb
|
42
43
|
homepage: https://github.com/ericbeland/html_validation
|
43
44
|
licenses: []
|
@@ -64,6 +65,7 @@ signing_key:
|
|
64
65
|
specification_version: 3
|
65
66
|
summary: Local HTML validation for tests and RSpec.
|
66
67
|
test_files:
|
67
|
-
- spec/
|
68
|
-
- spec/
|
68
|
+
- spec/helpers/html_validation_helpers.rb
|
69
|
+
- spec/html_validation_matcher_spec.rb
|
70
|
+
- spec/html_validation_spec.rb
|
69
71
|
- spec/spec_helper.rb
|