55 lines
1.7 KiB
Ruby
55 lines
1.7 KiB
Ruby
# typed: false
|
|
normalize_html = lambda { |html| Nokogiri::HTML5.fragment(html.to_s) }
|
|
|
|
nodes_equal =
|
|
lambda do |a, b|
|
|
return true if a == b
|
|
return false unless a.name == b.name
|
|
stype = a.node_type
|
|
otype = b.node_type
|
|
return false unless stype == otype
|
|
sa = a.attributes
|
|
oa = b.attributes
|
|
return false unless sa.length == oa.length
|
|
sa = sa.sort.map { |n, a| [n, a.value, a.namespace && a.namespace.href] }
|
|
oa = oa.sort.map { |n, a| [n, a.value, a.namespace && a.namespace.href] }
|
|
return false unless sa == oa
|
|
skids = a.children
|
|
okids = b.children
|
|
return false unless skids.length == okids.length
|
|
if stype == Nokogiri::XML::Node::TEXT_NODE &&
|
|
(a.content.strip != b.content.strip)
|
|
return false
|
|
end
|
|
skids.to_enum.with_index.all? { |ski, i| nodes_equal.call(ski, okids[i]) }
|
|
end
|
|
|
|
RSpec::Matchers.define :eq_html do |expected|
|
|
match do |actual|
|
|
nodes_equal.call(normalize_html.call(expected), normalize_html.call(actual))
|
|
end
|
|
|
|
failure_message do |actual|
|
|
"expected HTML to match.\nExpected: #{normalize_html.call(expected)}\nGot: #{normalize_html.call(actual)}"
|
|
end
|
|
end
|
|
|
|
RSpec::Matchers.define :include_html do |expected|
|
|
match do |actual|
|
|
actual = normalize_html.call(actual)
|
|
expected = normalize_html.call(expected).children.first
|
|
|
|
node_or_children_equal =
|
|
lambda do |node|
|
|
nodes_equal.call(node, expected) ||
|
|
node.children.any? { |child| node_or_children_equal.call(child) }
|
|
end
|
|
|
|
node_or_children_equal.call(actual)
|
|
end
|
|
|
|
failure_message do |actual|
|
|
"expected HTML to include fragment.\nExpected fragment:\n#{normalize_html.call(expected)}\nIn:\n#{normalize_html.call(actual)}"
|
|
end
|
|
end
|