validate-website 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +8 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/validate_website/core.rb +1 -0
- data/lib/validate_website/static.rb +4 -63
- data/lib/validate_website/static_link.rb +65 -0
- data/lib/validate_website/validator.rb +43 -39
- data/lib/validate_website/version.rb +1 -1
- data/man/man1/validate-website-static.1 +3 -3
- data/man/man1/validate-website.1 +3 -3
- data/test/crawler_test.rb +9 -5
- data/test/data/validator.nu-failure.json +1 -0
- data/test/data/validator.nu-success.json +1 -0
- data/test/static_test.rb +1 -1
- data/test/validator_test.rb +14 -41
- metadata +14 -68
- data/data/schemas/xhtml-access-1.xsd +0 -43
- data/data/schemas/xhtml-applet-1.xsd +0 -66
- data/data/schemas/xhtml-attribs-1.xsd +0 -67
- data/data/schemas/xhtml-basic-form-1.xsd +0 -195
- data/data/schemas/xhtml-basic-table-1.xsd +0 -169
- data/data/schemas/xhtml-basic10-model-1.xsd +0 -385
- data/data/schemas/xhtml-basic10-module-redefines-1.xsd +0 -61
- data/data/schemas/xhtml-basic10-modules-1.xsd +0 -233
- data/data/schemas/xhtml-basic10.xsd +0 -99
- data/data/schemas/xhtml-basic11-model-1.xsd +0 -622
- data/data/schemas/xhtml-basic11-modules-1.xsd +0 -508
- data/data/schemas/xhtml-basic11.xsd +0 -105
- data/data/schemas/xhtml-bdo-1.xsd +0 -72
- data/data/schemas/xhtml-blkphras-1.xsd +0 -155
- data/data/schemas/xhtml-blkpres-1.xsd +0 -32
- data/data/schemas/xhtml-blkstruct-1.xsd +0 -44
- data/data/schemas/xhtml-csismap-1.xsd +0 -91
- data/data/schemas/xhtml-edit-1.xsd +0 -34
- data/data/schemas/xhtml-form-1.xsd +0 -321
- data/data/schemas/xhtml-frames-1.xsd +0 -113
- data/data/schemas/xhtml-framework-1.xsd +0 -62
- data/data/schemas/xhtml-hypertext-1.xsd +0 -47
- data/data/schemas/xhtml-iframe-1.xsd +0 -68
- data/data/schemas/xhtml-image-1.xsd +0 -40
- data/data/schemas/xhtml-inlphras-1.xsd +0 -158
- data/data/schemas/xhtml-inlpres-1.xsd +0 -34
- data/data/schemas/xhtml-inlstruct-1.xsd +0 -45
- data/data/schemas/xhtml-legacy-1.xsd +0 -97
- data/data/schemas/xhtml-link-1.xsd +0 -45
- data/data/schemas/xhtml-list-1.xsd +0 -94
- data/data/schemas/xhtml-meta-1.xsd +0 -54
- data/data/schemas/xhtml-misc-1.xsd +0 -441
- data/data/schemas/xhtml-object-1.xsd +0 -71
- data/data/schemas/xhtml-param-1.xsd +0 -46
- data/data/schemas/xhtml-pres-1.xsd +0 -46
- data/data/schemas/xhtml-print-1.xsd +0 -85
- data/data/schemas/xhtml-print-model-1.xsd +0 -604
- data/data/schemas/xhtml-print-modules-1.xsd +0 -422
- data/data/schemas/xhtml-rdfa-1.xsd +0 -116
- data/data/schemas/xhtml-rdfa-model-1.xsd +0 -461
- data/data/schemas/xhtml-rdfa-modules-1.xsd +0 -548
- data/data/schemas/xhtml-ruby-1.xsd +0 -170
- data/data/schemas/xhtml-script-1.xsd +0 -65
- data/data/schemas/xhtml-struct-1.xsd +0 -85
- data/data/schemas/xhtml-style-1.xsd +0 -47
- data/data/schemas/xhtml-table-1.xsd +0 -267
- data/data/schemas/xhtml-text-1.xsd +0 -62
- data/data/schemas/xhtml11-model-1.xsd +0 -715
- data/data/schemas/xhtml11-module-redefines-1.xsd +0 -335
- data/data/schemas/xhtml11-modules-1.xsd +0 -605
- data/data/schemas/xhtml11.xsd +0 -107
- data/data/schemas/xml-handlers-2.xsd +0 -98
- data/data/schemas/xml-script-1.xsd +0 -38
- data/test/data/html5-linuxfr.html +0 -1286
- data/test/data/validator.nu-excessive.html +0 -118
- data/test/data/validator.nu-failure.html +0 -10
- data/test/data/validator.nu-success.html +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba01cfb0d05bb3670aecfb1afcc94bc72dd02088
|
4
|
+
data.tar.gz: 8f8259c854e992e72c18e48141509475378e3a91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8585f39f42b34a667c34f760c96b6c1dbeba03ab4d1adefc1bb26aa8a846038e26fba3e48f657007fb1973f10b4173e86e84e16b8b13f7bd20809adbd40e7f2e
|
7
|
+
data.tar.gz: 620cf747186ef3518b9bec8f248cf8d78d4c73510ff745117fbbecdad66f24816124a26287485b77396043574e48aa5878bcc61c123f8a2c9b0d00502b83761f
|
data/History.md
CHANGED
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2009-
|
3
|
+
Copyright (c) 2009-2017 Laurent Arnoud <laurent@spkdev.net>
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
6
6
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -122,7 +122,7 @@ See [GitHub](https://github.com/spk/validate-website/graphs/contributors).
|
|
122
122
|
|
123
123
|
The MIT License
|
124
124
|
|
125
|
-
Copyright (c) 2009-
|
125
|
+
Copyright (c) 2009-2017 Laurent Arnoud <laurent@spkdev.net>
|
126
126
|
|
127
127
|
---
|
128
128
|
[![Build](https://img.shields.io/travis-ci/spk/validate-website.svg)](https://travis-ci.org/spk/validate-website)
|
@@ -60,75 +60,16 @@ module ValidateWebsite
|
|
60
60
|
check_static_not_found(page.links) if options[:not_found]
|
61
61
|
end
|
62
62
|
|
63
|
-
StaticLink = Struct.new(:link, :site) do
|
64
|
-
def link_uri
|
65
|
-
@link_uri = URI.parse(URI.encode(link))
|
66
|
-
@link_uri = URI.join(site, @link_uri) if @link_uri.host.nil?
|
67
|
-
@link_uri
|
68
|
-
end
|
69
|
-
|
70
|
-
def in_static_domain?
|
71
|
-
URI.parse(site).host == link_uri.host
|
72
|
-
end
|
73
|
-
|
74
|
-
def content_types
|
75
|
-
if css?
|
76
|
-
['text/css']
|
77
|
-
else
|
78
|
-
CONTENT_TYPES
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def body
|
83
|
-
if File.exist?(link)
|
84
|
-
open(link).read
|
85
|
-
else
|
86
|
-
open(file_path).read
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def response
|
91
|
-
@response ||= ValidateWebsite::Static.fake_httpresponse(
|
92
|
-
body,
|
93
|
-
content_types
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
def page
|
98
|
-
@page ||= Spidr::Page.new(link_uri, response)
|
99
|
-
end
|
100
|
-
|
101
|
-
def extract_urls_from_fake_css_response
|
102
|
-
ValidateWebsite::Utils.extract_urls_from_css(page)
|
103
|
-
end
|
104
|
-
|
105
|
-
def file_path
|
106
|
-
@file_path ||= URI.parse(
|
107
|
-
File.join(Dir.getwd, link_uri.path || '/')
|
108
|
-
).path
|
109
|
-
end
|
110
|
-
|
111
|
-
def extname
|
112
|
-
@extname ||= File.extname(file_path)
|
113
|
-
end
|
114
|
-
|
115
|
-
def css?
|
116
|
-
extname == '.css'
|
117
|
-
end
|
118
|
-
|
119
|
-
def check?
|
120
|
-
!link.include?('#') && in_static_domain?
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
63
|
# check files linked on static document
|
125
64
|
# see lib/validate_website/runner.rb
|
126
65
|
def check_static_not_found(links)
|
127
66
|
static_links = links.map { |l| StaticLink.new(l, @site) }
|
128
67
|
static_links.each do |static_link|
|
129
68
|
next unless static_link.check?
|
130
|
-
|
131
|
-
|
69
|
+
unless File.exist?(static_link.file_path)
|
70
|
+
not_found_error(static_link.file_path)
|
71
|
+
next
|
72
|
+
end
|
132
73
|
next unless static_link.css?
|
133
74
|
check_static_not_found static_link.extract_urls_from_fake_css_response
|
134
75
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'validate_website/utils'
|
3
|
+
require 'validate_website/static'
|
4
|
+
require 'spidr'
|
5
|
+
|
6
|
+
StaticLink = Struct.new(:link, :site) do
|
7
|
+
def link_uri
|
8
|
+
@link_uri = URI.parse(URI.encode(link))
|
9
|
+
@link_uri = URI.join(site, @link_uri) if @link_uri.host.nil?
|
10
|
+
@link_uri
|
11
|
+
end
|
12
|
+
|
13
|
+
def in_static_domain?
|
14
|
+
URI.parse(site).host == link_uri.host
|
15
|
+
end
|
16
|
+
|
17
|
+
def content_types
|
18
|
+
if css?
|
19
|
+
['text/css']
|
20
|
+
else
|
21
|
+
ValidateWebsite::Static::CONTENT_TYPES
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def body
|
26
|
+
if File.exist?(link)
|
27
|
+
open(link).read
|
28
|
+
else
|
29
|
+
open(file_path).read
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def response
|
34
|
+
@response ||= ValidateWebsite::Static.fake_httpresponse(
|
35
|
+
body,
|
36
|
+
content_types
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def page
|
41
|
+
@page ||= Spidr::Page.new(link_uri, response)
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_urls_from_fake_css_response
|
45
|
+
ValidateWebsite::Utils.extract_urls_from_css(page)
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_path
|
49
|
+
@file_path ||= URI.parse(
|
50
|
+
File.join(Dir.getwd, link_uri.path || '/')
|
51
|
+
).path
|
52
|
+
end
|
53
|
+
|
54
|
+
def extname
|
55
|
+
@extname ||= File.extname(file_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def css?
|
59
|
+
extname == '.css'
|
60
|
+
end
|
61
|
+
|
62
|
+
def check?
|
63
|
+
!link.include?('#') && in_static_domain?
|
64
|
+
end
|
65
|
+
end
|
@@ -1,17 +1,39 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'uri'
|
3
2
|
require 'nokogiri'
|
4
|
-
require '
|
5
|
-
require 'multipart_body'
|
3
|
+
require 'w3c_validators'
|
6
4
|
|
7
5
|
module ValidateWebsite
|
8
6
|
# Document validation from DTD or XSD (webservice for html5)
|
9
7
|
class Validator
|
10
|
-
|
8
|
+
@html5_validator_service_url = 'https://checker.html5.org/'
|
11
9
|
|
12
|
-
@html5_validator_service_url = 'http://checker.html5.org:443/'
|
13
10
|
class << self
|
14
11
|
attr_accessor :html5_validator_service_url
|
12
|
+
|
13
|
+
def validator_uri
|
14
|
+
@validator_uri ||=
|
15
|
+
ENV['VALIDATOR_NU_URL'] || @html5_validator_service_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
XHTML_PATH = File.expand_path('../../../data/schemas', __FILE__)
|
20
|
+
|
21
|
+
@xsd_schemas = {}
|
22
|
+
class << self
|
23
|
+
attr_reader :xsd_schemas
|
24
|
+
end
|
25
|
+
# `Dir.chdir` is needed by `Nokogiri::XML::Schema` to validate with local
|
26
|
+
# files and cannot use file absolute path.
|
27
|
+
Dir.glob(File.join(XHTML_PATH, '*.xsd')).each do |schema|
|
28
|
+
Dir.chdir(XHTML_PATH) do
|
29
|
+
schema_name = File.basename(schema, '.xsd')
|
30
|
+
schema_content = File.read(File.basename(schema))
|
31
|
+
begin
|
32
|
+
@xsd_schemas[schema_name] = Nokogiri::XML::Schema(schema_content)
|
33
|
+
rescue Nokogiri::XML::SyntaxError
|
34
|
+
STDERR.puts "XSD SCHEMA: #{schema} cannot be loaded"
|
35
|
+
end
|
36
|
+
end
|
15
37
|
end
|
16
38
|
|
17
39
|
attr_reader :original_doc, :body, :dtd, :doc, :namespace
|
@@ -28,7 +50,7 @@ module ValidateWebsite
|
|
28
50
|
@body = body
|
29
51
|
@ignore = ignore
|
30
52
|
@dtd = @original_doc.internal_subset
|
31
|
-
@namespace =
|
53
|
+
@namespace = find_namespace(@dtd)
|
32
54
|
end
|
33
55
|
|
34
56
|
##
|
@@ -44,14 +66,20 @@ module ValidateWebsite
|
|
44
66
|
@ignore ? @errors.reject { |e| @ignore =~ e } : @errors
|
45
67
|
end
|
46
68
|
|
69
|
+
# http://www.w3.org/TR/xhtml1-schema/
|
70
|
+
def self.xsd(namespace)
|
71
|
+
return unless namespace
|
72
|
+
@xsd_schemas[namespace] if @xsd_schemas.key? namespace
|
73
|
+
end
|
74
|
+
|
47
75
|
private
|
48
76
|
|
49
|
-
|
77
|
+
# http://www.w3.org/TR/xhtml1/#dtds
|
78
|
+
def find_namespace(dtd)
|
50
79
|
return unless dtd.system_id
|
51
80
|
dtd_uri = URI.parse(dtd.system_id)
|
52
81
|
return unless dtd_uri.path
|
53
82
|
@dtd_uri = dtd_uri
|
54
|
-
# http://www.w3.org/TR/xhtml1/#dtds
|
55
83
|
File.basename(@dtd_uri.path, '.dtd')
|
56
84
|
end
|
57
85
|
|
@@ -64,19 +92,10 @@ module ValidateWebsite
|
|
64
92
|
end
|
65
93
|
end
|
66
94
|
|
67
|
-
# http://www.w3.org/TR/xhtml1-schema/
|
68
|
-
def xsd
|
69
|
-
@xsd ||= Dir.chdir(XHTML_PATH) do
|
70
|
-
if @namespace && File.exist?(@namespace + '.xsd')
|
71
|
-
Nokogiri::XML::Schema(File.read(@namespace + '.xsd'))
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
95
|
# @return [Array] contain result errors
|
77
96
|
def validate(xml_doc, document_body)
|
78
|
-
if
|
79
|
-
xsd.validate(xml_doc)
|
97
|
+
if self.class.xsd(@namespace)
|
98
|
+
self.class.xsd(@namespace).validate(xml_doc)
|
80
99
|
elsif document_body =~ /^\<!DOCTYPE html\>/i
|
81
100
|
html5_validate(document_body)
|
82
101
|
else
|
@@ -97,27 +116,12 @@ module ValidateWebsite
|
|
97
116
|
@errors << e
|
98
117
|
end
|
99
118
|
|
100
|
-
def html5_headers(multipart)
|
101
|
-
{
|
102
|
-
'Content-Type' => "multipart/form-data; boundary=#{multipart.boundary}",
|
103
|
-
'Content-Length' => multipart.to_s.bytesize.to_s
|
104
|
-
}
|
105
|
-
end
|
106
|
-
|
107
|
-
def html5_body(document)
|
108
|
-
url = ENV['VALIDATOR_NU_URL'] || self.class.html5_validator_service_url
|
109
|
-
uri = URI.parse(url)
|
110
|
-
multipart = MultipartBody.new(content: document)
|
111
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
112
|
-
http.start do |con|
|
113
|
-
con.post(uri.path, multipart.to_s, html5_headers(multipart))
|
114
|
-
end.body
|
115
|
-
end
|
116
|
-
|
117
119
|
def html5_validate(document)
|
118
|
-
|
119
|
-
|
120
|
-
|
120
|
+
validator = W3CValidators::NuValidator.new(
|
121
|
+
validator_uri: self.class.validator_uri
|
122
|
+
)
|
123
|
+
results = validator.validate_text(document)
|
124
|
+
errors.concat results.errors
|
121
125
|
end
|
122
126
|
end
|
123
127
|
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
.\" Title: validate-website-static
|
3
3
|
.\" Author: [see the "AUTHOR" section]
|
4
4
|
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
5
|
-
.\" Date:
|
5
|
+
.\" Date: 01/04/2017
|
6
6
|
.\" Manual: \ \&
|
7
7
|
.\" Source: \ \&
|
8
8
|
.\" Language: English
|
9
9
|
.\"
|
10
|
-
.TH "VALIDATE\-WEBSITE\-S" "1" "
|
10
|
+
.TH "VALIDATE\-WEBSITE\-S" "1" "01/04/2017" "\ \&" "\ \&"
|
11
11
|
.\" -----------------------------------------------------------------
|
12
12
|
.\" * Define some portability stuff
|
13
13
|
.\" -----------------------------------------------------------------
|
@@ -122,4 +122,4 @@ Laurent Arnoud <laurent@spkdev\&.net>
|
|
122
122
|
.sp
|
123
123
|
The MIT License
|
124
124
|
.sp
|
125
|
-
Copyright (c) 2009\-
|
125
|
+
Copyright (c) 2009\-2017 Laurent Arnoud <laurent@spkdev\&.net>
|
data/man/man1/validate-website.1
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
.\" Title: validate-website
|
3
3
|
.\" Author: [see the "AUTHOR" section]
|
4
4
|
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
5
|
-
.\" Date:
|
5
|
+
.\" Date: 01/04/2017
|
6
6
|
.\" Manual: \ \&
|
7
7
|
.\" Source: \ \&
|
8
8
|
.\" Language: English
|
9
9
|
.\"
|
10
|
-
.TH "VALIDATE\-WEBSITE" "1" "
|
10
|
+
.TH "VALIDATE\-WEBSITE" "1" "01/04/2017" "\ \&" "\ \&"
|
11
11
|
.\" -----------------------------------------------------------------
|
12
12
|
.\" * Define some portability stuff
|
13
13
|
.\" -----------------------------------------------------------------
|
@@ -127,4 +127,4 @@ Laurent Arnoud <laurent@spkdev\&.net>
|
|
127
127
|
.sp
|
128
128
|
The MIT License
|
129
129
|
.sp
|
130
|
-
Copyright (c) 2009\-
|
130
|
+
Copyright (c) 2009\-2017 Laurent Arnoud <laurent@spkdev\&.net>
|
data/test/crawler_test.rb
CHANGED
@@ -9,6 +9,10 @@ describe ValidateWebsite::Crawl do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
def validator
|
13
|
+
ValidateWebsite::Validator
|
14
|
+
end
|
15
|
+
|
12
16
|
describe 'options' do
|
13
17
|
it 'can change user-agent' do
|
14
18
|
ua = %{Linux / Firefox 29: Mozilla/5.0 (X11; Linux x86_64; rv:29.0) \
|
@@ -21,13 +25,13 @@ describe ValidateWebsite::Crawl do
|
|
21
25
|
end
|
22
26
|
|
23
27
|
it 'can change html5 validator service url' do
|
24
|
-
original =
|
28
|
+
original = validator.html5_validator_service_url
|
25
29
|
new = 'http://localhost:8888/'
|
26
30
|
_out, _err = capture_io do
|
27
31
|
ValidateWebsite::Crawl.new(site: TEST_DOMAIN,
|
28
32
|
html5_validator_service_url: new)
|
29
|
-
|
30
|
-
|
33
|
+
validator.html5_validator_service_url.must_equal new
|
34
|
+
validator.html5_validator_service_url = original
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
@@ -76,8 +80,8 @@ describe ValidateWebsite::Crawl do
|
|
76
80
|
page = FakePage.new(name,
|
77
81
|
body: open(file).read,
|
78
82
|
content_type: 'text/html')
|
79
|
-
validator_res = File.join('test', 'data', 'validator.nu-
|
80
|
-
stub_request(:any,
|
83
|
+
validator_res = File.join('test', 'data', 'validator.nu-failure.json')
|
84
|
+
stub_request(:any, /#{validator.html5_validator_service_url}/)
|
81
85
|
.to_return(body: open(validator_res).read)
|
82
86
|
@validate_website.site = page.url
|
83
87
|
_out, _err = capture_io do
|
@@ -0,0 +1 @@
|
|
1
|
+
{"url":"https://linuxfr.org/","messages":[{"type":"info","lastLine":198,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":195,"lastColumn":20,"firstColumn":1,"subType":"warning","message":"Section lacks heading. Consider using “h2”-“h6” elements to add identifying headings to all sections.","extract":"eil\"</h1>\n<section id=\"phare\">\n<arti","hiliteStart":10,"hiliteLength":20},{"type":"info","lastLine":313,"lastColumn":38,"firstColumn":7,"subType":"warning","message":"The “main” role is unnecessary for element “main”.","extract":"av>\n</nav><main id=\"contents\" role=\"main\">\n<arti","hiliteStart":10,"hiliteLength":32},{"type":"info","lastLine":316,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":374,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":429,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":488,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":546,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":624,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":663,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":739,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":781,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":845,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":908,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":967,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":1015,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"info","lastLine":1079,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40},{"type":"error","lastLine":1098,"lastColumn":18,"firstColumn":1,"message":"Duplicate ID “sommaire”.","extract":"ibre.</p>\n<h2 id=\"sommaire\">Sommai","hiliteStart":10,"hiliteLength":18},{"type":"info","lastLine":507,"lastColumn":18,"firstColumn":1,"subType":"warning","message":"The first occurrence of ID “sommaire” was here.","extract":"ibre.</p>\n<h2 id=\"sommaire\">Sommai","hiliteStart":10,"hiliteLength":18},{"type":"info","lastLine":1138,"lastColumn":40,"firstColumn":1,"subType":"warning","message":"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).","extract":"\n<header>\n<h1 class=\"entry-title\" itemprop=\"name\"><a hre","hiliteStart":10,"hiliteLength":40}],"language":"fr"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"url":"https://example.org/","messages":[],"language":"fr"}
|
data/test/static_test.rb
CHANGED
data/test/validator_test.rb
CHANGED
@@ -21,7 +21,7 @@ describe ValidateWebsite::Validator do
|
|
21
21
|
@xhtml1_page.body,
|
22
22
|
ignore)
|
23
23
|
validator.valid?.must_equal true
|
24
|
-
validator.errors.
|
24
|
+
validator.errors.must_equal []
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'xhtml1-strict should be valid' do
|
@@ -32,19 +32,22 @@ describe ValidateWebsite::Validator do
|
|
32
32
|
body: open(file).read,
|
33
33
|
content_type: 'text/html')
|
34
34
|
@xhtml1_page = @http.get_page(page.url)
|
35
|
+
ignore = /width|height|Length/
|
35
36
|
validator = subject.new(@xhtml1_page.doc,
|
36
|
-
@xhtml1_page.body
|
37
|
+
@xhtml1_page.body,
|
38
|
+
ignore)
|
37
39
|
validator.dtd.system_id.must_equal dtd_uri
|
38
40
|
validator.namespace.must_equal name
|
39
41
|
validator.valid?.must_equal true
|
42
|
+
validator.errors.must_equal []
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
46
|
describe('html5') do
|
44
47
|
describe('when valid') do
|
45
48
|
before do
|
46
|
-
validator_res = File.join('test', 'data', 'validator.nu-success.
|
47
|
-
stub_request(:any, subject.html5_validator_service_url)
|
49
|
+
validator_res = File.join('test', 'data', 'validator.nu-success.json')
|
50
|
+
stub_request(:any, /#{subject.html5_validator_service_url}/)
|
48
51
|
.to_return(body: open(validator_res).read)
|
49
52
|
end
|
50
53
|
it 'html5 should be valid' do
|
@@ -58,25 +61,14 @@ describe ValidateWebsite::Validator do
|
|
58
61
|
@html5_page.body)
|
59
62
|
validator.valid?.must_equal true
|
60
63
|
end
|
61
|
-
it 'with DLFP' do
|
62
|
-
name = 'html5'
|
63
|
-
file = File.join('test', 'data', "#{name}-linuxfr.html")
|
64
|
-
page = FakePage.new(name,
|
65
|
-
body: open(file).read,
|
66
|
-
content_type: 'text/html')
|
67
|
-
@html5_page = @http.get_page(page.url)
|
68
|
-
validator = subject.new(@html5_page.doc,
|
69
|
-
@html5_page.body)
|
70
|
-
validator.valid?.must_equal true
|
71
|
-
end
|
72
64
|
end
|
73
65
|
describe('when not valid') do
|
74
66
|
before do
|
75
|
-
validator_res = File.join('test', 'data', 'validator.nu-failure.
|
76
|
-
stub_request(:any, subject.html5_validator_service_url)
|
67
|
+
validator_res = File.join('test', 'data', 'validator.nu-failure.json')
|
68
|
+
stub_request(:any, /#{subject.html5_validator_service_url}/)
|
77
69
|
.to_return(body: open(validator_res).read)
|
78
70
|
name = 'html5'
|
79
|
-
file = File.join('test', 'data', "#{name}
|
71
|
+
file = File.join('test', 'data', "#{name}.html")
|
80
72
|
page = FakePage.new(name,
|
81
73
|
body: open(file).read,
|
82
74
|
content_type: 'text/html')
|
@@ -87,35 +79,16 @@ describe ValidateWebsite::Validator do
|
|
87
79
|
validator = subject.new(@html5_page.doc,
|
88
80
|
@html5_page.body)
|
89
81
|
validator.valid?.must_equal false
|
90
|
-
validator.errors.size.must_equal
|
82
|
+
validator.errors.size.must_equal 1
|
91
83
|
end
|
92
84
|
|
93
85
|
it 'should exclude errors ignored by :ignore option' do
|
94
|
-
ignore = /
|
86
|
+
ignore = /Duplicate ID/
|
95
87
|
validator = subject.new(@html5_page.doc,
|
96
88
|
@html5_page.body,
|
97
89
|
ignore)
|
98
|
-
validator.valid?.must_equal
|
99
|
-
validator.errors.size.must_equal
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe('excessive') do
|
104
|
-
before do
|
105
|
-
validator_res = File.join('test', 'data', 'validator.nu-excessive.html')
|
106
|
-
stub_request(:any, subject.html5_validator_service_url)
|
107
|
-
.to_return(body: open(validator_res).read)
|
108
|
-
end
|
109
|
-
it 'html5 should have errors' do
|
110
|
-
name = 'html5'
|
111
|
-
file = File.join('test', 'data', "#{name}.html")
|
112
|
-
page = FakePage.new(name,
|
113
|
-
body: open(file).read,
|
114
|
-
content_type: 'text/html')
|
115
|
-
@html5_page = @http.get_page(page.url)
|
116
|
-
validator = subject.new(@html5_page.doc,
|
117
|
-
@html5_page.body)
|
118
|
-
validator.valid?.must_equal false
|
90
|
+
validator.valid?.must_equal true
|
91
|
+
validator.errors.size.must_equal 0
|
119
92
|
end
|
120
93
|
end
|
121
94
|
end
|