rspec-html-matchers 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f28ddf0ddc2a0e321f8b3b291cfb2e3aa0b0e81
4
- data.tar.gz: a4dedc6075e05857f5d97b9e133e3fa8ec8d230b
3
+ metadata.gz: ed044ed780b0ef4fefc403e3d644e6759b45232e
4
+ data.tar.gz: 3a9a74c22ee2c89bfae15fd3de267b3cf048604e
5
5
  SHA512:
6
- metadata.gz: d66ca882d21fbba2ef260bdc3a5cebb5669568536583f1cdb10dac6a9c63068b3b46608def542c9960f3b90123a335048871aa49ed243fa92ae227683041cccf
7
- data.tar.gz: b838ba419b4e5150ffc08944fe1faa3babaf9b9926340b8aa3654f54c1368f8678ed5b457257cbf646116ebaa1c003b2deb2f6ff90ab535ea5309916ae445594
6
+ metadata.gz: 52855bb634b6ccf3a31995e7d3a7730410d3f7c3209b9bfe9a42b9c924db3b7eb7d028d95a5523d1c02e87eab4929aad565a5483e7e1f1101a8eee8bad55cc2c
7
+ data.tar.gz: ecedc6b4e6791348db17d86a0338ccdeccfa3aa35e97a99a641358247cae14c89a39c6f2a56f026eba9b0f1d94b8f3757cc87b3186d8aa59a96ddfcb58fa3cac
data/CHANGELOG.md CHANGED
@@ -11,6 +11,18 @@ unreleased(TODO)
11
11
  * order matching
12
12
  * improve documentation, add more usage examples (look at changelog and code!)
13
13
 
14
+ 0.7.0
15
+ -----
16
+
17
+ * new, explicit configuration, refer to README
18
+ * added ruby 2.2.0 to CI
19
+
20
+ 0.6.1
21
+ -----
22
+
23
+ * rspec 3 version update
24
+ * added ruby 2.1.2 to CI
25
+
14
26
  0.6.0
15
27
  -----
16
28
 
data/README.md CHANGED
@@ -28,6 +28,33 @@ Add to your Gemfile in the `:test` group:
28
28
  gem 'rspec-html-matchers'
29
29
  ```
30
30
 
31
+ and somewhere in RSpec configuration:
32
+
33
+ ```ruby
34
+ RSpec.configure do |config|
35
+ config.include RSpecHtmlMatchers
36
+ end
37
+ ```
38
+
39
+ or just in you spec(s):
40
+
41
+ ```ruby
42
+ describe "my view spec" do
43
+ include RSpecHtmlMatchers
44
+
45
+ it "has tags" do
46
+ expect(rendered).to have_tag('div')
47
+ end
48
+
49
+ end
50
+ ```
51
+
52
+ Cucumber configuration:
53
+
54
+ ```ruby
55
+ World RSpecHtmlMatchers
56
+ ```
57
+
31
58
  as this gem requires **nokogiri**, here [instructions for installing it](http://nokogiri.org/tutorials/installing_nokogiri.html).
32
59
 
33
60
  Usage
@@ -195,6 +222,7 @@ Contributors
195
222
  - [Felix Tjandrawibawa](https://github.com/cemenghttps://github.com/cemeng)
196
223
  - [Szymon Przybył](https://github.com/apocalyptiq)
197
224
  - [Manuel Meurer](https://github.com/manuelmeurer)
225
+ - [Andreas Riemer](https://github.com/arfl)
198
226
 
199
227
  MIT Licensed
200
228
  ============
@@ -5,6 +5,8 @@ require 'sinatra/base'
5
5
  require 'capybara/cucumber'
6
6
  require 'rspec-html-matchers'
7
7
 
8
+ World RSpecHtmlMatchers
9
+
8
10
  $ASSETS_DIR = File.expand_path('../tmp',__FILE__)
9
11
  $INDEX_HTML = File.join($ASSETS_DIR,'index.html')
10
12
 
@@ -2,568 +2,558 @@
2
2
  require 'rspec'
3
3
  require 'nokogiri'
4
4
 
5
- module RSpec
6
- module HtmlMatchers
7
-
8
- # @api
9
- # @private
10
- # for nokogiri regexp matching
11
- class NokogiriRegexpHelper
12
- def initialize(regex)
13
- @regex = regex
14
- end
5
+ module RSpecHtmlMatchers
15
6
 
16
- def regexp node_set
17
- node_set.find_all { |node| node.content =~ @regex }
18
- end
7
+ # @api
8
+ # @private
9
+ # for nokogiri regexp matching
10
+ class NokogiriRegexpHelper
11
+ def initialize(regex)
12
+ @regex = regex
19
13
  end
20
14
 
21
- # @api
22
- # @private
23
- class NokogiriTextHelper
24
- NON_BREAKING_SPACE = "\u00a0"
15
+ def regexp node_set
16
+ node_set.find_all { |node| node.content =~ @regex }
17
+ end
18
+ end
25
19
 
26
- def initialize text
27
- @text = text
28
- end
20
+ # @api
21
+ # @private
22
+ class NokogiriTextHelper
23
+ NON_BREAKING_SPACE = "\u00a0"
29
24
 
30
- def content node_set
31
- node_set.find_all do |node|
32
- actual_content = node.content.gsub(NON_BREAKING_SPACE, ' ')
25
+ def initialize text
26
+ @text = text
27
+ end
33
28
 
34
- actual_content == @text
35
- end
29
+ def content node_set
30
+ node_set.find_all do |node|
31
+ actual_content = node.content.gsub(NON_BREAKING_SPACE, ' ')
32
+
33
+ actual_content == @text
36
34
  end
37
35
  end
36
+ end
38
37
 
39
- # @api
40
- # @private
41
- class HaveTag
42
- attr_reader :failure_message, :failure_message_when_negated
43
- attr_reader :parent_scope, :current_scope
38
+ # @api
39
+ # @private
40
+ class HaveTag
41
+ attr_reader :failure_message, :failure_message_when_negated
42
+ attr_reader :parent_scope, :current_scope
44
43
 
45
- DESCRIPTIONS = {
46
- :have_at_least_1 => %Q|have at least 1 element matching "%s"|,
47
- :have_n => %Q|have %i element(s) matching "%s"|
48
- }
44
+ DESCRIPTIONS = {
45
+ :have_at_least_1 => %Q|have at least 1 element matching "%s"|,
46
+ :have_n => %Q|have %i element(s) matching "%s"|
47
+ }
49
48
 
50
- MESSAGES = {
51
- :expected_tag => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_at_least_1]}, found 0.|,
52
- :unexpected_tag => %Q|expected following:\n%s\nto NOT have element matching "%s", found %s.|,
49
+ MESSAGES = {
50
+ :expected_tag => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_at_least_1]}, found 0.|,
51
+ :unexpected_tag => %Q|expected following:\n%s\nto NOT have element matching "%s", found %s.|,
53
52
 
54
- :expected_count => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_n]}, found %s.|,
55
- :unexpected_count => %Q|expected following:\n%s\nto NOT have %i element(s) matching "%s", but found.|,
53
+ :expected_count => %Q|expected following:\n%s\nto #{DESCRIPTIONS[:have_n]}, found %s.|,
54
+ :unexpected_count => %Q|expected following:\n%s\nto NOT have %i element(s) matching "%s", but found.|,
56
55
 
57
- :expected_btw_count => %Q|expected following:\n%s\nto have at least %i and at most %i element(s) matching "%s", found %i.|,
58
- :unexpected_btw_count => %Q|expected following:\n%s\nto NOT have at least %i and at most %i element(s) matching "%s", but found %i.|,
56
+ :expected_btw_count => %Q|expected following:\n%s\nto have at least %i and at most %i element(s) matching "%s", found %i.|,
57
+ :unexpected_btw_count => %Q|expected following:\n%s\nto NOT have at least %i and at most %i element(s) matching "%s", but found %i.|,
59
58
 
60
- :expected_at_most => %Q|expected following:\n%s\nto have at most %i element(s) matching "%s", found %i.|,
61
- :unexpected_at_most => %Q|expected following:\n%s\nto NOT have at most %i element(s) matching "%s", but found %i.|,
59
+ :expected_at_most => %Q|expected following:\n%s\nto have at most %i element(s) matching "%s", found %i.|,
60
+ :unexpected_at_most => %Q|expected following:\n%s\nto NOT have at most %i element(s) matching "%s", but found %i.|,
62
61
 
63
- :expected_at_least => %Q|expected following:\n%s\nto have at least %i element(s) matching "%s", found %i.|,
64
- :unexpected_at_least => %Q|expected following:\n%s\nto NOT have at least %i element(s) matching "%s", but found %i.|,
62
+ :expected_at_least => %Q|expected following:\n%s\nto have at least %i element(s) matching "%s", found %i.|,
63
+ :unexpected_at_least => %Q|expected following:\n%s\nto NOT have at least %i element(s) matching "%s", but found %i.|,
65
64
 
66
- :expected_regexp => %Q|%s regexp expected within "%s" in following template:\n%s|,
67
- :unexpected_regexp => %Q|%s regexp unexpected within "%s" in following template:\n%s\nbut was found.|,
65
+ :expected_regexp => %Q|%s regexp expected within "%s" in following template:\n%s|,
66
+ :unexpected_regexp => %Q|%s regexp unexpected within "%s" in following template:\n%s\nbut was found.|,
68
67
 
69
- :expected_text => %Q|"%s" expected within "%s" in following template:\n%s|,
70
- :unexpected_text => %Q|"%s" unexpected within "%s" in following template:\n%s\nbut was found.|,
68
+ :expected_text => %Q|"%s" expected within "%s" in following template:\n%s|,
69
+ :unexpected_text => %Q|"%s" unexpected within "%s" in following template:\n%s\nbut was found.|,
71
70
 
72
- :wrong_count_error => %Q|:count with :minimum or :maximum has no sence!|,
73
- :min_max_error => %Q|:minimum should be less than :maximum!|,
74
- :bad_range_error => %Q|Your :count range(%s) has no sence!|,
75
- }
71
+ :wrong_count_error => %Q|:count with :minimum or :maximum has no sence!|,
72
+ :min_max_error => %Q|:minimum should be less than :maximum!|,
73
+ :bad_range_error => %Q|Your :count range(%s) has no sence!|,
74
+ }
76
75
 
77
76
 
78
- def initialize tag, options={}, &block
79
- @tag, @options, @block = tag.to_s, options, block
77
+ def initialize tag, options={}, &block
78
+ @tag, @options, @block = tag.to_s, options, block
80
79
 
81
- if with_attrs = @options.delete(:with)
82
- if classes = with_attrs.delete(:class)
83
- @tag << '.' + classes_to_selector(classes)
84
- end
85
- selector = with_attrs.inject('') do |html_attrs_string, (k, v)|
86
- html_attrs_string << "[#{k}='#{v}']"
87
- html_attrs_string
88
- end
89
- @tag << selector
80
+ if with_attrs = @options.delete(:with)
81
+ if classes = with_attrs.delete(:class)
82
+ @tag << '.' + classes_to_selector(classes)
90
83
  end
91
-
92
- if without_attrs = @options.delete(:without)
93
- if classes = without_attrs.delete(:class)
94
- @tag << ":not(.#{classes_to_selector(classes)})"
95
- end
84
+ selector = with_attrs.inject('') do |html_attrs_string, (k, v)|
85
+ html_attrs_string << "[#{k}='#{v}']"
86
+ html_attrs_string
96
87
  end
88
+ @tag << selector
89
+ end
97
90
 
98
- validate_options!
91
+ if without_attrs = @options.delete(:without)
92
+ if classes = without_attrs.delete(:class)
93
+ @tag << ":not(.#{classes_to_selector(classes)})"
94
+ end
99
95
  end
100
96
 
101
- def matches? document, &block
102
- @block = block if block
97
+ validate_options!
98
+ end
103
99
 
104
- document = document.html if defined?(Capybara::Session) && document.is_a?(Capybara::Session)
100
+ def matches? document, &block
101
+ @block = block if block
105
102
 
106
- case document
107
- when String
108
- @parent_scope = @current_scope = Nokogiri::HTML(document).css(@tag)
109
- @document = document
110
- else
111
- @parent_scope = document.current_scope
112
- @current_scope = begin
113
- document.parent_scope.css(@tag)
114
- # on jruby this produce exception if css was not found:
115
- # undefined method `decorate' for nil:NilClass
116
- rescue NoMethodError
117
- Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
118
- end
119
- @document = @parent_scope.to_html
120
- end
103
+ document = document.html if defined?(Capybara::Session) && document.is_a?(Capybara::Session)
121
104
 
122
- if tag_presents? and text_right? and count_right?
123
- @current_scope = @parent_scope
124
- @block.call if @block
125
- true
126
- else
127
- false
128
- end
105
+ case document
106
+ when String
107
+ @parent_scope = @current_scope = Nokogiri::HTML(document).css(@tag)
108
+ @document = document
109
+ else
110
+ @parent_scope = document.current_scope
111
+ @current_scope = begin
112
+ document.parent_scope.css(@tag)
113
+ # on jruby this produce exception if css was not found:
114
+ # undefined method `decorate' for nil:NilClass
115
+ rescue NoMethodError
116
+ Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
117
+ end
118
+ @document = @parent_scope.to_html
129
119
  end
130
120
 
131
- def description
132
- # TODO should it be more complicated?
133
- if @options.has_key?(:count)
134
- DESCRIPTIONS[:have_n] % [@options[:count],@tag]
135
- else
136
- DESCRIPTIONS[:have_at_least_1] % @tag
137
- end
121
+ if tag_presents? and text_right? and count_right?
122
+ @current_scope = @parent_scope
123
+ @block.call if @block
124
+ true
125
+ else
126
+ false
138
127
  end
128
+ end
139
129
 
140
- private
130
+ def description
131
+ # TODO should it be more complicated?
132
+ if @options.has_key?(:count)
133
+ DESCRIPTIONS[:have_n] % [@options[:count],@tag]
134
+ else
135
+ DESCRIPTIONS[:have_at_least_1] % @tag
136
+ end
137
+ end
141
138
 
142
- def classes_to_selector(classes)
143
- case classes
144
- when Array
145
- classes.join('.')
146
- when String
147
- classes.gsub(/\s+/, '.')
148
- end
139
+ private
140
+
141
+ def classes_to_selector(classes)
142
+ case classes
143
+ when Array
144
+ classes.join('.')
145
+ when String
146
+ classes.gsub(/\s+/, '.')
149
147
  end
148
+ end
150
149
 
151
- def tag_presents?
152
- if @current_scope.first
153
- @count = @current_scope.count
154
- @failure_message_when_negated = MESSAGES[:unexpected_tag] % [@document, @tag, @count]
155
- true
156
- else
157
- @failure_message = MESSAGES[:expected_tag] % [@document, @tag]
158
- false
159
- end
150
+ def tag_presents?
151
+ if @current_scope.first
152
+ @count = @current_scope.count
153
+ @failure_message_when_negated = MESSAGES[:unexpected_tag] % [@document, @tag, @count]
154
+ true
155
+ else
156
+ @failure_message = MESSAGES[:expected_tag] % [@document, @tag]
157
+ false
160
158
  end
159
+ end
161
160
 
162
- def count_right?
163
- case @options[:count]
164
- when Integer
165
- ((@failure_message_when_negated=MESSAGES[:unexpected_count] % [@document,@count,@tag]) && @count == @options[:count]) || (@failure_message=MESSAGES[:expected_count] % [@document,@options[:count],@tag,@count]; false)
166
- when Range
167
- ((@failure_message_when_negated=MESSAGES[:unexpected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]) && @options[:count].member?(@count)) || (@failure_message=MESSAGES[:expected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]; false)
168
- when nil
169
- if @options[:maximum]
170
- ((@failure_message_when_negated=MESSAGES[:unexpected_at_most] % [@document,@options[:maximum],@tag,@count]) && @count <= @options[:maximum]) || (@failure_message=MESSAGES[:expected_at_most] % [@document,@options[:maximum],@tag,@count]; false)
171
- elsif @options[:minimum]
172
- ((@failure_message_when_negated=MESSAGES[:unexpected_at_least] % [@document,@options[:minimum],@tag,@count]) && @count >= @options[:minimum]) || (@failure_message=MESSAGES[:expected_at_least] % [@document,@options[:minimum],@tag,@count]; false)
173
- else
174
- true
175
- end
161
+ def count_right?
162
+ case @options[:count]
163
+ when Integer
164
+ ((@failure_message_when_negated=MESSAGES[:unexpected_count] % [@document,@count,@tag]) && @count == @options[:count]) || (@failure_message=MESSAGES[:expected_count] % [@document,@options[:count],@tag,@count]; false)
165
+ when Range
166
+ ((@failure_message_when_negated=MESSAGES[:unexpected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]) && @options[:count].member?(@count)) || (@failure_message=MESSAGES[:expected_btw_count] % [@document,@options[:count].min,@options[:count].max,@tag,@count]; false)
167
+ when nil
168
+ if @options[:maximum]
169
+ ((@failure_message_when_negated=MESSAGES[:unexpected_at_most] % [@document,@options[:maximum],@tag,@count]) && @count <= @options[:maximum]) || (@failure_message=MESSAGES[:expected_at_most] % [@document,@options[:maximum],@tag,@count]; false)
170
+ elsif @options[:minimum]
171
+ ((@failure_message_when_negated=MESSAGES[:unexpected_at_least] % [@document,@options[:minimum],@tag,@count]) && @count >= @options[:minimum]) || (@failure_message=MESSAGES[:expected_at_least] % [@document,@options[:minimum],@tag,@count]; false)
172
+ else
173
+ true
176
174
  end
177
175
  end
176
+ end
177
+
178
+ def text_right?
179
+ return true unless @options[:text]
178
180
 
179
- def text_right?
180
- return true unless @options[:text]
181
-
182
- case text=@options[:text]
183
- when Regexp
184
- new_scope = @current_scope.css(':regexp()',NokogiriRegexpHelper.new(text))
185
- unless new_scope.empty?
186
- @count = new_scope.count
187
- @failure_message_when_negated = MESSAGES[:unexpected_regexp] % [text.inspect,@tag,@document]
188
- true
189
- else
190
- @failure_message = MESSAGES[:expected_regexp] % [text.inspect,@tag,@document]
191
- false
192
- end
181
+ case text=@options[:text]
182
+ when Regexp
183
+ new_scope = @current_scope.css(':regexp()',NokogiriRegexpHelper.new(text))
184
+ unless new_scope.empty?
185
+ @count = new_scope.count
186
+ @failure_message_when_negated = MESSAGES[:unexpected_regexp] % [text.inspect,@tag,@document]
187
+ true
193
188
  else
194
- new_scope = @current_scope.css(':content()',NokogiriTextHelper.new(text))
195
- unless new_scope.empty?
196
- @count = new_scope.count
197
- @failure_message_when_negated = MESSAGES[:unexpected_text] % [text,@tag,@document]
198
- true
199
- else
200
- @failure_message = MESSAGES[:expected_text] % [text,@tag,@document]
201
- false
202
- end
189
+ @failure_message = MESSAGES[:expected_regexp] % [text.inspect,@tag,@document]
190
+ false
191
+ end
192
+ else
193
+ new_scope = @current_scope.css(':content()',NokogiriTextHelper.new(text))
194
+ unless new_scope.empty?
195
+ @count = new_scope.count
196
+ @failure_message_when_negated = MESSAGES[:unexpected_text] % [text,@tag,@document]
197
+ true
198
+ else
199
+ @failure_message = MESSAGES[:expected_text] % [text,@tag,@document]
200
+ false
203
201
  end
204
202
  end
203
+ end
205
204
 
206
- protected
205
+ protected
207
206
 
208
- def validate_options!
209
- raise 'wrong :count specified' unless [Range, NilClass].include?(@options[:count].class) or @options[:count].is_a?(Integer)
207
+ def validate_options!
208
+ raise 'wrong :count specified' unless [Range, NilClass].include?(@options[:count].class) or @options[:count].is_a?(Integer)
210
209
 
211
- [:min, :minimum, :max, :maximum].each do |key|
212
- raise MESSAGES[:wrong_count_error] if @options.has_key?(key) and @options.has_key?(:count)
213
- end
210
+ [:min, :minimum, :max, :maximum].each do |key|
211
+ raise MESSAGES[:wrong_count_error] if @options.has_key?(key) and @options.has_key?(:count)
212
+ end
214
213
 
215
- begin
216
- raise MESSAGES[:min_max_error] if @options[:minimum] > @options[:maximum]
217
- rescue NoMethodError # nil > 4
218
- rescue ArgumentError # 2 < nil
219
- end
214
+ begin
215
+ raise MESSAGES[:min_max_error] if @options[:minimum] > @options[:maximum]
216
+ rescue NoMethodError # nil > 4
217
+ rescue ArgumentError # 2 < nil
218
+ end
220
219
 
220
+ begin
221
221
  begin
222
- begin
223
- raise MESSAGES[:bad_range_error] % [@options[:count].to_s] if @options[:count] && @options[:count].is_a?(Range) && (@options[:count].min.nil? or @options[:count].min < 0)
224
- rescue ArgumentError, "comparison of String with" # if @options[:count] == 'a'..'z'
225
- raise MESSAGES[:bad_range_error] % [@options[:count].to_s]
226
- end
227
- rescue TypeError # fix for 1.8.7 for 'rescue ArgumentError, "comparison of String with"' stroke
222
+ raise MESSAGES[:bad_range_error] % [@options[:count].to_s] if @options[:count] && @options[:count].is_a?(Range) && (@options[:count].min.nil? or @options[:count].min < 0)
223
+ rescue ArgumentError, "comparison of String with" # if @options[:count] == 'a'..'z'
228
224
  raise MESSAGES[:bad_range_error] % [@options[:count].to_s]
229
225
  end
230
-
231
- @options[:minimum] ||= @options.delete(:min)
232
- @options[:maximum] ||= @options.delete(:max)
233
-
234
- @options[:text] = @options[:text].to_s if @options.has_key?(:text) && !@options[:text].is_a?(Regexp)
226
+ rescue TypeError # fix for 1.8.7 for 'rescue ArgumentError, "comparison of String with"' stroke
227
+ raise MESSAGES[:bad_range_error] % [@options[:count].to_s]
235
228
  end
236
229
 
237
- end
230
+ @options[:minimum] ||= @options.delete(:min)
231
+ @options[:maximum] ||= @options.delete(:max)
238
232
 
239
- # tag assertion, this is the core of functionality, other matchers are shortcuts to this matcher
240
- #
241
- # @yield block where you should put with_tag, without_tag and/or other matchers
242
- #
243
- # @param [String] tag css selector for tag you want to match, e.g. 'div', 'section#my', 'article.red'
244
- # @param [Hash] options options hash(see below)
245
- # @option options [Hash] :with hash with html attributes, within this, *:class* option have special meaning, you may specify it as array of expected classes or string of classes separated by spaces, order does not matter
246
- # @option options [Fixnum] :count for tag count matching(*ATTENTION:* do not use :count with :minimum(:min) or :maximum(:max))
247
- # @option options [Range] :count not strict tag count matching, count of tags should be in specified range
248
- # @option options [Fixnum] :minimum minimum count of elements to match
249
- # @option options [Fixnum] :min same as :minimum
250
- # @option options [Fixnum] :maximum maximum count of elements to match
251
- # @option options [Fixnum] :max same as :maximum
252
- # @option options [String/Regexp] :text to match tag content, could be either String or Regexp
253
- #
254
- # @example
255
- # expect(rendered).to have_tag('div')
256
- # expect(rendered).to have_tag('h1.header')
257
- # expect(rendered).to have_tag('div#footer')
258
- # expect(rendered).to have_tag('input#email', :with => { :name => 'user[email]', :type => 'email' } )
259
- # expect(rendered).to have_tag('div', :count => 3) # matches exactly 3 'div' tags
260
- # expect(rendered).to have_tag('div', :count => 3..7) # shortcut for have_tag('div', :minimum => 3, :maximum => 7)
261
- # expect(rendered).to have_tag('div', :minimum => 3) # matches more(or equal) than 3 'div' tags
262
- # expect(rendered).to have_tag('div', :maximum => 3) # matches less(or equal) than 3 'div' tags
263
- # expect(rendered).to have_tag('p', :text => 'some content') # will match "<p>some content</p>"
264
- # expect(rendered).to have_tag('p', :text => /some content/i) # will match "<p>sOme cOntEnt</p>"
265
- # expect(rendered).to have_tag('textarea', :with => {:name => 'user[description]'}, :text => "I like pie")
266
- # expect("<html>
267
- # <body>
268
- # <h1>some html document</h1>
269
- # </body>
270
- # </html>").to have_tag('body') { with_tag('h1', :text => 'some html document') }
271
- # expect('<div class="one two">').to have_tag('div', :with => { :class => ['two', 'one'] })
272
- # expect('<div class="one two">').to have_tag('div', :with => { :class => 'two one' })
273
- def have_tag tag, options={}, &block
274
- # for backwards compatibility with rpecs have tag:
275
- options = { :text => options } if options.kind_of?(String) || options.kind_of?(Regexp)
276
- @__current_scope_for_nokogiri_matcher = HaveTag.new(tag, options, &block)
233
+ @options[:text] = @options[:text].to_s if @options.has_key?(:text) && !@options[:text].is_a?(Regexp)
277
234
  end
278
235
 
279
- def with_text text
280
- raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
281
- raise ArgumentError, 'this matcher does not accept block' if block_given?
282
- tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
283
- expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, :text => text)
284
- end
236
+ end
285
237
 
286
- def without_text text
287
- raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
288
- raise ArgumentError, 'this matcher does not accept block' if block_given?
289
- tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
290
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, :text => text)
291
- end
292
- alias :but_without_text :without_text
293
-
294
- # with_tag matcher
295
- # @yield block where you should put other with_tag or without_tag
296
- # @see #have_tag
297
- # @note this should be used within block of have_tag matcher
298
- def with_tag tag, options={}, &block
299
- expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
300
- end
238
+ # tag assertion, this is the core of functionality, other matchers are shortcuts to this matcher
239
+ #
240
+ # @yield block where you should put with_tag, without_tag and/or other matchers
241
+ #
242
+ # @param [String] tag css selector for tag you want to match, e.g. 'div', 'section#my', 'article.red'
243
+ # @param [Hash] options options hash(see below)
244
+ # @option options [Hash] :with hash with html attributes, within this, *:class* option have special meaning, you may specify it as array of expected classes or string of classes separated by spaces, order does not matter
245
+ # @option options [Fixnum] :count for tag count matching(*ATTENTION:* do not use :count with :minimum(:min) or :maximum(:max))
246
+ # @option options [Range] :count not strict tag count matching, count of tags should be in specified range
247
+ # @option options [Fixnum] :minimum minimum count of elements to match
248
+ # @option options [Fixnum] :min same as :minimum
249
+ # @option options [Fixnum] :maximum maximum count of elements to match
250
+ # @option options [Fixnum] :max same as :maximum
251
+ # @option options [String/Regexp] :text to match tag content, could be either String or Regexp
252
+ #
253
+ # @example
254
+ # expect(rendered).to have_tag('div')
255
+ # expect(rendered).to have_tag('h1.header')
256
+ # expect(rendered).to have_tag('div#footer')
257
+ # expect(rendered).to have_tag('input#email', :with => { :name => 'user[email]', :type => 'email' } )
258
+ # expect(rendered).to have_tag('div', :count => 3) # matches exactly 3 'div' tags
259
+ # expect(rendered).to have_tag('div', :count => 3..7) # shortcut for have_tag('div', :minimum => 3, :maximum => 7)
260
+ # expect(rendered).to have_tag('div', :minimum => 3) # matches more(or equal) than 3 'div' tags
261
+ # expect(rendered).to have_tag('div', :maximum => 3) # matches less(or equal) than 3 'div' tags
262
+ # expect(rendered).to have_tag('p', :text => 'some content') # will match "<p>some content</p>"
263
+ # expect(rendered).to have_tag('p', :text => /some content/i) # will match "<p>sOme cOntEnt</p>"
264
+ # expect(rendered).to have_tag('textarea', :with => {:name => 'user[description]'}, :text => "I like pie")
265
+ # expect("<html>
266
+ # <body>
267
+ # <h1>some html document</h1>
268
+ # </body>
269
+ # </html>").to have_tag('body') { with_tag('h1', :text => 'some html document') }
270
+ # expect('<div class="one two">').to have_tag('div', :with => { :class => ['two', 'one'] })
271
+ # expect('<div class="one two">').to have_tag('div', :with => { :class => 'two one' })
272
+ def have_tag tag, options={}, &block
273
+ # for backwards compatibility with rpecs have tag:
274
+ options = { :text => options } if options.kind_of?(String) || options.kind_of?(Regexp)
275
+ @__current_scope_for_nokogiri_matcher = HaveTag.new(tag, options, &block)
276
+ end
301
277
 
302
- # without_tag matcher
303
- # @yield block where you should put other with_tag or without_tag
304
- # @see #have_tag
305
- # @note this should be used within block of have_tag matcher
306
- def without_tag tag, options={}, &block
307
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
308
- end
278
+ def with_text text
279
+ raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
280
+ raise ArgumentError, 'this matcher does not accept block' if block_given?
281
+ tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
282
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, :text => text)
283
+ end
309
284
 
310
- # form assertion
311
- #
312
- # it is a shortcut to
313
- # have_tag 'form', :with => { :action => action_url, :method => method ... }
314
- # @yield block with with_<field>, see below
315
- # @see #have_tag
316
- def have_form action_url, method, options={}, &block
317
- options[:with] ||= {}
318
- id = options[:with].delete(:id)
319
- tag = 'form'; tag << '#'+id if id
320
- options[:with].merge!(:action => action_url)
321
- options[:with].merge!(:method => method.to_s)
322
- have_tag tag, options, &block
323
- end
285
+ def without_text text
286
+ raise StandardError, 'this matcher should be used inside "have_tag" matcher block' unless defined?(@__current_scope_for_nokogiri_matcher)
287
+ raise ArgumentError, 'this matcher does not accept block' if block_given?
288
+ tag = @__current_scope_for_nokogiri_matcher.instance_variable_get(:@tag)
289
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, :text => text)
290
+ end
291
+ alias :but_without_text :without_text
292
+
293
+ # with_tag matcher
294
+ # @yield block where you should put other with_tag or without_tag
295
+ # @see #have_tag
296
+ # @note this should be used within block of have_tag matcher
297
+ def with_tag tag, options={}, &block
298
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
299
+ end
324
300
 
325
- #TODO fix code duplications
301
+ # without_tag matcher
302
+ # @yield block where you should put other with_tag or without_tag
303
+ # @see #have_tag
304
+ # @note this should be used within block of have_tag matcher
305
+ def without_tag tag, options={}, &block
306
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
307
+ end
326
308
 
327
- def with_hidden_field name, value=nil
328
- options = form_tag_options('hidden',name,value)
329
- should_have_input(options)
330
- end
309
+ # form assertion
310
+ #
311
+ # it is a shortcut to
312
+ # have_tag 'form', :with => { :action => action_url, :method => method ... }
313
+ # @yield block with with_<field>, see below
314
+ # @see #have_tag
315
+ def have_form action_url, method, options={}, &block
316
+ options[:with] ||= {}
317
+ id = options[:with].delete(:id)
318
+ tag = 'form'; tag << '#'+id if id
319
+ options[:with].merge!(:action => action_url)
320
+ options[:with].merge!(:method => method.to_s)
321
+ have_tag tag, options, &block
322
+ end
331
323
 
332
- def without_hidden_field name, value=nil
333
- options = form_tag_options('hidden',name,value)
334
- should_not_have_input(options)
335
- end
324
+ #TODO fix code duplications
336
325
 
337
- def with_text_field name, value=nil
338
- options = form_tag_options('text',name,value)
339
- should_have_input(options)
340
- end
326
+ def with_hidden_field name, value=nil
327
+ options = form_tag_options('hidden',name,value)
328
+ should_have_input(options)
329
+ end
341
330
 
342
- def without_text_field name, value=nil
343
- options = form_tag_options('text',name,value)
344
- should_not_have_input(options)
345
- end
331
+ def without_hidden_field name, value=nil
332
+ options = form_tag_options('hidden',name,value)
333
+ should_not_have_input(options)
334
+ end
346
335
 
347
- def with_email_field name, value=nil
348
- options = form_tag_options('email',name,value)
349
- should_have_input(options)
350
- end
336
+ def with_text_field name, value=nil
337
+ options = form_tag_options('text',name,value)
338
+ should_have_input(options)
339
+ end
351
340
 
352
- def without_email_field name, value=nil
353
- options = form_tag_options('email',name,value)
354
- should_not_have_input(options)
355
- end
341
+ def without_text_field name, value=nil
342
+ options = form_tag_options('text',name,value)
343
+ should_not_have_input(options)
344
+ end
356
345
 
357
- def with_url_field name, value=nil
358
- options = form_tag_options('url',name,value)
359
- should_have_input(options)
360
- end
346
+ def with_email_field name, value=nil
347
+ options = form_tag_options('email',name,value)
348
+ should_have_input(options)
349
+ end
361
350
 
362
- def without_url_field name, value=nil
363
- options = form_tag_options('url',name,value)
364
- should_not_have_input(options)
365
- end
351
+ def without_email_field name, value=nil
352
+ options = form_tag_options('email',name,value)
353
+ should_not_have_input(options)
354
+ end
366
355
 
367
- def with_number_field name, value=nil
368
- options = form_tag_options('number',name,value)
369
- should_have_input(options)
370
- end
356
+ def with_url_field name, value=nil
357
+ options = form_tag_options('url',name,value)
358
+ should_have_input(options)
359
+ end
371
360
 
372
- def without_number_field name, value=nil
373
- options = form_tag_options('number',name,value)
374
- should_not_have_input(options)
375
- end
361
+ def without_url_field name, value=nil
362
+ options = form_tag_options('url',name,value)
363
+ should_not_have_input(options)
364
+ end
376
365
 
377
- def with_range_field name, min, max, options={}
378
- options = { :with => { :name => name, :type => 'range', :min => min.to_s, :max => max.to_s }.merge(options.delete(:with)||{}) }
379
- should_have_input(options)
380
- end
366
+ def with_number_field name, value=nil
367
+ options = form_tag_options('number',name,value)
368
+ should_have_input(options)
369
+ end
381
370
 
382
- def without_range_field name, min=nil, max=nil, options={}
383
- options = { :with => { :name => name, :type => 'range' }.merge(options.delete(:with)||{}) }
384
- options[:with].merge!(:min => min.to_s) if min
385
- options[:with].merge!(:max => max.to_s) if max
386
- should_not_have_input(options)
387
- end
371
+ def without_number_field name, value=nil
372
+ options = form_tag_options('number',name,value)
373
+ should_not_have_input(options)
374
+ end
388
375
 
389
- DATE_FIELD_TYPES = %w( date month week time datetime datetime-local )
376
+ def with_range_field name, min, max, options={}
377
+ options = { :with => { :name => name, :type => 'range', :min => min.to_s, :max => max.to_s }.merge(options.delete(:with)||{}) }
378
+ should_have_input(options)
379
+ end
390
380
 
391
- def with_date_field date_field_type, name=nil, options={}
392
- date_field_type = date_field_type.to_s
393
- raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
394
- options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with)||{}) }
395
- options[:with].merge!(:name => name.to_s) if name
396
- should_have_input(options)
397
- end
381
+ def without_range_field name, min=nil, max=nil, options={}
382
+ options = { :with => { :name => name, :type => 'range' }.merge(options.delete(:with)||{}) }
383
+ options[:with].merge!(:min => min.to_s) if min
384
+ options[:with].merge!(:max => max.to_s) if max
385
+ should_not_have_input(options)
386
+ end
398
387
 
399
- def without_date_field date_field_type, name=nil, options={}
400
- date_field_type = date_field_type.to_s
401
- raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
402
- options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with)||{}) }
403
- options[:with].merge!(:name => name.to_s) if name
404
- should_not_have_input(options)
405
- end
388
+ DATE_FIELD_TYPES = %w( date month week time datetime datetime-local )
406
389
 
407
- # TODO add ability to explicitly say that value should be empty
408
- def with_password_field name, value=nil
409
- options = form_tag_options('password',name,value)
410
- should_have_input(options)
411
- end
390
+ def with_date_field date_field_type, name=nil, options={}
391
+ date_field_type = date_field_type.to_s
392
+ raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
393
+ options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with)||{}) }
394
+ options[:with].merge!(:name => name.to_s) if name
395
+ should_have_input(options)
396
+ end
412
397
 
413
- def without_password_field name, value=nil
414
- options = form_tag_options('password',name,value)
415
- should_not_have_input(options)
416
- end
398
+ def without_date_field date_field_type, name=nil, options={}
399
+ date_field_type = date_field_type.to_s
400
+ raise "unknown type `#{date_field_type}` for date picker" unless DATE_FIELD_TYPES.include?(date_field_type)
401
+ options = { :with => { :type => date_field_type.to_s }.merge(options.delete(:with)||{}) }
402
+ options[:with].merge!(:name => name.to_s) if name
403
+ should_not_have_input(options)
404
+ end
417
405
 
418
- def with_file_field name, value=nil
419
- options = form_tag_options('file',name,value)
420
- should_have_input(options)
421
- end
406
+ # TODO add ability to explicitly say that value should be empty
407
+ def with_password_field name, value=nil
408
+ options = form_tag_options('password',name,value)
409
+ should_have_input(options)
410
+ end
422
411
 
423
- def without_file_field name, value=nil
424
- options = form_tag_options('file',name,value)
425
- should_not_have_input(options)
426
- end
412
+ def without_password_field name, value=nil
413
+ options = form_tag_options('password',name,value)
414
+ should_not_have_input(options)
415
+ end
427
416
 
428
- def with_text_area name#TODO, text=nil
429
- #options = form_tag_options('text',name,value)
430
- options = { :with => { :name => name } }
431
- expect(@__current_scope_for_nokogiri_matcher).to have_tag('textarea', options)
432
- end
417
+ def with_file_field name, value=nil
418
+ options = form_tag_options('file',name,value)
419
+ should_have_input(options)
420
+ end
433
421
 
434
- def without_text_area name#TODO, text=nil
435
- #options = form_tag_options('text',name,value)
436
- options = { :with => { :name => name } }
437
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('textarea', options)
438
- end
422
+ def without_file_field name, value=nil
423
+ options = form_tag_options('file',name,value)
424
+ should_not_have_input(options)
425
+ end
439
426
 
440
- def with_checkbox name, value=nil
441
- options = form_tag_options('checkbox',name,value)
442
- should_have_input(options)
443
- end
427
+ def with_text_area name#TODO, text=nil
428
+ #options = form_tag_options('text',name,value)
429
+ options = { :with => { :name => name } }
430
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag('textarea', options)
431
+ end
444
432
 
445
- def without_checkbox name, value=nil
446
- options = form_tag_options('checkbox',name,value)
447
- should_not_have_input(options)
448
- end
433
+ def without_text_area name#TODO, text=nil
434
+ #options = form_tag_options('text',name,value)
435
+ options = { :with => { :name => name } }
436
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('textarea', options)
437
+ end
449
438
 
450
- def with_radio_button name, value
451
- options = form_tag_options('radio',name,value)
452
- should_have_input(options)
453
- end
439
+ def with_checkbox name, value=nil
440
+ options = form_tag_options('checkbox',name,value)
441
+ should_have_input(options)
442
+ end
454
443
 
455
- def without_radio_button name, value
456
- options = form_tag_options('radio',name,value)
457
- should_not_have_input(options)
458
- end
444
+ def without_checkbox name, value=nil
445
+ options = form_tag_options('checkbox',name,value)
446
+ should_not_have_input(options)
447
+ end
459
448
 
460
- def with_select name, options={}, &block
461
- options[:with] ||= {}
462
- id = options[:with].delete(:id)
463
- tag='select'; tag << '#'+id if id
464
- options[:with].merge!(:name => name)
465
- expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
466
- end
449
+ def with_radio_button name, value
450
+ options = form_tag_options('radio',name,value)
451
+ should_have_input(options)
452
+ end
467
453
 
468
- def without_select name, options={}, &block
469
- options[:with] ||= {}
470
- id = options[:with].delete(:id)
471
- tag='select'; tag << '#'+id if id
472
- options[:with].merge!(:name => name)
473
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
474
- end
454
+ def without_radio_button name, value
455
+ options = form_tag_options('radio',name,value)
456
+ should_not_have_input(options)
457
+ end
475
458
 
476
- def with_option text, value=nil, options={}
477
- options[:with] ||= {}
478
- if value.is_a?(Hash)
479
- options.merge!(value)
480
- value=nil
481
- end
482
- tag='option'
483
- options[:with].merge!(:value => value.to_s) if value
484
- if options[:selected]
485
- options[:with].merge!(:selected => "selected")
486
- end
487
- options.delete(:selected)
488
- options.merge!(:text => text) if text
489
- expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options)
490
- end
459
+ def with_select name, options={}, &block
460
+ options[:with] ||= {}
461
+ id = options[:with].delete(:id)
462
+ tag='select'; tag << '#'+id if id
463
+ options[:with].merge!(:name => name)
464
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options, &block)
465
+ end
491
466
 
492
- def without_option text, value=nil, options={}
493
- options[:with] ||= {}
494
- if value.is_a?(Hash)
495
- options.merge!(value)
496
- value=nil
497
- end
498
- tag='option'
499
- options[:with].merge!(:value => value.to_s) if value
500
- if options[:selected]
501
- options[:with].merge!(:selected => "selected")
502
- end
503
- options.delete(:selected)
504
- options.merge!(:text => text) if text
505
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options)
506
- end
467
+ def without_select name, options={}, &block
468
+ options[:with] ||= {}
469
+ id = options[:with].delete(:id)
470
+ tag='select'; tag << '#'+id if id
471
+ options[:with].merge!(:name => name)
472
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options, &block)
473
+ end
507
474
 
508
- def with_button text, value=nil, options={}
509
- options[:with] ||= {}
510
- if value.is_a?(Hash)
511
- options.merge!(value)
512
- value=nil
513
- end
514
- options[:with].merge!(:value => value.to_s) if value
515
- options.merge!(:text => text) if text
516
- expect(@__current_scope_for_nokogiri_matcher).to have_tag('button', options)
475
+ def with_option text, value=nil, options={}
476
+ options[:with] ||= {}
477
+ if value.is_a?(Hash)
478
+ options.merge!(value)
479
+ value=nil
480
+ end
481
+ tag='option'
482
+ options[:with].merge!(:value => value.to_s) if value
483
+ if options[:selected]
484
+ options[:with].merge!(:selected => "selected")
517
485
  end
486
+ options.delete(:selected)
487
+ options.merge!(:text => text) if text
488
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag(tag, options)
489
+ end
518
490
 
519
- def without_button text, value=nil, options={}
520
- options[:with] ||= {}
521
- if value.is_a?(Hash)
522
- options.merge!(value)
523
- value=nil
524
- end
525
- options[:with].merge!(:value => value.to_s) if value
526
- options.merge!(:text => text) if text
527
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('button', options)
491
+ def without_option text, value=nil, options={}
492
+ options[:with] ||= {}
493
+ if value.is_a?(Hash)
494
+ options.merge!(value)
495
+ value=nil
496
+ end
497
+ tag='option'
498
+ options[:with].merge!(:value => value.to_s) if value
499
+ if options[:selected]
500
+ options[:with].merge!(:selected => "selected")
528
501
  end
502
+ options.delete(:selected)
503
+ options.merge!(:text => text) if text
504
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag(tag, options)
505
+ end
529
506
 
530
- def with_submit value
531
- options = { :with => { :type => 'submit', :value => value } }
532
- #options = form_tag_options('text',name,value)
533
- should_have_input(options)
507
+ def with_button text, value=nil, options={}
508
+ options[:with] ||= {}
509
+ if value.is_a?(Hash)
510
+ options.merge!(value)
511
+ value=nil
534
512
  end
513
+ options[:with].merge!(:value => value.to_s) if value
514
+ options.merge!(:text => text) if text
515
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag('button', options)
516
+ end
535
517
 
536
- def without_submit value
537
- #options = form_tag_options('text',name,value)
538
- options = { :with => { :type => 'submit', :value => value } }
539
- should_not_have_input(options)
518
+ def without_button text, value=nil, options={}
519
+ options[:with] ||= {}
520
+ if value.is_a?(Hash)
521
+ options.merge!(value)
522
+ value=nil
540
523
  end
524
+ options[:with].merge!(:value => value.to_s) if value
525
+ options.merge!(:text => text) if text
526
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('button', options)
527
+ end
541
528
 
542
- private
529
+ def with_submit value
530
+ options = { :with => { :type => 'submit', :value => value } }
531
+ #options = form_tag_options('text',name,value)
532
+ should_have_input(options)
533
+ end
543
534
 
544
- def should_have_input(options)
545
- expect(@__current_scope_for_nokogiri_matcher).to have_tag('input', options)
546
- end
535
+ def without_submit value
536
+ #options = form_tag_options('text',name,value)
537
+ options = { :with => { :type => 'submit', :value => value } }
538
+ should_not_have_input(options)
539
+ end
547
540
 
548
- def should_not_have_input(options)
549
- expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('input', options)
550
- end
541
+ private
551
542
 
552
- # form_tag in method name name mean smth. like input, submit, tags that should appear in a form
553
- def form_tag_options form_tag_type, form_tag_name, form_tag_value=nil
554
- options = { :with => { :name => form_tag_name, :type => form_tag_type } }
555
- # .to_s if value is a digit or smth. else, see issue#10
556
- options[:with].merge!(:value => form_tag_value.to_s) if form_tag_value
557
- return options
558
- end
543
+ def should_have_input(options)
544
+ expect(@__current_scope_for_nokogiri_matcher).to have_tag('input', options)
545
+ end
559
546
 
547
+ def should_not_have_input(options)
548
+ expect(@__current_scope_for_nokogiri_matcher).to_not have_tag('input', options)
560
549
  end
561
- end
562
550
 
563
- if defined? Cucumber
564
- World RSpec::HtmlMatchers
565
- else
566
- RSpec.configure do |config|
567
- config.include(RSpec::HtmlMatchers)
551
+ # form_tag in method name name mean smth. like input, submit, tags that should appear in a form
552
+ def form_tag_options form_tag_type, form_tag_name, form_tag_value=nil
553
+ options = { :with => { :name => form_tag_name, :type => form_tag_type } }
554
+ # .to_s if value is a digit or smth. else, see issue#10
555
+ options[:with].merge!(:value => form_tag_value.to_s) if form_tag_value
556
+ return options
568
557
  end
558
+
569
559
  end