rsxml 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/rsxml.rb +37 -2
  3. data/spec/rsxml_spec.rb +30 -0
  4. metadata +3 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
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: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Trampoline Systems Ltd