ROXML 3.0.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.
- data/.gitignore +6 -0
- data/.gitmodules +3 -0
- data/History.txt +299 -0
- data/MIT-LICENSE +18 -0
- data/README.rdoc +161 -0
- data/Rakefile +95 -0
- data/TODO +39 -0
- data/VERSION +1 -0
- data/config/website.yml +2 -0
- data/examples/amazon.rb +35 -0
- data/examples/current_weather.rb +27 -0
- data/examples/dashed_elements.rb +20 -0
- data/examples/library.rb +40 -0
- data/examples/posts.rb +27 -0
- data/examples/rails.rb +70 -0
- data/examples/twitter.rb +37 -0
- data/examples/xml/active_record.xml +70 -0
- data/examples/xml/amazon.xml +133 -0
- data/examples/xml/current_weather.xml +89 -0
- data/examples/xml/dashed_elements.xml +52 -0
- data/examples/xml/posts.xml +23 -0
- data/examples/xml/twitter.xml +422 -0
- data/lib/roxml.rb +547 -0
- data/lib/roxml/definition.rb +236 -0
- data/lib/roxml/hash_definition.rb +25 -0
- data/lib/roxml/xml.rb +43 -0
- data/lib/roxml/xml/parsers/libxml.rb +91 -0
- data/lib/roxml/xml/parsers/nokogiri.rb +77 -0
- data/lib/roxml/xml/references.rb +297 -0
- data/roxml.gemspec +201 -0
- data/spec/definition_spec.rb +486 -0
- data/spec/examples/active_record_spec.rb +40 -0
- data/spec/examples/amazon_spec.rb +54 -0
- data/spec/examples/current_weather_spec.rb +37 -0
- data/spec/examples/dashed_elements_spec.rb +20 -0
- data/spec/examples/library_spec.rb +46 -0
- data/spec/examples/post_spec.rb +24 -0
- data/spec/examples/twitter_spec.rb +32 -0
- data/spec/roxml_spec.rb +372 -0
- data/spec/shared_specs.rb +15 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/libxml.rb +3 -0
- data/spec/support/nokogiri.rb +3 -0
- data/spec/xml/attributes_spec.rb +36 -0
- data/spec/xml/namespace_spec.rb +240 -0
- data/spec/xml/namespaces_spec.rb +32 -0
- data/spec/xml/parser_spec.rb +26 -0
- data/tasks/rdoc.rake +13 -0
- data/tasks/rspec.rake +25 -0
- data/tasks/test.rake +35 -0
- data/test/fixtures/book_malformed.xml +5 -0
- data/test/fixtures/book_pair.xml +8 -0
- data/test/fixtures/book_text_with_attribute.xml +5 -0
- data/test/fixtures/book_valid.xml +5 -0
- data/test/fixtures/book_with_authors.xml +7 -0
- data/test/fixtures/book_with_contributions.xml +9 -0
- data/test/fixtures/book_with_contributors.xml +7 -0
- data/test/fixtures/book_with_contributors_attrs.xml +7 -0
- data/test/fixtures/book_with_default_namespace.xml +9 -0
- data/test/fixtures/book_with_depth.xml +6 -0
- data/test/fixtures/book_with_octal_pages.xml +4 -0
- data/test/fixtures/book_with_publisher.xml +7 -0
- data/test/fixtures/book_with_wrapped_attr.xml +3 -0
- data/test/fixtures/dictionary_of_attr_name_clashes.xml +8 -0
- data/test/fixtures/dictionary_of_attrs.xml +6 -0
- data/test/fixtures/dictionary_of_guarded_names.xml +6 -0
- data/test/fixtures/dictionary_of_mixeds.xml +4 -0
- data/test/fixtures/dictionary_of_name_clashes.xml +10 -0
- data/test/fixtures/dictionary_of_names.xml +4 -0
- data/test/fixtures/dictionary_of_texts.xml +10 -0
- data/test/fixtures/library.xml +30 -0
- data/test/fixtures/library_uppercase.xml +30 -0
- data/test/fixtures/muffins.xml +3 -0
- data/test/fixtures/nameless_ageless_youth.xml +2 -0
- data/test/fixtures/node_with_attr_name_conflicts.xml +1 -0
- data/test/fixtures/node_with_name_conflicts.xml +4 -0
- data/test/fixtures/numerology.xml +4 -0
- data/test/fixtures/person.xml +1 -0
- data/test/fixtures/person_with_guarded_mothers.xml +13 -0
- data/test/fixtures/person_with_mothers.xml +10 -0
- data/test/mocks/dictionaries.rb +57 -0
- data/test/mocks/mocks.rb +279 -0
- data/test/support/fixtures.rb +11 -0
- data/test/test_helper.rb +34 -0
- data/test/unit/definition_test.rb +235 -0
- data/test/unit/deprecations_test.rb +24 -0
- data/test/unit/to_xml_test.rb +81 -0
- data/test/unit/xml_attribute_test.rb +39 -0
- data/test/unit/xml_block_test.rb +81 -0
- data/test/unit/xml_bool_test.rb +122 -0
- data/test/unit/xml_convention_test.rb +150 -0
- data/test/unit/xml_hash_test.rb +115 -0
- data/test/unit/xml_initialize_test.rb +49 -0
- data/test/unit/xml_name_test.rb +141 -0
- data/test/unit/xml_namespace_test.rb +31 -0
- data/test/unit/xml_object_test.rb +207 -0
- data/test/unit/xml_required_test.rb +94 -0
- data/test/unit/xml_text_test.rb +71 -0
- data/website/index.html +98 -0
- metadata +254 -0
@@ -0,0 +1,486 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe ROXML::Definition do
|
4
|
+
describe "#name_explicit?" do
|
5
|
+
it "should indicate whether from option is present" do
|
6
|
+
ROXML::Definition.new(:element, :from => 'somewhere').name_explicit?.should be_true
|
7
|
+
ROXML::Definition.new(:element).name_explicit?.should be_false
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should not consider name proxies as explicit" do
|
11
|
+
ROXML::Definition.new(:element, :from => :attr).name_explicit?.should be_false
|
12
|
+
ROXML::Definition.new(:element, :from => :content).name_explicit?.should be_false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "DateTime reference", :shared => true do
|
17
|
+
it "should return nil on empty string" do
|
18
|
+
@subject.blocks.first.call(" ").should be_nil
|
19
|
+
end
|
20
|
+
|
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"
|
23
|
+
end
|
24
|
+
|
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
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
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
|
36
|
+
|
37
|
+
it "should return a time version of the string" do
|
38
|
+
@subject.blocks.first.call("September 3rd, 1970").to_s == "1970-09-03"
|
39
|
+
end
|
40
|
+
|
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"]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should unescape xml entities" do
|
49
|
+
ROXML::Definition.new(:questions, :as => []).to_ref(RoxmlObject.new).value_in(%{
|
50
|
+
<xml>
|
51
|
+
<question>"Wickard & Filburn" ></question>
|
52
|
+
<question> < McCulloch & 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"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
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"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe ":as" do
|
78
|
+
describe "=> []" do
|
79
|
+
it "should means array of texts" do
|
80
|
+
opts = ROXML::Definition.new(:authors, :as => [])
|
81
|
+
opts.array?.should be_true
|
82
|
+
opts.type.should == :text
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "=> RoxmlClass" do
|
87
|
+
class RoxmlClass
|
88
|
+
include ROXML
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should store type" do
|
92
|
+
opts = ROXML::Definition.new(:name, :as => RoxmlClass)
|
93
|
+
opts.type.should == RoxmlClass
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "=> NonRoxmlClassWithFromXmlDefined" do
|
98
|
+
class OctalInteger
|
99
|
+
def self.from_xml(val)
|
100
|
+
new(Integer(val.content))
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should accept type" do
|
105
|
+
opts = ROXML::Definition.new(:name, :as => OctalInteger)
|
106
|
+
opts.type.should == OctalInteger
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "=> NonRoxmlClass" do
|
111
|
+
it "should fail with a warning" do
|
112
|
+
proc { ROXML::Definition.new(:authors, :as => Module) }.should raise_error(ArgumentError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "=> [NonRoxmlClass]" do
|
117
|
+
it "should raise" do
|
118
|
+
proc { ROXML::Definition.new(:authors, :as => [Module]) }.should raise_error(ArgumentError)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
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
|
+
|
138
|
+
describe "hash with attr key and text val" do
|
139
|
+
before do
|
140
|
+
@opts = ROXML::Definition.new(:attributes, :as => {:key => '@name',
|
141
|
+
:value => 'value'})
|
142
|
+
@hash_args = {:key => {:attr => 'name'},
|
143
|
+
:value => {:text => 'value'}}
|
144
|
+
end
|
145
|
+
|
146
|
+
it_should_behave_like "hash options declaration"
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "hash with String class for type" do
|
150
|
+
before do
|
151
|
+
@opts = ROXML::Definition.new(:attributes, :as => {:key => 'name',
|
152
|
+
:value => 'value'})
|
153
|
+
@hash_args = {:key => {:text => 'name'}, :value => {:text => 'value'}}
|
154
|
+
end
|
155
|
+
|
156
|
+
it_should_behave_like "hash options declaration"
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "hash with attr key and content val" do
|
160
|
+
before do
|
161
|
+
@opts = ROXML::Definition.new(:attributes, :as => {:key => '@name',
|
162
|
+
:value => :content})
|
163
|
+
@hash_args = {:key => {:attr => 'name'}, :value => {:text => '.'}}
|
164
|
+
end
|
165
|
+
|
166
|
+
it_should_behave_like "hash options declaration"
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "hash with names as keys and content vals" do
|
170
|
+
before do
|
171
|
+
@opts = ROXML::Definition.new(:attributes, :as => {:key => :name,
|
172
|
+
:value => :content})
|
173
|
+
@hash_args = {:key => {:text => '*'}, :value => {:text => '.'}}
|
174
|
+
end
|
175
|
+
|
176
|
+
it_should_behave_like "hash options declaration"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "for block shorthand" do
|
181
|
+
describe "in literal array" do
|
182
|
+
before do
|
183
|
+
@opts = ROXML::Definition.new(:intarray, :as => [Integer])
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should be detected as array reference" do
|
187
|
+
@opts.array?.should be_true
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should be normal otherwise" do
|
191
|
+
@opts.type.should == :text
|
192
|
+
@opts.blocks.size.should == 1
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should have no blocks without a shorthand" do
|
197
|
+
ROXML::Definition.new(:count).blocks.should be_empty
|
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)
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "block shorthand type declaration", :shared => true do
|
206
|
+
it "should translate nil to nil" do
|
207
|
+
@definition.blocks.first.call(nil).should be_nil
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should translate empty strings to nil" do
|
211
|
+
@definition.blocks.first.call("").should be_nil
|
212
|
+
@definition.blocks.first.call(" ").should be_nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "Integer" do
|
217
|
+
before do
|
218
|
+
@definition = ROXML::Definition.new(:intvalue, :as => Integer)
|
219
|
+
end
|
220
|
+
|
221
|
+
it_should_behave_like "block shorthand type declaration"
|
222
|
+
|
223
|
+
it "should translate text to integers" do
|
224
|
+
@definition.blocks.first['3'].should == 3
|
225
|
+
@definition.blocks.first['792'].should == 792
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should raise on non-integer values" do
|
229
|
+
proc { @definition.blocks.first['08'] }.should raise_error(ArgumentError)
|
230
|
+
proc { @definition.blocks.first['793.12'] }.should raise_error(ArgumentError)
|
231
|
+
proc { @definition.blocks.first['junk 11'] }.should raise_error(ArgumentError)
|
232
|
+
proc { @definition.blocks.first['11sttf'] }.should raise_error(ArgumentError)
|
233
|
+
end
|
234
|
+
|
235
|
+
context "when passed an array" do
|
236
|
+
it "should translate the array elements to integer" do
|
237
|
+
@definition.blocks.first.call(["792", "12", "328"]).should == [792, 12, 328]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe "Float" do
|
243
|
+
before do
|
244
|
+
@definition = ROXML::Definition.new(:floatvalue, :as => Float)
|
245
|
+
end
|
246
|
+
|
247
|
+
it_should_behave_like "block shorthand type declaration"
|
248
|
+
|
249
|
+
it "should translate text to float" do
|
250
|
+
@definition.blocks.first['3'].should == 3.0
|
251
|
+
@definition.blocks.first['12.7'].should == 12.7
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should raise on non-float values" do
|
255
|
+
proc { @definition.blocks.first['junk 11.3'] }.should raise_error(ArgumentError)
|
256
|
+
proc { @definition.blocks.first['11.1sttf'] }.should raise_error(ArgumentError)
|
257
|
+
end
|
258
|
+
|
259
|
+
context "when passed an array" do
|
260
|
+
it "should translate the array elements to integer" do
|
261
|
+
@definition.blocks.first.call(["792.13", "240", "3.14"]).should == [792.13, 240.0, 3.14]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe "BigDecimal" do
|
267
|
+
before do
|
268
|
+
@definition = ROXML::Definition.new(:decimalvalue, :as => BigDecimal)
|
269
|
+
end
|
270
|
+
|
271
|
+
it_should_behave_like "block shorthand type declaration"
|
272
|
+
|
273
|
+
it "should translate text to decimal numbers" do
|
274
|
+
@definition.blocks.first['3'].should == BigDecimal.new("3.0")
|
275
|
+
@definition.blocks.first['0.3'].should == BigDecimal.new("0.3")
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should extract what it can, and fall back to 0" do
|
279
|
+
@definition.blocks.first['junk 11'].should eql(BigDecimal.new("0"))
|
280
|
+
@definition.blocks.first['11sttf'].should eql(BigDecimal.new("11.0"))
|
281
|
+
end
|
282
|
+
|
283
|
+
context "when passed an array" do
|
284
|
+
it "should translate the array elements to integer" do
|
285
|
+
@definition.blocks.first.call(["12.1", "328.2"]).should == [BigDecimal.new("12.1"), BigDecimal.new("328.2")]
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "Fixnum" do
|
291
|
+
before do
|
292
|
+
@definition = ROXML::Definition.new(:fixnumvalue, :as => Fixnum)
|
293
|
+
end
|
294
|
+
|
295
|
+
it_should_behave_like "block shorthand type declaration"
|
296
|
+
|
297
|
+
it "should translate text to integers" do
|
298
|
+
@definition.blocks.first['3'].should == 3
|
299
|
+
@definition.blocks.first['792'].should == 792
|
300
|
+
@definition.blocks.first['08'].should == 8
|
301
|
+
@definition.blocks.first['279.23'].should == 279
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should extract whatever is possible and fall back to 0" do
|
305
|
+
@definition.blocks.first['junk 11'].should eql(0)
|
306
|
+
@definition.blocks.first['.?sttf'].should eql(0)
|
307
|
+
@definition.blocks.first['11sttf'].should eql(11)
|
308
|
+
end
|
309
|
+
|
310
|
+
context "when passed an array" do
|
311
|
+
it "should translate the array elements to integer" do
|
312
|
+
@definition.blocks.first.call(["792", "12", "328"]).should == [792, 12, 328]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe ":bool" do
|
318
|
+
it "should boolify individual values" do
|
319
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("1").should be_true
|
320
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("True").should be_true
|
321
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("Yes").should be_true
|
322
|
+
end
|
323
|
+
|
324
|
+
context "when an array is passed in" do
|
325
|
+
it "should boolify arrays of values" do
|
326
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("0").should be_false
|
327
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("false").should be_false
|
328
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("nO").should be_false
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
context "when no value is detected" do
|
333
|
+
it "should return nil" do
|
334
|
+
ROXML::Definition.new(:floatvalue, :as => :bool).blocks.first.call("junk").should be_nil
|
335
|
+
end
|
336
|
+
|
337
|
+
context "when a literal block is available" do
|
338
|
+
it "should pass the value itself to the block"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
describe "Time" do
|
344
|
+
it "should return nil on empty string" do
|
345
|
+
ROXML::Definition.new(:floatvalue, :as => Time).blocks.first.call(" ").should be_nil
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should return a time version of the string" do
|
349
|
+
ROXML::Definition.new(:datevalue, :as => Time).blocks.first.call("12:31am").min.should == 31
|
350
|
+
end
|
351
|
+
|
352
|
+
context "when passed an array of values" do
|
353
|
+
it "should timify all of them" do
|
354
|
+
ROXML::Definition.new(:datevalue, :as => Time).blocks.first.call(["12:31am", "3:00pm", "11:59pm"]).map(&:min).should == [31, 0, 59]
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "Date" do
|
360
|
+
before do
|
361
|
+
@subject = ROXML::Definition.new(:datevalue, :as => Date)
|
362
|
+
end
|
363
|
+
it_should_behave_like "Date reference"
|
364
|
+
end
|
365
|
+
|
366
|
+
describe "DateTime" do
|
367
|
+
before do
|
368
|
+
@subject = ROXML::Definition.new(:datevalue, :as => DateTime)
|
369
|
+
end
|
370
|
+
it_should_behave_like "DateTime reference"
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should prohibit multiple shorthands" do
|
374
|
+
proc { ROXML::Definition.new(:count, :as => [Float, Integer]) }.should raise_error(ArgumentError)
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should stack block shorthands with explicit blocks" do
|
378
|
+
ROXML::Definition.new(:count, :as => Integer) {|val| val.to_i }.blocks.size.should == 2
|
379
|
+
ROXML::Definition.new(:count, :as => Float) {|val| val.object_id }.blocks.size.should == 2
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
describe ":from" do
|
385
|
+
describe "attribute reference", :shared => true do
|
386
|
+
it "should be interpreted as :attr" do
|
387
|
+
@opts.type.should == :attr
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should strip '@' from name" do
|
391
|
+
@opts.name.should == 'attr_name'
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should unescape xml entities" do
|
395
|
+
@opts.to_ref(RoxmlObject.new).value_in(%{
|
396
|
+
<question attr_name=""Wickard & Filburn" > / < McCulloch & Marryland?" />
|
397
|
+
}).should == "\"Wickard & Filburn\" > / < McCulloch & Marryland?"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
context ":attr" do
|
402
|
+
before do
|
403
|
+
@opts = ROXML::Definition.new(:attr_name, :from => :attr)
|
404
|
+
end
|
405
|
+
|
406
|
+
it_should_behave_like "attribute reference"
|
407
|
+
end
|
408
|
+
|
409
|
+
context "@attribute_name" do
|
410
|
+
before do
|
411
|
+
@opts = ROXML::Definition.new(:attr_name, :from => '@attr_name')
|
412
|
+
end
|
413
|
+
|
414
|
+
it_should_behave_like "attribute reference"
|
415
|
+
end
|
416
|
+
|
417
|
+
describe ":content" do
|
418
|
+
it "should be recognized" do
|
419
|
+
ROXML::Definition.new(:author).content?.should be_false
|
420
|
+
ROXML::Definition.new(:author, :from => :content).content?.should == true
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should be equivalent to :from => '.'" do
|
424
|
+
ROXML::Definition.new(:author, :from => '.').content?.should == true
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe ":in" do
|
430
|
+
context "as xpath" do
|
431
|
+
it "should pass through as wrapper" do
|
432
|
+
ROXML::Definition.new(:manufacturer, :in => './').wrapper.should == './'
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "as xpath" do
|
437
|
+
it "should pass through as wrapper" do
|
438
|
+
ROXML::Definition.new(:manufacturer, :in => 'wrapper').wrapper.should == 'wrapper'
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe "options" do
|
444
|
+
|
445
|
+
describe "boolean option", :shared => true do
|
446
|
+
it "should be recognized" do
|
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
|
450
|
+
end
|
451
|
+
|
452
|
+
it "should default to false" do
|
453
|
+
ROXML::Definition.new(:author, :from => :content).send(:"#{@option}?").should be_false
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe ":required" do
|
458
|
+
before do
|
459
|
+
@option = :required
|
460
|
+
end
|
461
|
+
|
462
|
+
it_should_behave_like "boolean option"
|
463
|
+
|
464
|
+
it "should not be allowed together with :else" do
|
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
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
describe ":frozen" do
|
471
|
+
before do
|
472
|
+
@option = :frozen
|
473
|
+
end
|
474
|
+
|
475
|
+
it_should_behave_like "boolean option"
|
476
|
+
end
|
477
|
+
|
478
|
+
describe ":cdata" do
|
479
|
+
before do
|
480
|
+
@option = :cdata
|
481
|
+
end
|
482
|
+
|
483
|
+
it_should_behave_like "boolean option"
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|