rspec2-rails-views-matchers 0.1.6 → 0.2.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.
@@ -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