xml-mapping 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/LICENSE +56 -0
  2. data/README +386 -0
  3. data/README_XPATH +175 -0
  4. data/Rakefile +214 -0
  5. data/TODO.txt +32 -0
  6. data/doc/xpath_impl_notes.txt +119 -0
  7. data/examples/company.rb +34 -0
  8. data/examples/company.xml +26 -0
  9. data/examples/company_usage.intin.rb +19 -0
  10. data/examples/company_usage.intout +39 -0
  11. data/examples/order.rb +61 -0
  12. data/examples/order.xml +54 -0
  13. data/examples/order_signature_enhanced.rb +7 -0
  14. data/examples/order_signature_enhanced.xml +9 -0
  15. data/examples/order_signature_enhanced_usage.intin.rb +12 -0
  16. data/examples/order_signature_enhanced_usage.intout +16 -0
  17. data/examples/order_usage.intin.rb +73 -0
  18. data/examples/order_usage.intout +147 -0
  19. data/examples/time_augm.intin.rb +19 -0
  20. data/examples/time_augm.intout +23 -0
  21. data/examples/time_node.rb +27 -0
  22. data/examples/xpath_create_new.intin.rb +85 -0
  23. data/examples/xpath_create_new.intout +181 -0
  24. data/examples/xpath_docvsroot.intin.rb +30 -0
  25. data/examples/xpath_docvsroot.intout +34 -0
  26. data/examples/xpath_ensure_created.intin.rb +62 -0
  27. data/examples/xpath_ensure_created.intout +114 -0
  28. data/examples/xpath_pathological.intin.rb +42 -0
  29. data/examples/xpath_pathological.intout +56 -0
  30. data/examples/xpath_usage.intin.rb +51 -0
  31. data/examples/xpath_usage.intout +57 -0
  32. data/install.rb +40 -0
  33. data/lib/xml/mapping.rb +14 -0
  34. data/lib/xml/mapping/base.rb +563 -0
  35. data/lib/xml/mapping/standard_nodes.rb +343 -0
  36. data/lib/xml/mapping/version.rb +8 -0
  37. data/lib/xml/xxpath.rb +354 -0
  38. data/test/all_tests.rb +6 -0
  39. data/test/company.rb +54 -0
  40. data/test/documents_folders.rb +33 -0
  41. data/test/fixtures/bookmarks1.xml +24 -0
  42. data/test/fixtures/company1.xml +85 -0
  43. data/test/fixtures/documents_folders.xml +71 -0
  44. data/test/fixtures/documents_folders2.xml +30 -0
  45. data/test/multiple_mappings.rb +80 -0
  46. data/test/tests_init.rb +2 -0
  47. data/test/xml_mapping_adv_test.rb +84 -0
  48. data/test/xml_mapping_test.rb +182 -0
  49. data/test/xpath_test.rb +273 -0
  50. metadata +96 -0
@@ -0,0 +1,182 @@
1
+ require File.dirname(__FILE__)+"/tests_init"
2
+
3
+ require 'test/unit'
4
+ require 'company'
5
+
6
+ module XML::Mapping
7
+ def ==(other)
8
+ Marshal.dump(self) == Marshal.dump(other)
9
+ end
10
+ end
11
+
12
+ class XmlMappingTest < Test::Unit::TestCase
13
+ def setup
14
+ # need to undo mapping class definitions that may have been
15
+ # established by other tests (and outlive those tests)
16
+
17
+ # this requires some ugly hackery with internal variables
18
+ XML::Mapping.module_eval <<-EOS
19
+ Classes_w_default_rootelt_names.clear
20
+ Classes_w_nondefault_rootelt_names.clear
21
+ EOS
22
+ Object.send(:remove_const, "Company")
23
+ Object.send(:remove_const, "Address")
24
+ Object.send(:remove_const, "Office")
25
+ Object.send(:remove_const, "Customer")
26
+ $".delete "company.rb"
27
+ $:.unshift File.dirname(__FILE__) # test/unit may have undone this (see test/unit/collector/dir.rb)
28
+ require 'company'
29
+
30
+ @xml = REXML::Document.new(File.new(File.dirname(__FILE__) + "/fixtures/company1.xml"))
31
+ @c = Company.load_from_xml(@xml.root)
32
+ end
33
+
34
+ def test_getter_text_node
35
+ assert_equal "bar", @c.ent2
36
+ end
37
+
38
+ def test_getter_int_node
39
+ assert_equal 18, @c.offices[1].address.number
40
+ end
41
+
42
+ def test_getter_boolean_node
43
+ path=XML::XXPath.new("offices/office[2]/classified")
44
+ assert_equal(path.first(@xml.root).text == "yes",
45
+ @c.offices[1].classified)
46
+ end
47
+
48
+ def test_getter_hash_node
49
+ assert_equal 4, @c.customers.keys.size
50
+ ["cm", "ernie", "jim", "sad"].zip(@c.customers.keys.sort).each do |exp,ckey|
51
+ assert_equal exp, ckey
52
+ assert_equal exp, @c.customers[ckey].uid
53
+ end
54
+ end
55
+
56
+ def test_getter_array_node
57
+ assert_equal ["pencils", "weapons of mass destruction"],
58
+ @c.offices.map{|o|o.speciality}
59
+ end
60
+
61
+
62
+ def test_setter_text_node
63
+ @c.ent2 = "lalala"
64
+ assert_equal "lalala", REXML::XPath.first(@c.save_to_xml, "arrtest/entry[2]").text
65
+ end
66
+
67
+
68
+ def test_setter_array_node
69
+ xml=@c.save_to_xml
70
+ assert_equal ["pencils", "weapons of mass destruction"],
71
+ XML::XXPath.new("offices/office/@speciality").all(xml).map{|n|n.text}
72
+ end
73
+
74
+
75
+ def test_setter_hash_node
76
+ xml=@c.save_to_xml
77
+ assert_equal @c.customers.keys.sort,
78
+ XML::XXPath.new("customers/customer/@uid").all(@xml.root).map{|n|n.text}.sort
79
+ end
80
+
81
+
82
+ def test_setter_boolean_node
83
+ @c.offices[0].classified = !@c.offices[0].classified
84
+ xml=@c.save_to_xml
85
+ assert_equal @c.offices[0].classified,
86
+ XML::XXPath.new("offices/office[1]/classified").first(xml).text == "yes"
87
+ end
88
+
89
+
90
+ def test_root_element
91
+ assert_equal @c, XML::Mapping.load_object_from_file(File.dirname(__FILE__) + "/fixtures/company1.xml")
92
+ assert_equal @c, XML::Mapping.load_object_from_xml(@xml.root)
93
+
94
+ assert_equal "company", Company.root_element_name
95
+ assert_equal Company, XML::Mapping.class_for_root_elt_name("company")
96
+ xml=@c.save_to_xml
97
+ assert_equal "company", xml.name
98
+ # Company.root_element_name 'my-test'
99
+ Company.class_eval <<-EOS
100
+ root_element_name 'my-test'
101
+ EOS
102
+ assert_equal "my-test", Company.root_element_name
103
+ assert_equal Company, XML::Mapping.class_for_root_elt_name("my-test")
104
+ assert_nil XML::Mapping.class_for_root_elt_name("company")
105
+ xml=@c.save_to_xml
106
+ assert_equal "my-test", xml.name
107
+ assert_equal "office", @c.offices[0].save_to_xml.name
108
+
109
+ assert_raises(XML::MappingError) {
110
+ XML::Mapping.load_object_from_xml @xml.root
111
+ }
112
+ @xml.root.name = 'my-test'
113
+ assert_equal @c, XML::Mapping.load_object_from_xml(@xml.root)
114
+
115
+ # white-box tests
116
+ assert_equal [["my-test", Company]], XML::Mapping::Classes_w_nondefault_rootelt_names.sort
117
+ assert_equal [["address", Address], ["customer", Customer], ["office", Office]],
118
+ XML::Mapping::Classes_w_default_rootelt_names.sort
119
+ end
120
+
121
+
122
+ def test_optional_flag
123
+ hamburg_address_path = XML::XXPath.new("offices/office[1]/address")
124
+ baghdad_address_path = XML::XXPath.new("offices/office[2]/address")
125
+ hamburg_zip_path = XML::XXPath.new("offices/office[1]/address/zip")
126
+ baghdad_zip_path = XML::XXPath.new("offices/office[2]/address/zip")
127
+
128
+ assert_equal 18282, @c.offices[0].address.zip
129
+ assert_equal 12576, @c.offices[1].address.zip
130
+ xml=@c.save_to_xml
131
+ assert_equal "18282", hamburg_zip_path.first(xml).text
132
+ assert_nil baghdad_zip_path.first(xml,:allow_nil=>true)
133
+ @c.offices[1].address.zip = 12577
134
+ xml=@c.save_to_xml
135
+ assert_equal "12577", baghdad_zip_path.first(xml).text
136
+ c2 = Company.load_from_xml(xml)
137
+ assert_equal 12577, c2.offices[1].address.zip
138
+ @c.offices[1].address.zip = 12576
139
+ xml=@c.save_to_xml
140
+ assert_nil baghdad_zip_path.first(xml,:allow_nil=>true)
141
+
142
+ hamburg_address_path.first(xml).delete_element("zip")
143
+ c3 = Company.load_from_xml(xml)
144
+ assert_equal 12576, c3.offices[0].address.zip
145
+ hamburg_address_path.first(xml).delete_element("city")
146
+ assert_raises(XML::MappingError) {
147
+ Company.load_from_xml(xml)
148
+ }
149
+ end
150
+
151
+
152
+ def test_optional_flag_nodefault
153
+ hamburg_address_path = XML::XXPath.new("offices/office[1]/address")
154
+ hamburg_street_path = XML::XXPath.new("offices/office[1]/address/street")
155
+
156
+ assert_equal hamburg_street_path.first(@xml.root).text,
157
+ @c.offices[0].address.street
158
+
159
+ hamburg_address_path.first(@xml.root).delete_element("street")
160
+ c2 = Company.load_from_xml(@xml.root)
161
+ assert_nil c2.offices[0].address.street
162
+
163
+ xml2=c2.save_to_xml
164
+ assert_nil hamburg_street_path.first(xml2,:allow_nil=>true)
165
+ end
166
+
167
+
168
+ def test_polymorphic_node
169
+ assert_equal 3, @c.stuff.size
170
+ assert_equal 'Saddam Hussein', @c.stuff[0].name
171
+ assert_equal 'Berlin', @c.stuff[1].city
172
+ assert_equal 'weapons of mass destruction', @c.stuff[2].speciality
173
+
174
+ @c.stuff[1].city = 'Munich'
175
+ @c.stuff[2].classified = false
176
+
177
+ xml2=@c.save_to_xml
178
+ assert_equal 'Munich', xml2.root.elements[5].elements[2].elements[1].text
179
+ assert_equal 'no', xml2.root.elements[5].elements[3].elements[1].text
180
+ end
181
+
182
+ end
@@ -0,0 +1,273 @@
1
+ require File.dirname(__FILE__)+"/tests_init"
2
+
3
+ require 'test/unit'
4
+
5
+ require "rexml/document"
6
+ require "xml/xxpath"
7
+
8
+
9
+ class XPathTest < Test::Unit::TestCase
10
+ include REXML
11
+
12
+ def setup
13
+ @d = Document.new <<-EOS
14
+ <bla>
15
+ <foo>x</foo>
16
+ <bar>bar1</bar>
17
+ <foo key='xy'>
18
+ y
19
+ <u/>
20
+ </foo>
21
+ </bla>
22
+ EOS
23
+ end
24
+
25
+ def test_read_byname
26
+ assert_equal @d.root.elements.to_a("foo"), XML::XXPath.new("foo").all(@d.root)
27
+ assert_equal @d.root.elements.to_a("foo")[1].elements.to_a("u"), XML::XXPath.new("foo/u").all(@d.root)
28
+ assert_equal [], XML::XXPath.new("foo/notthere").all(@d.root)
29
+ end
30
+
31
+
32
+ def test_read_byidx
33
+ assert_equal [@d.root.elements[1]], XML::XXPath.new("foo[1]").all(@d.root)
34
+ assert_equal [@d.root.elements[3]], XML::XXPath.new("foo[2]").all(@d.root)
35
+ assert_equal [], XML::XXPath.new("foo[10]").all(@d.root)
36
+ assert_equal [], XML::XXPath.new("foo[3]").all(@d.root)
37
+ end
38
+
39
+
40
+ def test_read_byall
41
+ assert_equal @d.root.elements.to_a, XML::XXPath.new("*").all(@d.root)
42
+ assert_equal [], XML::XXPath.new("notthere/*").all(@d.root)
43
+ end
44
+
45
+
46
+ def test_read_byattr
47
+ assert_equal [@d.root.elements[3]], XML::XXPath.new("foo[@key='xy']").all(@d.root)
48
+ assert_equal [], XML::XXPath.new("foo[@key='notthere']").all(@d.root)
49
+ assert_equal [], XML::XXPath.new("notthere[@key='xy']").all(@d.root)
50
+ end
51
+
52
+
53
+ def test_attribute
54
+ elt = @d.root.elements[3]
55
+ attr1 = XML::XXPath::Accessors::Attribute.new(elt,"key",false)
56
+ attr2 = XML::XXPath::Accessors::Attribute.new(elt,"key",false)
57
+ assert_not_nil attr1
58
+ assert_not_nil attr2
59
+ assert_equal attr1,attr2 # tests Attribute.==
60
+ assert_nil XML::XXPath::Accessors::Attribute.new(elt,"notthere",false)
61
+ assert_nil XML::XXPath::Accessors::Attribute.new(elt,"notthere",false)
62
+ newattr = XML::XXPath::Accessors::Attribute.new(elt,"new",true)
63
+ assert_not_nil newattr
64
+ assert_equal newattr, XML::XXPath::Accessors::Attribute.new(elt,"new",false)
65
+ newattr.text = "lala"
66
+ assert_equal "lala", elt.attributes["new"]
67
+ end
68
+
69
+ def test_read_byattrname
70
+ assert_equal [XML::XXPath::Accessors::Attribute.new(@d.root.elements[3],"key",false)],
71
+ XML::XXPath.new("foo/@key").all(@d.root)
72
+ assert_equal [], XML::XXPath.new("foo/@notthere").all(@d.root)
73
+ end
74
+
75
+
76
+ def test_read_byidx_then_name
77
+ assert_equal [@d.root.elements[3].elements[1]], XML::XXPath.new("foo[2]/u").all(@d.root)
78
+ assert_equal [], XML::XXPath.new("foo[2]/notthere").all(@d.root)
79
+ assert_equal [], XML::XXPath.new("notthere[2]/u").all(@d.root)
80
+ assert_equal [], XML::XXPath.new("foo[3]/u").all(@d.root)
81
+ end
82
+
83
+ def test_read_first
84
+ assert_equal @d.root.elements[3].elements[1], XML::XXPath.new("foo[2]/u").first(@d.root)
85
+ end
86
+
87
+ def test_read_first_nil
88
+ assert_equal nil, XML::XXPath.new("foo[2]/notthere").first(@d.root, :allow_nil=>true)
89
+ end
90
+
91
+ def test_read_first_exception
92
+ assert_raises(XML::XXPathError) {
93
+ XML::XXPath.new("foo[2]/notthere").first(@d.root)
94
+ }
95
+ end
96
+
97
+
98
+ def test_write_noop
99
+ assert_equal @d.root.elements[1], XML::XXPath.new("foo").first(@d.root, :ensure_created=>true)
100
+ assert_equal @d.root.elements[3].elements[1], XML::XXPath.new("foo[2]/u").first(@d.root, :ensure_created=>true)
101
+ # TODO: deep-compare of REXML documents?
102
+ end
103
+
104
+ def test_write_byname_then_name
105
+ s1 = @d.elements[1].elements.size
106
+ s2 = @d.elements[1].elements[1].elements.size
107
+ node = XML::XXPath.new("foo/new1").first(@d.root, :ensure_created=>true)
108
+ assert_equal "new1", node.name
109
+ assert node.attributes.empty?
110
+ assert_equal @d.elements[1].elements[1].elements[1], node
111
+ assert_equal s1, @d.elements[1].elements.size
112
+ assert_equal s2+1, @d.elements[1].elements[1].elements.size
113
+ end
114
+
115
+
116
+ def test_write_byidx
117
+ XML::XXPath.new("foo[2]").first(@d.root, :ensure_created=>true)
118
+ # TODO: deep-compare of REXML documents?
119
+ assert_equal 2, @d.root.elements.select{|elt| elt.name=="foo"}.size
120
+ node = XML::XXPath.new("foo[10]").first(@d.root, :ensure_created=>true)
121
+ assert_equal 10, @d.root.elements.select{|elt| elt.name=="foo"}.size
122
+ assert_equal "foo", node.name
123
+ end
124
+
125
+
126
+ def test_write_byattrname
127
+ elt = @d.root.elements[3]
128
+ s1 = elt.attributes.size
129
+ attr_key = XML::XXPath.new("foo[2]/@key").first(@d.root, :ensure_created=>true)
130
+ assert_equal elt.attributes["key"], attr_key.text
131
+
132
+ attr_new = XML::XXPath.new("foo[2]/@new").first(@d.root, :ensure_created=>true)
133
+ attr_new.text = "haha"
134
+ assert_equal "haha", attr_new.text
135
+ assert_equal "haha", elt.attributes["new"]
136
+ assert_equal s1+1, elt.attributes.size
137
+ end
138
+
139
+
140
+ def test_write_byname_and_attr
141
+ node1 = XML::XXPath.new("hiho[@blubb='bla']").first(@d.root,:ensure_created=>true)
142
+ node2 = XML::XXPath.new("hiho[@blubb='bla']").first(@d.root,:ensure_created=>true)
143
+ node3 = XML::XXPath.new("hiho[@blubb2='bla2']").first(@d.root,:ensure_created=>true)
144
+ assert_equal node1, node2
145
+ assert_equal node2, node3
146
+ assert_equal "hiho", node1.name
147
+ assert_equal 4, @d.root.elements.size
148
+ assert_equal @d.root.elements[4], node1
149
+ assert_equal @d.root.elements[4], node3
150
+ assert_equal 'bla', node3.attributes['blubb']
151
+ assert_equal 'bla2', node3.attributes['blubb2']
152
+
153
+ node4 = XML::XXPath.new("hiho[@blubb='foo42']").first(@d.root,:ensure_created=>true)
154
+ assert_not_equal node3, node4
155
+ assert_equal 5, @d.root.elements.size
156
+ assert_equal @d.root.elements[5], node4
157
+ assert_equal 'foo42', node4.attributes['blubb']
158
+ end
159
+
160
+
161
+ def test_create_new_byname
162
+ s1 = @d.elements[1].elements.size
163
+ s2 = @d.elements[1].elements[1].elements.size
164
+ startnode = @d.elements[1].elements[1]
165
+ node1 = XML::XXPath.new("new1").create_new(startnode)
166
+ node2 = XML::XXPath.new("new1").first(startnode, :create_new=>true) #same as .create_new(...)
167
+ assert_equal "new1", node1.name
168
+ assert_equal "new1", node2.name
169
+ assert node1.attributes.empty?
170
+ assert node2.attributes.empty?
171
+ assert_equal @d.elements[1].elements[1].elements[1], node1
172
+ assert_equal @d.elements[1].elements[1].elements[2], node2
173
+ assert_equal s1, @d.elements[1].elements.size
174
+ assert_equal s2+2, @d.elements[1].elements[1].elements.size
175
+ end
176
+
177
+
178
+ def test_create_new_byname_then_name
179
+ s1 = @d.elements[1].elements.size
180
+ node1 = XML::XXPath.new("foo/new1").create_new(@d.root)
181
+ node2 = XML::XXPath.new("foo/new1").create_new(@d.root)
182
+ assert_equal "new1", node1.name
183
+ assert_equal "new1", node2.name
184
+ assert node1.attributes.empty?
185
+ assert node2.attributes.empty?
186
+ assert_equal @d.elements[1].elements[s1+1].elements[1], node1
187
+ assert_equal @d.elements[1].elements[s1+2].elements[1], node2
188
+ assert_equal s1+2, @d.elements[1].elements.size
189
+ end
190
+
191
+
192
+ def test_create_new_byidx
193
+ assert_raises(XML::XXPathError) {
194
+ XML::XXPath.new("foo[2]").create_new(@d.root)
195
+ }
196
+ node1 = XML::XXPath.new("foo[3]").create_new(@d.root)
197
+ assert_raises(XML::XXPathError) {
198
+ XML::XXPath.new("foo[3]").create_new(@d.root)
199
+ }
200
+ assert_equal @d.elements[1].elements[4], node1
201
+ assert_equal "foo", node1.name
202
+ node2 = XML::XXPath.new("foo[4]").create_new(@d.root)
203
+ assert_equal @d.elements[1].elements[5], node2
204
+ assert_equal "foo", node2.name
205
+ node3 = XML::XXPath.new("foo[10]").create_new(@d.root)
206
+ assert_raises(XML::XXPathError) {
207
+ XML::XXPath.new("foo[10]").create_new(@d.root)
208
+ }
209
+ XML::XXPath.new("foo[11]").create_new(@d.root)
210
+ assert_equal @d.elements[1].elements[11], node3
211
+ assert_equal "foo", node3.name
212
+ # @d.write
213
+ end
214
+
215
+ def test_create_new_byname_then_idx
216
+ node1 = XML::XXPath.new("hello/bar[3]").create_new(@d.root)
217
+ node2 = XML::XXPath.new("hello/bar[3]").create_new(@d.root)
218
+ # same as create_new
219
+ node3 = XML::XXPath.new("hello/bar[3]").create_new(@d.root)
220
+ assert_equal @d.elements[1].elements[4].elements[3], node1
221
+ assert_equal @d.elements[1].elements[5].elements[3], node2
222
+ assert_equal @d.elements[1].elements[6].elements[3], node3
223
+ assert_not_equal node1, node2
224
+ assert_not_equal node1, node3
225
+ assert_not_equal node2, node3
226
+ end
227
+
228
+
229
+ def test_create_new_byattrname
230
+ node1 = XML::XXPath.new("@lala").create_new(@d.root)
231
+ assert_raises(XML::XXPathError) {
232
+ XML::XXPath.new("@lala").create_new(@d.root)
233
+ }
234
+ assert node1.kind_of?(XML::XXPath::Accessors::Attribute)
235
+ node1.text = "val1"
236
+ assert_equal "val1", @d.elements[1].attributes["lala"]
237
+ foo2 = XML::XXPath.new("foo[2]").first(@d.root)
238
+ assert_raises(XML::XXPathError) {
239
+ XML::XXPath.new("@key").create_new(foo2)
240
+ }
241
+ node2 = XML::XXPath.new("@bar").create_new(foo2)
242
+ assert node2.kind_of?(XML::XXPath::Accessors::Attribute)
243
+ node2.text = "val2"
244
+ assert_equal "val2", @d.elements[1].elements[3].attributes["bar"]
245
+ end
246
+
247
+
248
+ def test_create_new_byname_and_attr
249
+ node1 = XML::XXPath.new("hiho[@blubb='bla']").create_new(@d.root)
250
+ node2 = XML::XXPath.new("hiho[@blubb='bla']").create_new(@d.root)
251
+ node3 = XML::XXPath.new("hiho[@blubb2='bla']").create_new(@d.root)
252
+ assert_equal "hiho", node1.name
253
+ assert_equal "hiho", node2.name
254
+ assert_equal @d.root.elements[4], node1
255
+ assert_equal @d.root.elements[5], node2
256
+ assert_equal @d.root.elements[6], node3
257
+ assert_not_equal @d.root.elements[5], node1
258
+ end
259
+
260
+
261
+ def test_unspecifiedness
262
+ node1 = XML::XXPath.new("foo/hello").create_new(@d.root)
263
+ assert(!(node1.unspecified?))
264
+ assert_equal @d.root, node1.parent.parent
265
+ node2 = XML::XXPath.new("foo/*").create_new(@d.root)
266
+ assert_equal @d.root, node2.parent.parent
267
+ assert node2.unspecified?
268
+ node2.name = "newone"
269
+ assert_equal "newone", node2.name
270
+ assert(!(node2.unspecified?))
271
+ end
272
+
273
+ end