module Rails::Dom::Testing::Assertions::DomAssertions

Public Instance Methods

assert_dom_equal(expected, actual, message = nil, strict: false, html_version: nil) click to toggle source

Test two HTML strings for equivalency (e.g., equal even when attributes are in another order)

# assert that the referenced method generates the appropriate HTML string
assert_dom_equal(
  '<a href="http://www.example.com">Apples</a>',
  link_to("Apples", "http://www.example.com"),
)

By default, the matcher will not pay attention to whitespace in text nodes (e.g., spaces and newlines). If you want stricter matching with exact matching for whitespace, pass strict: true:

# these assertions will both pass
assert_dom_equal     "<div>\nfoo\n\</div>", "<div>foo</div>", strict: false
assert_dom_not_equal "<div>\nfoo\n\</div>", "<div>foo</div>", strict: true

The DOMs are created using an HTML parser specified by Rails::Dom::Testing.default_html_version (either :html4 or :html5).

When testing in a Rails application, the parser default can also be set by setting Rails.application.config.dom_testing_default_html_version.

If you want to specify the HTML parser just for a particular assertion, pass html_version: :html4 or html_version: :html5 keyword arguments:

assert_dom_equal expected, actual, html_version: :html5
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 35
def assert_dom_equal(expected, actual, message = nil, strict: false, html_version: nil)
  expected_dom, actual_dom = fragment(expected, html_version: html_version), fragment(actual, html_version: html_version)
  message ||= "Expected: #{expected}\nActual: #{actual}"
  assert compare_doms(expected_dom, actual_dom, strict), message
end
assert_dom_not_equal(expected, actual, message = nil, strict: false, html_version: nil) click to toggle source

The negated form of assert_dom_equal.

# assert that the referenced method does not generate the specified HTML string
assert_dom_not_equal(
  '<a href="http://www.example.com">Apples</a>',
  link_to("Oranges", "http://www.example.com"),
)

By default, the matcher will not pay attention to whitespace in text nodes (e.g., spaces and newlines). If you want stricter matching with exact matching for whitespace, pass strict: true:

# these assertions will both pass
assert_dom_equal     "<div>\nfoo\n\</div>", "<div>foo</div>", strict: false
assert_dom_not_equal "<div>\nfoo\n\</div>", "<div>foo</div>", strict: true

The DOMs are created using an HTML parser specified by Rails::Dom::Testing.default_html_version (either :html4 or :html5).

When testing in a Rails application, the parser default can also be set by setting Rails.application.config.dom_testing_default_html_version.

If you want to specify the HTML parser just for a particular assertion, pass html_version: :html4 or html_version: :html5 keyword arguments:

assert_dom_not_equal expected, actual, html_version: :html5
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 68
def assert_dom_not_equal(expected, actual, message = nil, strict: false, html_version: nil)
  expected_dom, actual_dom = fragment(expected, html_version: html_version), fragment(actual, html_version: html_version)
  message ||= "Expected: #{expected}\nActual: #{actual}"
  assert_not compare_doms(expected_dom, actual_dom, strict), message
end

Protected Instance Methods

compare_doms(expected, actual, strict) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 75
def compare_doms(expected, actual, strict)
  expected_children = extract_children(expected, strict)
  actual_children   = extract_children(actual, strict)
  return false unless expected_children.size == actual_children.size

  expected_children.each_with_index do |child, i|
    return false unless equal_children?(child, actual_children[i], strict)
  end

  true
end
equal_attribute?(attr, other_attr) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 128
def equal_attribute?(attr, other_attr)
  attr.name == other_attr.name && attr.value == other_attr.value
end
equal_attribute_nodes?(nodes, other_nodes) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 115
def equal_attribute_nodes?(nodes, other_nodes)
  return false unless nodes.size == other_nodes.size

  nodes = nodes.sort_by(&:name)
  other_nodes = other_nodes.sort_by(&:name)

  nodes.each_with_index do |attr, i|
    return false unless equal_attribute?(attr, other_nodes[i])
  end

  true
end
equal_child?(child, other_child, strict) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 107
def equal_child?(child, other_child, strict)
  if strict
    child.to_s == other_child.to_s
  else
    child.to_s.split == other_child.to_s.split
  end
end
equal_children?(child, other_child, strict) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 95
def equal_children?(child, other_child, strict)
  return false unless child.type == other_child.type

  if child.element?
    child.name == other_child.name &&
        equal_attribute_nodes?(child.attribute_nodes, other_child.attribute_nodes) &&
        compare_doms(child, other_child, strict)
  else
    equal_child?(child, other_child, strict)
  end
end
extract_children(node, strict) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 87
def extract_children(node, strict)
  if strict
    node.children
  else
    node.children.reject { |n| n.text? && n.text.blank? }
  end
end

Private Instance Methods

fragment(text, html_version: nil) click to toggle source
# File lib/rails/dom/testing/assertions/dom_assertions.rb, line 133
def fragment(text, html_version: nil)
  Rails::Dom::Testing.html_document_fragment(html_version: html_version).parse(text)
end