validate-website 1.6.0 → 1.7.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.
- 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
|
[](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
|