be_valid_asset 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE.txt +20 -0
- data/README.markdown +158 -0
- data/Rakefile +17 -0
- data/lib/be_valid_asset.rb +33 -0
- data/lib/be_valid_asset/be_valid_base.rb +98 -0
- data/lib/be_valid_asset/be_valid_css.rb +70 -0
- data/lib/be_valid_asset/be_valid_feed.rb +77 -0
- data/lib/be_valid_asset/be_valid_xhtml.rb +75 -0
- data/spec/be_valid_asset/be_valid_css_spec.rb +195 -0
- data/spec/be_valid_asset/be_valid_feed_spec.rb +178 -0
- data/spec/be_valid_asset/be_valid_xhtml_spec.rb +290 -0
- data/spec/files/invalid.css +43 -0
- data/spec/files/invalid.html +15 -0
- data/spec/files/invalid2.html +16 -0
- data/spec/files/invalid_feed.xml +37 -0
- data/spec/files/valid-1.css +31 -0
- data/spec/files/valid-2.css +42 -0
- data/spec/files/valid-3.css +48 -0
- data/spec/files/valid.css +42 -0
- data/spec/files/valid.html +15 -0
- data/spec/files/valid_feed.xml +34 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +32 -0
- metadata +88 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'cgi'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'rexml/document'
|
6
|
+
|
7
|
+
module BeValidAsset
|
8
|
+
|
9
|
+
Configuration.markup_validator_host = 'validator.w3.org'
|
10
|
+
Configuration.markup_validator_path = '/check'
|
11
|
+
|
12
|
+
class BeValidXhtml < BeValidBase
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@fragment = options[:fragment]
|
16
|
+
end
|
17
|
+
|
18
|
+
# Assert that markup (html/xhtml) is valid according the W3C validator web service.
|
19
|
+
|
20
|
+
def matches?(fragment)
|
21
|
+
|
22
|
+
if fragment.respond_to? :body
|
23
|
+
fragment = fragment.body.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
if fragment.empty?
|
27
|
+
@message = "Response was blank (maybe a missing integrate_views)"
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
query_params = { :fragment => fragment }
|
32
|
+
if @fragment
|
33
|
+
query_params[:prefill] = '1'
|
34
|
+
query_params[:prefill_doctype] = 'xhtml10'
|
35
|
+
end
|
36
|
+
|
37
|
+
return validate(query_params)
|
38
|
+
end
|
39
|
+
|
40
|
+
def description
|
41
|
+
"be valid xhtml"
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_message
|
45
|
+
" expected xhtml to be valid, but validation produced these errors:\n#{@message}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def negative_failure_message
|
49
|
+
" expected to not be valid, but was (missing validation?)"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def validator_host
|
55
|
+
Configuration.markup_validator_host
|
56
|
+
end
|
57
|
+
|
58
|
+
def validator_path
|
59
|
+
Configuration.markup_validator_path
|
60
|
+
end
|
61
|
+
|
62
|
+
def error_line_prefix
|
63
|
+
'Invalid markup'
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def be_valid_xhtml
|
69
|
+
BeValidXhtml.new
|
70
|
+
end
|
71
|
+
|
72
|
+
def be_valid_xhtml_fragment()
|
73
|
+
BeValidXhtml.new(:fragment => true)
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
unless defined?(SpecFailed)
|
4
|
+
SpecFailed = Spec::Expectations::ExpectationNotMetError
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'be_valid_css' do
|
8
|
+
|
9
|
+
describe "without caching" do
|
10
|
+
it "should validate a valid string" do
|
11
|
+
css = get_file('valid.css')
|
12
|
+
css.should be_valid_css
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should validate an empty string" do
|
16
|
+
''.should be_valid_css
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should validate a valid response" do
|
20
|
+
response = MockResponse.new(get_file('valid.css'))
|
21
|
+
response.should be_valid_css
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should validate if body is not a string but can be converted to valid string" do
|
25
|
+
response = MockResponse.new(stub("CSS", :to_s => get_file('valid.css')))
|
26
|
+
response.should be_valid_css
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not validate an invalid string" do
|
30
|
+
css = get_file('invalid.css')
|
31
|
+
lambda {
|
32
|
+
css.should be_valid_css
|
33
|
+
}.should raise_error(SpecFailed) { |e|
|
34
|
+
e.message.should match(/expected css to be valid, but validation produced these errors/)
|
35
|
+
e.message.should match(/Invalid css: line 8: Property wibble doesn't exist/)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not validate an invalid response" do
|
40
|
+
response = MockResponse.new(get_file('invalid.css'))
|
41
|
+
lambda {
|
42
|
+
response.should be_valid_css
|
43
|
+
}.should raise_error(SpecFailed) { |e|
|
44
|
+
e.message.should match(/expected css to be valid, but validation produced these errors/)
|
45
|
+
e.message.should match(/Invalid css: line 8: Property wibble doesn't exist/)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should display invalid content when requested" do
|
50
|
+
BeValidAsset::Configuration.display_invalid_content = true
|
51
|
+
css = get_file('invalid.css')
|
52
|
+
lambda {
|
53
|
+
css.should be_valid_css
|
54
|
+
}.should raise_error(SpecFailed) { |e|
|
55
|
+
e.message.should match(/wibble:0;/)
|
56
|
+
}
|
57
|
+
BeValidAsset::Configuration.display_invalid_content = false
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should fail unless resposne is HTTP OK" do
|
61
|
+
css = get_file('valid.css')
|
62
|
+
|
63
|
+
r = Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable')
|
64
|
+
h = Net::HTTP.new(BeValidAsset::Configuration.css_validator_host)
|
65
|
+
h.stub!(:post2).and_return(r)
|
66
|
+
Net::HTTP.stub!(:start).and_return(h)
|
67
|
+
|
68
|
+
lambda {
|
69
|
+
css.should be_valid_css
|
70
|
+
}.should raise_error
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should mark test as pending if ENV['NONET'] is true" do
|
74
|
+
ENV['NONET'] = 'true'
|
75
|
+
|
76
|
+
css = get_file('valid.css')
|
77
|
+
lambda {
|
78
|
+
css.should be_valid_css
|
79
|
+
}.should raise_error(Spec::Example::ExamplePendingError)
|
80
|
+
|
81
|
+
ENV.delete('NONET')
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "CSS version" do
|
85
|
+
(1..3).each do |version|
|
86
|
+
describe version.to_s do
|
87
|
+
before(:each) do
|
88
|
+
@css = get_file("valid-#{version.to_s}.css")
|
89
|
+
end
|
90
|
+
(1..3).each do |test_version|
|
91
|
+
if test_version < version
|
92
|
+
it "should not be valid css#{test_version.to_s}" do
|
93
|
+
lambda {
|
94
|
+
@css.should send("be_valid_css#{test_version.to_s}".to_sym)
|
95
|
+
}.should raise_error(SpecFailed)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
it "should be valid css#{test_version.to_s}" do
|
99
|
+
@css.should send("be_valid_css#{test_version.to_s}".to_sym)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "with caching" do
|
109
|
+
before(:each) do
|
110
|
+
BeValidAsset::Configuration.enable_caching = true
|
111
|
+
FileUtils.rm Dir.glob(BeValidAsset::Configuration.cache_path + '/*')
|
112
|
+
end
|
113
|
+
after(:each) do
|
114
|
+
BeValidAsset::Configuration.enable_caching = false
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should validate valid css and cache the response" do
|
118
|
+
css = get_file('valid.css')
|
119
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
120
|
+
css.should be_valid_css
|
121
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count + 1)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should validate valid css using the cached response" do
|
125
|
+
css = get_file('valid.css')
|
126
|
+
css.should be_valid_css
|
127
|
+
|
128
|
+
Net::HTTP.should_not_receive(:start)
|
129
|
+
css.should be_valid_css
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should not validate invalid css, but still cache the response" do
|
133
|
+
css = get_file('invalid.css')
|
134
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
135
|
+
lambda {
|
136
|
+
css.should be_valid_css
|
137
|
+
}.should raise_error(SpecFailed) { |e|
|
138
|
+
e.message.should match(/expected css to be valid, but validation produced these errors/)
|
139
|
+
e.message.should match(/Invalid css: line 8: Property wibble doesn't exist/)
|
140
|
+
}
|
141
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count + 1)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should not validate invalid css, but use the cached response" do
|
145
|
+
css = get_file('invalid.css')
|
146
|
+
css.should_not be_valid_css
|
147
|
+
|
148
|
+
Net::HTTP.should_not_receive(:start)
|
149
|
+
lambda {
|
150
|
+
css.should be_valid_css
|
151
|
+
}.should raise_error(SpecFailed) { |e|
|
152
|
+
e.message.should match(/expected css to be valid, but validation produced these errors/)
|
153
|
+
e.message.should match(/Invalid css: line 8: Property wibble doesn't exist/)
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should not cache the result unless it is an HTTP OK response" do
|
158
|
+
css = get_file('valid.css')
|
159
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
160
|
+
|
161
|
+
r = Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable')
|
162
|
+
h = Net::HTTP.new(BeValidAsset::Configuration.css_validator_host)
|
163
|
+
h.stub!(:post2).and_return(r)
|
164
|
+
Net::HTTP.stub!(:start).and_return(h)
|
165
|
+
|
166
|
+
lambda {
|
167
|
+
css.should be_valid_css
|
168
|
+
}.should raise_error
|
169
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should use the cached result (if available) when network tests disabled" do
|
173
|
+
css = get_file('valid.css')
|
174
|
+
css.should be_valid_css
|
175
|
+
|
176
|
+
ENV['NONET'] = 'true'
|
177
|
+
|
178
|
+
Net::HTTP.should_not_receive(:start)
|
179
|
+
css.should be_valid_css
|
180
|
+
|
181
|
+
ENV.delete('NONET')
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should mark test as pending if network tests are disabled, and no cached result is available" do
|
185
|
+
ENV['NONET'] = 'true'
|
186
|
+
|
187
|
+
css = get_file('valid.css')
|
188
|
+
lambda {
|
189
|
+
css.should be_valid_css
|
190
|
+
}.should raise_error(Spec::Example::ExamplePendingError)
|
191
|
+
|
192
|
+
ENV.delete('NONET')
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
unless defined?(SpecFailed)
|
4
|
+
SpecFailed = Spec::Expectations::ExpectationNotMetError
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'be_valid_feed' do
|
8
|
+
|
9
|
+
describe "without caching" do
|
10
|
+
it "should validate a valid string" do
|
11
|
+
feed = get_file('valid_feed.xml')
|
12
|
+
feed.should be_valid_feed
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should work when called as be_valid_rss" do
|
16
|
+
feed = get_file('valid_feed.xml')
|
17
|
+
feed.should be_valid_rss
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should work when called as be_valid_atom" do
|
21
|
+
feed = get_file('valid_feed.xml')
|
22
|
+
feed.should be_valid_atom
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should validate a valid response" do
|
26
|
+
response = MockResponse.new(get_file('valid_feed.xml'))
|
27
|
+
response.should be_valid_feed
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should validate if body is not a string but can be converted to valid string" do
|
31
|
+
response = MockResponse.new(stub("Feed", :to_s => get_file('valid_feed.xml')))
|
32
|
+
response.should be_valid_feed
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not validate an invalid string" do
|
36
|
+
feed = get_file('invalid_feed.xml')
|
37
|
+
lambda {
|
38
|
+
feed.should be_valid_feed
|
39
|
+
}.should raise_error(SpecFailed) { |e|
|
40
|
+
e.message.should match(/expected feed to be valid, but validation produced these errors/)
|
41
|
+
e.message.should match(/Invalid feed: line 12: Invalid email address/)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not validate an invalid response" do
|
46
|
+
response = MockResponse.new(get_file('invalid_feed.xml'))
|
47
|
+
lambda {
|
48
|
+
response.should be_valid_feed
|
49
|
+
}.should raise_error(SpecFailed) { |e|
|
50
|
+
e.message.should match(/expected feed to be valid, but validation produced these errors/)
|
51
|
+
e.message.should match(/Invalid feed: line 12: Invalid email address/)
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should display invalid content when requested" do
|
56
|
+
BeValidAsset::Configuration.display_invalid_content = true
|
57
|
+
feed = get_file('invalid_feed.xml')
|
58
|
+
lambda {
|
59
|
+
feed.should be_valid_feed
|
60
|
+
}.should raise_error(SpecFailed) { |e|
|
61
|
+
e.message.should match(%r{<link>http://site.example.com/articles/article-1-title</link>})
|
62
|
+
}
|
63
|
+
BeValidAsset::Configuration.display_invalid_content = false
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should fail unless resposne is HTTP OK" do
|
67
|
+
feed = get_file('valid_feed.xml')
|
68
|
+
|
69
|
+
r = Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable')
|
70
|
+
h = Net::HTTP.new(BeValidAsset::Configuration.feed_validator_host)
|
71
|
+
h.stub!(:post).and_return(r)
|
72
|
+
Net::HTTP.stub!(:start).and_return(h)
|
73
|
+
|
74
|
+
lambda {
|
75
|
+
feed.should be_valid_feed
|
76
|
+
}.should raise_error
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should mark test as pending if ENV['NONET'] is true" do
|
80
|
+
ENV['NONET'] = 'true'
|
81
|
+
|
82
|
+
feed = get_file('valid_feed.xml')
|
83
|
+
lambda {
|
84
|
+
feed.should be_valid_feed
|
85
|
+
}.should raise_error(Spec::Example::ExamplePendingError)
|
86
|
+
|
87
|
+
ENV.delete('NONET')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "with caching" do
|
92
|
+
before(:each) do
|
93
|
+
BeValidAsset::Configuration.enable_caching = true
|
94
|
+
FileUtils.rm Dir.glob(BeValidAsset::Configuration.cache_path + '/*')
|
95
|
+
end
|
96
|
+
after(:each) do
|
97
|
+
BeValidAsset::Configuration.enable_caching = false
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should validate valid feed and cache the response" do
|
101
|
+
feed = get_file('valid_feed.xml')
|
102
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
103
|
+
feed.should be_valid_feed
|
104
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count + 1)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should validate valid feed using the cached response" do
|
108
|
+
feed = get_file('valid_feed.xml')
|
109
|
+
feed.should be_valid_feed
|
110
|
+
|
111
|
+
Net::HTTP.should_not_receive(:start)
|
112
|
+
feed.should be_valid_feed
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should not validate invalid feed, but still cache the response" do
|
116
|
+
feed = get_file('invalid_feed.xml')
|
117
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
118
|
+
lambda {
|
119
|
+
feed.should be_valid_feed
|
120
|
+
}.should raise_error(SpecFailed) { |e|
|
121
|
+
e.message.should match(/expected feed to be valid, but validation produced these errors/)
|
122
|
+
e.message.should match(/Invalid feed: line 12: Invalid email address/)
|
123
|
+
}
|
124
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count + 1)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should not validate invalid feed, but use the cached response" do
|
128
|
+
feed = get_file('invalid_feed.xml')
|
129
|
+
feed.should_not be_valid_feed
|
130
|
+
|
131
|
+
Net::HTTP.should_not_receive(:start)
|
132
|
+
lambda {
|
133
|
+
feed.should be_valid_feed
|
134
|
+
}.should raise_error(SpecFailed) { |e|
|
135
|
+
e.message.should match(/expected feed to be valid, but validation produced these errors/)
|
136
|
+
e.message.should match(/Invalid feed: line 12: Invalid email address/)
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should not cache the result unless it is an HTTP OK response" do
|
141
|
+
feed = get_file('valid_feed.xml')
|
142
|
+
count = Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size
|
143
|
+
|
144
|
+
r = Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable')
|
145
|
+
h = Net::HTTP.new(BeValidAsset::Configuration.feed_validator_host)
|
146
|
+
h.stub!(:post).and_return(r)
|
147
|
+
Net::HTTP.stub!(:start).and_return(h)
|
148
|
+
|
149
|
+
lambda {
|
150
|
+
feed.should be_valid_feed
|
151
|
+
}.should raise_error
|
152
|
+
Dir.glob(BeValidAsset::Configuration.cache_path + '/*').size.should eql(count)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should use the cached result (if available) when network tests disabled" do
|
156
|
+
feed = get_file('valid_feed.xml')
|
157
|
+
feed.should be_valid_feed
|
158
|
+
|
159
|
+
ENV['NONET'] = 'true'
|
160
|
+
|
161
|
+
Net::HTTP.should_not_receive(:start)
|
162
|
+
feed.should be_valid_feed
|
163
|
+
|
164
|
+
ENV.delete('NONET')
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should mark test as pending if network tests are disabled, and no cached result is available" do
|
168
|
+
ENV['NONET'] = 'true'
|
169
|
+
|
170
|
+
feed = get_file('valid_feed.xml')
|
171
|
+
lambda {
|
172
|
+
feed.should be_valid_feed
|
173
|
+
}.should raise_error(Spec::Example::ExamplePendingError)
|
174
|
+
|
175
|
+
ENV.delete('NONET')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|