rails-dom-testing 2.0.2 → 2.1.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
- SHA1:
3
- metadata.gz: 1842469f0b76af06327ec4e2fccfcf90072628f0
4
- data.tar.gz: 413a881657051c8c41cb5f72fa18f709b471fa82
2
+ SHA256:
3
+ metadata.gz: d3af7ffd9f30304ed5cc33f9d2483fc9ba0827f6aade8d3e3bcef4410cb41956
4
+ data.tar.gz: f1ba5e86a04619e0c9943ce4543dca021b1f2f8593ce2fa18b2e2e66318ed2aa
5
5
  SHA512:
6
- metadata.gz: e02a2b88d647aca01978d1145d822d7b8f258cdbe0ed3e394020be194ffac9d3e122599f5aa500cca4b452efd0176a7cbafe8a22506ab8043f675c526192dbb5
7
- data.tar.gz: c7b4be94cd7c10bb8137f153da564c3117144a146cc247ec88120053eb845ae5a7b608b3bf5376331b1a9101735910692f13fa0a29bdcea234e187435ff7d8ca
6
+ metadata.gz: 89242830f894040fa4bfca0777099dbd41f45b48745fa155ce0084e9abd60d66d61ab3f8be307bdbe8fd543b0cac1970b0fd7b2e7205430e425866719d832774
7
+ data.tar.gz: f3398b23f429cc591c053750557135b7e5fc68cb9ba6b107b4f605c3ff2ca3e389261e060fa9a51755bc3d8b428cf7954588bf496b205fa84e10faf434dfe915
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This gem is responsible for comparing HTML doms and asserting that DOM elements are present in Rails applications.
4
4
  Doms are compared via `assert_dom_equal` and `assert_dom_not_equal`.
5
- Elements are asserted via `assert_select`, `assert_select_encoded`, `assert_select_email` and a subset of the dom can be selected with `css_select`.
5
+ Elements are asserted via `assert_dom`, `assert_dom_encoded`, `assert_dom_email` and a subset of the dom can be selected with `css_select`.
6
6
  The gem is developed for Rails 4.2 and above, and will not work on previous versions.
7
7
 
8
8
  ## Nokogiri::CSS::SyntaxError exceptions when upgrading to Rails 4.2:
@@ -41,21 +41,21 @@ assert_dom_not_equal '<h1>Portuguese</h1>', '<h1>Danish</h1>'
41
41
  # implicitly selects from the document_root_element
42
42
  css_select '.hello' # => Nokogiri::XML::NodeSet of elements with hello class
43
43
 
44
- # select from a supplied node. assert_select asserts elements exist.
45
- assert_select document_root_element.at('.hello'), '.goodbye'
44
+ # select from a supplied node. assert_dom asserts elements exist.
45
+ assert_dom document_root_element.at('.hello'), '.goodbye'
46
46
 
47
47
  # elements in CDATA encoded sections can also be selected
48
- assert_select_encoded '#out-of-your-element'
48
+ assert_dom_encoded '#out-of-your-element'
49
49
 
50
50
  # assert elements within an html email exists
51
- assert_select_email '#you-got-mail'
51
+ assert_dom_email '#you-got-mail'
52
52
  ```
53
53
 
54
54
  The documentation in [selector_assertions.rb](https://github.com/rails/rails-dom-testing/blob/master/lib/rails/dom/testing/assertions/selector_assertions.rb) goes into a lot more detail of how selector assertions can be used.
55
55
 
56
56
  ## Read more
57
57
 
58
- Under the hood the doms are parsed with Nokogiri and you'll generally be working with these two classes:
58
+ Under the hood the doms are parsed with Nokogiri, and you'll generally be working with these two classes:
59
59
  - [`Nokogiri::XML::Node`](http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node)
60
60
  - [`Nokogiri::XML::NodeSet`](http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/NodeSet)
61
61
 
@@ -7,43 +7,61 @@ module Rails
7
7
  #
8
8
  # # assert that the referenced method generates the appropriate HTML string
9
9
  # assert_dom_equal '<a href="http://www.example.com">Apples</a>', link_to("Apples", "http://www.example.com")
10
- def assert_dom_equal(expected, actual, message = nil)
10
+ def assert_dom_equal(expected, actual, message = nil, strict: false)
11
11
  expected_dom, actual_dom = fragment(expected), fragment(actual)
12
12
  message ||= "Expected: #{expected}\nActual: #{actual}"
13
- assert compare_doms(expected_dom, actual_dom), message
13
+ assert compare_doms(expected_dom, actual_dom, strict), message
14
14
  end
15
15
 
16
16
  # The negated form of +assert_dom_equal+.
17
17
  #
18
18
  # # assert that the referenced method does not generate the specified HTML string
19
19
  # assert_dom_not_equal '<a href="http://www.example.com">Apples</a>', link_to("Oranges", "http://www.example.com")
20
- def assert_dom_not_equal(expected, actual, message = nil)
20
+ def assert_dom_not_equal(expected, actual, message = nil, strict: false)
21
21
  expected_dom, actual_dom = fragment(expected), fragment(actual)
22
22
  message ||= "Expected: #{expected}\nActual: #{actual}"
23
- assert_not compare_doms(expected_dom, actual_dom), message
23
+ assert_not compare_doms(expected_dom, actual_dom, strict), message
24
24
  end
25
25
 
26
26
  protected
27
27
 
28
- def compare_doms(expected, actual)
29
- return false unless expected.children.size == actual.children.size
28
+ def compare_doms(expected, actual, strict)
29
+ expected_children = extract_children(expected, strict)
30
+ actual_children = extract_children(actual, strict)
31
+ return false unless expected_children.size == actual_children.size
30
32
 
31
- expected.children.each_with_index do |child, i|
32
- return false unless equal_children?(child, actual.children[i])
33
+ expected_children.each_with_index do |child, i|
34
+ return false unless equal_children?(child, actual_children[i], strict)
33
35
  end
34
36
 
35
37
  true
36
38
  end
37
39
 
38
- def equal_children?(child, other_child)
40
+ def extract_children(node, strict)
41
+ if strict
42
+ node.children
43
+ else
44
+ node.children.reject{|n| n.text? && n.text.blank?}
45
+ end
46
+ end
47
+
48
+ def equal_children?(child, other_child, strict)
39
49
  return false unless child.type == other_child.type
40
50
 
41
51
  if child.element?
42
52
  child.name == other_child.name &&
43
53
  equal_attribute_nodes?(child.attribute_nodes, other_child.attribute_nodes) &&
44
- compare_doms(child, other_child)
54
+ compare_doms(child, other_child, strict)
45
55
  else
56
+ equal_child?(child, other_child, strict)
57
+ end
58
+ end
59
+
60
+ def equal_child?(child, other_child, strict)
61
+ if strict
46
62
  child.to_s == other_child.to_s
63
+ else
64
+ child.to_s.split == other_child.to_s.split
47
65
  end
48
66
  end
49
67
 
@@ -1,13 +1,9 @@
1
- require 'active_support/concern'
2
-
3
1
  module Rails
4
2
  module Dom
5
3
  module Testing
6
4
  module Assertions
7
5
  module SelectorAssertions
8
6
  module CountDescribable
9
- extend ActiveSupport::Concern
10
-
11
7
  private
12
8
  def count_description(min, max, count) #:nodoc:
13
9
  if min && max && (max != min)
@@ -4,6 +4,8 @@ require_relative 'substitution_context'
4
4
  class HTMLSelector #:nodoc:
5
5
  attr_reader :css_selector, :tests, :message
6
6
 
7
+ include Minitest::Assertions
8
+
7
9
  def initialize(values, previous_selection = nil, &root_fallback)
8
10
  @values = values
9
11
  @root = extract_root(previous_selection, root_fallback)
@@ -11,6 +13,10 @@ class HTMLSelector #:nodoc:
11
13
  @tests = extract_equality_tests
12
14
  @message = @values.shift
13
15
 
16
+ if @message.is_a?(Hash)
17
+ raise ArgumentError, "Last argument was a Hash, which would be used for the assertion message. You probably want this to be a String, or you have the wrong type of arguments."
18
+ end
19
+
14
20
  if @values.shift
15
21
  raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type"
16
22
  end
@@ -48,7 +54,7 @@ class HTMLSelector #:nodoc:
48
54
  content.sub!(/\A\n/, '') if text_matches && match.name == "textarea"
49
55
 
50
56
  next if regex_matching ? (content =~ match_with) : (content == match_with)
51
- content_mismatch ||= sprintf("<%s> expected but was\n<%s>.", match_with, content)
57
+ content_mismatch ||= diff(match_with, content)
52
58
  true
53
59
  end
54
60
 
@@ -61,7 +67,7 @@ class HTMLSelector #:nodoc:
61
67
 
62
68
  if possible_root == nil
63
69
  raise ArgumentError, 'First argument is either selector or element ' \
64
- 'to select, but nil found. Perhaps you called assert_select with ' \
70
+ 'to select, but nil found. Perhaps you called assert_dom with ' \
65
71
  'an element that does not exist?'
66
72
  elsif possible_root.respond_to?(:css)
67
73
  @values.shift # remove the root, so selector is the first argument
@@ -87,20 +93,20 @@ class HTMLSelector #:nodoc:
87
93
  def extract_equality_tests
88
94
  comparisons = {}
89
95
  case comparator = @values.shift
90
- when Hash
91
- comparisons = comparator
92
- when String, Regexp
93
- comparisons[:text] = comparator
94
- when Integer
95
- comparisons[:count] = comparator
96
- when Range
97
- comparisons[:minimum] = comparator.begin
98
- comparisons[:maximum] = comparator.end
99
- when FalseClass
100
- comparisons[:count] = 0
101
- when NilClass, TrueClass
102
- comparisons[:minimum] = 1
103
- else raise ArgumentError, "I don't understand what you're trying to match"
96
+ when Hash
97
+ comparisons = comparator
98
+ when String, Regexp
99
+ comparisons[:text] = comparator
100
+ when Integer
101
+ comparisons[:count] = comparator
102
+ when Range
103
+ comparisons[:minimum] = comparator.begin
104
+ comparisons[:maximum] = comparator.end
105
+ when FalseClass
106
+ comparisons[:count] = 0
107
+ when NilClass, TrueClass
108
+ comparisons[:minimum] = 1
109
+ else raise ArgumentError, "I don't understand what you're trying to match"
104
110
  end
105
111
 
106
112
  # By default we're looking for at least one match.
@@ -4,13 +4,10 @@ class SubstitutionContext
4
4
  end
5
5
 
6
6
  def substitute!(selector, values, format_for_presentation = false)
7
- selector = selector.dup
8
-
9
- while !values.empty? && substitutable?(values.first) && selector.index(@substitute)
10
- selector.sub! @substitute, matcher_for(values.shift, format_for_presentation)
7
+ selector.gsub @substitute do |match|
8
+ next match[0] if values.empty? || !substitutable?(values.first)
9
+ matcher_for(values.shift, format_for_presentation)
11
10
  end
12
-
13
- selector
14
11
  end
15
12
 
16
13
  def match(matches, attribute, matcher)
@@ -23,11 +20,11 @@ class SubstitutionContext
23
20
  if format_for_presentation
24
21
  value.inspect # Avoid to_s so Regexps aren't put in quotes.
25
22
  else
26
- value.to_s.inspect
23
+ "\"#{value}\""
27
24
  end
28
25
  end
29
26
 
30
27
  def substitutable?(value)
31
- value.is_a?(String) || value.is_a?(Regexp)
28
+ [ Symbol, Numeric, String, Regexp ].any? { |type| value.is_a? type }
32
29
  end
33
30
  end
@@ -1,4 +1,3 @@
1
- require 'active_support/deprecation'
2
1
  require_relative 'selector_assertions/count_describable'
3
2
  require_relative 'selector_assertions/html_selector'
4
3
 
@@ -6,9 +5,9 @@ module Rails
6
5
  module Dom
7
6
  module Testing
8
7
  module Assertions
9
- # Adds the +assert_select+ method for use in Rails functional
8
+ # Adds the +assert_dom+ method for use in Rails functional
10
9
  # test cases, which can be used to make assertions on the response HTML of a controller
11
- # action. You can also call +assert_select+ within another +assert_select+ to
10
+ # action. You can also call +assert_dom+ within another +assert_dom+ to
12
11
  # make assertions on elements selected by the enclosing assertion.
13
12
  #
14
13
  # Use +css_select+ to select elements without making an assertions, either
@@ -16,8 +15,8 @@ module Rails
16
15
  #
17
16
  # In addition to HTML responses, you can make the following assertions:
18
17
  #
19
- # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
20
- # * +assert_select_email+ - Assertions on the HTML body of an e-mail.
18
+ # * +assert_dom_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
19
+ # * +assert_dom_email+ - Assertions on the HTML body of an e-mail.
21
20
  module SelectorAssertions
22
21
 
23
22
  # Select and return all matching elements.
@@ -70,38 +69,41 @@ module Rails
70
69
  # starting from (and including) that element and all its children in
71
70
  # depth-first order.
72
71
  #
73
- # If no element is specified +assert_select+ selects from
72
+ # If no element is specified +assert_dom+ selects from
74
73
  # the element returned in +document_root_element+
75
- # unless +assert_select+ is called from within an +assert_select+ block.
76
- # Override +document_root_element+ to tell +assert_select+ what to select from.
74
+ # unless +assert_dom+ is called from within an +assert_dom+ block.
75
+ # Override +document_root_element+ to tell +assert_dom+ what to select from.
77
76
  # The default implementation raises an exception explaining this.
78
77
  #
79
- # When called with a block +assert_select+ passes an array of selected elements
80
- # to the block. Calling +assert_select+ from the block, with no element specified,
78
+ # When called with a block +assert_dom+ passes an array of selected elements
79
+ # to the block. Calling +assert_dom+ from the block, with no element specified,
81
80
  # runs the assertion on the complete set of elements selected by the enclosing assertion.
82
- # Alternatively the array may be iterated through so that +assert_select+ can be called
81
+ # Alternatively the array may be iterated through so that +assert_dom+ can be called
83
82
  # separately for each element.
84
83
  #
85
84
  #
86
85
  # ==== Example
87
86
  # If the response contains two ordered lists, each with four list elements then:
88
- # assert_select "ol" do |elements|
87
+ # assert_dom "ol" do |elements|
89
88
  # elements.each do |element|
90
- # assert_select element, "li", 4
89
+ # assert_dom element, "li", 4
91
90
  # end
92
91
  # end
93
92
  #
94
93
  # will pass, as will:
95
- # assert_select "ol" do
96
- # assert_select "li", 8
94
+ # assert_dom "ol" do
95
+ # assert_dom "li", 8
97
96
  # end
98
97
  #
99
- # The selector may be a CSS selector expression (String) or an expression
98
+ # The selector may be a CSS selector expression (String, Symbol, or Numeric) or an expression
100
99
  # with substitution values (Array).
101
100
  # Substitution uses a custom pseudo class match. Pass in whatever attribute you want to match (enclosed in quotes) and a ? for the substitution.
102
- # assert_select returns nil if called with an invalid css selector.
101
+ # assert_dom returns nil if called with an invalid css selector.
103
102
  #
104
- # assert_select "div:match('id', ?)", /\d+/
103
+ # assert_dom "div:match('id', ?)", "id_string"
104
+ # assert_dom "div:match('id', ?)", :id_string
105
+ # assert_dom "div:match('id', ?)", 1
106
+ # assert_dom "div:match('id', ?)", /\d+/
105
107
  #
106
108
  # === Equality Tests
107
109
  #
@@ -133,32 +135,32 @@ module Rails
133
135
  # evaluated the block is called with an array of all matched elements.
134
136
  #
135
137
  # # At least one form element
136
- # assert_select "form"
138
+ # assert_dom "form"
137
139
  #
138
140
  # # Form element includes four input fields
139
- # assert_select "form input", 4
141
+ # assert_dom "form input", 4
140
142
  #
141
143
  # # Page title is "Welcome"
142
- # assert_select "title", "Welcome"
144
+ # assert_dom "title", "Welcome"
143
145
  #
144
146
  # # Page title is "Welcome" and there is only one title element
145
- # assert_select "title", {count: 1, text: "Welcome"},
147
+ # assert_dom "title", {count: 1, text: "Welcome"},
146
148
  # "Wrong title or more than one title element"
147
149
  #
148
150
  # # Page contains no forms
149
- # assert_select "form", false, "This page must contain no forms"
151
+ # assert_dom "form", false, "This page must contain no forms"
150
152
  #
151
153
  # # Test the content and style
152
- # assert_select "body div.header ul.menu"
154
+ # assert_dom "body div.header ul.menu"
153
155
  #
154
156
  # # Use substitution values
155
- # assert_select "ol>li:match('id', ?)", /item-\d+/
157
+ # assert_dom "ol>li:match('id', ?)", /item-\d+/
156
158
  #
157
159
  # # All input fields in the form have a name
158
- # assert_select "form input" do
159
- # assert_select ":match('name', ?)", /.+/ # Not empty
160
+ # assert_dom "form input" do
161
+ # assert_dom ":match('name', ?)", /.+/ # Not empty
160
162
  # end
161
- def assert_select(*args, &block)
163
+ def assert_dom(*args, &block)
162
164
  @selected ||= nil
163
165
 
164
166
  selector = HTMLSelector.new(args, @selected) { nodeset document_root_element }
@@ -175,6 +177,7 @@ module Rails
175
177
  nest_selection(matches, &block) if block_given? && !matches.empty?
176
178
  end
177
179
  end
180
+ alias_method :assert_select, :assert_dom
178
181
 
179
182
  # Extracts the content of an element, treats it as encoded HTML and runs
180
183
  # nested assertion on it.
@@ -187,30 +190,30 @@ module Rails
187
190
  # element +encoded+. It then calls the block with all un-encoded elements.
188
191
  #
189
192
  # # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix)
190
- # assert_select "feed[xmlns='http://www.w3.org/2005/Atom']" do
193
+ # assert_dom "feed[xmlns='http://www.w3.org/2005/Atom']" do
191
194
  # # Select each entry item and then the title item
192
- # assert_select "entry>title" do
195
+ # assert_dom "entry>title" do
193
196
  # # Run assertions on the encoded title elements
194
- # assert_select_encoded do
195
- # assert_select "b"
197
+ # assert_dom_encoded do
198
+ # assert_dom "b"
196
199
  # end
197
200
  # end
198
201
  # end
199
202
  #
200
203
  #
201
204
  # # Selects all paragraph tags from within the description of an RSS feed
202
- # assert_select "rss[version=2.0]" do
205
+ # assert_dom "rss[version=2.0]" do
203
206
  # # Select description element of each feed item.
204
- # assert_select "channel>item>description" do
207
+ # assert_dom "channel>item>description" do
205
208
  # # Run assertions on the encoded elements.
206
- # assert_select_encoded do
207
- # assert_select "p"
209
+ # assert_dom_encoded do
210
+ # assert_dom "p"
208
211
  # end
209
212
  # end
210
213
  # end
211
- def assert_select_encoded(element = nil, &block)
214
+ def assert_dom_encoded(element = nil, &block)
212
215
  if !element && !@selected
213
- raise ArgumentError, "Element is required when called from a nonnested assert_select"
216
+ raise ArgumentError, "Element is required when called from a nonnested assert_dom"
214
217
  end
215
218
 
216
219
  content = nodeset(element || @selected).map do |elem|
@@ -224,27 +227,28 @@ module Rails
224
227
  if content.empty?
225
228
  yield selected
226
229
  else
227
- assert_select ":root", &block
230
+ assert_dom ":root", &block
228
231
  end
229
232
  end
230
233
  end
234
+ alias_method :assert_select_encoded, :assert_dom_encoded
231
235
 
232
236
  # Extracts the body of an email and runs nested assertions on it.
233
237
  #
234
238
  # You must enable deliveries for this assertion to work, use:
235
239
  # ActionMailer::Base.perform_deliveries = true
236
240
  #
237
- # assert_select_email do
238
- # assert_select "h1", "Email alert"
241
+ # assert_dom_email do
242
+ # assert_dom "h1", "Email alert"
239
243
  # end
240
244
  #
241
- # assert_select_email do
242
- # items = assert_select "ol>li"
245
+ # assert_dom_email do
246
+ # items = assert_dom "ol>li"
243
247
  # items.each do
244
248
  # # Work with items here...
245
249
  # end
246
250
  # end
247
- def assert_select_email(&block)
251
+ def assert_dom_email(&block)
248
252
  deliveries = ActionMailer::Base.deliveries
249
253
  assert !deliveries.empty?, "No e-mail in delivery list"
250
254
 
@@ -252,25 +256,26 @@ module Rails
252
256
  (delivery.parts.empty? ? [delivery] : delivery.parts).each do |part|
253
257
  if part["Content-Type"].to_s =~ /^text\/html\W/
254
258
  root = Nokogiri::HTML::DocumentFragment.parse(part.body.to_s)
255
- assert_select root, ":root", &block
259
+ assert_dom root, ":root", &block
256
260
  end
257
261
  end
258
262
  end
259
263
  end
264
+ alias_method :assert_select_email, :assert_dom_email
260
265
 
261
266
  private
262
267
  include CountDescribable
263
268
 
264
269
  def document_root_element
265
270
  raise NotImplementedError, 'Implementing document_root_element makes ' \
266
- 'assert_select work without needing to specify an element to select from.'
271
+ 'assert_dom work without needing to specify an element to select from.'
267
272
  end
268
273
 
269
274
  # +equals+ must contain :minimum, :maximum and :count keys
270
275
  def assert_size_match!(size, equals, css_selector, message = nil)
271
276
  min, max, count = equals[:minimum], equals[:maximum], equals[:count]
272
277
 
273
- message ||= %(Expected #{count_description(min, max, count)} matching "#{css_selector}", found #{size}.)
278
+ message ||= %(Expected #{count_description(min, max, count)} matching #{css_selector.inspect}, found #{size})
274
279
  if count
275
280
  assert_equal count, size, message
276
281
  else
@@ -280,7 +285,7 @@ module Rails
280
285
  end
281
286
 
282
287
  def nest_selection(selection)
283
- # Set @selected to allow nested assert_select.
288
+ # Set @selected to allow nested assert_dom.
284
289
  # Can be nested several levels deep.
285
290
  old_selected, @selected = @selected, selection
286
291
  yield @selected
@@ -292,6 +297,7 @@ module Rails
292
297
  if node.is_a?(Nokogiri::XML::NodeSet)
293
298
  node
294
299
  else
300
+ node ||= Nokogiri::HTML::Document.new
295
301
  Nokogiri::XML::NodeSet.new(node.document, [node])
296
302
  end
297
303
  end
@@ -1,18 +1,14 @@
1
- require 'active_support/concern'
2
1
  require 'nokogiri'
2
+ require 'rails/dom/testing/assertions/dom_assertions'
3
+ require 'rails/dom/testing/assertions/selector_assertions'
3
4
 
4
5
  module Rails
5
6
  module Dom
6
7
  module Testing
7
8
  module Assertions
8
- autoload :DomAssertions, 'rails/dom/testing/assertions/dom_assertions'
9
- autoload :SelectorAssertions, 'rails/dom/testing/assertions/selector_assertions'
10
-
11
- extend ActiveSupport::Concern
12
-
13
9
  include DomAssertions
14
10
  include SelectorAssertions
15
11
  end
16
12
  end
17
13
  end
18
- end
14
+ end
@@ -1,7 +1,7 @@
1
1
  module Rails
2
2
  module Dom
3
3
  module Testing
4
- VERSION = "2.0.2"
4
+ VERSION = "2.1.0"
5
5
  end
6
6
  end
7
7
  end
@@ -47,4 +47,79 @@ class DomAssertionsTest < ActiveSupport::TestCase
47
47
  %{<a><b c="2" /></a>}
48
48
  )
49
49
  end
50
- end
50
+
51
+ def test_dom_equal_with_whitespace_strict
52
+ canonical = %{<a><b>hello</b> world</a>}
53
+ assert_dom_not_equal(canonical, %{<a>\n<b>hello\n </b> world</a>}, strict: true)
54
+ assert_dom_not_equal(canonical, %{<a> \n <b>\n hello</b> world</a>}, strict: true)
55
+ assert_dom_not_equal(canonical, %{<a>\n\t<b>hello</b> world</a>}, strict: true)
56
+ assert_dom_equal(canonical, %{<a><b>hello</b> world</a>}, strict: true)
57
+ end
58
+
59
+ def test_dom_equal_with_whitespace
60
+ canonical = %{<a><b>hello</b> world</a>}
61
+ assert_dom_equal(canonical, %{<a>\n<b>hello\n </b> world</a>})
62
+ assert_dom_equal(canonical, %{<a>\n<b>hello </b>\nworld</a>})
63
+ assert_dom_equal(canonical, %{<a> \n <b>\n hello</b> world</a>})
64
+ assert_dom_equal(canonical, %{<a> \n <b> hello </b>world</a>})
65
+ assert_dom_equal(canonical, %{<a> \n <b>hello </b>world\n</a>\n})
66
+ assert_dom_equal(canonical, %{<a>\n\t<b>hello</b> world</a>})
67
+ assert_dom_equal(canonical, %{<a>\n\t<b>hello </b>\n\tworld</a>})
68
+ end
69
+
70
+ def test_dom_equal_with_attribute_whitespace
71
+ canonical = %(<div data-wow="Don't strip this">)
72
+ assert_dom_equal(canonical, %(<div data-wow="Don't strip this">))
73
+ assert_dom_not_equal(canonical, %(<div data-wow="Don't strip this">))
74
+ end
75
+
76
+ def test_dom_equal_with_indentation
77
+ canonical = %{<a>hello <b>cruel</b> world</a>}
78
+ assert_dom_equal(canonical, <<-HTML)
79
+ <a>
80
+ hello
81
+ <b>cruel</b>
82
+ world
83
+ </a>
84
+ HTML
85
+
86
+ assert_dom_equal(canonical, <<-HTML)
87
+ <a>
88
+ hello
89
+ <b>cruel</b>
90
+ world
91
+ </a>
92
+ HTML
93
+
94
+ assert_dom_equal(canonical, <<-HTML)
95
+ <a>hello
96
+ <b>
97
+ cruel
98
+ </b>
99
+ world</a>
100
+ HTML
101
+ end
102
+
103
+ def test_dom_equal_with_surrounding_whitespace
104
+ canonical = %{<p>Lorem ipsum dolor</p><p>sit amet, consectetur adipiscing elit</p>}
105
+ assert_dom_equal(canonical, <<-HTML)
106
+ <p>
107
+ Lorem
108
+ ipsum
109
+ dolor
110
+ </p>
111
+
112
+ <p>
113
+ sit amet,
114
+ consectetur
115
+ adipiscing elit
116
+ </p>
117
+ HTML
118
+ end
119
+
120
+ def test_dom_not_equal_with_interior_whitespace
121
+ with_space = %{<a><b>hello world</b></a>}
122
+ without_space = %{<a><b>helloworld</b></a>}
123
+ assert_dom_not_equal(with_space, without_space)
124
+ end
125
+ end
@@ -135,6 +135,21 @@ class AssertSelectTest < ActiveSupport::TestCase
135
135
  end
136
136
  end
137
137
 
138
+ def test_multiple_substitution_values
139
+ render_html '<input name="foo[12]" value="34">'
140
+ assert_select ":match('name', ?):match('value', ?)", /\w+\[\d+\]/, /\d+/
141
+ end
142
+
143
+ def test_substitution_values_with_values_other_than_string_or_regexp
144
+ render_html %Q{<div id="id_string">symbol</div><div id="1">numeric</div>}
145
+ assert_select "div:match('id', ?)", :id_string do |elements|
146
+ assert_equal 1, elements.size
147
+ end
148
+ assert_select "div:match('id', ?)", 1 do |elements|
149
+ assert_equal 1, elements.size
150
+ end
151
+ end
152
+
138
153
  def test_assert_select_root_html
139
154
  render_html '<a></a>'
140
155
 
@@ -302,6 +317,24 @@ EOF
302
317
  assert_select '.foo'
303
318
  end
304
319
 
320
+ def test_assert_select_with_extra_argument
321
+ render_html '<html><head><title>Welcome</title></head><body><div></div></body></html>'
322
+
323
+ assert_raises ArgumentError do
324
+ assert_select "title", "Welcome", count: 1
325
+ end
326
+
327
+ assert_select "title", text: "Welcome", count: 1
328
+ end
329
+
330
+ def test_assert_select_on_blank_response
331
+ render_html ""
332
+ assert_select "div", 0
333
+ assert_failure(/Expected exactly 1 element matching \"div\", found 0./) do
334
+ assert_select "div", 1
335
+ end
336
+ end
337
+
305
338
  protected
306
339
  def render_html(html)
307
340
  fake_render(:html, html)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-dom-testing
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Mendonça França
@@ -9,20 +9,20 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-27 00:00:00.000000000 Z
12
+ date: 2023-06-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '1.6'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '1.6'
28
28
  - !ruby/object:Gem::Dependency
@@ -31,32 +31,26 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 4.2.0
35
- - - "<"
36
- - !ruby/object:Gem::Version
37
- version: '6.0'
34
+ version: 5.0.0
38
35
  type: :runtime
39
36
  prerelease: false
40
37
  version_requirements: !ruby/object:Gem::Requirement
41
38
  requirements:
42
39
  - - ">="
43
40
  - !ruby/object:Gem::Version
44
- version: 4.2.0
45
- - - "<"
46
- - !ruby/object:Gem::Version
47
- version: '6.0'
41
+ version: 5.0.0
48
42
  - !ruby/object:Gem::Dependency
49
43
  name: bundler
50
44
  requirement: !ruby/object:Gem::Requirement
51
45
  requirements:
52
- - - "~>"
46
+ - - ">="
53
47
  - !ruby/object:Gem::Version
54
48
  version: '1.3'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
52
  requirements:
59
- - - "~>"
53
+ - - ">="
60
54
  - !ruby/object:Gem::Version
61
55
  version: '1.3'
62
56
  - !ruby/object:Gem::Dependency
@@ -128,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
122
  - !ruby/object:Gem::Version
129
123
  version: '0'
130
124
  requirements: []
131
- rubyforge_project:
132
- rubygems_version: 2.6.8
125
+ rubygems_version: 3.4.10
133
126
  signing_key:
134
127
  specification_version: 4
135
128
  summary: Dom and Selector assertions for Rails applications