xml-mapping 0.8.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/ChangeLog +64 -3
  2. data/README +871 -173
  3. data/README_XPATH +40 -13
  4. data/Rakefile +37 -26
  5. data/TODO.txt +39 -8
  6. data/examples/README +5 -0
  7. data/examples/company_usage.intout +34 -22
  8. data/examples/documents_folders.rb +31 -0
  9. data/examples/documents_folders.xml +16 -0
  10. data/examples/documents_folders_usage.intin.rb +18 -0
  11. data/examples/documents_folders_usage.intout +46 -0
  12. data/examples/order_signature_enhanced_usage.intout +21 -11
  13. data/examples/order_usage.intin.rb +52 -5
  14. data/examples/order_usage.intout +154 -80
  15. data/examples/person.intin.rb +44 -0
  16. data/examples/person.intout +27 -0
  17. data/examples/person_mm.intin.rb +119 -0
  18. data/examples/person_mm.intout +114 -0
  19. data/examples/publication.intin.rb +44 -0
  20. data/examples/publication.intout +20 -0
  21. data/examples/reader.intin.rb +33 -0
  22. data/examples/reader.intout +19 -0
  23. data/examples/stringarray.rb +5 -0
  24. data/examples/stringarray.xml +10 -0
  25. data/examples/stringarray_usage.intin.rb +11 -0
  26. data/examples/stringarray_usage.intout +31 -0
  27. data/examples/time_augm.intout +19 -7
  28. data/examples/time_augm_loading.intin.rb +44 -0
  29. data/examples/time_augm_loading.intout +12 -0
  30. data/examples/time_node.intin.rb +79 -0
  31. data/examples/time_node.rb +3 -2
  32. data/examples/time_node_w_marshallers.intin.rb +48 -0
  33. data/examples/time_node_w_marshallers.intout +25 -0
  34. data/examples/time_node_w_marshallers.xml +9 -0
  35. data/examples/xpath_create_new.intout +132 -114
  36. data/examples/xpath_ensure_created.intout +86 -65
  37. data/examples/xpath_pathological.intout +16 -16
  38. data/examples/xpath_usage.intout +1 -1
  39. data/install.rb +1 -0
  40. data/lib/xml/mapping.rb +3 -1
  41. data/lib/xml/mapping/base.rb +442 -272
  42. data/lib/xml/mapping/core_classes_mapping.rb +32 -0
  43. data/lib/xml/mapping/standard_nodes.rb +176 -86
  44. data/lib/xml/mapping/version.rb +2 -2
  45. data/lib/xml/rexml_ext.rb +186 -0
  46. data/lib/xml/xxpath.rb +28 -265
  47. data/lib/xml/xxpath/steps.rb +345 -0
  48. data/lib/xml/xxpath_methods.rb +96 -0
  49. data/test/all_tests.rb +4 -1
  50. data/test/benchmark_fixtures.rb +14 -0
  51. data/test/{multiple_mappings.rb → bookmarks.rb} +0 -0
  52. data/test/company.rb +47 -0
  53. data/test/documents_folders.rb +11 -1
  54. data/test/examples_test.rb +29 -0
  55. data/test/fixtures/benchmark.xml +77 -0
  56. data/test/fixtures/company1.xml +9 -0
  57. data/test/fixtures/documents_folders.xml +0 -8
  58. data/test/fixtures/documents_folders2.xml +13 -19
  59. data/test/fixtures/triangle_m1.xml +17 -0
  60. data/test/fixtures/triangle_m2.xml +19 -0
  61. data/test/inheritance_test.rb +50 -0
  62. data/test/multiple_mappings_test.rb +155 -0
  63. data/test/rexml_xpath_benchmark.rb +29 -0
  64. data/test/triangle_mm.rb +57 -0
  65. data/test/xml_mapping_adv_test.rb +36 -1
  66. data/test/xml_mapping_test.rb +136 -7
  67. data/test/xpath_test.rb +154 -0
  68. data/test/xxpath_benchmark.rb +36 -0
  69. data/test/xxpath_benchmark.result1.txt +17 -0
  70. data/test/xxpath_methods_test.rb +61 -0
  71. metadata +139 -90
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__)+"/tests_init"
2
+
3
+ require 'test/unit'
4
+ require 'xml/mapping'
5
+ require 'xml/xxpath_methods'
6
+
7
+ class Base
8
+ attr_accessor :baseinit
9
+
10
+ def initialize(p)
11
+ self.baseinit = p
12
+ end
13
+ end
14
+
15
+ class Derived < Base
16
+ include XML::Mapping
17
+
18
+ text_node :mytext, "mytext"
19
+ end
20
+
21
+ class Derived2 < Base
22
+ include XML::Mapping
23
+
24
+ text_node :baseinit, "baseinit"
25
+ end
26
+
27
+ # test that tries to reproduce ticket #4783
28
+ class InheritanceTest < Test::Unit::TestCase
29
+
30
+ def test_inheritance_simple
31
+ d = Derived.new "foo"
32
+ assert_equal "foo", d.baseinit
33
+ d.mytext = "hello"
34
+ dxml=d.save_to_xml
35
+ assert_equal "hello", dxml.first_xpath("mytext").text
36
+ d2 = Derived.load_from_xml(dxml)
37
+ assert_nil d2.baseinit
38
+ assert_equal "hello", d2.mytext
39
+ end
40
+
41
+ def test_inheritance_superclass_initializing_mappedattr
42
+ d = Derived2.new "foo"
43
+ assert_equal "foo", d.baseinit
44
+ dxml=d.save_to_xml
45
+ assert_equal "foo", dxml.first_xpath("baseinit").text
46
+ d2 = Derived2.load_from_xml(dxml)
47
+ assert_equal "foo", d2.baseinit
48
+ end
49
+
50
+ end
@@ -0,0 +1,155 @@
1
+ require File.dirname(__FILE__)+"/tests_init"
2
+
3
+ require 'test/unit'
4
+ require 'triangle_mm'
5
+
6
+ require 'xml/xxpath_methods'
7
+
8
+ class MultipleMappingsTest < Test::Unit::TestCase
9
+ def setup
10
+ # need to undo mapping class definitions that may have been
11
+ # established by other tests (and outlive those tests)
12
+
13
+ # this requires some ugly hackery with internal variables
14
+ XML::Mapping.module_eval <<-EOS
15
+ Classes_by_rootelt_names.clear
16
+ EOS
17
+ Object.send(:remove_const, "Triangle")
18
+ $".delete "triangle_mm.rb"
19
+ $:.unshift File.dirname(__FILE__) # test/unit may have undone this (see test/unit/collector/dir.rb)
20
+ require 'triangle_mm'
21
+ end
22
+
23
+ def test_read
24
+ t1=Triangle.load_from_file File.dirname(__FILE__) + "/fixtures/triangle_m1.xml", :mapping=>:m1
25
+ assert_raises(XML::MappingError) do
26
+ Triangle.load_from_file File.dirname(__FILE__) + "/fixtures/triangle_m1.xml", :mapping=>:m2
27
+ end
28
+ t2=Triangle.load_from_file File.dirname(__FILE__) + "/fixtures/triangle_m2.xml", :mapping=>:m2
29
+
30
+ t=Triangle.new('tri1','green',
31
+ Point.new(3,0),Point.new(2,4),Point.new(0,1))
32
+
33
+ assert_equal t, t1
34
+ assert_equal t, t2
35
+ assert_equal t1, t2
36
+ assert_equal "default description", t2.descr
37
+ assert_nil t1.descr
38
+ assert_not_equal Triangle.allocate, t
39
+
40
+ # loading with default mapping should raise an exception because
41
+ # the default mapping was never used yet
42
+ assert_raises(XML::MappingError) do
43
+ Triangle.load_from_file(File.dirname(__FILE__) + "/fixtures/triangle_m1.xml")
44
+ end
45
+ assert_raises(XML::MappingError) do
46
+ Triangle.load_from_file(File.dirname(__FILE__) + "/fixtures/triangle_m2.xml")
47
+ end
48
+
49
+ # after using it once, we get empty objects
50
+ Triangle.class_eval "use_mapping :_default"
51
+ assert_equal Triangle.allocate,
52
+ Triangle.load_from_file(File.dirname(__FILE__) + "/fixtures/triangle_m1.xml")
53
+ assert_equal Triangle.allocate,
54
+ Triangle.load_from_file(File.dirname(__FILE__) + "/fixtures/triangle_m2.xml")
55
+ end
56
+
57
+
58
+ def test_read_polymorphic
59
+ t1=XML::Mapping.load_object_from_file File.dirname(__FILE__) + "/fixtures/triangle_m1.xml", :mapping=>:m1
60
+ t2=XML::Mapping.load_object_from_file File.dirname(__FILE__) + "/fixtures/triangle_m2.xml", :mapping=>:m2
61
+ t=Triangle.new('tri1','green',
62
+ Point.new(3,0),Point.new(2,4),Point.new(0,1))
63
+
64
+ assert_equal t, t1
65
+ assert_equal t, t2
66
+ assert_equal t1, t2
67
+ end
68
+
69
+
70
+ def test_write
71
+ t1=XML::Mapping.load_object_from_file File.dirname(__FILE__) + "/fixtures/triangle_m1.xml", :mapping=>:m1
72
+ m1xml = t1.save_to_xml :mapping=>:m1
73
+ m2xml = t1.save_to_xml :mapping=>:m2
74
+
75
+ assert_equal t1.name, m1xml.first_xpath('@name').text
76
+ assert_equal t1.name, m2xml.first_xpath('name').text
77
+ assert_equal t1.p2, Point.load_from_xml(m1xml.first_xpath('pt2'), :mapping=>:m1)
78
+ assert_equal t1.p2, Point.load_from_xml(m2xml.first_xpath('points/point[2]'), :mapping=>:m1)
79
+ end
80
+
81
+
82
+ def test_root_element
83
+ t1=XML::Mapping.load_object_from_file File.dirname(__FILE__) + "/fixtures/triangle_m1.xml", :mapping=>:m1
84
+ m1xml = t1.save_to_xml :mapping=>:m1
85
+ m2xml = t1.save_to_xml :mapping=>:m2
86
+
87
+ assert_equal "triangle", Triangle.root_element_name(:mapping=>:m1)
88
+ assert_equal "triangle", Triangle.root_element_name(:mapping=>:m2)
89
+ assert_equal Triangle, XML::Mapping.class_for_root_elt_name("triangle",:mapping=>:m1)
90
+ assert_equal Triangle, XML::Mapping.class_for_root_elt_name("triangle",:mapping=>:m2)
91
+ assert_equal "triangle", t1.save_to_xml(:mapping=>:m1).name
92
+ assert_equal "triangle", t1.save_to_xml(:mapping=>:m2).name
93
+
94
+ Triangle.class_eval <<-EOS
95
+ use_mapping :m1
96
+ root_element_name 'foobar'
97
+ EOS
98
+
99
+ assert_equal "foobar", Triangle.root_element_name(:mapping=>:m1)
100
+ assert_equal "triangle", Triangle.root_element_name(:mapping=>:m2)
101
+ assert_nil XML::Mapping.class_for_root_elt_name("triangle",:mapping=>:m1)
102
+ assert_equal Triangle, XML::Mapping.class_for_root_elt_name("foobar",:mapping=>:m1)
103
+ assert_equal Triangle, XML::Mapping.class_for_root_elt_name("triangle",:mapping=>:m2)
104
+ assert_equal "foobar", t1.save_to_xml(:mapping=>:m1).name
105
+ assert_equal "triangle", t1.save_to_xml(:mapping=>:m2).name
106
+ assert_equal [Triangle,:m1], XML::Mapping.class_and_mapping_for_root_elt_name("foobar")
107
+ assert_raises(XML::MappingError) do
108
+ XML::Mapping.load_object_from_xml(m1xml, :mapping=>:m1)
109
+ end
110
+ assert_equal t1, XML::Mapping.load_object_from_xml(m2xml, :mapping=>:m2)
111
+ m1xml.name = "foobar"
112
+ assert_equal t1, XML::Mapping.load_object_from_xml(m1xml, :mapping=>:m1)
113
+
114
+ Triangle.class_eval <<-EOS
115
+ use_mapping :m1
116
+ root_element_name 'triangle'
117
+ EOS
118
+
119
+ assert_raises(XML::MappingError) do
120
+ XML::Mapping.load_object_from_xml(m1xml, :mapping=>:m1)
121
+ end
122
+ m1xml.name = "triangle"
123
+ assert_equal t1, XML::Mapping.load_object_from_xml(m1xml, :mapping=>:m1)
124
+ end
125
+
126
+
127
+ def test_node_initialization
128
+ end
129
+
130
+
131
+ def test_misc
132
+ m1nodes = Triangle.xml_mapping_nodes(:mapping=>:m1).map{|n|n.class}
133
+ m2nodes = Triangle.xml_mapping_nodes(:mapping=>:m2).map{|n|n.class}
134
+ allnodes = Triangle.xml_mapping_nodes.map{|n|n.class}
135
+
136
+ t=XML::Mapping::TextNode
137
+ o=XML::Mapping::ObjectNode
138
+ assert_equal [t,o,o,t,o], m1nodes
139
+ assert_equal [o,t,t,o,o,t], m2nodes
140
+ begin
141
+ assert_equal m1nodes+m2nodes, allnodes
142
+ rescue Test::Unit::AssertionFailedError
143
+ assert_equal m2nodes+m1nodes, allnodes
144
+ end
145
+
146
+ allm1nodes = Triangle.all_xml_mapping_nodes(:mapping=>:m1).map{|n|n.class}
147
+ allm2nodes = Triangle.all_xml_mapping_nodes(:mapping=>:m2).map{|n|n.class}
148
+ allallnodes = Triangle.all_xml_mapping_nodes.map{|n|n.class}
149
+
150
+ assert_equal allm1nodes, m1nodes
151
+ assert_equal allm2nodes, m2nodes
152
+ assert_equal allnodes, allallnodes
153
+ end
154
+
155
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__)+"/benchmark_fixtures"
2
+
3
+ require "rexml/xpath"
4
+
5
+ require 'benchmark'
6
+ include Benchmark
7
+
8
+ rootelt = @d.root
9
+ foo2elt = rootelt.elements[3]
10
+ res1=res2=res3=res4=res5=nil
11
+ print "(#{@count} runs)\n"
12
+ bmbm(12) do |x|
13
+ x.report("by_name") { @count.times { res1 = XPath.first(rootelt, @path_by_name) } }
14
+ x.report("by_idx") { @count.times { res2 = XPath.first(rootelt, @path_by_idx) } }
15
+ x.report("by_idx_idx") { @count.times { res3 = XPath.first(rootelt, @path_by_idx_idx) } }
16
+ x.report("by_attr_idx") { @count.times { res4 = XPath.first(rootelt, @path_by_attr_idx) } }
17
+ x.report("xxpath_by_attr") { (@count*4).times { res5 = XPath.first(foo2elt, @path_by_attr) } }
18
+ end
19
+
20
+
21
+ def assert_equal(expected,actual)
22
+ expected==actual or raise "expected: #{expected.inspect}, actual: #{actual.inspect}"
23
+ end
24
+
25
+ assert_equal "bar4-2", res1.text.strip
26
+ assert_equal "bar6", res2.text.strip
27
+ assert_equal "bar4-6", res3.text.strip
28
+ assert_equal "bar4-6", res4.text.strip
29
+ assert_equal "xy", res5.value.strip
@@ -0,0 +1,57 @@
1
+ require 'xml/mapping'
2
+
3
+ module XML::Mapping
4
+ def ==(other)
5
+ Marshal.dump(self) == Marshal.dump(other)
6
+ end
7
+ end
8
+
9
+
10
+ # forward declarations
11
+ class Point; end
12
+
13
+ class Triangle
14
+ include XML::Mapping
15
+
16
+ use_mapping :m1
17
+
18
+ text_node :name, "@name"
19
+ object_node :p1, "pt1", :class=>Point
20
+ object_node :p2, "points/point[2]", :class=>Point, :mapping=>:m2, :sub_mapping=>:m1
21
+ object_node :p3, "pt3", :class=>Point
22
+ text_node :color, "color"
23
+
24
+
25
+ use_mapping :m2
26
+
27
+ text_node :color, "@color"
28
+ text_node :name, "name"
29
+ object_node :p1, "points/point[1]", :class=>Point, :sub_mapping=>:m1
30
+ object_node :p2, "pt2", :class=>Point, :mapping=>:m1
31
+ object_node :p3, "points/point[3]", :class=>Point, :sub_mapping=>:m1
32
+
33
+ text_node :descr, "description", :default_value=>"default description"
34
+
35
+ def initialize(name,color,p1,p2,p3)
36
+ @name,@color,@p1,@p2,@p3 = name,color,p1,p2,p3
37
+ end
38
+
39
+ def ==(other)
40
+ name==other.name and color==other.color and
41
+ p1==other.p1 and p2==other.p2 and p3==other.p3
42
+ end
43
+ end
44
+
45
+
46
+ class Point
47
+ include XML::Mapping
48
+
49
+ use_mapping :m1
50
+
51
+ numeric_node :x, "x"
52
+ numeric_node :y, "y"
53
+
54
+ def initialize(x,y)
55
+ @x,@y = x,y
56
+ end
57
+ end
@@ -2,11 +2,22 @@ require File.dirname(__FILE__)+"/tests_init"
2
2
 
3
3
  require 'test/unit'
4
4
  require 'documents_folders'
5
- require 'multiple_mappings'
5
+ require 'bookmarks'
6
6
  require 'yaml'
7
7
 
8
8
  class XmlMappingAdvancedTest < Test::Unit::TestCase
9
9
  def setup
10
+ XML::Mapping.module_eval <<-EOS
11
+ Classes_by_rootelt_names.clear
12
+ EOS
13
+ Object.send(:remove_const, "Document")
14
+ Object.send(:remove_const, "Folder")
15
+
16
+ $".delete "documents_folders.rb"
17
+ $".delete "bookmarks.rb"
18
+ require 'documents_folders'
19
+ require 'bookmarks'
20
+
10
21
  @f_xml = REXML::Document.new(File.new(File.dirname(__FILE__) + "/fixtures/documents_folders2.xml"))
11
22
  @f = XML::Mapping.load_object_from_xml(@f_xml.root)
12
23
 
@@ -34,6 +45,30 @@ class XmlMappingAdvancedTest < Test::Unit::TestCase
34
45
  EOS
35
46
  end
36
47
 
48
+ def test_write_polymorphic_object
49
+ xml = @f.save_to_xml
50
+ assert_equal "folder", xml.name
51
+ assert_equal "home", xml.elements[1].text
52
+ assert_equal "document", xml.elements[2].name
53
+ assert_equal "folder", xml.elements[3].name
54
+ assert_equal "name", xml.elements[3].elements[1].name
55
+ assert_equal "folder", xml.elements[3].elements[2].name
56
+ assert_equal "foo bar baz", xml.elements[3].elements[2].elements[2].elements[2].text
57
+
58
+ @f.append "etc", Folder.new
59
+ @f["etc"].append "passwd", Document.new
60
+ @f["etc"]["passwd"].contents = "foo:x:2:2:/bin/sh"
61
+ @f["etc"].append "hosts", Document.new
62
+ @f["etc"]["hosts"].contents = "127.0.0.1 localhost"
63
+
64
+ xml = @f.save_to_xml
65
+
66
+ xmletc = xml.elements[4]
67
+ assert_equal "etc", xmletc.elements[1].text
68
+ assert_equal "document", xmletc.elements[2].name
69
+ assert_equal "passwd", xmletc.elements[2].elements[1].text
70
+ assert_equal "foo:x:2:2:/bin/sh", xmletc.elements[2].elements[2].text
71
+ end
37
72
 
38
73
  def test_read_bookmars1_2
39
74
  expected = BMFolder.new{|x|
@@ -2,6 +2,7 @@ require File.dirname(__FILE__)+"/tests_init"
2
2
 
3
3
  require 'test/unit'
4
4
  require 'company'
5
+ require 'xml/xxpath_methods'
5
6
 
6
7
  module XML::Mapping
7
8
  def ==(other)
@@ -16,13 +17,16 @@ class XmlMappingTest < Test::Unit::TestCase
16
17
 
17
18
  # this requires some ugly hackery with internal variables
18
19
  XML::Mapping.module_eval <<-EOS
19
- Classes_w_default_rootelt_names.clear
20
- Classes_w_nondefault_rootelt_names.clear
20
+ Classes_by_rootelt_names.clear
21
21
  EOS
22
22
  Object.send(:remove_const, "Company")
23
23
  Object.send(:remove_const, "Address")
24
24
  Object.send(:remove_const, "Office")
25
25
  Object.send(:remove_const, "Customer")
26
+ Object.send(:remove_const, "Thing")
27
+ Object.send(:remove_const, "Names1")
28
+ Object.send(:remove_const, "ReaderTest")
29
+ Object.send(:remove_const, "WriterTest")
26
30
  $".delete "company.rb"
27
31
  $:.unshift File.dirname(__FILE__) # test/unit may have undone this (see test/unit/collector/dir.rb)
28
32
  require 'company'
@@ -52,12 +56,105 @@ class XmlMappingTest < Test::Unit::TestCase
52
56
  assert_equal exp, @c.customers[ckey].uid
53
57
  end
54
58
  end
55
-
59
+
60
+
61
+ def test_getter_choice_node
62
+ assert_equal 4, @c.things.size
63
+ assert_equal "name1", @c.things[0].name
64
+ assert_equal "name2", @c.things[1].name
65
+ assert_equal "name3", @c.things[2].name
66
+ assert_equal "name4-elt", @c.things[3].name
67
+ end
68
+
69
+
70
+ def test_getter_choice_node_multiple_attrs
71
+ d = REXML::Document.new <<-EOS
72
+ <names1>
73
+ <names>
74
+ <name>multi1</name>
75
+ <name>multi2</name>
76
+ </names>
77
+ <name>single</name>
78
+ </names1>
79
+ EOS
80
+ n1 = Names1.load_from_xml d.root
81
+ assert_equal "single", n1.name
82
+ assert_nil n1.names
83
+
84
+ d.root.delete_element "name"
85
+ n1 = Names1.load_from_xml d.root
86
+ assert_nil n1.name
87
+ assert_equal ["multi1","multi2"], n1.names
88
+ end
89
+
90
+
91
+ def test_choice_node_presence
92
+ node = Thing.xml_mapping_nodes[0]
93
+ t = Thing.new
94
+ assert !(node.is_present_in? t)
95
+ t.name = "Mary"
96
+ assert node.is_present_in? t
97
+ end
98
+
99
+
56
100
  def test_getter_array_node
57
101
  assert_equal ["pencils", "weapons of mass destruction"],
58
102
  @c.offices.map{|o|o.speciality}
59
103
  end
60
-
104
+
105
+
106
+ def test_reader
107
+ xml = REXML::Document.new("<test>
108
+ <foo>footext</foo>
109
+ <foo2>foo2text</foo2>
110
+ <foo3>foo3text</foo3>
111
+ <bar>bartext</bar>
112
+ </test>").root
113
+ r = ReaderTest.load_from_xml xml
114
+ assert_equal 'footext', r.foo
115
+ assert_nil r.foo2
116
+ assert_equal 'foo3text', r.foo3
117
+ assert_equal 'bartext', r.bar
118
+ assert_equal [:foo2,:foo3], r.read
119
+
120
+ r.foo = 'foonew'
121
+ r.foo2 = 'foo2new'
122
+ r.foo3 = 'foo3new'
123
+ r.bar = 'barnew'
124
+ xml2 = r.save_to_xml
125
+ assert_equal 'foonew', xml2.first_xpath("foo").text
126
+ assert_equal 'foo2new', xml2.first_xpath("foo2").text
127
+ assert_equal 'foo3new', xml2.first_xpath("foo3").text
128
+ assert_equal 'barnew', xml2.first_xpath("bar").text
129
+ end
130
+
131
+
132
+ def test_writer
133
+ xml = REXML::Document.new("<test>
134
+ <foo>footext</foo>
135
+ <foo2>foo2text</foo2>
136
+ <foo3>foo3text</foo3>
137
+ <bar>bartext</bar>
138
+ </test>").root
139
+ w = WriterTest.load_from_xml xml
140
+ assert_equal 'footext', w.foo
141
+ assert_equal 'foo2text', w.foo2
142
+ assert_equal 'foo3text', w.foo3
143
+ assert_equal 'bartext', w.bar
144
+
145
+ w.foo = 'foonew'
146
+ w.foo2 = 'foo2new'
147
+ w.foo3 = 'foo3new'
148
+ w.bar = 'barnew'
149
+ xml2 = w.save_to_xml
150
+ assert_equal 'foonew', xml2.first_xpath("foo").text
151
+ assert_nil xml2.first_xpath("foo2",:allow_nil=>true)
152
+ assert_equal 'foo3new', xml2.first_xpath("foo3").text
153
+ assert_equal 'barnew', xml2.first_xpath("bar").text
154
+
155
+ assert_equal %w{dingdong2 dingdong3}, xml2.all_xpath("quux").map{|elt|elt.text}
156
+ end
157
+
61
158
 
62
159
  def test_setter_text_node
63
160
  @c.ent2 = "lalala"
@@ -87,6 +184,35 @@ class XmlMappingTest < Test::Unit::TestCase
87
184
  end
88
185
 
89
186
 
187
+ def test_setter_choice_node
188
+ xml=@c.save_to_xml
189
+ thingselts = xml.all_xpath("stuff2/thing")
190
+ assert_equal @c.things.size, thingselts.size
191
+ assert_equal @c.things[0].name, thingselts[0].first_xpath("name").text
192
+ assert_equal @c.things[1].name, thingselts[1].first_xpath("name").text
193
+ assert_equal @c.things[2].name, thingselts[2].first_xpath("name").text
194
+ assert_equal @c.things[3].name, thingselts[3].first_xpath("name").text
195
+ end
196
+
197
+
198
+ def test_setter_choice_node_multiple_attrs
199
+ n1 = Names1.new
200
+ assert_raises(XML::MappingError) {
201
+ n1.save_to_xml # no choice present in n1
202
+ }
203
+
204
+ n1.names = ["multi1","multi2"]
205
+ xml = n1.save_to_xml
206
+ assert_equal n1.names, xml.all_xpath("names/name").map{|elt|elt.text}
207
+ assert_nil xml.first_xpath("name", :allow_nil=>true)
208
+
209
+ n1.name = "foo"
210
+ xml = n1.save_to_xml
211
+ assert_equal [], xml.all_xpath("names/name").map{|elt|elt.text}
212
+ assert_equal n1.name, xml.first_xpath("name", :allow_nil=>true).text
213
+ end
214
+
215
+
90
216
  def test_root_element
91
217
  assert_equal @c, XML::Mapping.load_object_from_file(File.dirname(__FILE__) + "/fixtures/company1.xml")
92
218
  assert_equal @c, XML::Mapping.load_object_from_xml(@xml.root)
@@ -113,9 +239,12 @@ class XmlMappingTest < Test::Unit::TestCase
113
239
  assert_equal @c, XML::Mapping.load_object_from_xml(@xml.root)
114
240
 
115
241
  # 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
242
+ #assert_equal [["my-test", {:_default=>Company}]], XML::Mapping::Classes_w_nondefault_rootelt_names.sort
243
+ #assert_equal [["address", {:_default=>Address}],
244
+ # ["company", {}],
245
+ # ["customer", {:_default=>Customer}],
246
+ # ["office", {:_default=>Office}]],
247
+ # XML::Mapping::Classes_w_default_rootelt_names.sort
119
248
  end
120
249
 
121
250