rsxml 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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