rsxml 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/rsxml.rb +37 -2
- data/spec/rsxml_spec.rb +30 -0
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/rsxml.rb
CHANGED
@@ -4,7 +4,7 @@ require 'builder'
|
|
4
4
|
module Rsxml
|
5
5
|
module_function
|
6
6
|
|
7
|
-
# convert an s-expression representation of an XML document to XML
|
7
|
+
# convert an Rsxml s-expression representation of an XML document to XML
|
8
8
|
# Rsxml.to_xml(["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"] ["Baz"]])
|
9
9
|
# => '<Foo foofoo="10"><Bar>barbar</Bar><Baz></Baz></Foo>'
|
10
10
|
def to_xml(rsxml)
|
@@ -13,7 +13,7 @@ module Rsxml
|
|
13
13
|
xml.target!
|
14
14
|
end
|
15
15
|
|
16
|
-
# convert an XML string to an s-expression representation
|
16
|
+
# convert an XML string to an Rsxml s-expression representation
|
17
17
|
# Rsxml.to_rsxml('<Foo foofoo="10"><Bar>barbar</Bar><Baz></Baz></Foo>')
|
18
18
|
# => ["Foo", {"foofoo"=>"10"}, ["Bar", "barbar"], ["Baz"]]
|
19
19
|
#
|
@@ -29,6 +29,14 @@ module Rsxml
|
|
29
29
|
Xml.read_xml(root, [])
|
30
30
|
end
|
31
31
|
|
32
|
+
# compare two documents in XML or Rsxml. returns +true+ if they are identical, and
|
33
|
+
# if not raises +ComparisonError+ describing where they differ
|
34
|
+
def compare(xml_or_sexp_a, xml_or_sexp_b)
|
35
|
+
sexp_a = xml_or_sexp_a.is_a?(String) ? to_rsxml(xml_or_sexp_a) : xml_or_sexp_a
|
36
|
+
sexp_b = xml_or_sexp_b.is_a?(String) ? to_rsxml(xml_or_sexp_b) : xml_or_sexp_b
|
37
|
+
Sexp.compare(sexp_a, sexp_b)
|
38
|
+
end
|
39
|
+
|
32
40
|
module Sexp
|
33
41
|
module_function
|
34
42
|
|
@@ -58,6 +66,33 @@ module Rsxml
|
|
58
66
|
end
|
59
67
|
[tag, attrs, children]
|
60
68
|
end
|
69
|
+
|
70
|
+
class ComparisonError < RuntimeError
|
71
|
+
attr_reader :path
|
72
|
+
def initialize(msg, path)
|
73
|
+
super("[#{path}]: #{msg}")
|
74
|
+
@path = path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def compare(sexpa, sexpb, path=nil)
|
79
|
+
taga, attrsa, childrena = decompose_sexp(sexpa)
|
80
|
+
tagb, attrsb, childrenb = decompose_sexp(sexpb)
|
81
|
+
|
82
|
+
raise ComparisonError.new("element names differ: '#{taga}', '#{tagb}'", path) if taga != tagb
|
83
|
+
raise ComparisonError.new("attributes differ", path) if attrsa != attrsb
|
84
|
+
raise ComparisonError.new("child cound differes", path) if childrena.length != childrenb.length
|
85
|
+
|
86
|
+
path = [path, taga].compact.join("/")
|
87
|
+
(0...childrena.length).each do |i|
|
88
|
+
if childrena[i].is_a?(Array) && childrenb[i].is_a?(Array)
|
89
|
+
compare(childrena[i], childrenb[i], path)
|
90
|
+
else
|
91
|
+
raise ComparisonError.new("content differs: '#{childrena[i]}', '#{childrenb[i]}'", path) if childrena[i] != childrenb[i]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
true
|
95
|
+
end
|
61
96
|
end
|
62
97
|
|
63
98
|
module Xml
|
data/spec/rsxml_spec.rb
CHANGED
@@ -111,4 +111,34 @@ describe Rsxml do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
end
|
114
|
+
|
115
|
+
describe "compare" do
|
116
|
+
it "should return true when two simple docs are equivalent" do
|
117
|
+
Rsxml.compare(["Foo"], "<Foo></Foo").should == true
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should return true when two simple docs with attributes are equivalent" do
|
121
|
+
Rsxml.compare([:foo, {:bar=>1, :baz=>"baz"}],
|
122
|
+
[:foo, {:bar=>1, :baz=>"baz"}]).should == true
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return true when two more complex docs are equivalent" do
|
126
|
+
Rsxml.compare(["foo:foofoo", {"xmlns:foo"=>"http://foo.com/foo", "foo:bar"=>1, "foo:baz"=>"baz"}, ["Bar", "barbar"], ["Baz"]],
|
127
|
+
["foo:foofoo", {"xmlns:foo"=>"http://foo.com/foo", "foo:bar"=>1, "foo:baz"=>"baz"}, ["Bar", "barbar"], ["Baz"]]).should ==true
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should raise an error when two simple docs differ" do
|
131
|
+
lambda {
|
132
|
+
Rsxml.compare(["Foo"], "<Boo></Boo").should == true
|
133
|
+
}.should raise_error("[]: element names differ: 'Foo', 'Boo'")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should raise an error when two more complex docs differ" do
|
137
|
+
lambda {
|
138
|
+
Rsxml.compare(["foo:foofoo", {"xmlns:foo"=>"http://foo.com/foo", "foo:bar"=>1, "foo:baz"=>"baz"}, ["Bar", "barbAr"], ["Baz"]],
|
139
|
+
["foo:foofoo", {"xmlns:foo"=>"http://foo.com/foo", "foo:bar"=>1, "foo:baz"=>"baz"}, ["Bar", "barbar"], ["Baz"]]).should ==true
|
140
|
+
}.should raise_error("[foo:foofoo/Bar]: content differs: 'barbAr', 'barbar'")
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
114
144
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsxml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Trampoline Systems Ltd
|