mbklein / equivalent-xml

Easy equivalency tests for Nokogiri and Oga XML
MIT License
94 stars 29 forks source link

equivalent-xml

Description

Problem

Testing XML output is difficult:

Solution

EquivalentXml - Now for Nokogiri and Oga!

Build Status Dependency Status

Use

EquivalentXml.equivalent?(node_1, node_2, opts = { :element_order => false, :normalize_whitespace => true }) { |n1, n2, result| ... }

node_1 and node_2 can be any Node descendants (or any string containing an XML document or document fragment). The most common use case is to compare two Document instances.

node_1 is equivalent to node_2 if and only if:

If a block is given, the block will be called every time two nodes are compared. The parameters will be the two nodes being compared as well as the result of the comparison. If the block explicitly returns true or false (a real TrueClass or FalseClass, not just an expression that can be coerced to true or false), the return value will override the result of the comparison.

Element nodes are equivalent if they have the same name, and their child nodesets are equal (as defined above)

Attribute nodes are equivalent if their names and values match exactly

CDATA nodes are equivalent if their text strings match exactly, including leading, trailing, and internal whitespace

Non-CDATA CharacterData nodes are equivalent if their text strings match after stripping leading and trailing whitespace and collapsing internal whitespace to a single space

Document nodes are equivalent if their root nodes are equal

ProcessingInstruction and Comment nodes are ignored

Options

:element_order => true

Require elements to be in the same relative position in order to be considered equivalent.

:normalize_whitespace => false

Don't normalize whitespace within text nodes; require text nodes to match exactly.

:ignore_content => ["Device > SerialNumber", "Device > ICCID"]

A single CSS selector, or an array of CSS selectors, of nodes for which the content (text and child nodes) should be ignored when comparing for equivalence. Defaults to nil. (Uses Nokogiri's Node#css(*rules) to conduct the search.)

Using with RSpec

EquivalentXml includes a custom matcher for RSpec (version >=1.2.4) that makes including XML equivalencies in your spec tests a cinch!

Add below two line to spec_helper.rb:

require 'rspec/matchers' # req by equivalent-xml custom matcher `be_equivalent_to`
require 'equivalent-xml'

Equivalency:

expect(node_1).to be_equivalent_to(node_2)
expect(node_1).not_to be_equivalent_to(node_2)

Chained modifiers:

expect(node_1).to be_equivalent_to(node_2).respecting_element_order
expect(node_1).to be_equivalent_to(node_2).with_whitespace_intact
expect(node_1).to be_equivalent_to(node_2).respecting_element_order.with_whitespace_intact
expect(node_1).to be_equivalent_to(node_2).ignoring_content_of("SerialNumber")

Contributing to equivalent-xml

History

Copyright

Copyright (c) 2011-16 Michael B. Klein. See LICENSE.txt for further details.