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
@@ -1,8 +1,4 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- class RoxmlObject
4
- include ROXML
5
- end
1
+ require 'spec/spec_helper'
6
2
 
7
3
  describe ROXML::Definition do
8
4
  describe "#name_explicit?" do
@@ -17,141 +13,132 @@ describe ROXML::Definition do
17
13
  end
18
14
  end
19
15
 
20
- describe "hash options declaration", :shared => true do
21
- it "should represent a hash" do
22
- @opts.hash?.should be_true
16
+ describe "DateTime reference", :shared => true do
17
+ it "should return nil on empty string" do
18
+ @subject.blocks.first.call(" ").should be_nil
23
19
  end
24
20
 
25
- it "should have hash definition" do
26
- {@opts.hash.key.type => @opts.hash.key.name}.should == @hash_args[:key]
27
- {@opts.hash.value.type => @opts.hash.value.name}.should == @hash_args[:value]
21
+ it "should return a time version of the string" do
22
+ @subject.blocks.first.call("12:05pm, September 3rd, 1970").to_s == "1970-09-03T12:05:00+00:00"
28
23
  end
29
24
 
30
- it "should not represent an array" do
31
- @opts.array?.should be_false
25
+ context "when passed an array of values" do
26
+ it "should timify all of them" do
27
+ @subject.blocks.first.call(["12:05pm, September 3rd, 1970", "3:00pm, May 22, 1700"]).map(&:to_s).should == ["1970-09-03T12:05:00+00:00", "1700-05-22T15:00:00+00:00"]
28
+ end
32
29
  end
33
30
  end
34
31
 
35
- describe "types" do
36
- describe ":content" do
37
- it "should be recognized" do
38
- ROXML::Definition.new(:author).content?.should be_false
39
- ROXML::Definition.new(:author, :content).content?.should be_true
40
- end
32
+ describe "Date reference", :shared => true do
33
+ it "should return nil on empty string" do
34
+ @subject.blocks.first.call(" ").should be_nil
35
+ end
41
36
 
42
- it "should be deprecated"
37
+ it "should return a time version of the string" do
38
+ @subject.blocks.first.call("September 3rd, 1970").to_s == "1970-09-03"
43
39
  end
44
40
 
45
- describe "array reference" do
46
- it "[] means array of texts" do
47
- opts = ROXML::Definition.new(:authors, [])
48
- opts.array?.should be_true
49
- opts.type.should == :text
41
+ context "when passed an array of values" do
42
+ it "should timify all of them" do
43
+ @subject.blocks.first.call(["September 3rd, 1970", "1776-07-04"]).map(&:to_s).should == ["1970-09-03", "1776-07-04"]
50
44
  end
45
+ end
46
+ end
51
47
 
52
- it "[:text] means array of texts" do
53
- opts = ROXML::Definition.new(:authors, [:text])
54
- opts.array?.should be_true
55
- opts.type.should == :text
48
+ it "should unescape xml entities" do
49
+ ROXML::Definition.new(:questions, :as => []).to_ref(RoxmlObject.new).value_in(%{
50
+ <xml>
51
+ <question>&quot;Wickard &amp; Filburn&quot; &gt;</question>
52
+ <question> &lt; McCulloch &amp; Maryland?</question>
53
+ </xml>
54
+ }).should == ["\"Wickard & Filburn\" >", "< McCulloch & Maryland?"]
55
+ end
56
+
57
+ describe "attr name" do
58
+ context "when ending with '_at'" do
59
+ context "and without an :as argument" do
60
+ before(:all) do
61
+ @subject = ROXML::Definition.new(:time_at)
62
+ end
63
+ it_should_behave_like "DateTime reference"
56
64
  end
65
+ end
57
66
 
58
- it "[:attr] means array of attrs" do
59
- opts = ROXML::Definition.new(:authors, [:attr])
60
- opts.array?.should be_true
61
- opts.type.should == :attr
67
+ context "when ending with '_on'" do
68
+ context "and without an :as argument" do
69
+ before(:all) do
70
+ @subject = ROXML::Definition.new(:created_on)
71
+ end
72
+ it_should_behave_like "Date reference"
62
73
  end
74
+ end
75
+ end
63
76
 
64
- it "[Object] means array of objects" do
65
- opts = ROXML::Definition.new(:authors, [Hash])
77
+ describe ":as" do
78
+ describe "=> []" do
79
+ it "should means array of texts" do
80
+ opts = ROXML::Definition.new(:authors, :as => [])
66
81
  opts.array?.should be_true
67
- opts.type.should == Hash
82
+ opts.type.should == :text
68
83
  end
69
84
  end
70
85
 
71
- describe "{}" do
72
- describe "hash with attr key and text val" do
73
- before do
74
- @opts = ROXML::Definition.new(:attributes, {:key => {:attr => :name},
75
- :value => :value})
76
- @hash_args = {:key => {:attr => 'name'},
77
- :value => {:text => 'value'}}
78
- end
79
-
80
- it_should_behave_like "hash options declaration"
86
+ describe "=> RoxmlClass" do
87
+ class RoxmlClass
88
+ include ROXML
81
89
  end
82
90
 
83
- describe "hash with String class for type" do
84
- before do
85
- @opts = ROXML::Definition.new(:attributes, {:key => {String => 'name'},
86
- :value => {String => 'value'}})
87
- @hash_args = {:key => {:text => 'name'}, :value => {:text => 'value'}}
88
- end
89
-
90
- it_should_behave_like "hash options declaration"
91
+ it "should store type" do
92
+ opts = ROXML::Definition.new(:name, :as => RoxmlClass)
93
+ opts.type.should == RoxmlClass
91
94
  end
95
+ end
92
96
 
93
- describe "hash with attr key and content val" do
94
- before do
95
- @opts = ROXML::Definition.new(:attributes, {:key => {:attr => :name},
96
- :value => :content})
97
- @hash_args = {:key => {:attr => 'name'}, :value => {:text => '.'}}
97
+ describe "=> NonRoxmlClassWithFromXmlDefined" do
98
+ class OctalInteger
99
+ def self.from_xml(val)
100
+ new(Integer(val.content))
98
101
  end
99
-
100
- it_should_behave_like "hash options declaration"
101
102
  end
102
103
 
103
- describe "hash of attrs" do
104
- before do
105
- @hash_args = {:key => {:attr => 'name'}, :value => {:attr => 'value'}}
106
- @opts = ROXML::Definition.new(:attributes, {:attrs => [:name, :value]})
107
- end
108
-
109
- it_should_behave_like "hash options declaration"
110
-
111
- describe "with options" do
112
- before do
113
- @hash_args = {:key => {:attr => 'dt'}, :value => {:attr => 'dd'}}
114
- @opts = ROXML::Definition.new(:definitions, {:attrs => [:dt, :dd]},
115
- :in => 'definitions')
116
- end
117
-
118
- it_should_behave_like "hash options declaration"
119
-
120
- it "should not interfere with options" do
121
- @opts.wrapper.should == 'definitions'
122
- end
123
- end
104
+ it "should accept type" do
105
+ opts = ROXML::Definition.new(:name, :as => OctalInteger)
106
+ opts.type.should == OctalInteger
124
107
  end
125
108
  end
126
- end
127
109
 
128
- describe ":as" do
129
- describe "=> :array" do
130
- it "should be deprecated"
131
- end
132
-
133
- describe "=> []" do
134
- it "should means array of texts" do
135
- opts = ROXML::Definition.new(:authors, :as => [])
136
- opts.array?.should be_true
137
- opts.type.should == :text
110
+ describe "=> NonRoxmlClass" do
111
+ it "should fail with a warning" do
112
+ proc { ROXML::Definition.new(:authors, :as => Module) }.should raise_error(ArgumentError)
138
113
  end
114
+ end
139
115
 
140
- it "should unescape xml entities" do
141
- ROXML::Definition.new(:questions, :as => []).to_ref(RoxmlObject.new).value_in(%{
142
- <xml>
143
- <question>&quot;Wickard &amp; Filburn&quot; &gt;</question>
144
- <question> &lt; McCulloch &amp; Maryland?</question>
145
- </xml>
146
- }).should == ["\"Wickard & Filburn\" >", "< McCulloch & Maryland?"]
116
+ describe "=> [NonRoxmlClass]" do
117
+ it "should raise" do
118
+ proc { ROXML::Definition.new(:authors, :as => [Module]) }.should raise_error(ArgumentError)
147
119
  end
148
120
  end
149
121
 
150
122
  describe "=> {}" do
123
+ describe "hash options declaration", :shared => true do
124
+ it "should represent a hash" do
125
+ @opts.hash?.should be_true
126
+ end
127
+
128
+ it "should have hash definition" do
129
+ {@opts.hash.key.type => @opts.hash.key.name}.should == @hash_args[:key]
130
+ {@opts.hash.value.type => @opts.hash.value.name}.should == @hash_args[:value]
131
+ end
132
+
133
+ it "should not represent an array" do
134
+ @opts.array?.should be_false
135
+ end
136
+ end
137
+
151
138
  describe "hash with attr key and text val" do
152
139
  before do
153
- @opts = ROXML::Definition.new(:attributes, :as => {:key => {:attr => :name},
154
- :value => :value})
140
+ @opts = ROXML::Definition.new(:attributes, :as => {:key => '@name',
141
+ :value => 'value'})
155
142
  @hash_args = {:key => {:attr => 'name'},
156
143
  :value => {:text => 'value'}}
157
144
  end
@@ -161,8 +148,8 @@ describe ROXML::Definition do
161
148
 
162
149
  describe "hash with String class for type" do
163
150
  before do
164
- @opts = ROXML::Definition.new(:attributes, :as => {:key => {String => 'name'},
165
- :value => {String => 'value'}})
151
+ @opts = ROXML::Definition.new(:attributes, :as => {:key => 'name',
152
+ :value => 'value'})
166
153
  @hash_args = {:key => {:text => 'name'}, :value => {:text => 'value'}}
167
154
  end
168
155
 
@@ -171,7 +158,7 @@ describe ROXML::Definition do
171
158
 
172
159
  describe "hash with attr key and content val" do
173
160
  before do
174
- @opts = ROXML::Definition.new(:attributes, :as => {:key => {:attr => :name},
161
+ @opts = ROXML::Definition.new(:attributes, :as => {:key => '@name',
175
162
  :value => :content})
176
163
  @hash_args = {:key => {:attr => 'name'}, :value => {:text => '.'}}
177
164
  end
@@ -179,27 +166,14 @@ describe ROXML::Definition do
179
166
  it_should_behave_like "hash options declaration"
180
167
  end
181
168
 
182
- describe "hash of attrs" do
169
+ describe "hash with names as keys and content vals" do
183
170
  before do
184
- @hash_args = {:key => {:attr => 'name'}, :value => {:attr => 'value'}}
185
- @opts = ROXML::Definition.new(:attributes, :as => {:attrs => [:name, :value]})
171
+ @opts = ROXML::Definition.new(:attributes, :as => {:key => :name,
172
+ :value => :content})
173
+ @hash_args = {:key => {:text => '*'}, :value => {:text => '.'}}
186
174
  end
187
175
 
188
176
  it_should_behave_like "hash options declaration"
189
-
190
- describe "with options" do
191
- before do
192
- @hash_args = {:key => {:attr => 'dt'}, :value => {:attr => 'dd'}}
193
- @opts = ROXML::Definition.new(:definitions, :as => {:attrs => [:dt, :dd]},
194
- :in => 'definitions')
195
- end
196
-
197
- it_should_behave_like "hash options declaration"
198
-
199
- it "should not interfere with options" do
200
- @opts.wrapper.should == 'definitions'
201
- end
202
- end
203
177
  end
204
178
  end
205
179
 
@@ -221,8 +195,11 @@ describe ROXML::Definition do
221
195
 
222
196
  it "should have no blocks without a shorthand" do
223
197
  ROXML::Definition.new(:count).blocks.should be_empty
224
- ROXML::Definition.new(:count, :as => :bogus).blocks.should be_empty
225
- ROXML::Definition.new(:count, :as => :foat).blocks.should be_empty # misspelled
198
+ end
199
+
200
+ it "should raise on unknown :as" do
201
+ proc { ROXML::Definition.new(:count, :as => :bogus) }.should raise_error(ArgumentError)
202
+ proc { ROXML::Definition.new(:count, :as => :foat) }.should raise_error(ArgumentError)
226
203
  end
227
204
 
228
205
  describe "block shorthand type declaration", :shared => true do
@@ -236,7 +213,11 @@ describe ROXML::Definition do
236
213
  end
237
214
  end
238
215
 
239
- describe ":as => Integer", :shared => true do
216
+ describe "Integer" do
217
+ before do
218
+ @definition = ROXML::Definition.new(:intvalue, :as => Integer)
219
+ end
220
+
240
221
  it_should_behave_like "block shorthand type declaration"
241
222
 
242
223
  it "should translate text to integers" do
@@ -258,25 +239,11 @@ describe ROXML::Definition do
258
239
  end
259
240
  end
260
241
 
261
- describe "Integer" do
262
- before do
263
- @definition = ROXML::Definition.new(:intvalue, :as => Integer)
264
- end
265
-
266
- it_should_behave_like ":as => Integer"
267
- end
268
-
269
- describe ":integer" do
242
+ describe "Float" do
270
243
  before do
271
- @definition = ROXML::Definition.new(:intvalue, :as => :integer)
244
+ @definition = ROXML::Definition.new(:floatvalue, :as => Float)
272
245
  end
273
246
 
274
- it_should_behave_like ":as => Integer"
275
-
276
- it "should be deprecated"
277
- end
278
-
279
- describe ":as => Float", :shared => true do
280
247
  it_should_behave_like "block shorthand type declaration"
281
248
 
282
249
  it "should translate text to float" do
@@ -296,24 +263,6 @@ describe ROXML::Definition do
296
263
  end
297
264
  end
298
265
 
299
- describe ":float" do
300
- before do
301
- @definition = ROXML::Definition.new(:floatvalue, :as => :float)
302
- end
303
-
304
- it_should_behave_like ":as => Float"
305
-
306
- it "should be deprecated"
307
- end
308
-
309
- describe "Float" do
310
- before do
311
- @definition = ROXML::Definition.new(:floatvalue, :as => Float)
312
- end
313
-
314
- it_should_behave_like ":as => Float"
315
- end
316
-
317
266
  describe "BigDecimal" do
318
267
  before do
319
268
  @definition = ROXML::Definition.new(:decimalvalue, :as => BigDecimal)
@@ -408,35 +357,17 @@ describe ROXML::Definition do
408
357
  end
409
358
 
410
359
  describe "Date" do
411
- it "should return nil on empty string" do
412
- ROXML::Definition.new(:floatvalue, :as => Date).blocks.first.call(" ").should be_nil
413
- end
414
-
415
- it "should return a time version of the string" do
416
- ROXML::Definition.new(:datevalue, :as => Date).blocks.first.call("September 3rd, 1970").to_s == "1970-09-03"
417
- end
418
-
419
- context "when passed an array of values" do
420
- it "should timify all of them" do
421
- ROXML::Definition.new(:datevalue, :as => Date).blocks.first.call(["September 3rd, 1970", "1776-07-04"]).map(&:to_s).should == ["1970-09-03", "1776-07-04"]
422
- end
360
+ before do
361
+ @subject = ROXML::Definition.new(:datevalue, :as => Date)
423
362
  end
363
+ it_should_behave_like "Date reference"
424
364
  end
425
365
 
426
366
  describe "DateTime" do
427
- it "should return nil on empty string" do
428
- ROXML::Definition.new(:floatvalue, :as => DateTime).blocks.first.call(" ").should be_nil
429
- end
430
-
431
- it "should return a time version of the string" do
432
- ROXML::Definition.new(:datevalue, :as => DateTime).blocks.first.call("12:05pm, September 3rd, 1970").to_s == "1970-09-03T12:05:00+00:00"
433
- end
434
-
435
- context "when passed an array of values" do
436
- it "should timify all of them" do
437
- ROXML::Definition.new(:datevalue, :as => DateTime).blocks.first.call(["12:05pm, September 3rd, 1970", "3:00pm, May 22, 1700"]).map(&:to_s).should == ["1970-09-03T12:05:00+00:00", "1700-05-22T15:00:00+00:00"]
438
- end
367
+ before do
368
+ @subject = ROXML::Definition.new(:datevalue, :as => DateTime)
439
369
  end
370
+ it_should_behave_like "DateTime reference"
440
371
  end
441
372
 
442
373
  it "should prohibit multiple shorthands" do
@@ -481,19 +412,11 @@ describe ROXML::Definition do
481
412
  end
482
413
 
483
414
  it_should_behave_like "attribute reference"
484
-
485
- describe "and with :attr" do
486
- before do
487
- @opts = ROXML::Definition.new(:attr_name, :attr, :from => '@attr_name')
488
- end
489
-
490
- it_should_behave_like "attribute reference"
491
- it "should be deprecated"
492
- end
493
415
  end
494
416
 
495
417
  describe ":content" do
496
418
  it "should be recognized" do
419
+ ROXML::Definition.new(:author).content?.should be_false
497
420
  ROXML::Definition.new(:author, :from => :content).content?.should == true
498
421
  end
499
422
 
@@ -521,13 +444,13 @@ describe ROXML::Definition do
521
444
 
522
445
  describe "boolean option", :shared => true do
523
446
  it "should be recognized" do
524
- ROXML::Definition.new(:author, :content, @option => true).respond_to?(:"#{@option}?")
525
- ROXML::Definition.new(:author, :content, @option => true).send(:"#{@option}?").should be_true
526
- ROXML::Definition.new(:author, :content, @option => false).send(:"#{@option}?").should be_false
447
+ ROXML::Definition.new(:author, :from => :content, @option => true).respond_to?(:"#{@option}?")
448
+ ROXML::Definition.new(:author, :from => :content, @option => true).send(:"#{@option}?").should be_true
449
+ ROXML::Definition.new(:author, :from => :content, @option => false).send(:"#{@option}?").should be_false
527
450
  end
528
451
 
529
452
  it "should default to false" do
530
- ROXML::Definition.new(:author, :content).send(:"#{@option}?").should be_false
453
+ ROXML::Definition.new(:author, :from => :content).send(:"#{@option}?").should be_false
531
454
  end
532
455
  end
533
456
 
@@ -539,8 +462,8 @@ describe ROXML::Definition do
539
462
  it_should_behave_like "boolean option"
540
463
 
541
464
  it "should not be allowed together with :else" do
542
- proc { ROXML::Definition.new(:author, :content, :required => true, :else => 'Johnny') }.should raise_error(ArgumentError)
543
- proc { ROXML::Definition.new(:author, :content, :required => false, :else => 'Johnny') }.should_not raise_error
465
+ proc { ROXML::Definition.new(:author, :from => :content, :required => true, :else => 'Johnny') }.should raise_error(ArgumentError)
466
+ proc { ROXML::Definition.new(:author, :from => :content, :required => false, :else => 'Johnny') }.should_not raise_error
544
467
  end
545
468
  end
546
469