Created
April 25, 2010 15:17
-
-
Save superfeedr/378473 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'nokogiri' | |
module Nokogiri | |
module XML | |
class Node | |
## | |
# Returns true of the argument is semantically equivalent to self | |
# Equivalent is defined as follows : | |
# - same name | |
# - same attributes | |
# - same same default namespace (different definitions are ok) | |
# - same number of children | |
# - each child is equivalent to one child of the argument | |
# - the order of the children can be different | |
def ===(_node) | |
if _node.name != self.name | |
false | |
elsif _node.text != self.text | |
false | |
elsif ( | |
!_node.is_a?(Nokogiri::XML::Attr) and | |
!_node.is_a?(Nokogiri::XML::Attr) and ( | |
(!_node.namespace.nil? and self.namespace.nil?) or | |
(_node.namespace.nil? and !self.namespace.nil?) or | |
(!_node.namespace.nil? and !self.namespace.nil? and _node.namespace.href != self.namespace.href) | |
) | |
) | |
false | |
elsif _node.attributes.count != self.attributes.count | |
false | |
elsif _node.children.count != self.children.count | |
false | |
else | |
_node.attributes.each do |n, a| | |
matched = false | |
self.attributes.each do |m, b| | |
if a === b | |
matched = true | |
end | |
end | |
return false unless matched | |
end | |
_node.children.each do |c| | |
matched = false | |
self.children.each do |d| | |
if d === c | |
matched = true | |
end | |
end | |
return false unless matched | |
end | |
true | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'node' | |
describe :=== do | |
before(:each) do | |
@doc = Nokogiri::XML::Document.new | |
end | |
describe "when comparing Attr" do | |
before(:each) do | |
@attr1 = Nokogiri::XML::Attr.new(@doc, "a") | |
@attr1.value = "a" | |
end | |
context "when the other attributes has a different name" do | |
before(:each) do | |
@attr2 = Nokogiri::XML::Attr.new(@doc, "b") | |
end | |
it "should return false" do | |
(@attr1 === @attr2).should be_false | |
end | |
end | |
context "when the other attributes has the same name but a different value" do | |
before(:each) do | |
@attr2 = Nokogiri::XML::Attr.new(@doc, "a") | |
@attr2.value = "b" | |
end | |
it "should return false" do | |
(@attr1 === @attr2).should be_false | |
end | |
end | |
context "when the other attributes has the same name and the same value" do | |
before(:each) do | |
@attr2 = Nokogiri::XML::Attr.new(@doc, "a") | |
@attr2.value = @attr1.value | |
end | |
it "should return false" do | |
(@attr1 === @attr2).should be_true | |
end | |
end | |
end | |
describe "when comparing Elements" do | |
context "when 2 nodes have different names" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2 = Nokogiri::XML::Node.new("node2", @doc) | |
end | |
it "should return false" do | |
(@node1 === @node2).should be_false | |
end | |
end | |
context "when 2 nodes have different set of attributes" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2 = Nokogiri::XML::Node.new("node1", @doc) | |
end | |
it "should return false if the 2 nodes don't have the same number of attributes" do | |
@node1["cool"] = "thegang" | |
@node1["jackson"] = "five" | |
@node2["jackson"] = "five" | |
(@node1 === @node2).should be_false | |
end | |
it "should return true if the 2 nodes have the same attributes but in a different order" do | |
@node1["cool"] = "thegang" | |
@node1["jackson"] = "five" | |
@node2["jackson"] = "five" | |
@node2["cool"] = "thegang" | |
(@node1 === @node2).should be_true | |
end | |
it "should return true if the 2 nodes have the same attributes but in the same order" do | |
@node1["cool"] = "thegang" | |
@node1["jackson"] = "five" | |
@node2["cool"] = "thegang" | |
@node2["jackson"] = "five" | |
(@node1 === @node2).should be_true | |
end | |
end | |
context "when 2 nodes have different default namespaces" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2 = Nokogiri::XML::Node.new("node1", @doc) | |
end | |
it "should return false if the 2 nodes don't have the same namespace" do | |
@node1.default_namespace= "http://mysupernamespace" | |
(@node1 === @node2).should be_false | |
end | |
it "should return true if the 2 have the same namespace" do | |
@node1.default_namespace= "http://mysupernamespace" | |
@node2.default_namespace= "http://mysupernamespace" | |
(@node1 === @node2).should be_true | |
end | |
it "should return true if the 2 have the same namespace, but then define different namespaces" do | |
@node1.default_namespace= "http://mysupernamespace" | |
@node1.add_namespace_definition("prefix", "http://anothernamespace") | |
@node2.default_namespace= "http://mysupernamespace" | |
(@node1 === @node2).should be_true | |
end | |
end | |
context "when 2 nodes have a different number of children" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node1.add_child(Nokogiri::XML::Node.new("child1", @doc)) | |
@node1.add_child(Nokogiri::XML::Node.new("child1", @doc)) | |
@node2 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2.add_child(Nokogiri::XML::Node.new("child1", @doc)) | |
end | |
it "should return false" do | |
(@node1 === @node2).should be_false | |
end | |
end | |
context "when 2 nodes have a different text" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node1.content= "hello world" | |
@node2 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2.content= "Ciao" | |
end | |
it "should return false" do | |
(@node1 === @node2).should be_false | |
end | |
end | |
context "when 2 nodes have different children" do | |
before(:each) do | |
@node1 = Nokogiri::XML::Node.new("node1", @doc) | |
@node1.add_child(Nokogiri::XML::Node.new("child1", @doc)) | |
@node1.add_child(Nokogiri::XML::Node.new("child2", @doc)) | |
@node2 = Nokogiri::XML::Node.new("node1", @doc) | |
@node2.add_child(Nokogiri::XML::Node.new("child1", @doc)) | |
@node2.add_child(Nokogiri::XML::Node.new("child2different", @doc)) | |
end | |
it "should return false" do | |
(@node1 === @node2).should be_false | |
end | |
end | |
context "when 2 documents are identical" do | |
before(:each) do | |
@doc1 = Nokogiri::XML::Builder.new do |xml| | |
xml.root("age" => "23", "name" => "john Doe") { | |
xml.products { | |
xml.widget { | |
xml.id_ "10" | |
xml.name(:lang => "english") { | |
xml.text="Awesome widget" | |
} | |
} | |
xml.widget { | |
xml.id_ "11" | |
xml.name "Good widget" | |
} | |
} | |
} | |
end.doc | |
xml= <<-EOXML | |
<?xml version="1.0"?> | |
<root name='john Doe' age="23" > | |
<products> | |
<widget> | |
<id>11</id> | |
<name lang="english">Good widget</name> | |
</widget> | |
<widget> | |
<id>10</id> | |
<name>Awesome widget</name> | |
</widget> | |
</products> | |
</root> | |
EOXML | |
@doc2 = Nokogiri::XML(xml) | |
end | |
it "should return true" do | |
(@node1 === @node2).should be_true | |
end | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment