validate-website 0.9.0 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/lib/validate_website/colorful_messages.rb +1 -1
- data/lib/validate_website/core.rb +26 -26
- data/lib/validate_website/option_parser.rb +53 -44
- data/lib/validate_website/validator.rb +12 -13
- data/spec/core_spec.rb +34 -26
- data/spec/validator_spec.rb +26 -18
- data/spec/webmock_helper.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e99e7c0d34cdd411b03d1a8a0990ae75f029a1b8
|
4
|
+
data.tar.gz: 601f3a5c01cba46f473a4cead89f10908e2e4d6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 833b02e5cdb8f91f314042c1db35e4f5dcd1ca17347d6bce93a31ba329424b97ad80caf13d6fcfb4ccf12f78a2618bbdcf7e17a89b7b9c440bc52e4b6fdcad9d
|
7
|
+
data.tar.gz: 96cc9f5b765251133c82d5525fcc1a5b1232aef251c76f2a65810f5d721d20bd1ae4dc3d158159726fcc6d1a3efdfbfa0c2688c2b1b3fd6aff0f9d8bf7eb4da2
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rdoc/task'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
|
-
task :
|
4
|
+
task default: [:test]
|
5
5
|
|
6
6
|
RDoc::Task.new do |rd|
|
7
7
|
rd.main = "README.rdoc"
|
@@ -17,4 +17,4 @@ end
|
|
17
17
|
Rake::TestTask.new do |t|
|
18
18
|
t.pattern = "spec/*_spec.rb"
|
19
19
|
end
|
20
|
-
task :
|
20
|
+
task spec: :test
|
@@ -10,10 +10,8 @@ require 'validate_website/colorful_messages'
|
|
10
10
|
require 'spidr'
|
11
11
|
|
12
12
|
module ValidateWebsite
|
13
|
-
|
14
13
|
# Core class for static or website validation
|
15
14
|
class Core
|
16
|
-
|
17
15
|
attr_accessor :site
|
18
16
|
attr_reader :options, :crawler
|
19
17
|
|
@@ -26,7 +24,7 @@ module ValidateWebsite
|
|
26
24
|
|
27
25
|
PING_URL = 'http://www.google.com/'
|
28
26
|
|
29
|
-
def initialize(options={}, validation_type
|
27
|
+
def initialize(options = {}, validation_type = :crawl)
|
30
28
|
@markup_error = nil
|
31
29
|
@not_found_error = nil
|
32
30
|
|
@@ -50,9 +48,9 @@ module ValidateWebsite
|
|
50
48
|
# :markup_validation [Boolean] Check the markup validity
|
51
49
|
# :not_found [Boolean] Check for not found page (404)
|
52
50
|
#
|
53
|
-
def crawl(opts={})
|
51
|
+
def crawl(opts = {})
|
54
52
|
opts = @options.merge(opts)
|
55
|
-
opts.merge!(:
|
53
|
+
opts.merge!(ignore_links: Regexp.new(opts[:exclude])) if opts[:exclude]
|
56
54
|
|
57
55
|
puts color(:note, "validating #{@site}", opts[:color]) unless opts[:quiet]
|
58
56
|
puts color(:warning, "No internet connection") unless internet_connection?
|
@@ -77,7 +75,7 @@ module ValidateWebsite
|
|
77
75
|
crawler.every_failed_url do |url|
|
78
76
|
if opts[:not_found]
|
79
77
|
@not_found_error = true
|
80
|
-
puts color(:error, "
|
78
|
+
puts color(:error, "#{url} linked but not exist", opts[:color])
|
81
79
|
to_file(url)
|
82
80
|
end
|
83
81
|
end
|
@@ -90,8 +88,7 @@ module ValidateWebsite
|
|
90
88
|
false
|
91
89
|
end
|
92
90
|
|
93
|
-
|
94
|
-
def crawl_static(opts={})
|
91
|
+
def crawl_static(opts = {})
|
95
92
|
opts = @options.merge(opts)
|
96
93
|
puts color(:note, "validating #{@site}", opts[:color])
|
97
94
|
|
@@ -126,39 +123,39 @@ module ValidateWebsite
|
|
126
123
|
private
|
127
124
|
|
128
125
|
def to_file(msg)
|
129
|
-
|
130
|
-
|
131
|
-
end
|
126
|
+
return unless @file
|
127
|
+
open(@file, 'a').write("#{msg}\n") if File.exist?(@file)
|
132
128
|
end
|
133
129
|
|
134
130
|
# check files linked on static document
|
135
131
|
# see lib/validate_website/runner.rb
|
136
|
-
def check_static_not_found(links
|
137
|
-
opts = @options.merge(opts)
|
132
|
+
def check_static_not_found(links)
|
138
133
|
links.each do |l|
|
139
134
|
file_location = URI.parse(File.join(Dir.getwd, l.path)).path
|
135
|
+
not_found_error and next unless File.exist?(file_location)
|
140
136
|
# Check CSS url()
|
141
|
-
if File.
|
137
|
+
if File.extname(file_location) == '.css'
|
142
138
|
response = fake_http_response(open(file_location).read, ['text/css'])
|
143
139
|
css_page = Spidr::Page.new(l, response)
|
144
140
|
links.concat extract_urls_from_css(css_page)
|
145
141
|
links.uniq!
|
146
142
|
end
|
147
|
-
unless File.exists?(file_location)
|
148
|
-
@not_found_error = true
|
149
|
-
puts color(:error, "%s linked but not exist" % file_location, opts[:color])
|
150
|
-
to_file(file_location)
|
151
|
-
end
|
152
143
|
end
|
153
144
|
end
|
154
145
|
|
146
|
+
def not_found_error
|
147
|
+
@not_found_error = true
|
148
|
+
puts color(:error, "#{file_location} linked but not exist", @options[:color])
|
149
|
+
to_file(file_location)
|
150
|
+
end
|
151
|
+
|
155
152
|
# Extract urls from CSS page
|
156
153
|
#
|
157
154
|
# @param [Spidr::Page] an Spidr::Page object
|
158
155
|
# @return [Array] Lists of urls
|
159
156
|
#
|
160
157
|
def extract_urls_from_css(page)
|
161
|
-
page.body.scan(/url\((['".\/\w-]+)\)/).
|
158
|
+
page.body.scan(/url\((['".\/\w-]+)\)/).reduce(Set[]) do |result, url|
|
162
159
|
url = url.first.gsub("'", "").gsub('"', '')
|
163
160
|
abs = page.to_absolute(URI.parse(url))
|
164
161
|
result << abs
|
@@ -171,7 +168,7 @@ module ValidateWebsite
|
|
171
168
|
# @return [Array] Lists of urls
|
172
169
|
#
|
173
170
|
def extract_imgs_from_page(page)
|
174
|
-
page.doc.search('//img[@src]').
|
171
|
+
page.doc.search('//img[@src]').reduce(Set[]) do |result, elem|
|
175
172
|
u = elem.attributes['src']
|
176
173
|
result << page.to_absolute(URI.parse(u))
|
177
174
|
end
|
@@ -185,12 +182,15 @@ module ValidateWebsite
|
|
185
182
|
# :quiet no output (true, false)
|
186
183
|
# :color color output (true, false)
|
187
184
|
#
|
188
|
-
def validate(doc, body, url, opts={})
|
185
|
+
def validate(doc, body, url, opts = {})
|
189
186
|
opts = @options.merge(opts)
|
190
187
|
validator = Validator.new(doc, body, opts)
|
191
|
-
msg = " well formed?
|
188
|
+
msg = " well formed? #{validator.valid?}"
|
189
|
+
# TODO: create a formatter
|
192
190
|
if validator.valid?
|
193
|
-
|
191
|
+
if opts[:quiet]
|
192
|
+
print color(:success, '.', opts[:color]) # rspec style
|
193
|
+
else
|
194
194
|
print color(:info, url, opts[:color])
|
195
195
|
puts color(:success, msg, opts[:color])
|
196
196
|
end
|
@@ -198,7 +198,7 @@ module ValidateWebsite
|
|
198
198
|
@markup_error = true
|
199
199
|
print color(:info, url, opts[:color])
|
200
200
|
puts color(:error, msg, opts[:color])
|
201
|
-
puts color(:error, validator.errors.join(', '), opts[:color]) if opts[:
|
201
|
+
puts color(:error, validator.errors.join(', '), opts[:color]) if opts[:verbose]
|
202
202
|
to_file(url)
|
203
203
|
end
|
204
204
|
end
|
@@ -209,7 +209,7 @@ module ValidateWebsite
|
|
209
209
|
# @param [String] response body
|
210
210
|
# @param [Array] content types
|
211
211
|
# @return [Net::HTTPResponse] fake http response
|
212
|
-
def fake_http_response(body, content_types=['text/html', 'text/xhtml+xml'])
|
212
|
+
def fake_http_response(body, content_types = ['text/html', 'text/xhtml+xml'])
|
213
213
|
response = Net::HTTPResponse.new '1.1', 200, 'OK'
|
214
214
|
response.instance_variable_set(:@read, true)
|
215
215
|
response.body = body
|
@@ -5,39 +5,40 @@ module ValidateWebsite
|
|
5
5
|
# Internal class for parse command line args
|
6
6
|
class Parser
|
7
7
|
DEFAULT_OPTS_ALL = {
|
8
|
-
:
|
8
|
+
markup_validation: true,
|
9
9
|
# crawler: log not found url (404 status code)
|
10
|
-
# static: log not found url (not on filesystem, pwd considered
|
11
|
-
|
12
|
-
:
|
13
|
-
:
|
10
|
+
# static: log not found url (not on filesystem, `pwd` considered
|
11
|
+
# as root « / »)
|
12
|
+
not_found: false,
|
13
|
+
quiet: false,
|
14
|
+
file: nil,
|
14
15
|
# regex to ignore certain validation errors
|
15
|
-
:
|
16
|
-
:
|
16
|
+
ignore_errors: nil,
|
17
|
+
color: true,
|
17
18
|
# internal verbose for ValidateWebsite
|
18
|
-
:
|
19
|
+
verbose: false,
|
19
20
|
}
|
20
21
|
|
21
22
|
DEFAULT_OPTS_CRAWL = {
|
22
|
-
:
|
23
|
-
:
|
23
|
+
site: 'http://localhost:3000/',
|
24
|
+
exclude: nil,
|
24
25
|
}.merge(DEFAULT_OPTS_ALL)
|
25
26
|
|
26
27
|
DEFAULT_OPTS_STATIC = {
|
27
|
-
:
|
28
|
-
:
|
28
|
+
site: 'http://www.example.com/',
|
29
|
+
pattern: '**/*.html',
|
29
30
|
}.merge(DEFAULT_OPTS_ALL)
|
30
31
|
|
31
32
|
def self.parse(options, type)
|
32
33
|
if const_defined?("DEFAULT_OPTS_#{type.to_s.upcase}")
|
33
|
-
|
34
|
+
@default_opts = const_get("DEFAULT_OPTS_#{type.to_s.upcase}")
|
34
35
|
if Array === options
|
35
36
|
send("command_line_parse_#{type}", options)
|
36
37
|
else
|
37
|
-
|
38
|
+
@default_opts.merge(options)
|
38
39
|
end
|
39
40
|
else
|
40
|
-
|
41
|
+
fail ArgumentError, "Unknown options type : #{type}"
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -46,12 +47,12 @@ module ValidateWebsite
|
|
46
47
|
opts = OptionParser.new do |o|
|
47
48
|
o.set_summary_indent(' ')
|
48
49
|
o.banner = 'Usage: validate-website [OPTIONS]'
|
49
|
-
o.define_head
|
50
|
-
|
51
|
-
o.separator
|
50
|
+
o.define_head %(validate-website - Web crawler for checking the \
|
51
|
+
validity of your documents)
|
52
|
+
o.separator ''
|
52
53
|
|
53
54
|
o.on("-s", "--site 'SITE'", String,
|
54
|
-
"Website to crawl (Default: #{
|
55
|
+
"Website to crawl (Default: #{@default_opts[:site]})") { |v|
|
55
56
|
options[:site] = v
|
56
57
|
}
|
57
58
|
o.on("-u", "--user-agent 'USERAGENT'", String,
|
@@ -73,7 +74,8 @@ module ValidateWebsite
|
|
73
74
|
}
|
74
75
|
|
75
76
|
o.on("-m", "--[no-]markup-validation",
|
76
|
-
|
77
|
+
%(Markup validation \
|
78
|
+
(Default: #{@default_opts[:markup_validation]}))) { |v|
|
77
79
|
options[:markup_validation] = v
|
78
80
|
}
|
79
81
|
o.on("-i", "--ignore-errors 'IGNORE'", String,
|
@@ -81,24 +83,28 @@ module ValidateWebsite
|
|
81
83
|
options[:ignore_errors] = v
|
82
84
|
}
|
83
85
|
o.on("-n", "--not-found",
|
84
|
-
"Log not found url (Default: #{
|
86
|
+
"Log not found url (Default: #{@default_opts[:not_found]})") { |v|
|
85
87
|
options[:not_found] = v
|
86
88
|
}
|
87
89
|
o.on("--[no-]color",
|
88
|
-
"Show colored output (Default: #{
|
90
|
+
"Show colored output (Default: #{@default_opts[:color]})") { |v|
|
89
91
|
options[:color] = v
|
90
92
|
}
|
91
93
|
o.on("-v", "--verbose",
|
92
|
-
|
93
|
-
|
94
|
+
%(Show validator errors \
|
95
|
+
(Default: #{@default_opts[:verbose]}))) { |v|
|
96
|
+
options[:verbose] = v
|
94
97
|
}
|
95
98
|
o.on("-q", "--quiet",
|
96
|
-
"Only report errors (Default: #{
|
99
|
+
"Only report errors (Default: #{@default_opts[:quiet]})") { |v|
|
97
100
|
options[:quiet] = v
|
98
101
|
}
|
99
102
|
|
100
103
|
o.separator ""
|
101
|
-
o.on_tail("-h", "--help", "Show this help message.")
|
104
|
+
o.on_tail("-h", "--help", "Show this help message.") do
|
105
|
+
puts o
|
106
|
+
exit
|
107
|
+
end
|
102
108
|
end
|
103
109
|
command_line_parse!(opts, args, options)
|
104
110
|
end
|
@@ -108,16 +114,18 @@ module ValidateWebsite
|
|
108
114
|
opts = OptionParser.new do |o|
|
109
115
|
o.set_summary_indent(' ')
|
110
116
|
o.banner = 'Usage: validate-website-static [OPTIONS]'
|
111
|
-
o.define_head
|
112
|
-
|
113
|
-
o.separator
|
117
|
+
o.define_head %(validate-website-static - check the validity of \
|
118
|
+
your documents)
|
119
|
+
o.separator ''
|
114
120
|
|
115
121
|
o.on("-s", "--site 'SITE'", String,
|
116
|
-
|
122
|
+
%(Where static files will be hosted \
|
123
|
+
(Default: #{@default_opts[:site]}))) { |v|
|
117
124
|
options[:site] = v
|
118
125
|
}
|
119
126
|
o.on("-p", "--pattern 'PATTERN'", String,
|
120
|
-
|
127
|
+
%(Change filenames pattern \
|
128
|
+
(Default: #{@default_opts[:pattern]}))) { |v|
|
121
129
|
options[:pattern] = v.strip
|
122
130
|
}
|
123
131
|
o.on("-f", "--file 'FILE'", String,
|
@@ -130,19 +138,22 @@ module ValidateWebsite
|
|
130
138
|
}
|
131
139
|
|
132
140
|
o.on("-m", "--[no-]markup-validation",
|
133
|
-
|
141
|
+
%(Markup validation \
|
142
|
+
(Default: #{@default_opts[:markup_validation]}))) { |v|
|
134
143
|
options[:markup_validation] = v
|
135
144
|
}
|
136
145
|
o.on("-n", "--not-found",
|
137
|
-
|
146
|
+
%(Log files not on filesystem, pwd considered as root « / » \
|
147
|
+
(Default: #{@default_opts[:not_found]}))) { |v|
|
138
148
|
options[:not_found] = v
|
139
149
|
}
|
140
150
|
o.on("-v", "--verbose",
|
141
|
-
|
142
|
-
|
151
|
+
%(Show validator errors \
|
152
|
+
(Default: #{@default_opts[:verbose]}))) { |v|
|
153
|
+
options[:verbose] = v
|
143
154
|
}
|
144
155
|
o.on("-q", "--quiet",
|
145
|
-
"Only report errors (Default: #{
|
156
|
+
"Only report errors (Default: #{@default_opts[:quiet]})") { |v|
|
146
157
|
options[:quiet] = v
|
147
158
|
}
|
148
159
|
end
|
@@ -150,14 +161,12 @@ module ValidateWebsite
|
|
150
161
|
end
|
151
162
|
|
152
163
|
def self.command_line_parse!(opts, args, options)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
end
|
160
|
-
@@default_opts.merge(options)
|
164
|
+
opts.parse!(args)
|
165
|
+
@default_opts.merge(options)
|
166
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
167
|
+
puts $ERROR_INFO.to_s
|
168
|
+
puts opts
|
169
|
+
exit 128
|
161
170
|
end
|
162
171
|
end
|
163
172
|
end
|
@@ -5,7 +5,7 @@ require 'nokogiri'
|
|
5
5
|
module ValidateWebsite
|
6
6
|
# Document validation from DTD or XSD (webservice for html5)
|
7
7
|
class Validator
|
8
|
-
XHTML_PATH = File.
|
8
|
+
XHTML_PATH = File.expand_path('../../../data/schemas', __FILE__)
|
9
9
|
HTML5_VALIDATOR_SERVICE = 'http://html5.validator.nu/'
|
10
10
|
|
11
11
|
attr_reader :original_doc, :body, :dtd, :doc, :namespace, :xsd, :errors
|
@@ -13,7 +13,7 @@ module ValidateWebsite
|
|
13
13
|
##
|
14
14
|
# @param [Nokogiri::HTML::Document] original_doc
|
15
15
|
# @param [String] The raw HTTP response body of the page
|
16
|
-
def initialize(original_doc, body, opts={})
|
16
|
+
def initialize(original_doc, body, opts = {})
|
17
17
|
@original_doc = original_doc
|
18
18
|
@body = body
|
19
19
|
@options = opts
|
@@ -38,15 +38,14 @@ module ValidateWebsite
|
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
|
+
|
41
42
|
def init_namespace(dtd)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
43
|
+
return unless dtd.system_id
|
44
|
+
dtd_uri = URI.parse(dtd.system_id)
|
45
|
+
return unless dtd_uri.path
|
46
|
+
@dtd_uri = dtd_uri
|
47
|
+
# http://www.w3.org/TR/xhtml1/#dtds
|
48
|
+
@namespace = File.basename(@dtd_uri.path, '.dtd')
|
50
49
|
end
|
51
50
|
|
52
51
|
def find_errors
|
@@ -65,7 +64,7 @@ module ValidateWebsite
|
|
65
64
|
|
66
65
|
# http://www.w3.org/TR/xhtml1-schema/
|
67
66
|
@xsd = Dir.chdir(XHTML_PATH) do
|
68
|
-
if @namespace && File.
|
67
|
+
if @namespace && File.exist?(@namespace + '.xsd')
|
69
68
|
Nokogiri::XML::Schema(File.read(@namespace + '.xsd'))
|
70
69
|
end
|
71
70
|
end
|
@@ -91,13 +90,13 @@ module ValidateWebsite
|
|
91
90
|
require 'net/http'
|
92
91
|
require 'multipart_body'
|
93
92
|
url = URI.parse(HTML5_VALIDATOR_SERVICE)
|
94
|
-
multipart = MultipartBody.new(:
|
93
|
+
multipart = MultipartBody.new(content: document)
|
95
94
|
http = Net::HTTP.new(url.host)
|
96
95
|
headers = {
|
97
96
|
'Content-Type' => "multipart/form-data; boundary=#{multipart.boundary}",
|
98
97
|
'Content-Length' => multipart.to_s.bytesize.to_s,
|
99
98
|
}
|
100
|
-
res = http.start {|con| con.post(url.path, multipart.to_s, headers) }
|
99
|
+
res = http.start { |con| con.post(url.path, multipart.to_s, headers) }
|
101
100
|
@errors = Nokogiri::HTML(res.body).css('ol li.error').map(&:content)
|
102
101
|
end
|
103
102
|
end
|
data/spec/core_spec.rb
CHANGED
@@ -5,9 +5,17 @@ describe ValidateWebsite::Core do
|
|
5
5
|
|
6
6
|
before do
|
7
7
|
WebMock.reset!
|
8
|
-
stub_request(:get, ValidateWebsite::Core::PING_URL).to_return(:
|
9
|
-
stub_request(:get, /#{SPEC_DOMAIN}/).to_return(:
|
10
|
-
@validate_website = ValidateWebsite::Core.new(:
|
8
|
+
stub_request(:get, ValidateWebsite::Core::PING_URL).to_return(status: 200)
|
9
|
+
stub_request(:get, /#{SPEC_DOMAIN}/).to_return(status: 200)
|
10
|
+
@validate_website = ValidateWebsite::Core.new(color: false)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'invalid options' do
|
14
|
+
it 'raise ArgumentError on wrong validation_type' do
|
15
|
+
proc {
|
16
|
+
ValidateWebsite::Core.new({ color: false }, :fail)
|
17
|
+
}.must_raise ArgumentError
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
describe('html') do
|
@@ -15,10 +23,10 @@ describe ValidateWebsite::Core do
|
|
15
23
|
name = 'xhtml1-strict'
|
16
24
|
file = File.join('spec', 'data', "#{name}.html")
|
17
25
|
page = FakePage.new(name,
|
18
|
-
:
|
19
|
-
:
|
26
|
+
body: open(file).read,
|
27
|
+
content_type: 'text/html')
|
20
28
|
@validate_website.site = page.url
|
21
|
-
@validate_website.crawl(:
|
29
|
+
@validate_website.crawl(quiet: true)
|
22
30
|
@validate_website.crawler.history.size.must_equal 5
|
23
31
|
end
|
24
32
|
|
@@ -26,10 +34,10 @@ describe ValidateWebsite::Core do
|
|
26
34
|
name = 'html4-strict'
|
27
35
|
file = File.join('spec', 'data', "#{name}.html")
|
28
36
|
page = FakePage.new(name,
|
29
|
-
:
|
30
|
-
:
|
37
|
+
body: open(file).read,
|
38
|
+
content_type: 'text/html')
|
31
39
|
@validate_website.site = page.url
|
32
|
-
@validate_website.crawl(:
|
40
|
+
@validate_website.crawl(quiet: true)
|
33
41
|
@validate_website.crawler.history.size.must_equal 98
|
34
42
|
end
|
35
43
|
end
|
@@ -37,31 +45,31 @@ describe ValidateWebsite::Core do
|
|
37
45
|
describe('css') do
|
38
46
|
it "crawl css and extract url" do
|
39
47
|
page = FakePage.new('test.css',
|
40
|
-
:
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
48
|
+
body: '.t {background-image: url(pouet);}
|
49
|
+
.t {background-image: url(/image/pouet.png)}
|
50
|
+
.t {background-image: url(/image/pouet_42.png)}
|
51
|
+
.t {background-image: url(/image/pouet)}',
|
52
|
+
content_type: 'text/css')
|
45
53
|
@validate_website.site = page.url
|
46
|
-
@validate_website.crawl(:
|
54
|
+
@validate_website.crawl(quiet: true)
|
47
55
|
@validate_website.crawler.history.size.must_equal 5
|
48
56
|
end
|
49
57
|
|
50
58
|
it "should extract url with single quote" do
|
51
59
|
page = FakePage.new('test.css',
|
52
|
-
:
|
53
|
-
:
|
60
|
+
body: ".test {background-image: url('pouet');}",
|
61
|
+
content_type: 'text/css')
|
54
62
|
@validate_website.site = page.url
|
55
|
-
@validate_website.crawl(:
|
63
|
+
@validate_website.crawl(quiet: true)
|
56
64
|
@validate_website.crawler.history.size.must_equal 2
|
57
65
|
end
|
58
66
|
|
59
67
|
it "should extract url with double quote" do
|
60
68
|
page = FakePage.new('test.css',
|
61
|
-
:
|
62
|
-
:
|
69
|
+
body: ".test {background-image: url(\"pouet\");}",
|
70
|
+
content_type: 'text/css')
|
63
71
|
@validate_website.site = page.url
|
64
|
-
@validate_website.crawl(:
|
72
|
+
@validate_website.crawl(quiet: true)
|
65
73
|
@validate_website.crawler.history.size.must_equal 2
|
66
74
|
end
|
67
75
|
end
|
@@ -69,11 +77,11 @@ describe ValidateWebsite::Core do
|
|
69
77
|
describe('static') do
|
70
78
|
it 'no space in directory name' do
|
71
79
|
pattern = File.join(File.dirname(__FILE__), 'example/**/*.html')
|
72
|
-
@validate_website.crawl_static(:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
80
|
+
@validate_website.crawl_static(pattern: pattern,
|
81
|
+
site: 'http://dev.af83.com/',
|
82
|
+
markup_validation: false,
|
83
|
+
not_found: false,
|
84
|
+
quiet: true)
|
77
85
|
end
|
78
86
|
end
|
79
87
|
end
|
data/spec/validator_spec.rb
CHANGED
@@ -13,10 +13,11 @@ describe ValidateWebsite::Validator do
|
|
13
13
|
dtd_uri = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
14
14
|
file = File.join('spec', 'data', "#{name}.html")
|
15
15
|
page = FakePage.new(name,
|
16
|
-
:
|
17
|
-
:
|
16
|
+
body: open(file).read,
|
17
|
+
content_type: 'text/html')
|
18
18
|
@xhtml1_page = @http.get_page(page.url)
|
19
|
-
validator = ValidateWebsite::Validator.new(@xhtml1_page.doc,
|
19
|
+
validator = ValidateWebsite::Validator.new(@xhtml1_page.doc,
|
20
|
+
@xhtml1_page.body)
|
20
21
|
validator.dtd.system_id.must_equal dtd_uri
|
21
22
|
validator.namespace.must_equal name
|
22
23
|
validator.valid?.must_equal true
|
@@ -28,26 +29,28 @@ describe ValidateWebsite::Validator do
|
|
28
29
|
before do
|
29
30
|
validator_res = File.join('spec', 'data', 'validator.nu-success.html')
|
30
31
|
stub_request(:any, ValidateWebsite::Validator::HTML5_VALIDATOR_SERVICE)
|
31
|
-
.to_return(:
|
32
|
+
.to_return(body: open(validator_res).read)
|
32
33
|
end
|
33
34
|
it "html5 should be valid" do
|
34
35
|
name = 'html5'
|
35
36
|
file = File.join('spec', 'data', "#{name}.html")
|
36
37
|
page = FakePage.new(name,
|
37
|
-
:
|
38
|
-
:
|
38
|
+
body: open(file).read,
|
39
|
+
content_type: 'text/html')
|
39
40
|
@html5_page = @http.get_page(page.url)
|
40
|
-
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
41
|
+
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
42
|
+
@html5_page.body)
|
41
43
|
validator.valid?.must_equal true
|
42
44
|
end
|
43
45
|
it "with DLFP" do
|
44
46
|
name = 'html5'
|
45
47
|
file = File.join('spec', 'data', "#{name}-linuxfr.html")
|
46
48
|
page = FakePage.new(name,
|
47
|
-
:
|
48
|
-
:
|
49
|
+
body: open(file).read,
|
50
|
+
content_type: 'text/html')
|
49
51
|
@html5_page = @http.get_page(page.url)
|
50
|
-
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
52
|
+
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
53
|
+
@html5_page.body)
|
51
54
|
validator.valid?.must_equal true
|
52
55
|
end
|
53
56
|
end
|
@@ -55,23 +58,27 @@ describe ValidateWebsite::Validator do
|
|
55
58
|
before do
|
56
59
|
validator_res = File.join('spec', 'data', 'validator.nu-failure.html')
|
57
60
|
stub_request(:any, ValidateWebsite::Validator::HTML5_VALIDATOR_SERVICE)
|
58
|
-
.to_return(:
|
61
|
+
.to_return(body: open(validator_res).read)
|
59
62
|
name = 'html5'
|
60
63
|
file = File.join('spec', 'data', "#{name}-linuxfr.html")
|
61
64
|
page = FakePage.new(name,
|
62
|
-
:
|
63
|
-
:
|
65
|
+
body: open(file).read,
|
66
|
+
content_type: 'text/html')
|
64
67
|
@html5_page = @http.get_page(page.url)
|
65
68
|
end
|
66
69
|
|
67
70
|
it 'should have an array of errors' do
|
68
|
-
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
71
|
+
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
72
|
+
@html5_page.body)
|
69
73
|
validator.valid?.must_equal false
|
70
74
|
validator.errors.size.must_equal 38
|
71
75
|
end
|
72
76
|
|
73
77
|
it 'should exclude errors ignored by :ignore_errors option' do
|
74
|
-
|
78
|
+
ignore = "The nowrap attribute on the td element is obsolete"
|
79
|
+
validator = ValidateWebsite::Validator.new(@html5_page.doc,
|
80
|
+
@html5_page.body,
|
81
|
+
ignore_errors: ignore)
|
75
82
|
validator.valid?.must_equal false
|
76
83
|
validator.errors.size.must_equal 36
|
77
84
|
end
|
@@ -83,10 +90,11 @@ describe ValidateWebsite::Validator do
|
|
83
90
|
name = 'html4-strict'
|
84
91
|
file = File.join('spec', 'data', "#{name}.html")
|
85
92
|
page = FakePage.new(name,
|
86
|
-
:
|
87
|
-
:
|
93
|
+
body: open(file).read,
|
94
|
+
content_type: 'text/html')
|
88
95
|
@html4_strict_page = @http.get_page(page.url)
|
89
|
-
validator = ValidateWebsite::Validator.new(@html4_strict_page.doc,
|
96
|
+
validator = ValidateWebsite::Validator.new(@html4_strict_page.doc,
|
97
|
+
@html4_strict_page.body)
|
90
98
|
validator.valid?.must_equal true
|
91
99
|
end
|
92
100
|
end
|
data/spec/webmock_helper.rb
CHANGED
@@ -10,8 +10,8 @@ class FakePage
|
|
10
10
|
|
11
11
|
def initialize(name = '', options = {})
|
12
12
|
@name = name
|
13
|
-
@links = [options[:links]].flatten if options.
|
14
|
-
@hrefs = [options[:hrefs]].flatten if options.
|
13
|
+
@links = [options[:links]].flatten if options.key?(:links)
|
14
|
+
@hrefs = [options[:hrefs]].flatten if options.key?(:hrefs)
|
15
15
|
@content_type = options[:content_type] || "text/html"
|
16
16
|
@body = options[:body]
|
17
17
|
|
@@ -27,13 +27,13 @@ class FakePage
|
|
27
27
|
|
28
28
|
def create_body
|
29
29
|
@body = "<html><body>"
|
30
|
-
@links.each{|l| @body += "<a href=\"#{SPEC_DOMAIN}#{l}\"></a>"} if @links
|
31
|
-
@hrefs.each{|h| @body += "<a href=\"#{h}\"></a>"} if @hrefs
|
30
|
+
@links.each { |l| @body += "<a href=\"#{SPEC_DOMAIN}#{l}\"></a>" } if @links
|
31
|
+
@hrefs.each { |h| @body += "<a href=\"#{h}\"></a>" } if @hrefs
|
32
32
|
@body += "</body></html>"
|
33
33
|
end
|
34
34
|
|
35
35
|
def add_to_webmock
|
36
|
-
options = {body: @body, headers: { 'Content-Type' => @content_type }}
|
36
|
+
options = { body: @body, headers: { 'Content-Type' => @content_type } }
|
37
37
|
stub_request(:get, url).to_return(options)
|
38
38
|
end
|
39
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validate-website
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Arnoud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spidr
|