roxml 2.5.3 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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