html_validation 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|