Skip to content

Commit

Permalink
make assert_dom_equal ignore insignificant whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
jduff committed May 20, 2020
1 parent 579fa72 commit 7417fb0
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 11 deletions.
38 changes: 28 additions & 10 deletions lib/rails/dom/testing/assertions/dom_assertions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,61 @@ module DomAssertions
#
# # 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")
def assert_dom_equal(expected, actual, message = nil)
def assert_dom_equal(expected, actual, message = nil, strict: false)
expected_dom, actual_dom = fragment(expected), fragment(actual)
message ||= "Expected: #{expected}\nActual: #{actual}"
assert compare_doms(expected_dom, actual_dom), message
assert compare_doms(expected_dom, actual_dom, strict), message
end

# 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")
def assert_dom_not_equal(expected, actual, message = nil)
def assert_dom_not_equal(expected, actual, message = nil, strict: false)
expected_dom, actual_dom = fragment(expected), fragment(actual)
message ||= "Expected: #{expected}\nActual: #{actual}"
assert_not compare_doms(expected_dom, actual_dom), message
assert_not compare_doms(expected_dom, actual_dom, strict), message
end

protected

def compare_doms(expected, actual)
return false unless expected.children.size == actual.children.size
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])
expected_children.each_with_index do |child, i|
return false unless equal_children?(child, actual_children[i], strict)
end

true
end

def equal_children?(child, other_child)
def extract_children(node, strict)
if strict
node.children
else
node.children.reject{|n| n.text? && n.text.blank?}
end
end

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)
compare_doms(child, other_child, strict)
else
equal_child?(child, other_child, strict)
end
end

def equal_child?(child, other_child, strict)
if strict
child.to_s == other_child.to_s
else
child.to_s.strip == other_child.to_s.strip
end
end

Expand Down
60 changes: 59 additions & 1 deletion test/dom_assertions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,62 @@ def test_unequal_dom_attributes_in_children
%{<a><b c="2" /></a>}
)
end
end

def test_dom_equal_with_whitespace_strict
canonical = %{<a><b>hello</b> world</a>}
assert_dom_not_equal(canonical, %{<a>\n<b>hello\n </b> world</a>}, strict: true)
assert_dom_not_equal(canonical, %{<a> \n <b>\n hello</b> world</a>}, strict: true)
assert_dom_not_equal(canonical, %{<a>\n\t<b>hello</b> world</a>}, strict: true)
assert_dom_equal(canonical, %{<a><b>hello</b> world</a>}, strict: true)
end

def test_dom_equal_with_whitespace
canonical = %{<a><b>hello</b> world</a>}
assert_dom_equal(canonical, %{<a>\n<b>hello\n </b> world</a>})
assert_dom_equal(canonical, %{<a>\n<b>hello </b>\nworld</a>})
assert_dom_equal(canonical, %{<a> \n <b>\n hello</b> world</a>})
assert_dom_equal(canonical, %{<a> \n <b> hello </b>world</a>})
assert_dom_equal(canonical, %{<a> \n <b>hello </b>world\n</a>\n})
assert_dom_equal(canonical, %{<a>\n\t<b>hello</b> world</a>})
assert_dom_equal(canonical, %{<a>\n\t<b>hello </b>\n\tworld</a>})
end

def test_dom_equal_with_attribute_whitespace
canonical = %(<div data-wow="Don't strip this">)
assert_dom_equal(canonical, %(<div data-wow="Don't strip this">))
assert_dom_not_equal(canonical, %(<div data-wow="Don't strip this">))
end

def test_dom_equal_with_indentation
canonical = %{<a>hello <b>cruel</b> world</a>}
assert_dom_equal(canonical, <<-HTML)
<a>
hello
<b>cruel</b>
world
</a>
HTML

assert_dom_equal(canonical, <<-HTML)
<a>
hello
<b>cruel</b>
world
</a>
HTML

assert_dom_equal(canonical, <<-HTML)
<a>hello
<b>
cruel
</b>
world</a>
HTML
end

def test_dom_not_equal_with_interior_whitespace
with_space = %{<a><b>hello world</b></a>}
without_space = %{<a><b>helloworld</b></a>}
assert_dom_not_equal(with_space, without_space)
end
end

0 comments on commit 7417fb0

Please sign in to comment.