wycats-merb-core 0.9.8
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/CHANGELOG +992 -0
- data/CONTRIBUTORS +94 -0
- data/LICENSE +20 -0
- data/PUBLIC_CHANGELOG +142 -0
- data/README +21 -0
- data/Rakefile +458 -0
- data/TODO +0 -0
- data/bin/merb +11 -0
- data/bin/merb-specs +5 -0
- data/lib/merb-core.rb +598 -0
- data/lib/merb-core/autoload.rb +31 -0
- data/lib/merb-core/bootloader.rb +717 -0
- data/lib/merb-core/config.rb +305 -0
- data/lib/merb-core/constants.rb +45 -0
- data/lib/merb-core/controller/abstract_controller.rb +568 -0
- data/lib/merb-core/controller/exceptions.rb +315 -0
- data/lib/merb-core/controller/merb_controller.rb +256 -0
- data/lib/merb-core/controller/mime.rb +107 -0
- data/lib/merb-core/controller/mixins/authentication.rb +123 -0
- data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
- data/lib/merb-core/controller/mixins/controller.rb +319 -0
- data/lib/merb-core/controller/mixins/render.rb +513 -0
- data/lib/merb-core/controller/mixins/responder.rb +469 -0
- data/lib/merb-core/controller/template.rb +254 -0
- data/lib/merb-core/core_ext.rb +9 -0
- data/lib/merb-core/core_ext/hash.rb +7 -0
- data/lib/merb-core/core_ext/kernel.rb +340 -0
- data/lib/merb-core/dispatch/cookies.rb +130 -0
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +93 -0
- data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +198 -0
- data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +73 -0
- data/lib/merb-core/dispatch/default_exception/views/index.html.erb +94 -0
- data/lib/merb-core/dispatch/dispatcher.rb +176 -0
- data/lib/merb-core/dispatch/request.rb +729 -0
- data/lib/merb-core/dispatch/router.rb +151 -0
- data/lib/merb-core/dispatch/router/behavior.rb +566 -0
- data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
- data/lib/merb-core/dispatch/router/resources.rb +191 -0
- data/lib/merb-core/dispatch/router/route.rb +511 -0
- data/lib/merb-core/dispatch/session.rb +222 -0
- data/lib/merb-core/dispatch/session/container.rb +74 -0
- data/lib/merb-core/dispatch/session/cookie.rb +173 -0
- data/lib/merb-core/dispatch/session/memcached.rb +68 -0
- data/lib/merb-core/dispatch/session/memory.rb +99 -0
- data/lib/merb-core/dispatch/session/store_container.rb +150 -0
- data/lib/merb-core/dispatch/worker.rb +28 -0
- data/lib/merb-core/gem_ext/erubis.rb +77 -0
- data/lib/merb-core/logger.rb +203 -0
- data/lib/merb-core/plugins.rb +67 -0
- data/lib/merb-core/rack.rb +25 -0
- data/lib/merb-core/rack/adapter.rb +44 -0
- data/lib/merb-core/rack/adapter/ebb.rb +25 -0
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
- data/lib/merb-core/rack/adapter/irb.rb +118 -0
- data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/runner.rb +28 -0
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/thin.rb +39 -0
- data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
- data/lib/merb-core/rack/adapter/webrick.rb +36 -0
- data/lib/merb-core/rack/application.rb +32 -0
- data/lib/merb-core/rack/handler/mongrel.rb +97 -0
- data/lib/merb-core/rack/middleware.rb +20 -0
- data/lib/merb-core/rack/middleware/conditional_get.rb +29 -0
- data/lib/merb-core/rack/middleware/content_length.rb +18 -0
- data/lib/merb-core/rack/middleware/csrf.rb +73 -0
- data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
- data/lib/merb-core/rack/middleware/profiler.rb +19 -0
- data/lib/merb-core/rack/middleware/static.rb +45 -0
- data/lib/merb-core/rack/middleware/tracer.rb +20 -0
- data/lib/merb-core/server.rb +284 -0
- data/lib/merb-core/tasks/audit.rake +68 -0
- data/lib/merb-core/tasks/gem_management.rb +229 -0
- data/lib/merb-core/tasks/merb.rb +1 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +80 -0
- data/lib/merb-core/tasks/stats.rake +71 -0
- data/lib/merb-core/test.rb +11 -0
- data/lib/merb-core/test/helpers.rb +9 -0
- data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
- data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
- data/lib/merb-core/test/helpers/request_helper.rb +393 -0
- data/lib/merb-core/test/helpers/route_helper.rb +39 -0
- data/lib/merb-core/test/helpers/view_helper.rb +121 -0
- data/lib/merb-core/test/matchers.rb +9 -0
- data/lib/merb-core/test/matchers/controller_matchers.rb +351 -0
- data/lib/merb-core/test/matchers/route_matchers.rb +137 -0
- data/lib/merb-core/test/matchers/view_matchers.rb +375 -0
- data/lib/merb-core/test/run_specs.rb +49 -0
- data/lib/merb-core/test/tasks/spectasks.rb +68 -0
- data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
- data/lib/merb-core/test/test_ext/object.rb +14 -0
- data/lib/merb-core/test/test_ext/string.rb +14 -0
- data/lib/merb-core/vendor/facets.rb +2 -0
- data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
- data/lib/merb-core/vendor/facets/inflect.rb +342 -0
- data/lib/merb-core/version.rb +3 -0
- metadata +253 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
module Merb::Test::Rspec::RouteMatchers
|
2
|
+
|
3
|
+
class RouteToMatcher
|
4
|
+
|
5
|
+
# ==== Parameters
|
6
|
+
# klass_or_name<Class, String>::
|
7
|
+
# The controller class or class name to match routes for.
|
8
|
+
# action<~to_s>:: The name of the action to match routes for.
|
9
|
+
def initialize(klass_or_name, action)
|
10
|
+
@expected_controller = Class === klass_or_name ? klass_or_name.name : klass_or_name
|
11
|
+
@expected_action = action.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
# ==== Parameters
|
15
|
+
# target<Hash>:: The route parameters to match.
|
16
|
+
#
|
17
|
+
# ==== Returns
|
18
|
+
# Boolean:: True if the controller action and parameters match.
|
19
|
+
def matches?(target)
|
20
|
+
@target_env = target.dup
|
21
|
+
@target_controller, @target_action = @target_env.delete(:controller).to_s, @target_env.delete(:action).to_s
|
22
|
+
|
23
|
+
@target_controller = "#{target.delete(:namespace)}::#{@target_controller}" if target.has_key?(:namespace)
|
24
|
+
|
25
|
+
@expected_controller.snake_case == @target_controller.snake_case && @expected_action == @target_action && match_parameters(@target_env)
|
26
|
+
end
|
27
|
+
|
28
|
+
# ==== Parameters
|
29
|
+
# target<Hash>:: The route parameters to match.
|
30
|
+
#
|
31
|
+
# ==== Returns
|
32
|
+
# Boolean::
|
33
|
+
# True if the parameter matcher created with #with matches or if no
|
34
|
+
# parameter matcher exists.
|
35
|
+
def match_parameters(target)
|
36
|
+
@parameter_matcher.nil? ? true : @parameter_matcher.matches?(target)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a new paramter matcher.
|
40
|
+
#
|
41
|
+
# ==== Parameters
|
42
|
+
# parameters<Hash, ~to_param>:: The parameters to match.
|
43
|
+
#
|
44
|
+
# ==== Returns
|
45
|
+
# RouteToMatcher:: This matcher.
|
46
|
+
#
|
47
|
+
# ==== Alternatives
|
48
|
+
# If parameters is an object, then a new expected hash will be constructed
|
49
|
+
# with the key :id set to parameters.to_param.
|
50
|
+
def with(parameters)
|
51
|
+
@parameter_matcher = ParameterMatcher.new(parameters)
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
# ==== Returns
|
57
|
+
# String:: The failure message.
|
58
|
+
def failure_message
|
59
|
+
"expected the request to route to #{@expected_controller.camel_case}##{@expected_action}#{expected_parameters_message}, but was #{@target_controller.camel_case}##{@target_action}#{actual_parameters_message}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# ==== Returns
|
63
|
+
# String:: The failure message to be displayed in negative matches.
|
64
|
+
def negative_failure_message
|
65
|
+
"expected the request not to route to #{@expected_controller.camel_case}##{@expected_action}#{expected_parameters_message}, but it did"
|
66
|
+
end
|
67
|
+
|
68
|
+
def expected_parameters_message
|
69
|
+
" with #{@parameter_matcher.expected.inspect}" if @parameter_matcher
|
70
|
+
end
|
71
|
+
|
72
|
+
def actual_parameters_message
|
73
|
+
" with #{(@parameter_matcher.actual || {}).inspect}" if @parameter_matcher
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class ParameterMatcher
|
78
|
+
attr_accessor :expected, :actual
|
79
|
+
|
80
|
+
# ==== Parameters
|
81
|
+
# hash_or_object<Hash, ~to_param>:: The parameters to match.
|
82
|
+
#
|
83
|
+
# ==== Alternatives
|
84
|
+
# If hash_or_object is an object, then a new expected hash will be
|
85
|
+
# constructed with the key :id set to hash_or_object.to_param.
|
86
|
+
def initialize(hash_or_object)
|
87
|
+
@expected = {}
|
88
|
+
case hash_or_object
|
89
|
+
when Hash then @expected = hash_or_object
|
90
|
+
else @expected[:id] = hash_or_object.to_param
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# ==== Parameters
|
95
|
+
# parameter_hash<Hash>:: The route parameters to match.
|
96
|
+
#
|
97
|
+
# ==== Returns
|
98
|
+
# Boolean:: True if the route parameters match the expected ones.
|
99
|
+
def matches?(parameter_hash)
|
100
|
+
@actual = parameter_hash.dup.except(:controller, :action)
|
101
|
+
|
102
|
+
return @actual.empty? if @expected.empty?
|
103
|
+
@expected.all? {|(k, v)| @actual.has_key?(k) && @actual[k] == v}
|
104
|
+
end
|
105
|
+
|
106
|
+
# ==== Returns
|
107
|
+
# String:: The failure message.
|
108
|
+
def failure_message
|
109
|
+
"expected the route to contain parameters #{@expected.inspect}, but instead contained #{@actual.inspect}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# ==== Returns
|
113
|
+
# String:: The failure message to be displayed in negative matches.
|
114
|
+
def negative_failure_message
|
115
|
+
"expected the route not to contain parameters #{@expected.inspect}, but it did"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Passes when the actual route parameters match the expected controller class
|
120
|
+
# and controller action. Exposes a +with+ method for specifying parameters.
|
121
|
+
#
|
122
|
+
# ==== Parameters
|
123
|
+
# klass_or_name<Class, String>::
|
124
|
+
# The controller class or class name to match routes for.
|
125
|
+
# action<~to_s>:: The name of the action to match routes for.
|
126
|
+
#
|
127
|
+
# ==== Example
|
128
|
+
# # Passes if a GET request to "/" is routed to the Widgets controller's
|
129
|
+
# # index action.
|
130
|
+
# request_to("/", :get).should route_to(Widgets, :index)
|
131
|
+
#
|
132
|
+
# # Use the 'with' method for parameter checks
|
133
|
+
# request_to("/123").should route_to(widgets, :show).with(:id => "123")
|
134
|
+
def route_to(klass_or_name, action)
|
135
|
+
RouteToMatcher.new(klass_or_name, action)
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,375 @@
|
|
1
|
+
module Merb::Test::Rspec::ViewMatchers
|
2
|
+
class HaveXpath
|
3
|
+
def initialize(expected)
|
4
|
+
@expected = expected
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(stringlike)
|
8
|
+
@document = case stringlike
|
9
|
+
when LibXML::XML::Document, LibXML::XML::Node
|
10
|
+
stringlike
|
11
|
+
when StringIO
|
12
|
+
LibXML::XML::HTMLParser.string(stringlike.string).parse
|
13
|
+
else
|
14
|
+
LibXML::XML::HTMLParser.string(stringlike).parse
|
15
|
+
end
|
16
|
+
!@document.find(@expected).empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
# ==== Returns
|
20
|
+
# String:: The failure message.
|
21
|
+
def failure_message
|
22
|
+
"expected following text to match xpath #{@expected}:\n#{@document}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# ==== Returns
|
26
|
+
# String:: The failure message to be displayed in negative matches.
|
27
|
+
def negative_failure_message
|
28
|
+
"expected following text to not match xpath #{@expected}:\n#{@document}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class HaveSelector
|
33
|
+
|
34
|
+
# ==== Parameters
|
35
|
+
# expected<String>:: The string to look for.
|
36
|
+
def initialize(expected)
|
37
|
+
@expected = expected
|
38
|
+
end
|
39
|
+
|
40
|
+
# ==== Parameters
|
41
|
+
# stringlike<Hpricot::Elem, StringIO, String>:: The thing to search in.
|
42
|
+
#
|
43
|
+
# ==== Returns
|
44
|
+
# Boolean:: True if there was at least one match.
|
45
|
+
def matches?(stringlike)
|
46
|
+
@document = case stringlike
|
47
|
+
when Hpricot::Elem
|
48
|
+
stringlike
|
49
|
+
when StringIO
|
50
|
+
Hpricot.parse(stringlike.string)
|
51
|
+
else
|
52
|
+
Hpricot.parse(stringlike)
|
53
|
+
end
|
54
|
+
!@document.search(@expected).empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
# ==== Returns
|
58
|
+
# String:: The failure message.
|
59
|
+
def failure_message
|
60
|
+
"expected following text to match selector #{@expected}:\n#{@document}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# ==== Returns
|
64
|
+
# String:: The failure message to be displayed in negative matches.
|
65
|
+
def negative_failure_message
|
66
|
+
"expected following text to not match selector #{@expected}:\n#{@document}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class MatchTag
|
71
|
+
|
72
|
+
# ==== Parameters
|
73
|
+
# name<~to_s>:: The name of the tag to look for.
|
74
|
+
# attrs<Hash>:: Attributes to look for in the tag (see below).
|
75
|
+
#
|
76
|
+
# ==== Options (attrs)
|
77
|
+
# :content<String>:: Optional content to match.
|
78
|
+
def initialize(name, attrs)
|
79
|
+
@name, @attrs = name, attrs
|
80
|
+
@content = @attrs.delete(:content)
|
81
|
+
end
|
82
|
+
|
83
|
+
# ==== Parameters
|
84
|
+
# target<String>:: The string to look for the tag in.
|
85
|
+
#
|
86
|
+
# ==== Returns
|
87
|
+
# Boolean:: True if the tag matched.
|
88
|
+
def matches?(target)
|
89
|
+
@errors = []
|
90
|
+
unless target.include?("<#{@name}")
|
91
|
+
@errors << "Expected a <#{@name}>, but was #{target}"
|
92
|
+
end
|
93
|
+
@attrs.each do |attr, val|
|
94
|
+
unless target.include?("#{attr}=\"#{val}\"")
|
95
|
+
@errors << "Expected #{attr}=\"#{val}\", but was #{target}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
if @content
|
99
|
+
unless target.include?(">#{@content}<")
|
100
|
+
@errors << "Expected #{target} to include #{@content}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
@errors.size == 0
|
104
|
+
end
|
105
|
+
|
106
|
+
# ==== Returns
|
107
|
+
# String:: The failure message.
|
108
|
+
def failure_message
|
109
|
+
@errors[0]
|
110
|
+
end
|
111
|
+
|
112
|
+
# ==== Returns
|
113
|
+
# String:: The failure message to be displayed in negative matches.
|
114
|
+
def negative_failure_message
|
115
|
+
"Expected not to match against <#{@name} #{@attrs.map{ |a,v| "#{a}=\"#{v}\"" }.join(" ")}> tag, but it matched"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class NotMatchTag
|
120
|
+
|
121
|
+
# === Parameters
|
122
|
+
# attrs<Hash>:: A set of attributes that must not be matched.
|
123
|
+
def initialize(attrs)
|
124
|
+
@attrs = attrs
|
125
|
+
end
|
126
|
+
|
127
|
+
# ==== Parameters
|
128
|
+
# target<String>:: The target to look for the match in.
|
129
|
+
#
|
130
|
+
# ==== Returns
|
131
|
+
# Boolean:: True if none of the attributes were matched.
|
132
|
+
def matches?(target)
|
133
|
+
@errors = []
|
134
|
+
@attrs.each do |attr, val|
|
135
|
+
if target.include?("#{attr}=\"#{val}\"")
|
136
|
+
@errors << "Should not include #{attr}=\"#{val}\", but was #{target}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
@errors.size == 0
|
140
|
+
end
|
141
|
+
|
142
|
+
# ==== Returns
|
143
|
+
# String:: The failure message.
|
144
|
+
def failure_message
|
145
|
+
@errors[0]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class HasTag
|
150
|
+
|
151
|
+
# ==== Parameters
|
152
|
+
# tag<~to_s>:: The tag to look for.
|
153
|
+
# attributes<Hash>:: Attributes for the tag (see below).
|
154
|
+
def initialize(tag, attributes = {}, &blk)
|
155
|
+
@tag, @attributes = tag, attributes
|
156
|
+
@id, @class = @attributes.delete(:id), @attributes.delete(:class)
|
157
|
+
@blk = blk
|
158
|
+
end
|
159
|
+
|
160
|
+
# ==== Parameters
|
161
|
+
# stringlike<Hpricot::Elem, StringIO, String>:: The thing to search in.
|
162
|
+
# &blk:: An optional block for searching in child elements using with_tag.
|
163
|
+
#
|
164
|
+
# ==== Returns
|
165
|
+
# Boolean:: True if there was at least one match.
|
166
|
+
def matches?(stringlike, &blk)
|
167
|
+
@document = case stringlike
|
168
|
+
when Hpricot::Elem
|
169
|
+
stringlike
|
170
|
+
when StringIO
|
171
|
+
Hpricot.parse(stringlike.string)
|
172
|
+
else
|
173
|
+
Hpricot.parse(stringlike)
|
174
|
+
end
|
175
|
+
|
176
|
+
@blk = blk unless blk.nil?
|
177
|
+
|
178
|
+
unless @blk.nil?
|
179
|
+
!@document.search(selector).select do |ele|
|
180
|
+
@blk.call ele
|
181
|
+
true
|
182
|
+
end.empty?
|
183
|
+
else
|
184
|
+
!@document.search(selector).empty?
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# ==== Returns
|
189
|
+
# String:: The complete selector for element queries.
|
190
|
+
def selector
|
191
|
+
@selector = "//#{@tag}#{id_selector}#{class_selector}"
|
192
|
+
@selector << @attributes.map{|a, v| "[@#{a}=\"#{v}\"]"}.join
|
193
|
+
|
194
|
+
@selector << @inner_has_tag.selector unless @inner_has_tag.nil?
|
195
|
+
|
196
|
+
@selector
|
197
|
+
end
|
198
|
+
|
199
|
+
# ==== Returns
|
200
|
+
# String:: ID selector for use in element queries.
|
201
|
+
def id_selector
|
202
|
+
"##{@id}" if @id
|
203
|
+
end
|
204
|
+
|
205
|
+
# ==== Returns
|
206
|
+
# String:: Class selector for use in element queries.
|
207
|
+
def class_selector
|
208
|
+
".#{@class}" if @class
|
209
|
+
end
|
210
|
+
|
211
|
+
# ==== Returns
|
212
|
+
# String:: The failure message.
|
213
|
+
def failure_message
|
214
|
+
"expected following output to contain a #{tag_for_error} tag:\n#{@document}"
|
215
|
+
end
|
216
|
+
|
217
|
+
# ==== Returns
|
218
|
+
# String:: The failure message to be displayed in negative matches.
|
219
|
+
def negative_failure_message
|
220
|
+
"expected following output to omit a #{tag_for_error} tag:\n#{@document}"
|
221
|
+
end
|
222
|
+
|
223
|
+
# ==== Returns
|
224
|
+
# String:: The tag used in failure messages.
|
225
|
+
def tag_for_error
|
226
|
+
"#{inner_failure_message}<#{@tag}#{id_for_error}#{class_for_error}#{attributes_for_error}>"
|
227
|
+
end
|
228
|
+
|
229
|
+
# ==== Returns
|
230
|
+
# String::
|
231
|
+
# The failure message to be displayed in negative matches within the
|
232
|
+
# have_tag block.
|
233
|
+
def inner_failure_message
|
234
|
+
"#{@inner_has_tag.tag_for_error} tag within a " unless @inner_has_tag.nil?
|
235
|
+
end
|
236
|
+
|
237
|
+
# ==== Returns
|
238
|
+
# String:: ID for the error tag.
|
239
|
+
def id_for_error
|
240
|
+
" id=\"#{@id}\"" unless @id.nil?
|
241
|
+
end
|
242
|
+
|
243
|
+
# ==== Returns
|
244
|
+
# String:: Class for the error tag.
|
245
|
+
def class_for_error
|
246
|
+
" class=\"#{@class}\"" unless @class.nil?
|
247
|
+
end
|
248
|
+
|
249
|
+
# ==== Returns
|
250
|
+
# String:: Class for the error tag.
|
251
|
+
def attributes_for_error
|
252
|
+
@attributes.map{|a,v| " #{a}=\"#{v}\""}.join
|
253
|
+
end
|
254
|
+
|
255
|
+
# Search for a child tag within a have_tag block.
|
256
|
+
#
|
257
|
+
# ==== Parameters
|
258
|
+
# tag<~to_s>:: The tag to look for.
|
259
|
+
# attributes<Hash>:: Attributes for the tag (see below).
|
260
|
+
def with_tag(name, attrs={})
|
261
|
+
@inner_has_tag = HasTag.new(name, attrs)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
class HasContent
|
266
|
+
def initialize(content)
|
267
|
+
@content = content
|
268
|
+
end
|
269
|
+
|
270
|
+
def matches?(element)
|
271
|
+
@element = element
|
272
|
+
|
273
|
+
case @content
|
274
|
+
when String
|
275
|
+
@element.contains?(@content)
|
276
|
+
when Regexp
|
277
|
+
@element.matches?(@content)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# ==== Returns
|
282
|
+
# String:: The failure message.
|
283
|
+
def failure_message
|
284
|
+
"expected the following element's content to #{content_message}:\n#{@element.inner_text}"
|
285
|
+
end
|
286
|
+
|
287
|
+
# ==== Returns
|
288
|
+
# String:: The failure message to be displayed in negative matches.
|
289
|
+
def negative_failure_message
|
290
|
+
"expected the following element's content to not #{content_message}:\n#{@element.inner_text}"
|
291
|
+
end
|
292
|
+
|
293
|
+
def content_message
|
294
|
+
case @content
|
295
|
+
when String
|
296
|
+
"include \"#{@content}\""
|
297
|
+
when Regexp
|
298
|
+
"match #{@content.inspect}"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# ==== Parameters
|
304
|
+
# name<~to_s>:: The name of the tag to look for.
|
305
|
+
# attrs<Hash>:: Attributes to look for in the tag (see below).
|
306
|
+
#
|
307
|
+
# ==== Options (attrs)
|
308
|
+
# :content<String>:: Optional content to match.
|
309
|
+
#
|
310
|
+
# ==== Returns
|
311
|
+
# MatchTag:: A new match tag matcher.
|
312
|
+
def match_tag(name, attrs={})
|
313
|
+
MatchTag.new(name, attrs)
|
314
|
+
end
|
315
|
+
|
316
|
+
# ==== Parameters
|
317
|
+
# attrs<Hash>:: A set of attributes that must not be matched.
|
318
|
+
#
|
319
|
+
# ==== Returns
|
320
|
+
# NotMatchTag:: A new not match tag matcher.
|
321
|
+
def not_match_tag(attrs)
|
322
|
+
NotMatchTag.new(attrs)
|
323
|
+
end
|
324
|
+
|
325
|
+
# ==== Parameters
|
326
|
+
# expected<String>:: The string to look for.
|
327
|
+
#
|
328
|
+
# ==== Returns
|
329
|
+
# HaveSelector:: A new have selector matcher.
|
330
|
+
def have_selector(expected)
|
331
|
+
HaveSelector.new(expected)
|
332
|
+
end
|
333
|
+
alias_method :match_selector, :have_selector
|
334
|
+
|
335
|
+
def have_xpath(expected)
|
336
|
+
begin
|
337
|
+
require "libxml"
|
338
|
+
rescue LoadError => e
|
339
|
+
puts "To use have_xpath helper you need to install libxml-ruby gem"
|
340
|
+
end
|
341
|
+
HaveXpath.new(expected)
|
342
|
+
end
|
343
|
+
alias_method :match_xpath, :have_xpath
|
344
|
+
|
345
|
+
# RSpec matcher to test for the presence of tags.
|
346
|
+
#
|
347
|
+
# ==== Parameters
|
348
|
+
# tag<~to_s>:: The name of the tag.
|
349
|
+
# attributes<Hash>:: Tag attributes.
|
350
|
+
#
|
351
|
+
# ==== Returns
|
352
|
+
# HasTag:: A new has tag matcher.
|
353
|
+
#
|
354
|
+
# ==== Examples
|
355
|
+
# # Check for <div>
|
356
|
+
# body.should have_tag("div")
|
357
|
+
#
|
358
|
+
# # Check for <span id="notice">
|
359
|
+
# body.should have_tag("span", :id => :notice)
|
360
|
+
#
|
361
|
+
# # Check for <h1 id="foo" class="bar">
|
362
|
+
# body.should have_tag(:h2, :class => "bar", :id => "foo")
|
363
|
+
#
|
364
|
+
# # Check for <div attr="val">
|
365
|
+
# body.should have_tag(:div, :attr => :val)
|
366
|
+
def have_tag(tag, attributes = {}, &blk)
|
367
|
+
HasTag.new(tag, attributes, &blk)
|
368
|
+
end
|
369
|
+
|
370
|
+
alias_method :with_tag, :have_tag
|
371
|
+
|
372
|
+
def contain(content)
|
373
|
+
HasContent.new(content)
|
374
|
+
end
|
375
|
+
end
|