rspec-tag_matchers 0.1.1 → 0.1.2

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.
@@ -4,5 +4,6 @@ rvm:
4
4
  - 1.9.2
5
5
  - 1.9.3
6
6
  - ree
7
- - rbx-2.0
7
+ - rbx-18mode
8
+ - rbx-19mode
8
9
  - jruby
@@ -17,10 +17,27 @@ containing HTML (this includes Nokogiri classes). They assume Rails conventions.
17
17
  it { should have_checkbox.for(:user => :terms_of_service) }
18
18
  end
19
19
 
20
+ == Getting Started
21
+
22
+ * Add +rspec-tag_matchers+ to your +Gemfile+:
23
+
24
+ group :test do
25
+ gem "rspec-tag_matchers"
26
+ end
27
+
28
+ * Add the tag matchers to the RSpec context. In +spec_helper+:
29
+
30
+ RSpec.configure do |config|
31
+ config.include RSpec::TagMatchers
32
+ end
33
+
34
+ * Now you can use the tag matchers in your RSpec tests. The included matchers are documented
35
+ here: http://rdoc.info/github/dcuddeback/rspec-tag_matchers/master/RSpec/TagMatchers.
36
+
20
37
  == Status
21
38
 
22
39
  <tt>rspec-tag_matchers</tt> is tested against Ruby 1.8.7, 1.9.2, 1.9.3, REE,
23
- Rubinius (1.8 mode) and JRuby.
40
+ Rubinius (1.8 and 1.9 modes) and JRuby.
24
41
 
25
42
  {<img src="https://secure.travis-ci.org/dcuddeback/rspec-tag_matchers.png?branch=master" />}[http://travis-ci.org/dcuddeback/rspec-tag_matchers]
26
43
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -1,5 +1,5 @@
1
1
  module RSpec::TagMatchers
2
- # Matches +<form>+ tags in HTML.
2
+ # Matches <tt><form></tt> tags in HTML.
3
3
  #
4
4
  # @modifier with_verb
5
5
  # Adds a criteria that the form must have the given HTTP verb.
@@ -1,7 +1,7 @@
1
1
  require 'deep_flattening'
2
2
 
3
3
  module RSpec::TagMatchers
4
- # Matches +<input>+ tags in HTML.
4
+ # Matches <tt><input></tt> tags in HTML.
5
5
  #
6
6
  # @modifier for
7
7
  # Adds a criteria that the input must be for the given attribute.
@@ -1,5 +1,5 @@
1
1
  module RSpec::TagMatchers
2
- # Matches +<select>+ tags in HTML.
2
+ # Matches <tt><select></tt> tags in HTML.
3
3
  #
4
4
  # @example Matching a select tag for a user's role
5
5
  # it { should have_select.for(:user => :role) }
@@ -6,12 +6,21 @@ module RSpec::TagMatchers
6
6
  # @modifier with_attribute
7
7
  # Adds a criteria that an element must match the given attributes.
8
8
  #
9
+ # @modifier with_content
10
+ # Adds a criteria that an element's content must match the given content.
11
+ #
12
+ # @modifier with_count
13
+ # Adds a criteria that the element must be found a certain number of times.
14
+ #
9
15
  # @modifier with_criteria
10
16
  # Adds an arbitrary criteria.
11
17
  #
12
18
  # @example Matching anchor tags
13
19
  # it { should have_tag(:a) }
14
20
  #
21
+ # @example Matching contents of a tag
22
+ # it { should have_tag(:a).with_content("my site") }
23
+ #
15
24
  # @example Matching anchor tags that link to "/"
16
25
  # it { should have_tag(:a).with_attribute(:href => "/") }
17
26
  #
@@ -130,9 +139,10 @@ module RSpec::TagMatchers
130
139
  # @return [Boolean]
131
140
  def matches?(rendered)
132
141
  @rendered = rendered
133
- Nokogiri::HTML::Document.parse(@rendered.to_s).css(@name).select do |element|
134
- matches_attributes?(element) && matches_criteria?(element)
135
- end.length > 0
142
+ matches = Nokogiri::HTML::Document.parse(@rendered.to_s).css(@name).select do |element|
143
+ matches_attributes?(element) && matches_content?(element) && matches_criteria?(element)
144
+ end
145
+ matches_count?(matches)
136
146
  end
137
147
 
138
148
  # Adds a constraint that the matched elements must match certain attributes. The +attributes+
@@ -157,6 +167,20 @@ module RSpec::TagMatchers
157
167
  end
158
168
  alias :with_attributes :with_attribute
159
169
 
170
+ # Adds a constraint on the matched element's content.
171
+ #
172
+ # @example
173
+ # have_tag(:p).with_content("Welcome!")
174
+ # have_tag(:p).with_content(/^Hello, \w+$/)
175
+ #
176
+ # @param [String, Regexp] content The expected contents of the matched element.
177
+ #
178
+ # @return [self]
179
+ def with_content(content)
180
+ @content = content
181
+ self
182
+ end
183
+
160
184
  # Adds an arbitrary criteria to the matched elements. The criteria can be a method name or a
161
185
  # block. The method or block should accept a single Nokogiri::XML::Node object as its argument
162
186
  # and return whether or not the element passed as an argument matches the criteria.
@@ -174,6 +198,19 @@ module RSpec::TagMatchers
174
198
  self
175
199
  end
176
200
 
201
+ # Adds a constraint that the matched elements appear a given number of times. The criteria must be a Fixnum
202
+ #
203
+ # @example
204
+ # have_div.with_count(2)
205
+ #
206
+ # @param [Fixnum] method The name of the method to be called.
207
+ #
208
+ # @return [self]
209
+ def with_count(count)
210
+ @count = count
211
+ self
212
+ end
213
+
177
214
  protected
178
215
 
179
216
  # Tests with +attribute+ matches +expected+ according the the attribute matching rules described
@@ -224,6 +261,22 @@ module RSpec::TagMatchers
224
261
  end
225
262
  end
226
263
 
264
+ # Answers whether or not +element+ matches the content set by {#with_content}.
265
+ #
266
+ # @param [Nokogiri::XML::Node] element The element to be tested.
267
+ #
268
+ # @return [Boolean]
269
+ def matches_content?(element)
270
+ return true if @content.nil?
271
+
272
+ case @content
273
+ when String
274
+ element.content == @content
275
+ when Regexp
276
+ element.content =~ @content
277
+ end
278
+ end
279
+
227
280
  # Answers whether or not +element+ matches the custom criteria set by {#with_criteria}.
228
281
  #
229
282
  # @param [Nokogiri::XML::Node] element The element to be tested.
@@ -240,11 +293,20 @@ module RSpec::TagMatchers
240
293
  end
241
294
  end
242
295
 
296
+ # Answers whether or not +element+ appears the number of times set by {#with_count}.
297
+ #
298
+ # @param [Array] matches The matched elements to be tested.
299
+ #
300
+ # @return [Boolean]
301
+ def matches_count?(matches)
302
+ @count ? matches.length == @count : matches.length > 0
303
+ end
304
+
243
305
  # Provides extra description that can be appended to the basic description.
244
306
  #
245
307
  # @return [String]
246
308
  def extra_description
247
- attributes_description
309
+ attributes_description + content_description + count_description
248
310
  end
249
311
 
250
312
  # Returns a description of the attribute criteria. For example, the description of an attribute
@@ -272,7 +334,7 @@ module RSpec::TagMatchers
272
334
  )
273
335
  end
274
336
 
275
- # Provides a prefix that can be used before a list of attribute criteria. Possible oututs are
337
+ # Provides a prefix that can be used before a list of attribute criteria. Possible outputs are
276
338
  # <tt>"with attribute"</tt>, <tt>"with attributes"</tt>, <tt>"without attribute"</tt>, and
277
339
  # <tt>"without attributes"</tt>.
278
340
  #
@@ -319,5 +381,21 @@ module RSpec::TagMatchers
319
381
  "#{key}=#{value.inspect}"
320
382
  end
321
383
  end
384
+
385
+ # Returns a string describing the contents that the element must match.
386
+ #
387
+ # @return [String]
388
+ def content_description
389
+ @content ? "with content #{@content.inspect}" : ""
390
+ end
391
+
392
+ # Returns a string describing the number of times the element must be matched. For example, the
393
+ # description of an attribute criteria of <tt>with_count(2)</tt> will look like <tt>'2
394
+ # times'</tt>.
395
+ #
396
+ # @return [String]
397
+ def count_description
398
+ @count ? "#{@count} times" : ""
399
+ end
322
400
  end
323
401
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rspec-tag_matchers}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{David Cuddeback}]
12
- s.date = %q{2012-02-18}
12
+ s.date = %q{2012-04-02}
13
13
  s.description = %q{A collection of RSpec matchers that understand Rails conventions, allowing for more concise specs.}
14
14
  s.email = %q{david.cuddeback@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -57,6 +57,53 @@ describe RSpec::TagMatchers::HasTag do
57
57
  end
58
58
  end
59
59
 
60
+ describe "content matching" do
61
+ context "matches with string" do
62
+ context 'have_tag(:foo).with_content("bar")' do
63
+ subject { have_tag(:foo).with_content("bar") }
64
+ it { should match("<foo>bar</foo>") }
65
+ it { should match("<foo><span>bar</span></foo>") }
66
+ it { should match("<foo><span>b</span>ar</foo>") }
67
+ it { should_not match("<foo>1bar</foo>") }
68
+ it { should_not match("<foo>bar2</foo>") }
69
+ it { should_not match("<foo>1bar2</foo>") }
70
+ end
71
+ end
72
+
73
+ context "matches with regexp" do
74
+ context 'have_tag(:foo).with_content(/bar/)' do
75
+ subject { have_tag(:foo).with_content(/bar/) }
76
+ it { should match("<foo>bar</foo>") }
77
+ it { should match("<foo>123bar456</foo>") }
78
+ it { should match("<foo>123<span>b</span>ar456</foo>") }
79
+ it { should_not match("<foo></foo>") }
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "count matching" do
85
+ context 'have_tag(:foo).with_count(1)' do
86
+ subject { have_tag(:foo).with_count(1) }
87
+ it { should match("<foo></foo>") }
88
+ it { should_not match("<foo></foo><foo></foo>") }
89
+ it { should_not match("<foo></foo><foo></foo><foo></foo>") }
90
+ end
91
+
92
+ context 'have_tag(:foo).with_count(2)' do
93
+ subject { have_tag(:foo).with_count(2) }
94
+ it { should_not match("<foo></foo>") }
95
+ it { should match("<foo></foo><foo></foo>") }
96
+ it { should_not match("<foo></foo><foo></foo><foo></foo>") }
97
+ end
98
+
99
+ context 'have_tag(:foo).with_count(3)' do
100
+ subject { have_tag(:foo).with_count(3) }
101
+ it { should_not match("<foo></foo>") }
102
+ it { should_not match("<foo></foo><foo></foo>") }
103
+ it { should match("<foo></foo><foo></foo><foo></foo>") }
104
+ end
105
+ end
106
+
60
107
  describe "attribute value matching" do
61
108
  context "true matches presence of attribute" do
62
109
  context 'have_tag(:foo).with_attribute(:bar => true)' do
@@ -346,6 +393,25 @@ describe RSpec::TagMatchers::HasTag do
346
393
  its(:description) { should == 'have "foo" tag with attribute bar=anything and without attribute baz' }
347
394
  end
348
395
  end
396
+
397
+ context "for matchers with content criteria" do
398
+ context 'have_tag(:foo).with_content("bar")' do
399
+ subject { have_tag(:foo).with_content("bar") }
400
+ its(:description) { should == 'have "foo" tag with content "bar"' }
401
+ end
402
+
403
+ context 'have_tag(:foo).with_content(/bar/)' do
404
+ subject { have_tag(:foo).with_content(/bar/) }
405
+ its(:description) { should == 'have "foo" tag with content /bar/' }
406
+ end
407
+ end
408
+
409
+ context "for matchers with count criteria" do
410
+ context 'have_tag(:foo).with_count(2)' do
411
+ subject { have_tag(:foo).with_count(2) }
412
+ its(:description) { should == 'have "foo" tag 2 times'}
413
+ end
414
+ end
349
415
  end
350
416
 
351
417
  describe "#failure_message" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-tag_matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-18 00:00:00.000000000Z
12
+ date: 2012-04-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &2154865400 !ruby/object:Gem::Requirement
16
+ requirement: &2153537300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2154865400
24
+ version_requirements: *2153537300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2154864620 !ruby/object:Gem::Requirement
27
+ requirement: &2153536760 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2154864620
35
+ version_requirements: *2153536760
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yard
38
- requirement: &2154864000 !ruby/object:Gem::Requirement
38
+ requirement: &2153536120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2154864000
46
+ version_requirements: *2153536120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &2154863260 !ruby/object:Gem::Requirement
49
+ requirement: &2153535280 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2154863260
57
+ version_requirements: *2153535280
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &2154862600 !ruby/object:Gem::Requirement
60
+ requirement: &2153534540 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2154862600
68
+ version_requirements: *2153534540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: guard
71
- requirement: &2154861880 !ruby/object:Gem::Requirement
71
+ requirement: &2153533480 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2154861880
79
+ version_requirements: *2153533480
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: guard-rspec
82
- requirement: &2154861180 !ruby/object:Gem::Requirement
82
+ requirement: &2153532360 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2154861180
90
+ version_requirements: *2153532360
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: guard-bundler
93
- requirement: &2154859720 !ruby/object:Gem::Requirement
93
+ requirement: &2153531700 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2154859720
101
+ version_requirements: *2153531700
102
102
  description: A collection of RSpec matchers that understand Rails conventions, allowing
103
103
  for more concise specs.
104
104
  email: david.cuddeback@gmail.com
@@ -156,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
156
  version: '0'
157
157
  segments:
158
158
  - 0
159
- hash: 95040879081577537
159
+ hash: -1376525107478153861
160
160
  required_rubygems_version: !ruby/object:Gem::Requirement
161
161
  none: false
162
162
  requirements: