rails-dom-testing 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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