roxml 1.2 → 2.3.2

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 (97) hide show
  1. data/MIT-LICENSE +18 -0
  2. data/README.rdoc +126 -0
  3. data/Rakefile +100 -0
  4. data/lib/roxml.rb +479 -485
  5. data/lib/roxml/extensions/active_support.rb +32 -0
  6. data/lib/roxml/extensions/array.rb +5 -0
  7. data/lib/roxml/extensions/array/conversions.rb +25 -0
  8. data/lib/roxml/extensions/deprecation.rb +28 -0
  9. data/lib/roxml/extensions/string.rb +21 -0
  10. data/lib/roxml/extensions/string/conversions.rb +44 -0
  11. data/lib/roxml/extensions/string/iterators.rb +12 -0
  12. data/lib/roxml/options.rb +266 -0
  13. data/lib/roxml/xml.rb +223 -0
  14. data/lib/roxml/xml/libxml.rb +63 -0
  15. data/lib/roxml/xml/rexml.rb +64 -0
  16. data/roxml.gemspec +105 -0
  17. data/test/fixtures/book_text_with_attribute.xml +1 -1
  18. data/test/fixtures/book_valid.xml +2 -2
  19. data/test/fixtures/book_with_authors.xml +7 -0
  20. data/test/fixtures/book_with_contributors_attrs.xml +7 -0
  21. data/test/fixtures/book_with_default_namespace.xml +9 -0
  22. data/test/fixtures/book_with_depth.xml +6 -0
  23. data/test/fixtures/book_with_wrapped_attr.xml +3 -0
  24. data/test/fixtures/dictionary_of_attr_name_clashes.xml +8 -0
  25. data/test/fixtures/dictionary_of_attrs.xml +6 -0
  26. data/test/fixtures/dictionary_of_guarded_names.xml +6 -0
  27. data/test/fixtures/dictionary_of_mixeds.xml +4 -0
  28. data/test/fixtures/dictionary_of_name_clashes.xml +10 -0
  29. data/test/fixtures/dictionary_of_names.xml +4 -0
  30. data/test/fixtures/dictionary_of_texts.xml +10 -0
  31. data/test/fixtures/library.xml +1 -1
  32. data/test/fixtures/library_uppercase.xml +30 -0
  33. data/test/fixtures/muffins.xml +3 -0
  34. data/test/fixtures/nameless_ageless_youth.xml +2 -0
  35. data/test/fixtures/node_with_attr_name_conflicts.xml +1 -0
  36. data/test/fixtures/node_with_name_conflicts.xml +4 -0
  37. data/test/fixtures/numerology.xml +4 -0
  38. data/test/fixtures/person_with_guarded_mothers.xml +13 -0
  39. data/test/fixtures/person_with_mothers.xml +10 -0
  40. data/test/mocks/dictionaries.rb +56 -0
  41. data/test/mocks/mocks.rb +244 -48
  42. data/test/release/dependencies_test.rb +32 -0
  43. data/test/test_helper.rb +44 -0
  44. data/test/unit/inheritance_test.rb +19 -0
  45. data/test/unit/options_test.rb +102 -0
  46. data/test/unit/roxml_test.rb +24 -0
  47. data/test/unit/string_test.rb +11 -0
  48. data/test/unit/to_xml_test.rb +52 -0
  49. data/test/unit/xml_attribute_test.rb +39 -0
  50. data/test/unit/xml_block_test.rb +81 -0
  51. data/test/unit/xml_bool_test.rb +105 -0
  52. data/test/unit/xml_construct_test.rb +77 -0
  53. data/test/unit/xml_hash_test.rb +65 -0
  54. data/test/unit/xml_initialize_test.rb +50 -0
  55. data/test/unit/xml_name_test.rb +108 -0
  56. data/test/unit/xml_namespace_test.rb +38 -0
  57. data/test/unit/xml_object_test.rb +116 -0
  58. data/test/unit/xml_required_test.rb +93 -0
  59. data/test/unit/xml_text_test.rb +68 -0
  60. metadata +138 -87
  61. data/MIT-LICENSE.txt +0 -9
  62. data/README +0 -2
  63. data/doc/classes/ROXML.html +0 -374
  64. data/doc/classes/ROXML.src/M000003.html +0 -19
  65. data/doc/classes/ROXML.src/M000004.html +0 -25
  66. data/doc/classes/ROXML.src/M000005.html +0 -22
  67. data/doc/classes/ROXML/ROXML_Class.html +0 -429
  68. data/doc/classes/ROXML/ROXML_Class.src/M000006.html +0 -27
  69. data/doc/classes/ROXML/ROXML_Class.src/M000007.html +0 -18
  70. data/doc/classes/ROXML/ROXML_Class.src/M000008.html +0 -19
  71. data/doc/classes/ROXML/ROXML_Class.src/M000009.html +0 -25
  72. data/doc/classes/ROXML/ROXML_Class.src/M000010.html +0 -24
  73. data/doc/classes/ROXML/ROXML_Class.src/M000011.html +0 -18
  74. data/doc/classes/ROXML/ROXML_Class.src/M000012.html +0 -18
  75. data/doc/classes/ROXML/XMLAttributeRef.html +0 -175
  76. data/doc/classes/ROXML/XMLAttributeRef.src/M000015.html +0 -19
  77. data/doc/classes/ROXML/XMLAttributeRef.src/M000016.html +0 -19
  78. data/doc/classes/ROXML/XMLObjectRef.html +0 -175
  79. data/doc/classes/ROXML/XMLObjectRef.src/M000013.html +0 -26
  80. data/doc/classes/ROXML/XMLObjectRef.src/M000014.html +0 -32
  81. data/doc/classes/ROXML/XMLRef.html +0 -166
  82. data/doc/classes/ROXML/XMLRef.src/M000017.html +0 -21
  83. data/doc/classes/ROXML/XMLTextRef.html +0 -198
  84. data/doc/classes/ROXML/XMLTextRef.src/M000018.html +0 -28
  85. data/doc/classes/ROXML/XMLTextRef.src/M000019.html +0 -34
  86. data/doc/classes/String.html +0 -165
  87. data/doc/classes/String.src/M000001.html +0 -23
  88. data/doc/classes/String.src/M000002.html +0 -23
  89. data/doc/created.rid +0 -1
  90. data/doc/files/lib/roxml_rb.html +0 -234
  91. data/doc/fr_class_index.html +0 -33
  92. data/doc/fr_file_index.html +0 -27
  93. data/doc/fr_method_index.html +0 -45
  94. data/doc/index.html +0 -24
  95. data/doc/rdoc-style.css +0 -208
  96. data/test/fixture_helper.rb +0 -5
  97. data/test/test_roxml.rb +0 -105
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TestInheritance < Test::Unit::TestCase
4
+ def setup
5
+ @b = InheritedBookWithDepth.from_xml(fixture(:book_with_depth))
6
+ end
7
+
8
+ def test_inherited_object_should_include_parents_attributes
9
+ assert_equal '0201710897', @b.isbn
10
+ assert_equal 'The PickAxe', @b.title
11
+ assert_equal 'Probably the best Ruby book out there', @b.description
12
+ assert_equal 'David Thomas, Andrew Hunt, Dave Thomas', @b.author
13
+ assert_equal 0, @b.pages
14
+ end
15
+
16
+ def test_inherited_object_should_include_its_own_attributes
17
+ assert_equal '11.3 meters', @b.depth.to_s
18
+ end
19
+ end
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TestOptions < Test::Unit::TestCase
4
+ def test_text_in_array_means_as_array_for_text
5
+ opts = ROXML::Opts.new(:authors, [:text])
6
+ assert opts.array?
7
+ assert_equal :text, opts.type
8
+ end
9
+
10
+ def test_attr_in_array_means_as_array_for_attr
11
+ opts = ROXML::Opts.new(:authors, [:attr])
12
+ assert opts.array?
13
+ assert_equal :attr, opts.type
14
+ end
15
+
16
+ def test_object_in_array_means_as_array_for_object
17
+ opts = ROXML::Opts.new(:authors, [Hash])
18
+ assert opts.array?
19
+ assert_equal Hash, opts.type
20
+ end
21
+
22
+ def test_content_is_a_recognized_type
23
+ assert ROXML::Opts.new(:author, :content).content?
24
+ end
25
+
26
+ def test_required
27
+ assert !ROXML::Opts.new(:author, :content).required?
28
+ assert ROXML::Opts.new(:author, :content, :required => true).required?
29
+ assert !ROXML::Opts.new(:author, :content, :required => false).required?
30
+ end
31
+
32
+ def test_required_conflicts_with_else
33
+ assert_raise ArgumentError do
34
+ ROXML::Opts.new(:author, :content, :required => true, :else => 'Johnny')
35
+ end
36
+ ROXML::Opts.new(:author, :content, :required => false, :else => 'Johnny')
37
+ end
38
+
39
+ def test_hash_of_attrs
40
+ opts = ROXML::Opts.new(:attributes, {:attrs => [:name, :value]})
41
+ assert opts.hash?
42
+ assert !opts.array?
43
+ assert_equal [ROXML::XMLAttributeRef, ROXML::XMLAttributeRef], opts.hash.types
44
+ assert_equal ['name', 'value'], opts.hash.names
45
+ end
46
+
47
+ def test_hash_with_attr_key_and_text_val
48
+ opts = ROXML::Opts.new(:attributes, {:key => {:attr => :name},
49
+ :value => :value})
50
+ assert opts.hash?
51
+ assert !opts.array?
52
+ assert_equal [ROXML::XMLAttributeRef, ROXML::XMLTextRef], opts.hash.types
53
+ assert_equal ['name', 'value'], opts.hash.names
54
+ end
55
+
56
+ def test_hash_with_attr_key_and_content_val
57
+ opts = ROXML::Opts.new(:attributes, {:key => {:attr => :name},
58
+ :value => :content})
59
+ assert opts.hash?
60
+ assert !opts.array?
61
+ assert opts.hash.value.content?
62
+ assert_equal [ROXML::XMLAttributeRef, ROXML::XMLTextRef], opts.hash.types
63
+ assert_equal ['name', ''], opts.hash.names
64
+ end
65
+
66
+ def test_hash_with_options
67
+ opts = ROXML::Opts.new(:definitions, {:attrs => [:dt, :dd]},
68
+ :in => :definitions)
69
+
70
+ assert opts.hash?
71
+ assert !opts.array?
72
+ assert_equal [ROXML::XMLAttributeRef, ROXML::XMLAttributeRef], opts.hash.types
73
+ assert_equal ['dt', 'dd'], opts.hash.names
74
+ end
75
+
76
+ def test_no_block_shorthand_means_no_block
77
+ assert ROXML::Opts.new(:count).blocks.empty?
78
+ assert ROXML::Opts.new(:count, :as => :intager).blocks.empty?
79
+ assert ROXML::Opts.new(:count, :as => :foat).blocks.empty?
80
+ end
81
+
82
+ def test_block_integer_shorthand
83
+ assert_equal 3, ROXML::Opts.new(:count, :as => :integer).blocks.only['3']
84
+ assert_equal 3, ROXML::Opts.new(:count, :as => Integer).blocks.only['3']
85
+ end
86
+
87
+ def test_block_float_shorthand
88
+ assert_equal 3.1, ROXML::Opts.new(:count, :as => :float).blocks.only['3.1']
89
+ assert_equal 3.1, ROXML::Opts.new(:count, :as => Float).blocks.only['3.1']
90
+ end
91
+
92
+ def test_multiple_shorthands_raises
93
+ assert_raises ArgumentError do
94
+ ROXML::Opts.new(:count, :as => [Float, Integer])
95
+ end
96
+ end
97
+
98
+ def test_stacked_blocks
99
+ assert_equal 2, ROXML::Opts.new(:count, :as => Integer) {|val| val.to_i }.blocks.size
100
+ assert_equal 2, ROXML::Opts.new(:count, :as => Float) {|val| val.object_id }.blocks.size
101
+ end
102
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TestROXML < Test::Unit::TestCase
4
+ # Malformed XML parsing should throw REXML::ParseException
5
+ def test_malformed
6
+ ROXML::XML::Parser.register_error_handler {|err| }
7
+ assert_raise ROXML::XML::Parser::ParseError do
8
+ book = Book.from_xml(fixture(:book_malformed))
9
+ end
10
+ end
11
+
12
+ # Verify that an exception is thrown when two accessors have the same
13
+ # name in a ROXML class.
14
+ def test_duplicate_accessor
15
+ assert_raise RuntimeError do
16
+ Class.new do
17
+ include ROXML
18
+
19
+ xml_reader :id
20
+ xml_accessor :id
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'lib/roxml/extensions/string'
2
+
3
+ class TestROXML < Test::Unit::TestCase
4
+ def test_to_latin_is_accessible
5
+ assert String.instance_methods.include?('to_latin')
6
+ end
7
+
8
+ def test_to_utf_is_accessible
9
+ assert String.instance_methods.include?('to_utf')
10
+ end
11
+ end
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TestHashToXml < Test::Unit::TestCase
4
+ to_xml_test :dictionary_of_attrs,
5
+ :dictionary_of_mixeds,
6
+ :dictionary_of_texts,
7
+ :dictionary_of_names,
8
+ :dictionary_of_guarded_names,
9
+ :dictionary_of_name_clashes,
10
+ :dictionary_of_attr_name_clashes
11
+ end
12
+
13
+ class TestOtherToXml < Test::Unit::TestCase
14
+ to_xml_test :book => :book_valid,
15
+ :book_with_author_text_attribute => :book_text_with_attribute,
16
+ :uppercase_library => :library_uppercase
17
+
18
+ to_xml_test :book_with_authors,
19
+ :book_with_contributors,
20
+ :book_with_contributions,
21
+ :library,
22
+ :node_with_name_conflicts,
23
+ :node_with_attr_name_conflicts
24
+
25
+ to_xml_test :person_with_mother => :person_with_mothers,
26
+ :person_with_guarded_mother => :person_with_guarded_mothers
27
+
28
+ to_xml_test :book_with_wrapped_attr
29
+ end
30
+
31
+ class TestToXmlWithDefaults < Test::Unit::TestCase
32
+ def test_content_and_attr_defaults_are_represented_in_output
33
+ dict = Person.from_xml(fixture(:nameless_ageless_youth))
34
+
35
+ xml = '<person age="21">Unknown</person>'
36
+ assert_equal ROXML::XML::Parser.parse(xml).root, dict.to_xml
37
+ end
38
+ end
39
+
40
+ class TestToXmlWithBlocks < Test::Unit::TestCase
41
+ def test_pagecount_serialized_properly_after_modification
42
+ b = Book.from_xml(fixture(:book_valid))
43
+ xml = xml_fixture(:book_valid)
44
+ assert_equal '357', xml.search('pagecount').first.content
45
+ assert_equal 357, b.pages
46
+
47
+ b.pages = 500
48
+ doc = ROXML::XML::Document.new()
49
+ doc.root = b.to_xml
50
+ assert_equal '500', doc.search('pagecount').first.content
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TestXMLAttribute < Test::Unit::TestCase
4
+ def test_attr_from
5
+ # :attr => *
6
+ book = Book.from_xml(fixture(:book_text_with_attribute))
7
+ assert_equal '0201710897', book.isbn
8
+
9
+ # :attr, :from => *
10
+ book = BookWithAttrFrom.from_xml(fixture(:book_text_with_attribute))
11
+ assert_equal '0201710897', book.isbn
12
+ end
13
+
14
+ def test_mutable_attr
15
+ book = Book.from_xml(fixture(:book_text_with_attribute))
16
+ assert book.respond_to?(:'isbn=')
17
+ end
18
+
19
+ def test_default_initialization
20
+ person = PersonWithMotherOrMissing.from_xml(fixture(:nameless_ageless_youth))
21
+ assert_equal 21, person.age
22
+ end
23
+
24
+ def test_recursive_with_default_initialization
25
+ p = PersonWithMotherOrMissing.from_xml(fixture(:person_with_mothers))
26
+ assert_equal 21, p.mother.mother.mother.age
27
+ end
28
+
29
+ def test_no_name_clashes
30
+ n = NodeWithAttrNameConflicts.from_xml(fixture(:node_with_attr_name_conflicts))
31
+ assert_equal "Just junk... really", n.content
32
+ assert_equal "Cartwheel", n.name
33
+ end
34
+
35
+ def test_wrapped_attr_accessible
36
+ b = BookWithWrappedAttr.from_xml(fixture(:book_with_wrapped_attr))
37
+ assert_equal "0974514055", b.isbn
38
+ end
39
+ end
@@ -0,0 +1,81 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ArrayWithBlockShorthand
4
+ include ROXML
5
+
6
+ xml_reader :array, [:text], :from => 'number', :as => Integer
7
+ end
8
+
9
+ class ArrayWithBlock
10
+ include ROXML
11
+
12
+ xml_reader :array, [:text], :from => 'number' do |arr|
13
+ arr.map(&:to_i).reverse
14
+ end
15
+ end
16
+
17
+ class TestXMLBlocks < Test::Unit::TestCase
18
+ def test_block_is_applied
19
+ muffins = Muffins.from_xml(fixture(:muffins))
20
+
21
+ assert muffins.count > 0
22
+ assert_equal 0, muffins.count % 13
23
+ end
24
+
25
+ def test_block_is_applied_to_hash
26
+ numerology = Numerology.from_xml(fixture(:numerology))
27
+
28
+ assert !numerology.predictions.keys.empty?
29
+ assert numerology.predictions.keys.all? {|k| k.is_a? Integer }
30
+ assert numerology.predictions.values.all? {|k| k.is_a? String }
31
+ end
32
+
33
+ def test_stacked_blocks_are_applied
34
+ muffins = MuffinsWithStackedBlocks.from_xml(fixture(:muffins))
35
+
36
+ assert muffins.count > 0
37
+ assert_equal 0, muffins.count % 13
38
+ end
39
+
40
+ def test_block_shorthand_applied_properly_to_array
41
+ obj = ArrayWithBlockShorthand.from_xml(%{
42
+ <array_with_block_shorthand>
43
+ <number>1</number>
44
+ <number>2</number>
45
+ <number>3</number>
46
+ </array_with_block_shorthand>
47
+ })
48
+
49
+ assert_equal [1, 2, 3], obj.array
50
+ end
51
+
52
+ def test_block_applied_properly_to_array
53
+ obj = ArrayWithBlock.from_xml(%{
54
+ <array_with_block>
55
+ <number>1</number>
56
+ <number>2</number>
57
+ <number>3</number>
58
+ </array_with_block>
59
+ })
60
+
61
+ assert_equal [3, 2, 1], obj.array
62
+ end
63
+
64
+ def test_block_shorthand_applied_properly_to_empty_array
65
+ obj = ArrayWithBlockShorthand.from_xml(%{
66
+ <array_with_block_shorthand>
67
+ </array_with_block_shorthand>
68
+ })
69
+
70
+ assert_equal [], obj.array
71
+ end
72
+
73
+ def test_block_applied_properly_to_empty_array
74
+ obj = ArrayWithBlock.from_xml(%{
75
+ <array_with_block>
76
+ </array_with_block>
77
+ })
78
+
79
+ assert_equal [], obj.array
80
+ end
81
+ end
@@ -0,0 +1,105 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class XmlBool
4
+ include ROXML
5
+
6
+ xml_reader :true_from_TRUE?
7
+ xml_reader :false_from_FALSE?, :text => 'text_for_FALSE'
8
+ xml_reader :true_from_one?, :attr => 'attr_for_one'
9
+ xml_reader :false_from_zero?, :text => 'text_for_zero', :in => 'container'
10
+ xml_reader :true_from_True?, :attr => 'attr_for_True', :in => 'container'
11
+ xml_reader :false_from_False?, :text => 'false_from_cdata_False', :as => :cdata
12
+ xml_reader :true_from_true?
13
+ xml_reader :false_from_false?
14
+ xml_reader :missing?
15
+ end
16
+
17
+ class XmlBoolRequired
18
+ include ROXML
19
+
20
+ xml_reader :required?, :required => true
21
+ end
22
+
23
+ class XmlBoolUnexpected
24
+ include ROXML
25
+
26
+ xml_reader :unexpected?
27
+ end
28
+
29
+ class XmlBoolUnexpectedWithBlock
30
+ include ROXML
31
+
32
+ xml_reader :unexpected? do |val|
33
+ val
34
+ end
35
+ end
36
+
37
+ BOOL_XML = %{
38
+ <xml_bool attr_for_one="1">
39
+ <true_from_TRUE>TRUE</true_from_TRUE>
40
+ <text_for_FALSE>FALSE</text_for_FALSE>
41
+ <container attr_for_True="True">
42
+ <text_for_zero>0</text_for_zero>
43
+ </container>
44
+ <false_from_cdata_False><![CDATA[False]]></false_from_cdata_False>
45
+ <true_from_true>true</true_from_true>
46
+ <false_from_false>false</false_from_false>
47
+ <present_and_required>true</present_and_required>
48
+ </xml_bool>
49
+ }
50
+ PRESENT = %{
51
+ <xml_bool_required>
52
+ <required>true</required>
53
+ </xml_bool_required>
54
+ }
55
+ ABSENT = %{
56
+ <xml_bool_required>
57
+ </xml_bool_required>
58
+ }
59
+ UNEXPECTED_VALUE_XML = %{
60
+ <xml_bool_unexpected>
61
+ <unexpected>Unexpected Value</unexpected>
62
+ </xml_bool_unexpected>
63
+ }
64
+
65
+
66
+ class TestXMLBool < Test::Unit::TestCase
67
+ def test_bool_results_for_various_inputs
68
+ x = XmlBool.from_xml(BOOL_XML)
69
+ assert_equal true, x.true_from_TRUE?
70
+ assert_equal false, x.false_from_FALSE?
71
+ assert_equal true, x.true_from_one?
72
+ assert_equal false, x.false_from_zero?
73
+ assert_equal true, x.true_from_True?
74
+ assert_equal false, x.false_from_False?
75
+ assert_equal true, x.true_from_true?
76
+ assert_equal false, x.false_from_false?
77
+ end
78
+
79
+ def test_missing_results_in_nil
80
+ x = XmlBool.from_xml(BOOL_XML)
81
+ assert_equal nil, x.missing?
82
+ end
83
+
84
+ def test_unexpected_value_results_in_nil
85
+ x = XmlBoolUnexpected.from_xml(UNEXPECTED_VALUE_XML)
86
+ assert_equal nil, x.unexpected?
87
+ end
88
+
89
+ def test_block_recieves_unexpected_value_rather_than_nil
90
+ x = XmlBoolUnexpectedWithBlock.from_xml(UNEXPECTED_VALUE_XML)
91
+ assert_equal "Unexpected Value", x.unexpected?
92
+ end
93
+
94
+ def test_required_raises_on_missing
95
+ assert_nothing_raised do
96
+ XmlBoolRequired.from_xml(PRESENT)
97
+ end
98
+
99
+ assert_raises(ROXML::RequiredElementMissing) do
100
+ XmlBoolRequired.from_xml(ABSENT)
101
+ end
102
+ end
103
+
104
+ # to_xml_test XmlBool => BOOL_XML
105
+ end
@@ -0,0 +1,77 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class MeasurementWithXmlConstruct
4
+ include ROXML
5
+
6
+ xml_reader :units, :attr
7
+ xml_reader :value, :content
8
+
9
+ xml_construct_without_deprecation :value, :units
10
+
11
+ def initialize(value, units = 'pixels')
12
+ @value = Float(value)
13
+ @units = units.to_s
14
+ if @units.starts_with? 'hundredths-'
15
+ @value /= 100
16
+ @units = @units.split('hundredths-')[1]
17
+ end
18
+ end
19
+
20
+ def ==(other)
21
+ other.units == @units && other.value == @value
22
+ end
23
+ end
24
+
25
+ class BookWithDepthWithXmlConstruct
26
+ include ROXML
27
+
28
+ xml_reader :isbn, :attr => 'ISBN'
29
+ xml_reader :title
30
+ xml_reader :description, :as => :cdata
31
+ xml_reader :author
32
+ xml_reader :depth, MeasurementWithXmlConstruct
33
+ end
34
+
35
+ class InheritedBookWithDepthWithXmlConstruct < Book
36
+ xml_reader :depth, MeasurementWithXmlConstruct
37
+ end
38
+
39
+ class TestXMLConstruct < Test::Unit::TestCase
40
+ def test_is_deprecated
41
+ assert_deprecated do
42
+ MeasurementWithXmlConstruct.xml_construction_args
43
+ end
44
+ end
45
+
46
+ def test_initialize_is_run
47
+ m = MeasurementWithXmlConstruct.from_xml('<measurement units="hundredths-meters">1130</measurement>')
48
+ assert_equal 11.3, m.value
49
+ assert_equal 'meters', m.units
50
+ end
51
+
52
+ def test_initialize_is_run_for_nested_type
53
+ b = BookWithDepthWithXmlConstruct.from_xml(fixture(:book_with_depth))
54
+ assert_equal Measurement.new(11.3, 'meters'), b.depth
55
+ end
56
+
57
+ def test_initialize_is_run_for_nested_type_with_inheritance
58
+ b = InheritedBookWithDepthWithXmlConstruct.from_xml(fixture(:book_with_depth))
59
+ assert_equal Measurement.new(11.3, 'meters'), b.depth
60
+ end
61
+
62
+ def test_xml_name_uses_accessor_not_name
63
+ assert_nothing_raised do
64
+ Class.new do
65
+ include ROXML
66
+
67
+ xml_reader :bar, :attr => 'Foo'
68
+ xml_reader :foo, :text => 'Foo'
69
+ xml_reader :baz, :attr => 'Bar'
70
+
71
+ xml_construct_without_deprecation :baz, :bar, :foo
72
+ def initialize(baz, bar, foo)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end