Empact-roxml 2.1 → 2.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.
@@ -1,7 +1,7 @@
1
1
  require 'libxml'
2
2
 
3
3
  module ROXML
4
- module XML # ::nodoc::
4
+ module XML # :nodoc:all
5
5
  Document = LibXML::XML::Document
6
6
  Node = LibXML::XML::Node
7
7
  Parser = LibXML::XML::Parser
@@ -19,7 +19,7 @@ module ROXML
19
19
  private
20
20
  def namespaced(xpath)
21
21
  xpath.between('/') do |component|
22
- if component =~ /\w+/ && !component.include?(':')
22
+ if component =~ /\w+/ && !component.include?(':') && !component.starts_with?('@')
23
23
  in_default_namespace(component)
24
24
  else
25
25
  component
@@ -1,5 +1,5 @@
1
1
  module ROXML
2
- module XML # ::nodoc::
2
+ module XML # :nodoc:all
3
3
  Document = REXML::Document
4
4
  Node = REXML::Element
5
5
 
@@ -16,7 +16,10 @@ module ROXML
16
16
  end
17
17
 
18
18
  alias_attribute :content, :text
19
- alias :search :get_elements
19
+
20
+ def search(xpath)
21
+ REXML::XPath.match(self, xpath)
22
+ end
20
23
 
21
24
  def child_add(element)
22
25
  if element.is_a?(REXML::CData)
data/roxml.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "roxml"
3
3
  s.summary = "Ruby Object to XML mapping library"
4
- s.version = "2.1"
4
+ s.version = "2.2"
5
5
  s.homepage = "http://roxml.rubyforge.org"
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ["Ben Woosley", "Zak Mandhro", "Anders Engstrom", "Russ Olsen"]
@@ -13,9 +13,13 @@ Gem::Specification.new do |s|
13
13
  'Rakefile',
14
14
  'roxml.gemspec',
15
15
  'lib/roxml.rb',
16
- 'lib/roxml/array.rb',
16
+ 'lib/roxml/extensions/array.rb',
17
+ 'lib/roxml/extensions/array/conversions.rb',
18
+ 'lib/roxml/extensions/string.rb',
19
+ 'lib/roxml/extensions/string/conversions.rb',
20
+ 'lib/roxml/extensions/string/iterators.rb',
21
+ 'lib/roxml/extensions/deprecation.rb',
17
22
  'lib/roxml/options.rb',
18
- 'lib/roxml/string.rb',
19
23
  'lib/roxml/xml.rb',
20
24
  'lib/roxml/xml/libxml.rb',
21
25
  'lib/roxml/xml/rexml.rb',
@@ -30,11 +34,18 @@ Gem::Specification.new do |s|
30
34
  'test/fixtures/book_with_default_namespace.xml',
31
35
  'test/fixtures/book_with_depth.xml',
32
36
  'test/fixtures/book_with_publisher.xml',
37
+ 'test/fixtures/book_with_wrapped_attr.xml',
33
38
  'test/fixtures/dictionary_of_attrs.xml',
39
+ 'test/fixtures/dictionary_of_attr_name_clashes.xml',
40
+ 'test/fixtures/dictionary_of_guarded_names.xml',
34
41
  'test/fixtures/dictionary_of_mixeds.xml',
42
+ 'test/fixtures/dictionary_of_names.xml',
43
+ 'test/fixtures/dictionary_of_name_clashes.xml',
35
44
  'test/fixtures/dictionary_of_texts.xml',
36
45
  'test/fixtures/library_uppercase.xml',
37
46
  'test/fixtures/library.xml',
47
+ 'test/fixtures/node_with_attr_name_conflicts.xml',
48
+ 'test/fixtures/node_with_name_conflicts.xml',
38
49
  'test/fixtures/nameless_ageless_youth.xml',
39
50
  'test/fixtures/person_with_guarded_mothers.xml',
40
51
  'test/fixtures/person_with_mothers.xml',
@@ -54,6 +65,8 @@ Gem::Specification.new do |s|
54
65
  'test/unit/xml_object_test.rb',
55
66
  'test/unit/xml_text_test.rb']
56
67
  s.requirements << 'none'
68
+ s.add_dependency 'extensions', '>= 0.6.0'
69
+ s.add_development_dependency('Empact-rails-plugin-package-task', '>= 0.1') if s.respond_to?(:add_development_dependency)
57
70
  s.require_path = 'lib'
58
71
  s.test_files = [
59
72
  'test/unit/options_test.rb',
@@ -0,0 +1,3 @@
1
+ <book>
2
+ <ids ISBN="0974514055" />
3
+ </book>
@@ -0,0 +1,8 @@
1
+ <dictionary>
2
+ <definition name="quaquaversally">
3
+ <content>adjective: (of a geological formation) sloping downward from the center in all directions.</content>
4
+ </definition>
5
+ <definition name="tergiversate">
6
+ <content>To use evasions or ambiguities; equivocate.</content>
7
+ </definition>
8
+ </dictionary>
@@ -0,0 +1,6 @@
1
+ <dictionary>
2
+ <definitions>
3
+ <quaquaversally>adjective: (of a geological formation) sloping downward from the center in all directions.</quaquaversally>
4
+ <tergiversate>To use evasions or ambiguities; equivocate.</tergiversate>
5
+ </definitions>
6
+ </dictionary>
@@ -0,0 +1,10 @@
1
+ <dictionary>
2
+ <definition>
3
+ <name>quaquaversally</name>
4
+ <content>adjective: (of a geological formation) sloping downward from the center in all directions.</content>
5
+ </definition>
6
+ <definition>
7
+ <name>tergiversate</name>
8
+ <content>To use evasions or ambiguities; equivocate.</content>
9
+ </definition>
10
+ </dictionary>
@@ -0,0 +1,4 @@
1
+ <dictionary>
2
+ <quaquaversally>adjective: (of a geological formation) sloping downward from the center in all directions.</quaquaversally>
3
+ <tergiversate>To use evasions or ambiguities; equivocate.</tergiversate>
4
+ </dictionary>
@@ -0,0 +1 @@
1
+ <node content="Just junk... really" name="Cartwheel" />
@@ -0,0 +1,4 @@
1
+ <node>
2
+ <content>Just junk... really</content>
3
+ <name>Cartwheel</name>
4
+ </node>
data/test/mocks/mocks.rb CHANGED
@@ -1,5 +1,39 @@
1
1
  require "lib/roxml"
2
2
 
3
+ class Muffins
4
+ include ROXML
5
+
6
+ xml_reader(:count, :from => 'bakers_dozens') {|val| val.to_i * 13 }
7
+ end
8
+
9
+ class MuffinsWithStackedBlocks
10
+ include ROXML
11
+
12
+ xml_reader(:count, :from => 'bakers_dozens', :as => Integer) {|val| val * 13 }
13
+ end
14
+
15
+ class Numerology
16
+ include ROXML
17
+
18
+ xml_reader :predictions, {:attrs => ['number', 'meaning']} do |k, v|
19
+ [Integer(k), v]
20
+ end
21
+ end
22
+
23
+ class Contributor
24
+ include ROXML
25
+
26
+ xml_reader :role, :attr
27
+ xml_reader :name
28
+ end
29
+
30
+ class WriteableContributor
31
+ include ROXML
32
+
33
+ xml_accessor :role, :attr
34
+ xml_accessor :name
35
+ end
36
+
3
37
  class Book
4
38
  include ROXML
5
39
 
@@ -7,9 +41,17 @@ class Book
7
41
  xml_reader :title
8
42
  xml_reader :description, :as => :cdata
9
43
  xml_reader :author
10
- xml_accessor :pages, :text => 'pagecount' do |val|
11
- Integer(val)
12
- end
44
+ xml_accessor :pages, :text => 'pagecount', :as => Integer
45
+ end
46
+
47
+ class BookWithRequired
48
+ include ROXML
49
+
50
+ xml_accessor :isbn, :attr => 'ISBN', :required => true
51
+ xml_reader :title, :required => true
52
+ xml_reader :contributors, [Contributor], :in => 'contributor_array', :required => true
53
+ xml_reader :contributor_hash, {:attrs => ['role', 'name']},
54
+ :from => 'contributor', :in => 'contributor_hash', :required => true
13
55
  end
14
56
 
15
57
  class BookWithAttrFrom
@@ -18,6 +60,13 @@ class BookWithAttrFrom
18
60
  xml_accessor :isbn, :attr, :from => 'ISBN'
19
61
  end
20
62
 
63
+ class BookWithWrappedAttr
64
+ include ROXML
65
+
66
+ xml_name :book
67
+ xml_accessor :isbn, :attr => 'ISBN', :in => 'ids'
68
+ end
69
+
21
70
  class Measurement
22
71
  include ROXML
23
72
 
@@ -80,13 +129,6 @@ class BookWithAuthorTextAttribute
80
129
  xml_reader :author, Author
81
130
  end
82
131
 
83
- class Contributor
84
- include ROXML
85
-
86
- xml_reader :role, :attr
87
- xml_reader :name
88
- end
89
-
90
132
  class BookWithContributions
91
133
  include ROXML
92
134
 
@@ -107,6 +149,16 @@ class BookWithContributors
107
149
  xml_reader :contributors, Contributor, :as => :array
108
150
  end
109
151
 
152
+ class WriteableBookWithContributors
153
+ include ROXML
154
+
155
+ xml_name :book
156
+ xml_accessor :isbn, :attr
157
+ xml_accessor :title
158
+ xml_accessor :description
159
+ xml_accessor :contributors, Contributor, :as => :array
160
+ end
161
+
110
162
  class NamelessBook
111
163
  include ROXML
112
164
 
@@ -209,4 +261,4 @@ class PersonWithMotherOrMissing
209
261
  xml_reader :age, :attr, :else => 21
210
262
  xml_reader :name, :else => 'Anonymous'
211
263
  xml_reader :mother, PersonWithMotherOrMissing, :else => Person.new
212
- end
264
+ end
@@ -23,6 +23,19 @@ class TestOptions < Test::Unit::TestCase
23
23
  assert ROXML::Opts.new(:author, :content).content?
24
24
  end
25
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
+
26
39
  def test_hash_of_attrs
27
40
  opts = ROXML::Opts.new(:attributes, {:attrs => [:name, :value]})
28
41
  assert opts.hash?
@@ -45,7 +58,7 @@ class TestOptions < Test::Unit::TestCase
45
58
  :value => :content})
46
59
  assert opts.hash?
47
60
  assert !opts.array?
48
- assert opts.hash.value.content
61
+ assert opts.hash.value.content?
49
62
  assert_equal [ROXML::XMLAttributeRef, ROXML::XMLTextRef], opts.hash.types
50
63
  assert_equal ['name', ''], opts.hash.names
51
64
  end
@@ -59,4 +72,31 @@ class TestOptions < Test::Unit::TestCase
59
72
  assert_equal [ROXML::XMLAttributeRef, ROXML::XMLAttributeRef], opts.hash.types
60
73
  assert_equal ['dt', 'dd'], opts.hash.names
61
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
62
102
  end
@@ -5,7 +5,7 @@ class TestROXML < Test::Unit::TestCase
5
5
  def test_malformed
6
6
  ROXML::XML::Parser.register_error_handler {|err| }
7
7
  assert_raise ROXML::XML::Parser::ParseError do
8
- book = Book.parse(fixture(:book_malformed))
8
+ book = Book.from_xml(fixture(:book_malformed))
9
9
  end
10
10
  end
11
11
 
@@ -1,4 +1,4 @@
1
- require 'lib/roxml/string'
1
+ require 'lib/roxml/extensions/string'
2
2
 
3
3
  class TestROXML < Test::Unit::TestCase
4
4
  def test_to_latin_is_accessible
@@ -6,7 +6,7 @@ def to_xml_test(*names)
6
6
  xml_name ||= name
7
7
 
8
8
  define_method "test_#{name}" do
9
- dict = name.to_s.camelize.constantize.parse(fixture(xml_name))
9
+ dict = name.to_s.camelize.constantize.from_xml(fixture(xml_name))
10
10
  xml = xml_fixture(xml_name)
11
11
  remove_children(xml)
12
12
  assert_equal xml, dict.to_xml
@@ -49,11 +49,13 @@ class TestOtherToXml < Test::Unit::TestCase
49
49
 
50
50
  to_xml_test :person_with_mother => :person_with_mothers,
51
51
  :person_with_guarded_mother => :person_with_guarded_mothers
52
+
53
+ to_xml_test :book_with_wrapped_attr
52
54
  end
53
55
 
54
56
  class TestToXmlWithDefaults < Test::Unit::TestCase
55
57
  def test_content_and_attr_defaults_are_represented_in_output
56
- dict = Person.parse(fixture(:nameless_ageless_youth))
58
+ dict = Person.from_xml(fixture(:nameless_ageless_youth))
57
59
 
58
60
  xml = '<person age="21">Unknown</person>'
59
61
  assert_equal ROXML::XML::Parser.parse(xml).root, dict.to_xml
@@ -62,7 +64,7 @@ end
62
64
 
63
65
  class TestToXmlWithBlocks < Test::Unit::TestCase
64
66
  def test_pagecount_serialized_properly_after_modification
65
- b = Book.parse(fixture(:book_valid))
67
+ b = Book.from_xml(fixture(:book_valid))
66
68
  xml = xml_fixture(:book_valid)
67
69
  assert_equal '357', xml.search('pagecount').first.content
68
70
  assert_equal 357, b.pages
@@ -3,32 +3,37 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
3
3
  class TestXMLAttribute < Test::Unit::TestCase
4
4
  def test_attr_from
5
5
  # :attr => *
6
- book = Book.parse(fixture(:book_text_with_attribute))
6
+ book = Book.from_xml(fixture(:book_text_with_attribute))
7
7
  assert_equal '0201710897', book.isbn
8
8
 
9
9
  # :attr, :from => *
10
- book = BookWithAttrFrom.parse(fixture(:book_text_with_attribute))
10
+ book = BookWithAttrFrom.from_xml(fixture(:book_text_with_attribute))
11
11
  assert_equal '0201710897', book.isbn
12
12
  end
13
13
 
14
14
  def test_mutable_attr
15
- book = Book.parse(fixture(:book_text_with_attribute))
15
+ book = Book.from_xml(fixture(:book_text_with_attribute))
16
16
  assert book.respond_to?(:'isbn=')
17
17
  end
18
18
 
19
19
  def test_default_initialization
20
- person = PersonWithMotherOrMissing.parse(fixture(:nameless_ageless_youth))
20
+ person = PersonWithMotherOrMissing.from_xml(fixture(:nameless_ageless_youth))
21
21
  assert_equal 21, person.age
22
22
  end
23
23
 
24
24
  def test_recursive_with_default_initialization
25
- p = PersonWithMotherOrMissing.parse(fixture(:person_with_mothers))
25
+ p = PersonWithMotherOrMissing.from_xml(fixture(:person_with_mothers))
26
26
  assert_equal 21, p.mother.mother.mother.age
27
27
  end
28
28
 
29
29
  def test_no_name_clashes
30
- n = NodeWithAttrNameConflicts.parse(fixture(:node_with_attr_name_conflicts))
30
+ n = NodeWithAttrNameConflicts.from_xml(fixture(:node_with_attr_name_conflicts))
31
31
  assert_equal "Just junk... really", n.content
32
32
  assert_equal "Cartwheel", n.name
33
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
34
39
  end
@@ -2,18 +2,18 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
3
  class TestXMLAttribute < Test::Unit::TestCase
4
4
  def test_initialize_is_run
5
- m = Measurement.parse('<measurement units="hundredths-meters">1130</measurement>')
5
+ m = Measurement.from_xml('<measurement units="hundredths-meters">1130</measurement>')
6
6
  assert_equal 11.3, m.value
7
7
  assert_equal 'meters', m.units
8
8
  end
9
9
 
10
10
  def test_initialize_is_run_for_nested_type
11
- b = BookWithDepth.parse(fixture(:book_with_depth))
11
+ b = BookWithDepth.from_xml(fixture(:book_with_depth))
12
12
  assert_equal Measurement.new(11.3, 'meters'), b.depth
13
13
  end
14
14
 
15
15
  def test_initialize_is_run_for_nested_type_with_inheritance
16
- b = InheritedBookWithDepth.parse(fixture(:book_with_depth))
16
+ b = InheritedBookWithDepth.from_xml(fixture(:book_with_depth))
17
17
  assert_equal Measurement.new(11.3, 'meters'), b.depth
18
18
  end
19
19
  end
@@ -7,47 +7,43 @@ class TestXMLHash < Test::Unit::TestCase
7
7
  end
8
8
 
9
9
  def test_attrs_hash
10
- dict = DictionaryOfAttrs.parse(fixture(:dictionary_of_attrs))
10
+ dict = DictionaryOfAttrs.from_xml(fixture(:dictionary_of_attrs))
11
11
  assert_equal Hash, dict.definitions.class
12
12
  assert_equal @contents, dict.definitions
13
13
  end
14
14
 
15
15
  def test_text_hash
16
- assert_equal 'definition', DictionaryOfTexts.tag_refs.only.name
17
- assert_equal 'word', DictionaryOfTexts.tag_refs.only.hash.key.name
18
- assert_equal 'meaning', DictionaryOfTexts.tag_refs.only.hash.value.name
19
-
20
- dict = DictionaryOfTexts.parse(fixture(:dictionary_of_texts))
16
+ dict = DictionaryOfTexts.from_xml(fixture(:dictionary_of_texts))
21
17
  assert_equal Hash, dict.definitions.class
22
18
  assert_equal @contents, dict.definitions
23
19
  end
24
20
 
25
21
  def test_mixed_content_hash
26
- dict = DictionaryOfMixeds.parse(fixture(:dictionary_of_mixeds))
22
+ dict = DictionaryOfMixeds.from_xml(fixture(:dictionary_of_mixeds))
27
23
  assert_equal Hash, dict.definitions.class
28
24
  assert_equal @contents, dict.definitions
29
25
  end
30
26
 
31
27
  def test_name_hash
32
- dict = DictionaryOfNames.parse(fixture(:dictionary_of_names))
28
+ dict = DictionaryOfNames.from_xml(fixture(:dictionary_of_names))
33
29
  assert_equal Hash, dict.definitions.class
34
30
  assert_equal @contents, dict.definitions
35
31
  end
36
32
 
37
33
  def test_guarded_name_hash
38
- dict = DictionaryOfGuardedNames.parse(fixture(:dictionary_of_guarded_names))
34
+ dict = DictionaryOfGuardedNames.from_xml(fixture(:dictionary_of_guarded_names))
39
35
  assert_equal Hash, dict.definitions.class
40
36
  assert_equal @contents, dict.definitions
41
37
  end
42
38
 
43
39
  def test_text_name_clashes
44
- dict = DictionaryOfNameClashes.parse(fixture(:dictionary_of_name_clashes))
40
+ dict = DictionaryOfNameClashes.from_xml(fixture(:dictionary_of_name_clashes))
45
41
  assert_equal Hash, dict.definitions.class
46
42
  assert_equal @contents, dict.definitions
47
43
  end
48
44
 
49
45
  def test_attr_name_clashes
50
- dict = DictionaryOfAttrNameClashes.parse(fixture(:dictionary_of_attr_name_clashes))
46
+ dict = DictionaryOfAttrNameClashes.from_xml(fixture(:dictionary_of_attr_name_clashes))
51
47
  assert_equal Hash, dict.definitions.class
52
48
  assert_equal @contents, dict.definitions
53
49
  end