rspec_w3c_matchers 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.rdoc +103 -0
- data/Rakefile +3 -0
- data/lib/rspec_w3c_matchers.rb +8 -0
- data/lib/rspec_w3c_matchers/matchers.rb +87 -0
- data/lib/rspec_w3c_matchers/notices.rb +130 -0
- data/lib/rspec_w3c_matchers/version.rb +8 -0
- data/rspec_w3c_matchers.gemspec +26 -0
- data/spec/base/matchers_spec.rb +36 -0
- data/spec/base/notices_spec.rb +38 -0
- data/spec/base/version_spec.rb +16 -0
- data/spec/fixtures/error.marshal +0 -0
- data/spec/fixtures/valid.marshal +0 -0
- data/spec/fixtures/warning.marshal +0 -0
- data/spec/responses/error.rb +27 -0
- data/spec/responses/responses.rb +40 -0
- data/spec/responses/valid.rb +25 -0
- data/spec/responses/warning.rb +26 -0
- data/spec/shared_examples/matchers.rb +80 -0
- data/spec/shared_examples/notice_matcher.rb +150 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/.fixtures.rb.swp +0 -0
- data/tasks/fixtures.rb +67 -0
- metadata +117 -0
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
= RspecW3cMatchers
|
2
|
+
|
3
|
+
Wiki[http://wiki.github.com/takaltoo/rspec_w3c_matchers] | RDocs[http://rdoc.info/projects/takaltoo/rspec_w3c_matchers]
|
4
|
+
|
5
|
+
RspecW3cMatchers provides custom matchers for detecting validation errors reported by
|
6
|
+
{w3c validator service}[http://validator.w3.org]. The {w3c_validator gem}[https://github.com/alexdunae/w3c_validators] by
|
7
|
+
{alexdunae}[https://github.com/alexdunae]. The matchers return detailed information regarding errors or warnings that are
|
8
|
+
returned by the w3c validator.
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
In <b>Rails 3</b>, add this to your Gemfile:
|
13
|
+
gem "flickrmocks"
|
14
|
+
|
15
|
+
Alternatively, you can install it as a plugin:
|
16
|
+
rails plugin install git://github.com/takaltoo/rspec_w3c_matchers.git
|
17
|
+
|
18
|
+
== Getting Started
|
19
|
+
RspecW3cMatchers API helpers expect the FlickRaw.api_key to be initialized before they are called:
|
20
|
+
FlickRaw.api_key = your_flickr_api_key
|
21
|
+
|
22
|
+
== Including the matchers in Rspec or Cucumber
|
23
|
+
In <b>RSPEC 2.0</b> tests you can place the following in your spec_helper.rb file inside the config block
|
24
|
+
config.include(RspecW3cMatchers::InstanceMethods)
|
25
|
+
|
26
|
+
In <b>Cucumber</b> you can place the following in any step definition file that uses the helpers:
|
27
|
+
include RspecW3cMatchers::InstanceMethods
|
28
|
+
|
29
|
+
== Commonly used matchers
|
30
|
+
Matchers to detect that page is free from errors or warnings:
|
31
|
+
have_no_w3c_errors_in(page)
|
32
|
+
have_no_w3c_errors_in(page)
|
33
|
+
|
34
|
+
Matchers to detect that page has specified number of errors or warnings:
|
35
|
+
have_specified_number_of_w3c_errors_in(page,number)
|
36
|
+
have_specified_number_of_w3c_errors_in(page,number)
|
37
|
+
|
38
|
+
You can find a complete list of the matchers by looking at the RspecW3cMatchers::InstanceMethods in
|
39
|
+
RDOCS[http://rdoc.info/projects/takaltoo/rspec_w3c_matchers]
|
40
|
+
|
41
|
+
== Sample usage of matchers
|
42
|
+
A sample RSPEC test that ensures the page has no w3c warnings or errors is given below (assuming body contains the
|
43
|
+
html for the page):
|
44
|
+
w3c = W3CValidators::MarkupValidator.new
|
45
|
+
response = w3c.validate_text(body)
|
46
|
+
response.should have_no_w3c_errors_in(body)
|
47
|
+
response.should have_no_w3c_warnings_in(body)
|
48
|
+
|
49
|
+
== Generating a response object from W3C validator
|
50
|
+
|
51
|
+
A w3c response is can be checked using various matchers. You can generate a w3c response using
|
52
|
+
the w3c_validator gem:
|
53
|
+
w3c = W3CValidators::MarkupValidator.new
|
54
|
+
response = w3c.validate_text(body)
|
55
|
+
|
56
|
+
Once you have the response you can compare it against a matcher. NOTE: the variable body contains the html for the page.
|
57
|
+
If you are using Capybara[https://github.com/jnicklas/capybara]
|
58
|
+
and Cucumber[https://github.com/aslakhellesoy/cucumber] you can simply
|
59
|
+
access the text by passing in 'page.body'.
|
60
|
+
|
61
|
+
A sample step file for cucumber (that is used with capybara) is given below:
|
62
|
+
include RspecW3cMatchers::InstanceMethods
|
63
|
+
|
64
|
+
Then /^the page should have valid html$/ do
|
65
|
+
w3c = W3CValidators::MarkupValidator.new
|
66
|
+
response = w3c.validate_text(page.body)
|
67
|
+
response.should have_no_w3c_errors_in(page.body)
|
68
|
+
response.should have_no_w3c_warnings_in(page.body)
|
69
|
+
end
|
70
|
+
|
71
|
+
== Additional Docs
|
72
|
+
|
73
|
+
* {RDOCs}[http://rdoc.info/projects/takaltoo/rspec_w3c_matchers]
|
74
|
+
* Run the specs manually once you have checked out the repository:
|
75
|
+
rspec spec -f d
|
76
|
+
|
77
|
+
|
78
|
+
== Questions or Problems?
|
79
|
+
|
80
|
+
If you have any issues with RspecW3cMatchers which you cannot find the solution to in the documentation,
|
81
|
+
please add an issue on GitHub[http://github.com/takaltoo/rspec_w3c_matchers/issues] or fork the project
|
82
|
+
and send a pull request.
|
83
|
+
|
84
|
+
To get the specs running you should call +bundle+ and then +rake+.
|
85
|
+
|
86
|
+
== Note on Patches/Pull Requests
|
87
|
+
|
88
|
+
* Fork the project.
|
89
|
+
* Make your feature addition or bug fix.
|
90
|
+
* Add tests for it. This is important so I do not break it
|
91
|
+
in a future version unintentionally.
|
92
|
+
* Commit, do not mess with rakefile, version, or history.
|
93
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself
|
94
|
+
I can ignore when I pull)
|
95
|
+
* Send me a pull request.
|
96
|
+
|
97
|
+
== License
|
98
|
+
|
99
|
+
RspecW3cMatchers is released under the MIT license.
|
100
|
+
|
101
|
+
== Copyright
|
102
|
+
|
103
|
+
Copyright (c) 2010 Takaltoo
|
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module RspecW3cMatchers
|
2
|
+
# Contains RSPEC 2.0 instance methods. To use the matchers in RSPEC 2.0,
|
3
|
+
# include this module inside your RSPEC config block inside of spec_helper.rb
|
4
|
+
#
|
5
|
+
# Rspec.configure do |config|
|
6
|
+
# config.include(RspecW3cMatchers::InstanceMethods)
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# To use matchers in Cucumber steps, simply include this module inside any
|
10
|
+
# step definitions:
|
11
|
+
#
|
12
|
+
# include RspecW3cMatchers::InstanceMethods
|
13
|
+
module InstanceMethods
|
14
|
+
# matcher for detecting zero errors
|
15
|
+
def have_no_w3c_errors_in(page)
|
16
|
+
RspecW3cMatchers::Notices.new(page,:==,0,:errors)
|
17
|
+
end
|
18
|
+
|
19
|
+
# matcher for detecting zero warnings
|
20
|
+
def have_no_w3c_warnings_in(page)
|
21
|
+
RspecW3cMatchers::Notices.new(page,:==,0,:warnings)
|
22
|
+
end
|
23
|
+
|
24
|
+
# matcher for detecting >0 errors
|
25
|
+
def have_w3c_errors_in(page)
|
26
|
+
RspecW3cMatchers::Notices.new(page,:>,0,:errors)
|
27
|
+
end
|
28
|
+
|
29
|
+
# matcher for detecting >0 errors
|
30
|
+
def have_w3c_warnings_in(page)
|
31
|
+
RspecW3cMatchers::Notices.new(page,:>,0,:warnings)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# matcher for detecting expected number of errors
|
36
|
+
def have_specified_number_of_w3c_errors_in(page,number)
|
37
|
+
RspecW3cMatchers::Notices.new(page,:==,number,:errors)
|
38
|
+
end
|
39
|
+
|
40
|
+
# matcher for detecting expected number of warnings
|
41
|
+
def have_specified_number_of_w3c_warnings_in(page,number)
|
42
|
+
RspecW3cMatchers::Notices.new(page,:==,number,:warnings)
|
43
|
+
end
|
44
|
+
|
45
|
+
# matcher for detecing > specified number of errors
|
46
|
+
def have_more_than_specified_number_of_errors_in(page,number)
|
47
|
+
RspecW3cMatchers::Notices.new(page,:>,number,:errors)
|
48
|
+
end
|
49
|
+
|
50
|
+
# matcher for detecing > specified number of warnings
|
51
|
+
def have_more_than_specified_number_of_warnings_in(page,number)
|
52
|
+
RspecW3cMatchers::Notices.new(page,:>,number,:warnings)
|
53
|
+
end
|
54
|
+
|
55
|
+
# matcher for detecing >= specified number of errors
|
56
|
+
def have_greater_than_or_equal_to_specified_number_of_errors_in(page,number)
|
57
|
+
RspecW3cMatchers::Notices.new(page,:>=,number,:errors)
|
58
|
+
end
|
59
|
+
|
60
|
+
# matcher for detecing >= specified number of warnings
|
61
|
+
def have_greater_than_or_equal_to_specified_number_of_warnings_in(page,number)
|
62
|
+
RspecW3cMatchers::Notices.new(page,:>=,number,:warnings)
|
63
|
+
end
|
64
|
+
|
65
|
+
# matcher for detecing < specified number of errors
|
66
|
+
def have_less_than_specified_number_of_errors_in(page,number)
|
67
|
+
RspecW3cMatchers::Notices.new(page,:<,number,:errors)
|
68
|
+
end
|
69
|
+
|
70
|
+
# matcher for detecing < specified number of warnings
|
71
|
+
def have_less_than_specified_number_of_warnings_in(page,number)
|
72
|
+
RspecW3cMatchers::Notices.new(page,:<,number,:warnings)
|
73
|
+
end
|
74
|
+
|
75
|
+
# matcher for detecing <= specified number of errors
|
76
|
+
def have_less_than_or_equal_to_specified_number_of_errors_in(page,number)
|
77
|
+
RspecW3cMatchers::Notices.new(page,:<=,number,:errors)
|
78
|
+
end
|
79
|
+
|
80
|
+
# matcher for detecing <= specified number of warnings
|
81
|
+
def have_less_than_or_equal_to_specified_number_of_warnings_in(page,number)
|
82
|
+
RspecW3cMatchers::Notices.new(page,:<=,number,:warnings)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module RspecW3cMatchers
|
2
|
+
# Low level matcher that is used as a base for the high level matchers.
|
3
|
+
# You should not need to use this class directly. Look at the definitions in
|
4
|
+
# RspecW3cMatchers::InstanceMethods for a complete list of available matchers.
|
5
|
+
#
|
6
|
+
# The arguments to Notice are as follows:
|
7
|
+
#
|
8
|
+
# page: text containing the html that is being validated
|
9
|
+
# comparator: comparison to be performed, can be :==,:<,:>,:<=,:>=. The number of errors
|
10
|
+
# or warnings in the response is compared against the msg_count using this operator.
|
11
|
+
# msg_count: expected number of notices
|
12
|
+
# type: message type, either :errors or :warnings
|
13
|
+
#
|
14
|
+
# To create a matcher that checks whether a response has more than 2 warnings you would use the
|
15
|
+
# declaration:
|
16
|
+
#
|
17
|
+
# RspecW3cMatchers::Notices.new(page,:>,2,:warnings)
|
18
|
+
#
|
19
|
+
# To create a matcher that checks to make sure a response has exactly 1 error you would use the
|
20
|
+
# declaration:
|
21
|
+
#
|
22
|
+
# RspecW3cMatchers::Notices.new(page,:==,1,:errors)
|
23
|
+
#
|
24
|
+
class Notices
|
25
|
+
def initialize(page,comparator,msg_count,type)
|
26
|
+
@page = page
|
27
|
+
@msg_count = msg_count
|
28
|
+
self.comparator = comparator
|
29
|
+
self.type = type
|
30
|
+
end
|
31
|
+
|
32
|
+
# Used by the should() and should_not() methods to determine whether the expectation passes or fails.
|
33
|
+
def matches?(response)
|
34
|
+
@response = response
|
35
|
+
notices.length.send(@comparator,@msg_count)
|
36
|
+
end
|
37
|
+
|
38
|
+
# The failure message used when should() is used and the matches?() method returns false.
|
39
|
+
def failure_message_for_should
|
40
|
+
["Expected #{comparison}#{@msg_count} W3C validation #{type} but received #{notices.length} #{type}",
|
41
|
+
summary
|
42
|
+
].join("\n")
|
43
|
+
end
|
44
|
+
|
45
|
+
# The failure message used when should_not() is used and the matches?() method returns true.
|
46
|
+
def failure_message_for_should_not
|
47
|
+
["Did not expect #{comparison}#{@msg_count} W3C validation #{type} but received #{notices.length} #{type}",
|
48
|
+
summary
|
49
|
+
].join("\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
# description that is returned when none is provided
|
53
|
+
def description
|
54
|
+
"should receive #{comparison}#{@msg_count} W3C validation #{type} in #{uri}"
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def notices
|
59
|
+
@response.send(@type.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def summary
|
63
|
+
(
|
64
|
+
["Checked by: %s" % @response.checked_by,
|
65
|
+
"Document type: %s" % @response.doctype,
|
66
|
+
"Character set: %s" % @response.charset,
|
67
|
+
"\n#{@type.capitalize}: %s\n" % [notices.length]
|
68
|
+
].join("\n") +
|
69
|
+
messages
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def messages
|
74
|
+
notices.map do |message|
|
75
|
+
["Type: %s" % message.type,
|
76
|
+
"Location: line '%s' column '%s'" %[message.line,message.col],
|
77
|
+
"URI: %s" % uri,
|
78
|
+
"Message: %s" % message.message,
|
79
|
+
"Source (line #{message.line}): \n%s\n" % extract_source(message.line)].join("\n")
|
80
|
+
end.join("\n"*2)
|
81
|
+
end
|
82
|
+
|
83
|
+
def extract_source(line)
|
84
|
+
body.split("\n")[line.to_i-1]
|
85
|
+
end
|
86
|
+
|
87
|
+
def uri
|
88
|
+
@page.respond_to?(:current_path) ? @page.current_path : '(Unknown, input probably came from text)'
|
89
|
+
end
|
90
|
+
|
91
|
+
def body
|
92
|
+
@page.respond_to?(:body) ? @page.body : @page.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
def type
|
96
|
+
@msg_count == 1 ? @type.to_s[0..-2] : @type.to_s
|
97
|
+
end
|
98
|
+
|
99
|
+
def comparison
|
100
|
+
case @comparator
|
101
|
+
when :== then
|
102
|
+
''
|
103
|
+
when :<= then
|
104
|
+
'less than or equal to '
|
105
|
+
when :>= then
|
106
|
+
'greater than or equal to '
|
107
|
+
when :< then
|
108
|
+
'less than '
|
109
|
+
when :> then
|
110
|
+
'greater than '
|
111
|
+
else
|
112
|
+
''
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def comparator=(value)
|
117
|
+
raise ArgumentError unless [:==,:<=,:>=,:<,:>].include?(value)
|
118
|
+
@comparator = value
|
119
|
+
end
|
120
|
+
|
121
|
+
def type=(value)
|
122
|
+
raise ArgumentError unless [:errors,:warnings].include?(value)
|
123
|
+
@type = value
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rspec_w3c_matchers/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rspec_w3c_matchers"
|
7
|
+
s.version = RspecW3cMatchers::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Takaltoo"]
|
10
|
+
s.email = ["pouya@lavabit.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/rspec_w3c_matchers"
|
12
|
+
s.summary = %q{Rspec 2.0 matchers that detect and report detailed error and warning
|
13
|
+
responses from w3c_validators GEM.}
|
14
|
+
s.description = %q{ add description}
|
15
|
+
|
16
|
+
s.rubyforge_project = "rspec_w3c_matchers"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
s.add_runtime_dependency(%q<w3c_validators>, [">= 1.1.1"])
|
23
|
+
s.add_development_dependency(%q<rspec>, [">= 2.3.0"])
|
24
|
+
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe APP do
|
4
|
+
let(:klass) {APP}
|
5
|
+
let(:matcher) {klass}
|
6
|
+
let(:clean_page){ SampleResponses::Valid.html}
|
7
|
+
let(:clean_response){ SampleResponses.load(:valid)}
|
8
|
+
|
9
|
+
context "Errors" do
|
10
|
+
let(:type){:errors}
|
11
|
+
let(:dirty_page){SampleResponses::Error.html}
|
12
|
+
let(:dirty_response){SampleResponses.load(:error)}
|
13
|
+
|
14
|
+
it_should_behave_like "w3c notices matcher for have no"
|
15
|
+
it_should_behave_like "w3c notices matcher for have more than zero"
|
16
|
+
it_should_behave_like "w3c notices matcher for have specified"
|
17
|
+
it_should_behave_like "w3c notices matcher for have more than"
|
18
|
+
it_should_behave_like "w3c notices matcher for have greater than or equal to"
|
19
|
+
it_should_behave_like "w3c notices matcher for have less than"
|
20
|
+
it_should_behave_like "w3c notices matcher for have less than or equal to"
|
21
|
+
end
|
22
|
+
|
23
|
+
context "Warnings" do
|
24
|
+
let(:type){:warnings}
|
25
|
+
let(:dirty_page){SampleResponses::Warning.html}
|
26
|
+
let(:dirty_response){SampleResponses.load(:warning)}
|
27
|
+
|
28
|
+
it_should_behave_like "w3c notices matcher for have no"
|
29
|
+
it_should_behave_like "w3c notices matcher for have more than zero"
|
30
|
+
it_should_behave_like "w3c notices matcher for have specified"
|
31
|
+
it_should_behave_like "w3c notices matcher for have more than"
|
32
|
+
it_should_behave_like "w3c notices matcher for have greater than or equal to"
|
33
|
+
it_should_behave_like "w3c notices matcher for have less than"
|
34
|
+
it_should_behave_like "w3c notices matcher for have less than or equal to"
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe APP::Notices do
|
4
|
+
let(:klass) {APP::Notices}
|
5
|
+
let(:notices) {klass}
|
6
|
+
let(:validator){W3CValidators::MarkupValidator}
|
7
|
+
|
8
|
+
let(:clean_page){ SampleResponses::Valid.html}
|
9
|
+
let(:clean_response){ SampleResponses.load(:valid)}
|
10
|
+
|
11
|
+
context "Errors" do
|
12
|
+
let(:type){:errors}
|
13
|
+
let(:dirty_page){ SampleResponses::Error.html}
|
14
|
+
let(:dirty_response){ SampleResponses.load(:error)}
|
15
|
+
|
16
|
+
it_should_behave_like "w3c matcher for :== operator"
|
17
|
+
it_should_behave_like "w3c matcher for :> operator"
|
18
|
+
it_should_behave_like "w3c matcher for :< operator"
|
19
|
+
it_should_behave_like "w3c matcher for :<= operator"
|
20
|
+
it_should_behave_like "w3c matcher for :>= operator"
|
21
|
+
it_should_behave_like "w3c matcher with detailed notice reporting"
|
22
|
+
it_should_behave_like "w3c matcher with description when none provided"
|
23
|
+
end
|
24
|
+
|
25
|
+
context "Warnings" do
|
26
|
+
let(:type){:warnings}
|
27
|
+
let(:dirty_page){ SampleResponses::Warning.html}
|
28
|
+
let(:dirty_response){ SampleResponses.load(:warning)}
|
29
|
+
|
30
|
+
it_should_behave_like "w3c matcher for :== operator"
|
31
|
+
it_should_behave_like "w3c matcher for :> operator"
|
32
|
+
it_should_behave_like "w3c matcher for :< operator"
|
33
|
+
it_should_behave_like "w3c matcher for :<= operator"
|
34
|
+
it_should_behave_like "w3c matcher for :>= operator"
|
35
|
+
it_should_behave_like "w3c matcher with detailed notice reporting"
|
36
|
+
it_should_behave_like "w3c matcher with description when none provided"
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe APP do
|
4
|
+
let(:klass){APP}
|
5
|
+
context "class methods" do
|
6
|
+
it "should have VERSION constant" do
|
7
|
+
klass.constants.include?(:VERSION).should be true
|
8
|
+
end
|
9
|
+
specify {klass.should respond_to(:version)}
|
10
|
+
context "version" do
|
11
|
+
it "should return the VERSION constant" do
|
12
|
+
klass.version.should == klass::VERSION
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SampleResponses
|
2
|
+
|
3
|
+
module Error
|
4
|
+
def self.html
|
5
|
+
%q(
|
6
|
+
<!DOCTYPE html>
|
7
|
+
<html>
|
8
|
+
<head>
|
9
|
+
<meta charset="utf-8">
|
10
|
+
<title>Two Error</title>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>Page with a Two Errors</h1>
|
14
|
+
<p>Hello world</p>
|
15
|
+
<usr_nav></usr_nav>
|
16
|
+
<boo_boo></boo_boo>
|
17
|
+
</body>
|
18
|
+
</html>
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.response
|
23
|
+
SampeResponses.load(:error)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
[
|
2
|
+
'error',
|
3
|
+
'warning',
|
4
|
+
'valid'
|
5
|
+
].each do |file|
|
6
|
+
require File.expand_path(File.dirname(__FILE__)) + '/' + file
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
module SampleResponses
|
12
|
+
|
13
|
+
def self.load(name)
|
14
|
+
file = File.open(self.file(name),'r')
|
15
|
+
data = Marshal.load(file)
|
16
|
+
file.close
|
17
|
+
return data
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.warning
|
21
|
+
SampleResponses::Warning
|
22
|
+
end
|
23
|
+
def self.error
|
24
|
+
SampleResponses::Error
|
25
|
+
end
|
26
|
+
def self.valid
|
27
|
+
SampleResponses::Valid
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def self.path
|
33
|
+
File.expand_path(File.dirname(__FILE__) + '/../' + 'fixtures/')
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.file(name)
|
37
|
+
self.path + '/' + name.to_s + ".marshal"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SampleResponses
|
2
|
+
|
3
|
+
module Valid
|
4
|
+
def self.html
|
5
|
+
%q(
|
6
|
+
<!DOCTYPE html>
|
7
|
+
<html>
|
8
|
+
<head>
|
9
|
+
<meta charset="utf-8">
|
10
|
+
<title>Clean Page</title>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>This is a clean page</h1>
|
14
|
+
<p>Hello world</p>
|
15
|
+
</body>
|
16
|
+
</html>
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.response
|
21
|
+
SampeResponses.load(:valid)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SampleResponses
|
2
|
+
|
3
|
+
module Warning
|
4
|
+
|
5
|
+
def self.html
|
6
|
+
%q(
|
7
|
+
<!DOCTYPE html5>
|
8
|
+
<html>
|
9
|
+
<head>
|
10
|
+
<title>Single Warning</title>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>Page with a Single Warning</h1>
|
14
|
+
<p>Hello world</p>
|
15
|
+
<br/>
|
16
|
+
</body>
|
17
|
+
</html>
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.response
|
22
|
+
SampeResponses.load(:warning)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
shared_examples_for "w3c notices matcher for have no" do
|
2
|
+
let(:method){"have_no_w3c_#{type}_in".to_sym}
|
3
|
+
|
4
|
+
it "should return true with valid page" do
|
5
|
+
self.send(method,clean_page).matches?(clean_response).should be true
|
6
|
+
end
|
7
|
+
it "should return false for invalid page" do
|
8
|
+
self.send(method,dirty_page).matches?(dirty_response).should be false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
shared_examples_for "w3c notices matcher for have more than zero" do
|
13
|
+
let(:method){"have_w3c_#{type}_in"}
|
14
|
+
|
15
|
+
it "should return true for invalid page" do
|
16
|
+
self.send(method,dirty_page).matches?(dirty_response).should be true
|
17
|
+
end
|
18
|
+
it "should return false for valid page" do
|
19
|
+
self.send(method,clean_page).matches?(clean_response).should be false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples_for "w3c notices matcher for have specified" do
|
24
|
+
let(:method){"have_specified_number_of_w3c_#{type}_in"}
|
25
|
+
|
26
|
+
it "should return true when 2 notices expected and page contains 2 notices" do
|
27
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be true
|
28
|
+
end
|
29
|
+
it "should return false when 3 notices expected and page contains 2 notices" do
|
30
|
+
self.send(method,dirty_page,3).matches?(dirty_response).should be false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
shared_examples_for "w3c notices matcher for have more than" do
|
35
|
+
let(:method){"have_more_than_specified_number_of_#{type}_in"}
|
36
|
+
|
37
|
+
it "should return true when 1 notice expected and page contains 2 notices" do
|
38
|
+
self.send(method,dirty_page,1).matches?(dirty_response).should be true
|
39
|
+
end
|
40
|
+
it "should return false when 2 notices expected and page contains 2 notices" do
|
41
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
shared_examples_for "w3c notices matcher for have greater than or equal to" do
|
46
|
+
let(:method){"have_greater_than_or_equal_to_specified_number_of_#{type}_in"}
|
47
|
+
|
48
|
+
it "should return true when 1 notice expected and page contains 2 notices" do
|
49
|
+
self.send(method,dirty_page,1).matches?(dirty_response).should be true
|
50
|
+
end
|
51
|
+
it "should return true when 2 notices expected and page contains 2 notices" do
|
52
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be true
|
53
|
+
end
|
54
|
+
it "should return false when 3 notices expected and page contains 2 notices" do
|
55
|
+
self.send(method,dirty_page,3).matches?(dirty_response).should be false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
shared_examples_for "w3c notices matcher for have less than" do
|
60
|
+
let(:method){"have_less_than_specified_number_of_#{type}_in"}
|
61
|
+
it "should return true when 3 notice expected and page returns 2 notices" do
|
62
|
+
self.send(method,dirty_page,3).matches?(dirty_response).should be true
|
63
|
+
end
|
64
|
+
it "should return false when 2 notices expected and page returns 2 notices" do
|
65
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
shared_examples_for "w3c notices matcher for have less than or equal to" do
|
70
|
+
let(:method){"have_less_than_or_equal_to_specified_number_of_#{type}_in"}
|
71
|
+
it "should return true when 2 notices expected and page returns 2 notices" do
|
72
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be true
|
73
|
+
end
|
74
|
+
it "should return true when 2 notices expected and page returns 1 notice" do
|
75
|
+
self.send(method,dirty_page,2).matches?(dirty_response).should be true
|
76
|
+
end
|
77
|
+
it "should return false when 1 notice expected and page returns 2 notices" do
|
78
|
+
self.send(method,dirty_page,1).matches?(dirty_response).should be false
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
shared_examples_for "w3c matcher for :== operator" do
|
2
|
+
it "returns true when response contains 0 notices and 0 expected" do
|
3
|
+
klass.new(clean_page,:==,0,type).matches?(clean_response).should be true
|
4
|
+
end
|
5
|
+
it "returns true when response contains 2 notices and 2 expected" do
|
6
|
+
klass.new(dirty_page,:==,2,type).matches?(dirty_response).should be true
|
7
|
+
end
|
8
|
+
it "returns false when response contains 0 notices and 2 expected" do
|
9
|
+
klass.new(dirty_page,:==,2,type).matches?(clean_response).should be false
|
10
|
+
end
|
11
|
+
it "returns false when response contains 2 notices and 0 expected" do
|
12
|
+
klass.new(dirty_page,:==,0,type).matches?(dirty_response).should be false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
shared_examples_for "w3c matcher for :> operator" do
|
18
|
+
it "returns true when response contains 2 notices and >1 expected" do
|
19
|
+
klass.new(dirty_page,:>,1,type).matches?(dirty_response).should be true
|
20
|
+
end
|
21
|
+
it "returns false when response contains 2 notices and >2 expected" do
|
22
|
+
klass.new(dirty_page,:>,2,type).matches?(dirty_response).should be false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
shared_examples_for "w3c matcher for :< operator" do
|
28
|
+
it "returns true when response contains 0 notices and <2 expected" do
|
29
|
+
klass.new(clean_page,:<,2,type).matches?(clean_response).should be true
|
30
|
+
end
|
31
|
+
it "returns false when response contains 2 notices and <2 expected" do
|
32
|
+
klass.new(dirty_page,:<,2,type).matches?(dirty_response).should be false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
shared_examples_for "w3c matcher for :<= operator" do
|
37
|
+
it "returns true when response contains 2 notices and <=2 expected" do
|
38
|
+
klass.new(dirty_page,:<=,2,type).matches?(dirty_response).should be true
|
39
|
+
end
|
40
|
+
it "returns true when response contains 2 notices and <=1 expected" do
|
41
|
+
klass.new(dirty_page,:<=,1,type).matches?(dirty_response).should be false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
shared_examples_for "w3c matcher for :>= operator" do
|
46
|
+
it "returns true when response contains 2 notices and >=2 expected" do
|
47
|
+
klass.new(dirty_page,:>=,2,type).matches?(dirty_response).should be true
|
48
|
+
end
|
49
|
+
it "returns true when response contains 0 notices and >=2 expected" do
|
50
|
+
klass.new(clean_page,:>=,2,type).matches?(clean_response).should be false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
shared_examples_for "w3c matcher with description when none provided" do
|
55
|
+
let(:regexp){Regexp.new("^should receive 0 W3C validation #{type} in")}
|
56
|
+
it "returns proper description" do
|
57
|
+
matcher = klass.new(dirty_page,:==,0,type)
|
58
|
+
matcher.matches?(dirty_response)
|
59
|
+
regexp.match(matcher.description).should_not be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
shared_examples_for "w3c matcher with detailed notice reporting" do
|
64
|
+
let(:regexp_should_header){Regexp.new("Expected (?<expected>\\d+) W3C validation #{type.to_s}? but received (?<actual>\\d+) #{type.to_s}?")}
|
65
|
+
let(:regexp_should_not_header){Regexp.new("Did not expect (?<expected>\\d+) W3C validation #{type.to_s}? but received (?<actual>\\d+) #{type.to_s}?")}
|
66
|
+
|
67
|
+
context ":failure_message_for_should" do
|
68
|
+
before(:each) do
|
69
|
+
@matcher = klass.new(dirty_page,:==,0,type)
|
70
|
+
@matcher.matches?(dirty_response)
|
71
|
+
@matcher
|
72
|
+
end
|
73
|
+
|
74
|
+
let(:msg){@matcher.failure_message_for_should.split("\n")}
|
75
|
+
|
76
|
+
it "returns proper header" do
|
77
|
+
num_matches(msg, regexp_should_header).should be 1
|
78
|
+
end
|
79
|
+
it_behaves_like "w3c detailed notices"
|
80
|
+
end
|
81
|
+
|
82
|
+
context ":failure_message_for_should_not" do
|
83
|
+
before(:each) do
|
84
|
+
@matcher = klass.new(dirty_page,:==,2,type)
|
85
|
+
@matcher.matches?(dirty_response)
|
86
|
+
@matcher
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:matcher){@matcher}
|
90
|
+
let(:msg){@matcher.failure_message_for_should_not.split("\n")}
|
91
|
+
|
92
|
+
it "returns proper header" do
|
93
|
+
num_matches(msg,regexp_should_not_header).should be 1
|
94
|
+
end
|
95
|
+
it_behaves_like "w3c detailed notices"
|
96
|
+
end
|
97
|
+
|
98
|
+
def num_matches(array,regexp)
|
99
|
+
array.map do |string|
|
100
|
+
string =~ regexp
|
101
|
+
end.keep_if do |value| value == 0 end.length
|
102
|
+
end
|
103
|
+
|
104
|
+
def num_notices(array)
|
105
|
+
array.map do |string|
|
106
|
+
matches = /#{type.to_s.capitalize}s?: (\d+)/.match(string)
|
107
|
+
matches.nil? ? nil : matches[1].to_i
|
108
|
+
end.keep_if do |value| !value.nil? end.first
|
109
|
+
end
|
110
|
+
|
111
|
+
def expected_notices(array)
|
112
|
+
abc = array.map do |string|
|
113
|
+
|
114
|
+
if (matches = regexp_should_header.match(string)) || (matches = regexp_should_not_header.match(string))
|
115
|
+
matches['expected'].to_i
|
116
|
+
else
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
end.keep_if do |value| !value.nil? end.first
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
shared_examples_for "w3c detailed notices" do
|
124
|
+
it "returns proper validator string" do
|
125
|
+
num_matches(msg,/^\s*Checked by: \S+/).should be 1
|
126
|
+
end
|
127
|
+
it "returns proper character set" do
|
128
|
+
num_matches(msg,/^\s*Character set: \S+/).should be 1
|
129
|
+
end
|
130
|
+
it "returns proper number of notices" do
|
131
|
+
num_matches(msg,/^\s*#{type.to_s.capitalize}s?: \S+/).should be 1
|
132
|
+
end
|
133
|
+
it "returns Type declaration for every notice" do
|
134
|
+
num_matches(msg,/^\s*Type: #{type}?/).should be num_notices(msg)
|
135
|
+
end
|
136
|
+
it "returns Location declaration for every notice" do
|
137
|
+
num_matches(msg,/^\s*Location: line \S+ column \S+/).should be num_notices(msg)
|
138
|
+
end
|
139
|
+
it "returns URI declaration for every notice" do
|
140
|
+
num_matches(msg,/^\s*URI: .*/).should be num_notices(msg)
|
141
|
+
end
|
142
|
+
it "returns Message declaration for every notice" do
|
143
|
+
num_matches(msg,/^\s*Message: .*/).should be num_notices(msg)
|
144
|
+
end
|
145
|
+
it "returns expected number of Source declarations" do
|
146
|
+
num_matches(msg,/^\s*Source \(line \d*\): .*/).should be num_notices(msg)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'rspec_w3c_matchers'
|
4
|
+
|
5
|
+
require 'shared_examples/notice_matcher'
|
6
|
+
require 'shared_examples/matchers'
|
7
|
+
require 'responses/responses'
|
8
|
+
|
9
|
+
Rspec.configure do |config|
|
10
|
+
# c.mock_with :mocha
|
11
|
+
APP = RspecW3cMatchers
|
12
|
+
|
13
|
+
# include the matchers
|
14
|
+
config.include(APP::InstanceMethods)
|
15
|
+
end
|
16
|
+
|
Binary file
|
data/tasks/fixtures.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/rspec_w3c_matchers')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec/responses/responses')
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
|
6
|
+
# used for providing fixtures to users of the gem
|
7
|
+
namespace :fixtures do
|
8
|
+
desc 'generate all fixtures for USERS of the GEM'
|
9
|
+
task :all => [:valid,:error,:warning]
|
10
|
+
|
11
|
+
desc 'generate fixture sample valid response'
|
12
|
+
task :valid => :repository do
|
13
|
+
dump W3CValidators::MarkupValidator.new.validate_text(response.valid.html),:valid
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'generate fixture sample error response'
|
17
|
+
task :error => :repository do
|
18
|
+
dump W3CValidators::MarkupValidator.new.validate_text(response.error.html),:error
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'generate fixture sample error response'
|
22
|
+
task :warning => :repository do
|
23
|
+
dump W3CValidators::MarkupValidator.new.validate_text(response.warning.html),:warning
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'removing all fixture files'
|
27
|
+
task :clean do
|
28
|
+
files = Dir.glob "#{repo_dir}*.marshal"
|
29
|
+
if files.empty?
|
30
|
+
puts 'nothing to remove'
|
31
|
+
else
|
32
|
+
puts "removing files #{files}"
|
33
|
+
FileUtils.rm files
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'create directory for Fixtures'
|
38
|
+
task :repository do
|
39
|
+
repo = repo_dir
|
40
|
+
unless File.exists? repo
|
41
|
+
puts "generating directory #{repo}"
|
42
|
+
FileUtils.mkdir_p repo
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# helper methods for configuration
|
48
|
+
def config_dir
|
49
|
+
File.expand_path(File.dirname(__FILE__) + '/../')
|
50
|
+
end
|
51
|
+
|
52
|
+
def repo_dir
|
53
|
+
config_dir + '/spec/fixtures/'
|
54
|
+
end
|
55
|
+
|
56
|
+
def dump(data,fname)
|
57
|
+
puts "generating file #{fname}"
|
58
|
+
file = File.open(repo_dir + fname.to_s + '.marshal','w')
|
59
|
+
file.write(Marshal.dump(data))
|
60
|
+
file.close
|
61
|
+
end
|
62
|
+
|
63
|
+
def response
|
64
|
+
SampleResponses
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec_w3c_matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Takaltoo
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-18 00:00:00 -08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: w3c_validators
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 1
|
31
|
+
- 1
|
32
|
+
version: 1.1.1
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
- 3
|
46
|
+
- 0
|
47
|
+
version: 2.3.0
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
description: " add description"
|
51
|
+
email:
|
52
|
+
- pouya@lavabit.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- .gitignore
|
61
|
+
- Gemfile
|
62
|
+
- README.rdoc
|
63
|
+
- Rakefile
|
64
|
+
- lib/rspec_w3c_matchers.rb
|
65
|
+
- lib/rspec_w3c_matchers/matchers.rb
|
66
|
+
- lib/rspec_w3c_matchers/notices.rb
|
67
|
+
- lib/rspec_w3c_matchers/version.rb
|
68
|
+
- rspec_w3c_matchers.gemspec
|
69
|
+
- spec/base/matchers_spec.rb
|
70
|
+
- spec/base/notices_spec.rb
|
71
|
+
- spec/base/version_spec.rb
|
72
|
+
- spec/fixtures/error.marshal
|
73
|
+
- spec/fixtures/valid.marshal
|
74
|
+
- spec/fixtures/warning.marshal
|
75
|
+
- spec/responses/error.rb
|
76
|
+
- spec/responses/responses.rb
|
77
|
+
- spec/responses/valid.rb
|
78
|
+
- spec/responses/warning.rb
|
79
|
+
- spec/shared_examples/matchers.rb
|
80
|
+
- spec/shared_examples/notice_matcher.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- tasks/.fixtures.rb.swp
|
83
|
+
- tasks/fixtures.rb
|
84
|
+
has_rdoc: true
|
85
|
+
homepage: http://rubygems.org/gems/rspec_w3c_matchers
|
86
|
+
licenses: []
|
87
|
+
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
requirements: []
|
110
|
+
|
111
|
+
rubyforge_project: rspec_w3c_matchers
|
112
|
+
rubygems_version: 1.3.7
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: Rspec 2.0 matchers that detect and report detailed error and warning responses from w3c_validators GEM.
|
116
|
+
test_files: []
|
117
|
+
|