roxml 2.5.3 → 3.1.0

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 (76) hide show
  1. data/.gitignore +7 -0
  2. data/.gitmodules +3 -0
  3. data/History.txt +38 -1
  4. data/README.rdoc +8 -5
  5. data/Rakefile +35 -36
  6. data/TODO +12 -35
  7. data/VERSION +1 -0
  8. data/examples/amazon.rb +8 -6
  9. data/examples/posts.rb +1 -1
  10. data/examples/{active_record.rb → rails.rb} +2 -2
  11. data/examples/twitter.rb +1 -1
  12. data/lib/roxml.rb +86 -151
  13. data/lib/roxml/definition.rb +64 -152
  14. data/lib/roxml/hash_definition.rb +5 -40
  15. data/lib/roxml/xml.rb +12 -9
  16. data/lib/roxml/xml/parsers/libxml.rb +22 -17
  17. data/lib/roxml/xml/parsers/nokogiri.rb +77 -0
  18. data/lib/roxml/xml/references.rb +66 -57
  19. data/roxml.gemspec +170 -19
  20. data/spec/definition_spec.rb +121 -198
  21. data/spec/examples/active_record_spec.rb +2 -2
  22. data/spec/examples/amazon_spec.rb +3 -2
  23. data/spec/examples/current_weather_spec.rb +2 -2
  24. data/spec/examples/dashed_elements_spec.rb +2 -2
  25. data/spec/examples/library_spec.rb +11 -6
  26. data/spec/examples/post_spec.rb +3 -3
  27. data/spec/examples/twitter_spec.rb +2 -2
  28. data/spec/roxml_spec.rb +15 -15
  29. data/spec/shared_specs.rb +1 -1
  30. data/spec/spec_helper.rb +8 -27
  31. data/spec/support/libxml.rb +3 -0
  32. data/spec/support/nokogiri.rb +3 -0
  33. data/spec/xml/attributes_spec.rb +36 -0
  34. data/spec/xml/namespace_spec.rb +240 -0
  35. data/spec/xml/namespaces_spec.rb +32 -0
  36. data/spec/xml/parser_spec.rb +9 -30
  37. data/tasks/rdoc.rake +13 -0
  38. data/tasks/rspec.rake +21 -17
  39. data/tasks/test.rake +13 -20
  40. data/test/mocks/dictionaries.rb +8 -7
  41. data/test/mocks/mocks.rb +20 -20
  42. data/test/support/fixtures.rb +11 -0
  43. data/test/test_helper.rb +3 -14
  44. data/test/unit/definition_test.rb +21 -95
  45. data/test/unit/deprecations_test.rb +1 -74
  46. data/test/unit/to_xml_test.rb +3 -3
  47. data/test/unit/xml_attribute_test.rb +1 -1
  48. data/test/unit/xml_block_test.rb +3 -3
  49. data/test/unit/xml_bool_test.rb +4 -4
  50. data/test/unit/xml_convention_test.rb +3 -3
  51. data/test/unit/xml_hash_test.rb +5 -14
  52. data/test/unit/xml_initialize_test.rb +2 -6
  53. data/test/unit/xml_name_test.rb +5 -24
  54. data/test/unit/xml_namespace_test.rb +1 -46
  55. data/test/unit/xml_object_test.rb +6 -6
  56. data/test/unit/xml_required_test.rb +3 -2
  57. data/test/unit/xml_text_test.rb +2 -2
  58. data/website/index.html +1 -1
  59. metadata +68 -51
  60. data/Manifest.txt +0 -106
  61. data/lib/roxml/extensions.rb +0 -6
  62. data/lib/roxml/extensions/array.rb +0 -13
  63. data/lib/roxml/extensions/array/conversions.rb +0 -35
  64. data/lib/roxml/extensions/deprecation.rb +0 -33
  65. data/lib/roxml/extensions/string.rb +0 -21
  66. data/lib/roxml/extensions/string/conversions.rb +0 -43
  67. data/lib/roxml/extensions/string/iterators.rb +0 -12
  68. data/lib/roxml/xml/parsers/rexml.rb +0 -84
  69. data/spec/string_spec.rb +0 -15
  70. data/test/bugs/rexml_bugs.rb +0 -15
  71. data/test/release/dependencies_test.rb +0 -32
  72. data/test/unit/xml_construct_test.rb +0 -77
  73. data/vendor/override_rake_task/README +0 -30
  74. data/vendor/override_rake_task/init.rb +0 -1
  75. data/vendor/override_rake_task/install.rb +0 -46
  76. data/vendor/override_rake_task/lib/override_rake_task.rb +0 -16
@@ -0,0 +1,32 @@
1
+ require 'spec/spec_helper.rb'
2
+
3
+ describe ROXML, "#xml_namespaces" do
4
+ class Tires
5
+ include ROXML
6
+
7
+ xml_namespaces \
8
+ :bobsbike => 'http://bobsbikes.example.com',
9
+ :alicesauto => 'http://alicesautosupply.example.com/'
10
+
11
+ xml_reader :bike_tires, :as => [], :from => '@name', :in => 'bobsbike:tire'
12
+ xml_reader :car_tires, :as => [], :from => '@name', :in => 'alicesauto:tire'
13
+ end
14
+
15
+ before do
16
+ @xml = %{<?xml version="1.0"?>
17
+ <inventory xmlns="http://alicesautosupply.example.com/" xmlns:bike="http://bobsbikes.example.com">
18
+ <tire name="super slick racing tire" />
19
+ <tire name="all weather tire" />
20
+ <bike:tire name="skinny street" />
21
+ </inventory>
22
+ }
23
+ end
24
+
25
+ it "should remap default namespaces" do
26
+ Tires.from_xml(@xml).car_tires.should =~ ['super slick racing tire', 'all weather tire']
27
+ end
28
+
29
+ it "should remap prefix namespaces" do
30
+ Tires.from_xml(@xml).bike_tires.should == ['skinny street']
31
+ end
32
+ end
@@ -1,47 +1,26 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
1
+ require 'spec/spec_helper.rb'
2
2
 
3
3
  describe ROXML::XML::Parser do
4
4
  before do
5
5
  # quiet the error handler
6
- ROXML::XML::Error.reset_handler
6
+ ROXML::XML::Error.reset_handler if ROXML::XML::Error.respond_to?(:reset_handler)
7
7
  end
8
8
 
9
9
  it "should raise on malformed xml" do
10
- proc { Book.from_xml(fixture(:book_malformed)) }.should raise_error(ROXML::XML::Error)
10
+ unless ROXML::XML_PARSER == 'nokogiri' # nokogiri is less strict and auto-closes for some reason
11
+ proc { Book.from_xml(fixture(:book_malformed)) }.should raise_error(ROXML::XML::Error)
12
+ end
11
13
  end
12
14
 
13
15
  it "should escape invalid characters on output to text node" do
14
- node = ROXML::XML::Node.new("entities")
16
+ node = ROXML::XML::Node.create("entities")
15
17
  node.content = " < > ' \" & "
16
- if ROXML::XML_PARSER == 'libxml'
17
- node.to_s.should == "<entities> &lt; &gt; ' \" &amp; </entities>"
18
- else
19
- node.to_s.should == "<entities> &lt; &gt; &apos; &quot; &amp; </entities>"
20
- end
18
+ node.to_s.should == "<entities> &lt; &gt; ' \" &amp; </entities>"
21
19
  end
22
20
 
23
21
  it "should esape invalid characters for attribute name" do
24
- node = ROXML::XML::Node.new("attr_holder")
22
+ node = ROXML::XML::Node.create("attr_holder")
25
23
  node.attributes["entities"] = "\"'<>&"
26
- if ROXML::XML_PARSER == 'libxml'
27
- node.to_s.should == %{<attr_holder entities="&quot;'&lt;&gt;&amp;"/>}
28
- else
29
- node.to_s.should == %{<attr_holder entities='&quot;&apos;&lt;&gt;&amp;'/>}
30
- end
24
+ node.to_s.should == %{<attr_holder entities="&quot;'&lt;&gt;&amp;"/>}
31
25
  end
32
26
  end
33
-
34
- describe ROXML::XML::Document do
35
- describe "#save" do
36
- context "with rexml parser" do
37
- it "should defer to existing XMLDecl" do
38
- if ROXML::XML_PARSER == 'rexml'
39
- @doc = ROXML::XML::Document.new
40
- @doc << REXML::XMLDecl.new('1.1')
41
- @doc.save('spec/xml/decl_test.xml')
42
- ROXML::XML::Parser.parse(File.read('spec/xml/decl_test.xml')).to_s.should == ROXML::XML::Parser.parse(%{<?xml version="1.1"?>}).to_s
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -0,0 +1,13 @@
1
+ require 'rake/rdoctask'
2
+ Rake::RDocTask.new do |rdoc|
3
+ if File.exist?('VERSION')
4
+ version = File.read('VERSION')
5
+ else
6
+ version = ""
7
+ end
8
+
9
+ rdoc.rdoc_dir = 'rdoc'
10
+ rdoc.title = "roxml-new #{version}"
11
+ rdoc.rdoc_files.include('README*')
12
+ rdoc.rdoc_files.include('lib/**/*.rb')
13
+ end
@@ -1,21 +1,25 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems'
5
- require 'spec'
1
+ require 'spec/rake/spectask'
2
+ desc "Run specs"
3
+ Spec::Rake::SpecTask.new(:spec) do |spec|
4
+ spec.libs << 'lib' << 'spec' << 'examples'
5
+ spec.spec_opts = ['--options', "spec/spec.opts"]
6
+ spec.spec_files = FileList['spec/**/*_spec.rb']
6
7
  end
7
- begin
8
- require 'spec/rake/spectask'
9
- rescue LoadError
10
- puts <<-EOS
11
- To use rspec for testing you must install rspec gem:
12
- gem install rspec
13
- EOS
14
- exit(0)
8
+
9
+ namespace :spec do
10
+ [:libxml, :nokogiri].each do |parser|
11
+ desc "Spec ROXML under the #{parser} parser"
12
+ Spec::Rake::SpecTask.new(parser) do |spec|
13
+ spec.libs << 'lib' << 'spec' << 'examples'
14
+ spec.spec_opts = ['--options=spec/spec.opts']
15
+ spec.spec_files = ["spec/support/#{parser}.rb"] + FileList['spec/**/*_spec.rb']
16
+ end
17
+ end
15
18
  end
16
19
 
17
- desc "Run the specs under spec/models"
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
20
+ desc "Run specs with rcov"
21
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
22
+ spec.libs << 'lib' << 'spec'
23
+ spec.pattern = 'spec/**/*_spec.rb'
24
+ spec.rcov = true
21
25
  end
@@ -1,42 +1,35 @@
1
- # We need to override hoe's test task in order to support separate REXML & LibXML testing
2
- require File.join(File.dirname(__FILE__), '../vendor/override_rake_task/lib/override_rake_task')
3
-
4
- Rake::TestTask.new(:bugs) do |t|
5
- t.libs << 'test'
6
- t.test_files = FileList['test/bugs/*_bugs.rb']
7
- t.verbose = true
1
+ require 'rake/testtask'
2
+ Rake::TestTask.new(:bugs) do |test|
3
+ test.libs << 'lib' << 'test'
4
+ test.pattern = 'test/bugs/*_bugs.rb'
5
+ test.verbose = true
8
6
  end
9
7
 
10
- remove_task :test
11
8
  desc "Test ROXML using the default parser selection behavior"
12
9
  task :test do
13
- module ROXML
14
- SILENCE_XML_NAME_WARNING = true
15
- end
16
- require 'lib/roxml'
17
10
  require 'rake/runtest'
18
- Rake.run_tests $hoe.test_globs
11
+ Rake.run_tests 'test/unit/*_test.rb'
19
12
  end
20
13
 
21
14
  namespace :test do
22
- desc "Test ROXML under the LibXML parser"
23
- task :libxml do
15
+ desc "Test ROXML under the Nokogiri parser"
16
+ task :nokogiri do
24
17
  module ROXML
25
- XML_PARSER = 'libxml'
18
+ XML_PARSER = 'nokogiri'
26
19
  end
27
20
  Rake::Task["test"].invoke
28
21
  end
29
22
 
30
- desc "Test ROXML under the REXML parser"
31
- task :rexml do
23
+ desc "Test ROXML under the LibXML parser"
24
+ task :libxml do
32
25
  module ROXML
33
- XML_PARSER = 'rexml'
26
+ XML_PARSER = 'libxml'
34
27
  end
35
28
  Rake::Task["test"].invoke
36
29
  end
37
30
 
38
31
  desc "Runs tests under RCOV"
39
32
  task :rcov do
40
- system "rcov -T --no-html -x '^/' #{FileList[$hoe.test_globs]}"
33
+ system "rcov -T --no-html -x '^/' #{FileList['test/unit/*_test.rb']}"
41
34
  end
42
35
  end
@@ -4,14 +4,15 @@ class DictionaryOfAttrs
4
4
  include ROXML
5
5
 
6
6
  xml_name :dictionary
7
- xml_reader :definitions, {:attrs => [:dt, :dd]}, :in => :definitions
7
+ xml_reader :definitions, :as => {:key => '@dt',
8
+ :value => '@dd'}, :in => :definitions
8
9
  end
9
10
 
10
11
  class DictionaryOfTexts
11
12
  include ROXML
12
13
 
13
14
  xml_name :dictionary
14
- xml_reader :definitions, {:key => :word,
15
+ xml_reader :definitions, :as => {:key => :word,
15
16
  :value => :meaning}
16
17
  end
17
18
 
@@ -19,7 +20,7 @@ class DictionaryOfMixeds
19
20
  include ROXML
20
21
 
21
22
  xml_name :dictionary
22
- xml_reader :definitions, {:key => {:attr => :word},
23
+ xml_reader :definitions, :as => {:key => '@word',
23
24
  :value => :content}
24
25
  end
25
26
 
@@ -27,7 +28,7 @@ class DictionaryOfNames
27
28
  include ROXML
28
29
 
29
30
  xml_name :dictionary
30
- xml_reader :definitions, {:key => :name,
31
+ xml_reader :definitions, :as => {:key => :name,
31
32
  :value => :content}
32
33
  end
33
34
 
@@ -35,7 +36,7 @@ class DictionaryOfGuardedNames
35
36
  include ROXML
36
37
 
37
38
  xml_name :dictionary
38
- xml_reader :definitions, {:key => :name,
39
+ xml_reader :definitions, :as => {:key => :name,
39
40
  :value => :content}, :in => :definitions
40
41
  end
41
42
 
@@ -43,7 +44,7 @@ class DictionaryOfNameClashes
43
44
  include ROXML
44
45
 
45
46
  xml_name :dictionary
46
- xml_reader :definitions, {:key => 'name',
47
+ xml_reader :definitions, :as => {:key => 'name',
47
48
  :value => 'content'}, :from => :definition
48
49
  end
49
50
 
@@ -51,6 +52,6 @@ class DictionaryOfAttrNameClashes
51
52
  include ROXML
52
53
 
53
54
  xml_name :dictionary
54
- xml_reader :definitions, {:key => {:attr => :name},
55
+ xml_reader :definitions, :as => {:key => '@name',
55
56
  :value => 'content'}, :from => :definition
56
57
  end
@@ -15,7 +15,7 @@ end
15
15
  class Numerology
16
16
  include ROXML
17
17
 
18
- xml_reader :predictions, {:attrs => ['number', 'meaning']} do |k, v|
18
+ xml_reader :predictions, :as => {:key => '@number', :value => '@meaning'} do |k, v|
19
19
  [Integer(k), v]
20
20
  end
21
21
  end
@@ -41,7 +41,7 @@ class Book
41
41
  xml_reader :title
42
42
  xml_reader :description, :cdata => true
43
43
  xml_reader :author
44
- xml_accessor :pages, :text => 'pagecount', :as => Integer
44
+ xml_accessor :pages, :from => 'pagecount', :as => Integer
45
45
  end
46
46
 
47
47
  class BookWithRequired
@@ -49,8 +49,8 @@ class BookWithRequired
49
49
 
50
50
  xml_accessor :isbn, :from => '@ISBN', :required => true
51
51
  xml_reader :title, :required => true
52
- xml_reader :contributors, [Contributor], :in => 'contributor_array', :required => true
53
- xml_reader :contributor_hash, {:attrs => ['role', 'name']},
52
+ xml_reader :contributors, :as => [Contributor], :in => 'contributor_array', :required => true
53
+ xml_reader :contributor_hash, :as => {:key => '@role', :value => '@name'},
54
54
  :from => 'contributor', :in => 'contributor_hash', :required => true
55
55
  end
56
56
 
@@ -107,7 +107,7 @@ class BookWithDepth
107
107
  xml_reader :title
108
108
  xml_reader :description, :cdata => true
109
109
  xml_reader :author
110
- xml_reader :depth, Measurement
110
+ xml_reader :depth, :as => Measurement
111
111
  end
112
112
 
113
113
  class Author
@@ -124,7 +124,7 @@ class BookWithAuthors
124
124
  xml_reader :isbn, :from => '@ISBN'
125
125
  xml_reader :title
126
126
  xml_reader :description, :cdata => true
127
- xml_reader :authors, []
127
+ xml_reader :authors, :as => []
128
128
  end
129
129
 
130
130
  class BookWithAuthorTextAttribute
@@ -134,7 +134,7 @@ class BookWithAuthorTextAttribute
134
134
  xml_reader :isbn, :from => '@ISBN'
135
135
  xml_reader :title
136
136
  xml_reader :description, :cdata => true
137
- xml_reader :author, Author
137
+ xml_reader :author, :as => Author
138
138
  end
139
139
 
140
140
  class BookWithContributions
@@ -144,7 +144,7 @@ class BookWithContributions
144
144
  xml_reader :isbn, :from => :attr
145
145
  xml_reader :title
146
146
  xml_reader :description
147
- xml_reader :contributions, [Contributor], :from => 'contributor', :in => "contributions"
147
+ xml_reader :contributions, :as => [Contributor], :from => 'contributor', :in => "contributions"
148
148
  end
149
149
 
150
150
  class BookWithContributors
@@ -154,7 +154,7 @@ class BookWithContributors
154
154
  xml_reader :isbn, :from => :attr
155
155
  xml_reader :title
156
156
  xml_reader :description
157
- xml_reader :contributors, [Contributor]
157
+ xml_reader :contributors, :as => [Contributor]
158
158
  end
159
159
 
160
160
  class WriteableBookWithContributors
@@ -164,7 +164,7 @@ class WriteableBookWithContributors
164
164
  xml_accessor :isbn, :from => :attr
165
165
  xml_accessor :title
166
166
  xml_accessor :description
167
- xml_accessor :contributors, [Contributor]
167
+ xml_accessor :contributors, :as => [Contributor]
168
168
  end
169
169
 
170
170
  class NamelessBook
@@ -173,7 +173,7 @@ class NamelessBook
173
173
  xml_reader :isbn, :from => :attr
174
174
  xml_reader :title
175
175
  xml_reader :description
176
- xml_reader :contributors, [Contributor]
176
+ xml_reader :contributors, :as => [Contributor]
177
177
  end
178
178
 
179
179
  class Publisher
@@ -189,7 +189,7 @@ class BookWithPublisher
189
189
  xml_reader :isbn, :from => :attr
190
190
  xml_reader :title
191
191
  xml_reader :description
192
- xml_reader :publisher, Publisher
192
+ xml_reader :publisher, :as => Publisher
193
193
  end
194
194
 
195
195
  class BookPair
@@ -199,14 +199,14 @@ class BookPair
199
199
  xml_reader :title
200
200
  xml_reader :description
201
201
  xml_reader :author
202
- xml_reader :book, Book
202
+ xml_reader :book, :as => Book
203
203
  end
204
204
 
205
205
  class Library
206
206
  include ROXML
207
207
 
208
208
  xml_reader :name
209
- xml_reader :books, [BookWithContributions]
209
+ xml_reader :books, :as => [BookWithContributions]
210
210
  end
211
211
 
212
212
  class UppercaseLibrary
@@ -214,14 +214,14 @@ class UppercaseLibrary
214
214
 
215
215
  xml_name :library
216
216
  xml_reader :name, :from => 'NAME'
217
- xml_reader :books, [BookWithContributions], :from => 'BOOK'
217
+ xml_reader :books, :as => [BookWithContributions], :from => 'BOOK'
218
218
  end
219
219
 
220
220
  class LibraryWithBooksOfUnderivableName
221
221
  include ROXML
222
222
 
223
223
  xml_accessor :name
224
- xml_reader :novels, [NamelessBook]
224
+ xml_reader :novels, :as => [NamelessBook]
225
225
  end
226
226
 
227
227
  class NodeWithNameConflicts
@@ -247,7 +247,7 @@ class Person
247
247
  xml_accessor :name, :from => :content, :else => 'Unknown'
248
248
 
249
249
  def self.blank
250
- returning new do |instance|
250
+ new.tap do |instance|
251
251
  instance.age = 21
252
252
  instance.name = 'Unknown'
253
253
  end
@@ -259,7 +259,7 @@ class PersonWithMother
259
259
 
260
260
  xml_name :person
261
261
  xml_reader :name
262
- xml_reader :mother, PersonWithMother, :from => 'mother'
262
+ xml_reader :mother, :as => PersonWithMother, :from => 'mother'
263
263
  end
264
264
 
265
265
  class PersonWithGuardedMother
@@ -267,7 +267,7 @@ class PersonWithGuardedMother
267
267
 
268
268
  xml_name :person
269
269
  xml_reader :name
270
- xml_reader :mother, PersonWithGuardedMother, :from => :person, :in => :mother
270
+ xml_reader :mother, :as => PersonWithGuardedMother, :from => :person, :in => :mother
271
271
  end
272
272
 
273
273
  class PersonWithMotherOrMissing
@@ -275,5 +275,5 @@ class PersonWithMotherOrMissing
275
275
 
276
276
  xml_reader :age, :from => :attr, :else => 21
277
277
  xml_reader :name, :else => 'Anonymous'
278
- xml_reader :mother, PersonWithMotherOrMissing, :else => Person.blank
278
+ xml_reader :mother,:as => PersonWithMotherOrMissing, :else => Person.blank
279
279
  end
@@ -0,0 +1,11 @@
1
+ def fixture(name)
2
+ File.read(fixture_path(name))
3
+ end
4
+
5
+ def xml_fixture(name)
6
+ ROXML::XML::Parser.parse_file(fixture_path(name)).root
7
+ end
8
+
9
+ def fixture_path(name)
10
+ "test/fixtures/#{name}.xml"
11
+ end
@@ -1,22 +1,11 @@
1
- require "lib/roxml"
1
+ require 'rubygems'
2
2
  require 'active_support/test_case'
3
3
  require 'test/mocks/mocks'
4
4
  require 'test/mocks/dictionaries'
5
-
6
- def fixture(name)
7
- File.read(fixture_path(name))
8
- end
9
-
10
- def xml_fixture(name)
11
- ROXML::XML::Parser.parse_file(fixture_path(name)).root
12
- end
13
-
14
- def fixture_path(name)
15
- "test/fixtures/#{name}.xml"
16
- end
5
+ require 'test/support/fixtures'
17
6
 
18
7
  def to_xml_test(*names)
19
- names = names.first if names.one? && names.first.is_a?(Hash)
8
+ names = names.first if names.size == 1 && names.first.is_a?(Hash)
20
9
  names.each do |name, xml_name|
21
10
  xml_name ||= name
22
11