rspec2-rails-views-matchers 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +0,0 @@
1
- require 'rspec/rails/views/matchers/have_tag'
@@ -1,325 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module RSpec
4
- module Matchers
5
-
6
- # @api
7
- # @private
8
- class NokogiriMatcher
9
- attr_reader :failure_message
10
- attr_reader :parent_scope, :current_scope
11
-
12
- def initialize tag, options={}, &block
13
- @tag, @options, @block = tag.to_s, options, block
14
-
15
- if attrs = @options.delete(:with)
16
- if classes=attrs.delete(:class)
17
- classes = case classes
18
- when Array
19
- classes.join('.')
20
- when String
21
- classes.gsub("\s",'.')
22
- end
23
- @tag << '.'+classes
24
- end
25
- html_attrs_string=''
26
- attrs.each_pair { |k,v| html_attrs_string << %Q{[#{k.to_s}='#{v.to_s}']} }
27
- @tag << html_attrs_string
28
- end
29
-
30
- # TODO add min and max processing
31
- @options[:minimum] ||= @options.delete(:min)
32
- @options[:maximum] ||= @options.delete(:max)
33
- end
34
-
35
- def matches? document, &block
36
- @block = block if block
37
-
38
- case document
39
- when String
40
- @parent_scope = @current_scope = Nokogiri::HTML(document).css(@tag)
41
- @document = document
42
- else
43
- @parent_scope = document.current_scope
44
- @current_scope = document.parent_scope.css(@tag)
45
- @document = @parent_scope.to_html
46
- end
47
-
48
- if tag_presents? and content_right? and count_right?
49
- @current_scope = @parent_scope
50
- @block.call if @block
51
- true
52
- else
53
- false
54
- end
55
- end
56
-
57
- private
58
-
59
- def tag_presents?
60
- if @current_scope.first
61
- @count = @current_scope.count
62
- true
63
- else
64
- @failure_message = %Q{expected following:\n#{@document}\nto have at least 1 element matching "#{@tag}", found 0.}
65
- false
66
- end
67
- end
68
-
69
- def count_right?
70
- case @options[:count]
71
- when Integer
72
- @count == @options[:count] || (@failure_message=%Q{expected following:\n#{@document}\nto have #{@options[:count]} element(s) matching "#{@tag}", found #{@count}.}; false)
73
- when Range
74
- @options[:count].member?(@count) || (@failure_message=%Q{expected following:\n#{@document}\nto have at least #{@options[:count].min} and at most #{@options[:count].max} element(s) matching "#{@tag}", found #{@count}.}; false)
75
- when nil
76
- if @options[:maximum]
77
- @count <= @options[:maximum] || (@failure_message=%Q{expected following:\n#{@document}\nto have at most #{@options[:maximum]} element(s) matching "#{@tag}", found #{@count}.}; false)
78
- elsif @options[:minimum]
79
- @count >= @options[:minimum] || (@failure_message=%Q{expected following:\n#{@document}\nto have at least #{@options[:minimum]} element(s) matching "#{@tag}", found #{@count}.}; false)
80
- else
81
- true
82
- end
83
- else
84
- @failure_message = 'wrong count specified'
85
- return false
86
- end
87
- end
88
-
89
- def content_right?
90
- return true unless @options[:text]
91
-
92
- case text=@options[:text]
93
- when Regexp
94
- new_scope = @current_scope.css(":regexp('#{text}')",Class.new {
95
- def regexp node_set, text
96
- node_set.find_all { |node| node.content =~ Regexp.new(text) }
97
- end
98
- }.new)
99
- unless new_scope.empty?
100
- @count = new_scope.count
101
- true
102
- else
103
- @failure_message=%Q{#{text.inspect} regexp expected within "#{@tag}" in following template:\n#{@document}}
104
- false
105
- end
106
- else
107
- css_param = text.gsub(/'/) { %q{\000027} }
108
- new_scope = @current_scope.css(":content('#{css_param}')",Class.new {
109
- def content node_set, text
110
- match_text = text.gsub(/\\000027/, "'")
111
- node_set.find_all { |node| node.content == match_text }
112
- end
113
- }.new)
114
- unless new_scope.empty?
115
- @count = new_scope.count
116
- true
117
- else
118
- @failure_message=%Q{"#{text}" expected within "#{@tag}" in following template:\n#{@document}}
119
- false
120
- end
121
- end
122
- end
123
- end
124
-
125
- # have_tag matcher
126
- #
127
- # @yield block where you should put with_tag
128
- #
129
- # @param [String] tag css selector for tag you want to match
130
- # @param [Hash] options options hash(see below)
131
- # @option options [Hash] :with hash with other attributes, within this, key :class have special meaning, you may specify it as array of expected classes or string of classes separated by spaces, order does not matter
132
- # @option options [Fixnum] :count count of matched tags(DO NOT USE :count with :minimum(:min) or :maximum(:max)*)
133
- # @option options [Range] :count count of matched tags should be between range minimum and maximum values
134
- # @option options [Fixnum] :minimum minimum count of elements to match
135
- # @option options [Fixnum] :min same as :minimum
136
- # @option options [Fixnum] :maximum maximum count of elements to match
137
- # @option options [Fixnum] :max same as :maximum
138
- #
139
- #
140
- # @example
141
- # rendered.should have_tag('div')
142
- # rendered.should have_tag('h1.header')
143
- # rendered.should have_tag('div#footer')
144
- # rendered.should have_tag('input#email', :with => { :name => 'user[email]', :type => 'email' } )
145
- # rendered.should have_tag('div', :count => 3) # matches exactly 3 'div' tags
146
- # rendered.should have_tag('div', :count => 3..7) # something like have_tag('div', :minimum => 3, :maximum => 7)
147
- # rendered.should have_tag('div', :minimum => 3) # matches more(or equal) than 3 'div' tags
148
- # rendered.should have_tag('div', :maximum => 3) # matches less(or equal) than 3 'div' tags
149
- # rendered.should have_tag('p', :text => 'some content') # will match "<p>some content</p>"
150
- # rendered.should have_tag('p', :text => /some content/i) # will match "<p>sOme cOntEnt</p>"
151
- # rendered.should have_tag('textarea', :with => {:name => 'user[description]'}, :text => "I like pie")
152
- # "<html>
153
- # <body>
154
- # <h1>some html document</h1>
155
- # </body>
156
- # </html>".should have_tag('body') { with_tag('h1', :text => 'some html document') }
157
- # '<div class="one two">'.should have_tag('div', :with => { :class => ['two', 'one'] })
158
- # '<div class="one two">'.should have_tag('div', :with => { :class => 'two one' })
159
- def have_tag tag, options={}, &block
160
- @__current_scope_for_nokogiri_matcher = NokogiriMatcher.new(tag, options, &block)
161
- end
162
-
163
- # with_tag matcher
164
- # @yield
165
- # @see #have_tag
166
- # @note this should be used within block of have_tag matcher
167
- def with_tag tag, options={}, &block
168
- @__current_scope_for_nokogiri_matcher.should have_tag(tag, options, &block)
169
- end
170
-
171
- # without_tag matcher
172
- # @yield
173
- # @see #have_tag
174
- # @note this should be used within block of have_tag matcher
175
- def without_tag tag, options={}, &block
176
- @__current_scope_for_nokogiri_matcher.should_not have_tag(tag, options, &block)
177
- end
178
-
179
- def have_form action_url, method, options={}, &block
180
- options[:with] ||= {}
181
- id = options[:with].delete(:id)
182
- tag = 'form'; tag += '#'+id if id
183
- options[:with].merge!(:action => action_url)
184
- options[:with].merge!(:method => method.to_s)
185
- have_tag tag, options, &block
186
- end
187
-
188
- def with_hidden_field name, value=nil
189
- options = { :with => { :name => name, :type => 'hidden' } }
190
- options[:with].merge!(:value => value) if value
191
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
192
- end
193
-
194
- def without_hidden_field name, value=nil
195
- options = { :with => { :name => name, :type => 'hidden' } }
196
- options[:with].merge!(:value => value) if value
197
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
198
- end
199
-
200
- def with_text_field name, value=nil
201
- options = { :with => { :name => name, :type => 'text' } }
202
- options[:with].merge!(:value => value) if value
203
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
204
- end
205
-
206
- def without_text_field name, value=nil
207
- options = { :with => { :name => name, :type => 'text' } }
208
- options[:with].merge!(:value => value) if value
209
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
210
- end
211
-
212
- def with_password_field name
213
- options = { :with => { :name => name, :type => 'password' } }
214
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
215
- end
216
-
217
- def without_password_field name
218
- options = { :with => { :name => name, :type => 'password' } }
219
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
220
- end
221
-
222
- def with_file_field name
223
- options = { :with => { :name => name, :type => 'file' } }
224
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
225
- end
226
-
227
- def without_file_field name
228
- options = { :with => { :name => name, :type => 'file' } }
229
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
230
- end
231
-
232
- def with_text_area name
233
- options = { :with => { :name => name } }
234
- @__current_scope_for_nokogiri_matcher.should have_tag('textarea', options)
235
- end
236
-
237
- def without_text_area name
238
- options = { :with => { :name => name } }
239
- @__current_scope_for_nokogiri_matcher.should_not have_tag('textarea', options)
240
- end
241
-
242
- def with_checkbox name, value=nil
243
- options = { :with => { :name => name, :type => 'checkbox' } }
244
- options[:with].merge!(:value => value) if value
245
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
246
- end
247
-
248
- def without_checkbox name, value=nil
249
- options = { :with => { :name => name, :type => 'checkbox' } }
250
- options[:with].merge!(:value => value) if value
251
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
252
- end
253
-
254
- def with_radio_button name, value
255
- options = { :with => { :name => name, :type => 'radio' } }
256
- options[:with].merge!(:value => value)
257
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
258
- end
259
-
260
- def without_radio_button name, value
261
- options = { :with => { :name => name, :type => 'radio' } }
262
- options[:with].merge!(:value => value)
263
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
264
- end
265
-
266
- def with_select name, options={}, &block
267
- options[:with] ||= {}
268
- id = options[:with].delete(:id)
269
- tag='select'; tag += '#'+id if id
270
- options[:with].merge!(:name => name)
271
- @__current_scope_for_nokogiri_matcher.should have_tag(tag, options, &block)
272
- end
273
-
274
- def without_select name, options={}, &block
275
- options[:with] ||= {}
276
- id = options[:with].delete(:id)
277
- tag='select'; tag += '#'+id if id
278
- options[:with].merge!(:name => name)
279
- @__current_scope_for_nokogiri_matcher.should_not have_tag(tag, options, &block)
280
- end
281
-
282
- def with_option text, value=nil, options={}
283
- options[:with] ||= {}
284
- if value.is_a?(Hash)
285
- options.merge!(value)
286
- value=nil
287
- end
288
- tag='option'
289
- options[:with].merge!(:value => value.to_s) if value
290
- if options[:selected]
291
- options[:with].merge!(:selected => "selected")
292
- end
293
- options.delete(:selected)
294
- options.merge!(:text => text) if text
295
- @__current_scope_for_nokogiri_matcher.should have_tag(tag, options)
296
- end
297
-
298
- def without_option text, value=nil, options={}
299
- options[:with] ||= {}
300
- if value.is_a?(Hash)
301
- options.merge!(value)
302
- value=nil
303
- end
304
- tag='option'
305
- options[:with].merge!(:value => value.to_s) if value
306
- if options[:selected]
307
- options[:with].merge!(:selected => "selected")
308
- end
309
- options.delete(:selected)
310
- options.merge!(:text => text) if text
311
- @__current_scope_for_nokogiri_matcher.should_not have_tag(tag, options)
312
- end
313
-
314
- def with_submit value
315
- options = { :with => { :type => 'submit', :value => value } }
316
- @__current_scope_for_nokogiri_matcher.should have_tag('input', options)
317
- end
318
-
319
- def without_submit value
320
- options = { :with => { :type => 'submit', :value => value } }
321
- @__current_scope_for_nokogiri_matcher.should_not have_tag('input', options)
322
- end
323
-
324
- end
325
- end
data/lib/version.rb DELETED
@@ -1,13 +0,0 @@
1
- module RSpec
2
- # @private
3
- module Rails
4
- # @private
5
- module Views
6
- # @private
7
- module Matchers
8
- # @private
9
- VERSION = "0.1.6"
10
- end
11
- end
12
- end
13
- end