rspec-tag_matchers 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: