representable 0.0.1.alpha1
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 +7 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/History.txt +354 -0
- data/LICENSE +20 -0
- data/README.rdoc +186 -0
- data/Rakefile +10 -0
- data/TODO +37 -0
- data/VERSION +1 -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/representable.rb +257 -0
- data/lib/representable/definition.rb +109 -0
- data/lib/representable/nokogiri_extensions.rb +19 -0
- data/lib/representable/references.rb +153 -0
- data/lib/representable/version.rb +3 -0
- data/lib/representable/xml.rb +79 -0
- data/representable.gemspec +29 -0
- data/spec/definition_spec.rb +495 -0
- data/spec/examples/active_record_spec.rb +41 -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_integration_test.rb +289 -0
- data/spec/roxml_spec.rb +372 -0
- data/spec/shared_specs.rb +15 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/libxml.rb +3 -0
- data/spec/support/nokogiri.rb +3 -0
- data/spec/xml/array_spec.rb +36 -0
- data/spec/xml/attributes_spec.rb +71 -0
- data/spec/xml/encoding_spec.rb +53 -0
- data/spec/xml/namespace_spec.rb +270 -0
- data/spec/xml/namespaces_spec.rb +67 -0
- data/spec/xml/object_spec.rb +82 -0
- data/spec/xml/parser_spec.rb +21 -0
- data/spec/xml/text_spec.rb +71 -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/roxml_test.rb +58 -0
- data/test/support/fixtures.rb +11 -0
- data/test/test_helper.rb +6 -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 +206 -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 +248 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative './../spec_helper'
|
3
|
+
|
4
|
+
describe ROXML, "encoding" do
|
5
|
+
class TestResult
|
6
|
+
include ROXML
|
7
|
+
xml_accessor :message
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when provided non-latin characters" do
|
11
|
+
it "should output those characters as input via methods" do
|
12
|
+
res = TestResult.new
|
13
|
+
res.message = "sadfk одловыа jjklsd " #random russian and english charecters
|
14
|
+
doc = ROXML::XML::Document.new
|
15
|
+
doc.root = res.to_xml
|
16
|
+
if defined?(Nokogiri)
|
17
|
+
doc.at('message').inner_text
|
18
|
+
else
|
19
|
+
doc.find_first('message').inner_xml
|
20
|
+
end.should == "sadfk одловыа jjklsd "
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should output those characters as input via xml" do
|
24
|
+
res = TestResult.from_xml("<test_result><message>sadfk одловыа jjklsd </message></test_result>")
|
25
|
+
doc = ROXML::XML::Document.new
|
26
|
+
doc.root = res.to_xml
|
27
|
+
if defined?(Nokogiri)
|
28
|
+
doc.at('message').inner_text
|
29
|
+
else
|
30
|
+
doc.find_first('message').inner_xml
|
31
|
+
end.should == "sadfk одловыа jjklsd "
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should allow override via the document" do
|
35
|
+
res = TestResult.from_xml("<test_result><message>sadfk одловыа jjklsd </message></test_result>")
|
36
|
+
if defined?(Nokogiri)
|
37
|
+
xml = res.to_xml
|
38
|
+
doc = xml.document
|
39
|
+
doc.root = xml
|
40
|
+
doc.encoding = 'ISO-8859-1'
|
41
|
+
doc.to_s.should include('ISO-8859-1')
|
42
|
+
doc.at('message').inner_text
|
43
|
+
else
|
44
|
+
doc = LibXML::XML::Document.new
|
45
|
+
doc.encoding = LibXML::XML::Encoding::ASCII
|
46
|
+
doc.root = res.to_xml
|
47
|
+
pending "Libxml bug"
|
48
|
+
doc.to_s.should include('ISO-8859-1')
|
49
|
+
doc.find_first('message').inner_xml
|
50
|
+
end.should == "sadfk одловыа jjklsd "
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require_relative './../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ROXML, "with namespaces" do
|
4
|
+
describe "for writing" do
|
5
|
+
before do
|
6
|
+
@xml = <<EOS
|
7
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
8
|
+
<gronk:VApp name="My new vApp" status="1" href="https://vcloud.example.com/vapp/833" type="application/vnd.vmware.vcloud.vapp+xml" xmlns:vmw="http://foo.example.com" xmlns:gronk="http://gronk.example.com">
|
9
|
+
<gronk:NetworkConfig name="Network 1">
|
10
|
+
<vmw:FenceMode>allowInOut</vmw:FenceMode>
|
11
|
+
<vmw:Dhcp>true</vmw:Dhcp>
|
12
|
+
<gronk:errors>
|
13
|
+
<gronk:error>OhNo!</gronk:error>
|
14
|
+
<gronk:error>Another!</gronk:error>
|
15
|
+
</gronk:errors>
|
16
|
+
</gronk:NetworkConfig>
|
17
|
+
<foo />
|
18
|
+
<bar>
|
19
|
+
gronk
|
20
|
+
</bar>
|
21
|
+
</gronk:VApp>
|
22
|
+
EOS
|
23
|
+
end
|
24
|
+
|
25
|
+
class NetworkConfig
|
26
|
+
include ROXML
|
27
|
+
xml_namespace :gronk
|
28
|
+
|
29
|
+
xml_name 'NetworkConfig'
|
30
|
+
xml_reader :name, :from => '@name'
|
31
|
+
xml_reader :errors, :as => []
|
32
|
+
xml_accessor :fence_mode, :from => 'vmw:FenceMode'
|
33
|
+
xml_accessor :dhcp?, :from => 'vmw:Dhcp'
|
34
|
+
end
|
35
|
+
|
36
|
+
class VApp
|
37
|
+
include ROXML
|
38
|
+
xml_namespace :gronk
|
39
|
+
|
40
|
+
xml_name "VApp"
|
41
|
+
xml_reader :name, :from => '@name'
|
42
|
+
xml_reader :status, :from => '@status'
|
43
|
+
xml_reader :href, :from => '@href'
|
44
|
+
xml_reader :type, :from => '@type'
|
45
|
+
xml_accessor :foo, :from => 'foo', :namespace => false
|
46
|
+
xml_accessor :bar, :from => 'bar', :namespace => false
|
47
|
+
xml_accessor :network_configs, :as => [NetworkConfig], :namespace => :gronk
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#to_xml" do
|
51
|
+
it "should reproduce the input xml" do
|
52
|
+
output = ROXML::XML::Document.new
|
53
|
+
output.root = VApp.from_xml(@xml).to_xml
|
54
|
+
pending "Full namespace write support"
|
55
|
+
output.should == ROXML::XML.parse_string(@xml)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
shared_examples_for "roxml namespacey declaration" do
|
61
|
+
context "with a namespacey :from" do
|
62
|
+
context "and an explicit :namespace" do
|
63
|
+
it "should raise" do
|
64
|
+
proc do
|
65
|
+
Class.new do
|
66
|
+
include ROXML
|
67
|
+
xml_reader :default_namespace_with_namespacey_from_and_explicit_namespace, :from => 'namespacey:with_namespacey_from', :namespace => 'explicit'
|
68
|
+
end
|
69
|
+
end.should raise_error(ROXML::ContradictoryNamespaces)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "and :namespace => false" do
|
74
|
+
it "should raise" do
|
75
|
+
proc do
|
76
|
+
Class.new do
|
77
|
+
include ROXML
|
78
|
+
xml_reader :default_namespace_with_namespacey_from_and_namespace_false, :from => 'namespacey:with_namespacey_from', :namespace => false
|
79
|
+
end
|
80
|
+
end.should raise_error(ROXML::ContradictoryNamespaces)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
shared_examples_for "roxml namespacey declaration with default" do
|
87
|
+
it_should_behave_like "roxml namespacey declaration"
|
88
|
+
|
89
|
+
it "should use the default namespace" do
|
90
|
+
@instance.default_namespace.should == 'default namespace node'
|
91
|
+
end
|
92
|
+
|
93
|
+
context "and :namespace => false" do
|
94
|
+
it "should find the namespace-less node" do
|
95
|
+
@instance.default_namespace_with_namespace_false.should == 'namespaceless node'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "with an explicit :namespace" do
|
100
|
+
it "should use the explicit namespace" do
|
101
|
+
@instance.default_and_explicit_namespace == 'explicit namespace node'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "with a namespace-less :from" do
|
106
|
+
it "should use the default namespace" do
|
107
|
+
@instance.default_namespace_with_namespaceless_from.should == 'default namespace node'
|
108
|
+
end
|
109
|
+
|
110
|
+
context "and :namespace => false" do
|
111
|
+
it "should find the namespace-less node" do
|
112
|
+
@instance.default_namespace_with_namespaceless_from_and_namespace_false.should == 'namespaceless node'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "and an explicit :namespace" do
|
117
|
+
it "should use the explicit namespace" do
|
118
|
+
@instance.default_namespace_with_namespaceless_from_and_explicit_namespace.should == 'explicit namespace node'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "with a namespacey :from" do
|
124
|
+
it "should use the :from namespace" do
|
125
|
+
@instance.default_namespace_with_namespacey_from.should == 'namespacey node'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "with a default namespace declared" do
|
131
|
+
class DefaultNamespaceyObject
|
132
|
+
include ROXML
|
133
|
+
xml_namespace :default_declared
|
134
|
+
|
135
|
+
xml_reader :default_namespace
|
136
|
+
xml_reader :default_namespace_with_namespace_false, :namespace => false
|
137
|
+
xml_reader :default_and_explicit_namespace, :namespace => 'explicit'
|
138
|
+
xml_reader :default_namespace_with_namespaceless_from, :from => 'with_namespaceless_from'
|
139
|
+
xml_reader :default_namespace_with_namespaceless_from_and_explicit_namespace, :from => 'with_namespaceless_from', :namespace => 'explicit'
|
140
|
+
xml_reader :default_namespace_with_namespaceless_from_and_namespace_false, :from => 'with_namespaceless_from', :namespace => false
|
141
|
+
xml_reader :default_namespace_with_namespacey_from, :from => 'namespacey:with_namespacey_from'
|
142
|
+
|
143
|
+
# These are handled in the "roxml namespacey declaration" shared spec
|
144
|
+
# xml_reader :default_namespace_with_namespacey_from_and_namespace_false, :from => 'namespacey:with_namespaceless_from', :namespace => false
|
145
|
+
# xml_reader :default_namespace_with_namespacey_from_and_explicit_namespace, :from => 'namespacey:with_namespaceless_from', :namespace => 'explicit'
|
146
|
+
end
|
147
|
+
|
148
|
+
before do
|
149
|
+
@instance = DefaultNamespaceyObject.from_xml(%{
|
150
|
+
<book xmlns:namespacey="http://www.aws.com/aws" xmlns:default_declared="http://www.aws.com/default" xmlns:explicit="http://www.aws.com/different">
|
151
|
+
<default_declared:default_namespace>default namespace node</default_declared:default_namespace>
|
152
|
+
<namespacey:with_namespacey_from>namespacey node</namespacey:with_namespacey_from>
|
153
|
+
<explicit:with_namespaceless_from>explicit namespace node</explicit:with_namespaceless_from>
|
154
|
+
<with_namespaceless_from>namespaceless node</with_namespaceless_from>
|
155
|
+
<default_declared:with_namespaceless_from>default namespace node</default_declared:with_namespaceless_from>
|
156
|
+
<explicit:default_and_explicit_namespace>explicit namespace node</explicit:default_and_explicit_namespace>
|
157
|
+
<default_namespace_with_namespace_false>namespaceless node</default_namespace_with_namespace_false>
|
158
|
+
</book>
|
159
|
+
})
|
160
|
+
end
|
161
|
+
|
162
|
+
it_should_behave_like "roxml namespacey declaration with default"
|
163
|
+
end
|
164
|
+
|
165
|
+
context "with a default namespace on the root node" do
|
166
|
+
class XmlDefaultNamespaceyObject
|
167
|
+
include ROXML
|
168
|
+
xml_reader :default_namespace
|
169
|
+
xml_reader :default_namespace_with_namespace_false, :namespace => false
|
170
|
+
xml_reader :default_and_explicit_namespace, :namespace => 'explicit'
|
171
|
+
xml_reader :default_namespace_with_namespaceless_from, :from => 'with_namespaceless_from'
|
172
|
+
xml_reader :default_namespace_with_namespaceless_from_and_explicit_namespace, :from => 'with_namespaceless_from', :namespace => 'explicit'
|
173
|
+
xml_reader :default_namespace_with_namespaceless_from_and_namespace_false, :from => 'with_namespaceless_from', :namespace => false
|
174
|
+
xml_reader :default_namespace_with_namespacey_from, :from => 'namespacey:with_namespacey_from'
|
175
|
+
|
176
|
+
# These are handled in the "roxml namespacey declaration" shared spec
|
177
|
+
# xml_reader :default_namespace_with_namespacey_from_and_namespace_false, :from => 'namespacey:with_namespaceless_from', :namespace => false
|
178
|
+
# xml_reader :default_namespace_with_namespacey_from_and_explicit_namespace, :from => 'namespacey:with_namespaceless_from', :namespace => 'explicit'
|
179
|
+
end
|
180
|
+
|
181
|
+
before do
|
182
|
+
@instance = XmlDefaultNamespaceyObject.from_xml(%{
|
183
|
+
<book xmlns="http://www.aws.com/xml_default" xmlns:namespacey="http://www.aws.com/aws" xmlns:default_declared="http://www.aws.com/default" xmlns:explicit="http://www.aws.com/different">
|
184
|
+
<default_namespace>default namespace node</default_namespace>
|
185
|
+
<namespacey:with_namespacey_from>namespacey node</namespacey:with_namespacey_from>
|
186
|
+
<explicit:with_namespaceless_from>explicit namespace node</explicit:with_namespaceless_from>
|
187
|
+
<with_namespaceless_from xmlns="">namespaceless node</with_namespaceless_from>
|
188
|
+
<with_namespaceless_from>default namespace node</with_namespaceless_from>
|
189
|
+
<explicit:default_and_explicit_namespace>explicit namespace node</explicit:default_and_explicit_namespace>
|
190
|
+
<default_namespace_with_namespace_false xmlns="">namespaceless node</default_namespace_with_namespace_false>
|
191
|
+
</book>
|
192
|
+
})
|
193
|
+
end
|
194
|
+
|
195
|
+
it_should_behave_like "roxml namespacey declaration with default"
|
196
|
+
end
|
197
|
+
|
198
|
+
context "without a default namespace" do
|
199
|
+
class NamespaceyObject
|
200
|
+
include ROXML
|
201
|
+
|
202
|
+
xml_reader :no_default_namespace
|
203
|
+
xml_reader :no_default_namespace_with_namespace_false, :namespace => false
|
204
|
+
xml_reader :no_default_but_an_explicit_namespace, :namespace => 'explicit'
|
205
|
+
xml_reader :no_default_namespace_with_namespaceless_from, :from => 'with_namespaceless_from'
|
206
|
+
xml_reader :no_default_namespace_with_namespaceless_from_and_explicit_namespace, :from => 'with_namespaceless_from', :namespace => 'explicit'
|
207
|
+
xml_reader :no_default_namespace_with_namespaceless_from_and_namespace_false, :from => 'with_namespaceless_from', :namespace => false
|
208
|
+
xml_reader :no_default_namespace_with_namespacey_from, :from => 'namespacey:with_namespacey_from'
|
209
|
+
|
210
|
+
# These are handled in the "roxml namespacey declaration" shared spec
|
211
|
+
# xml_reader :no_default_namespace_with_namespacey_from_and_explicit_namespace, :from => 'namespacey:with_namespacey_from', :namespace => 'explicit'
|
212
|
+
# xml_reader :no_default_namespace_with_namespacey_from_and_namespace_false, :from => 'namespacey:with_namespacey_from', :namespace => false
|
213
|
+
end
|
214
|
+
|
215
|
+
before do
|
216
|
+
@instance = NamespaceyObject.from_xml(%{
|
217
|
+
<book xmlns:namespacey="http://www.aws.com/aws" xmlns:explicit="http://www.aws.com/different">
|
218
|
+
<namespacey:with_namespacey_from>namespacey node</namespacey:with_namespacey_from>
|
219
|
+
<explicit:with_namespaceless_from>explicit namespace node</explicit:with_namespaceless_from>
|
220
|
+
<with_namespaceless_from>namespaceless node</with_namespaceless_from>
|
221
|
+
<explicit:no_default_but_an_explicit_namespace>explicit namespace node</explicit:no_default_but_an_explicit_namespace>
|
222
|
+
<no_default_namespace_with_namespace_false>namespaceless node</no_default_namespace_with_namespace_false>
|
223
|
+
<no_default_namespace>namespaceless node</no_default_namespace>
|
224
|
+
</book>
|
225
|
+
})
|
226
|
+
end
|
227
|
+
|
228
|
+
it_should_behave_like "roxml namespacey declaration"
|
229
|
+
|
230
|
+
it "should find the namespace-less node" do
|
231
|
+
@instance.no_default_namespace.should == 'namespaceless node'
|
232
|
+
end
|
233
|
+
|
234
|
+
context "with :namespace => false" do
|
235
|
+
it "should find the namespace-less node" do
|
236
|
+
@instance.no_default_namespace_with_namespace_false.should == 'namespaceless node'
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "with an explicit :namespace" do
|
241
|
+
it "should use the explicit namespace" do
|
242
|
+
@instance.no_default_but_an_explicit_namespace.should == 'explicit namespace node'
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "with a namespace-less :from" do
|
247
|
+
it "should find the namespace-less node" do
|
248
|
+
@instance.no_default_namespace_with_namespaceless_from.should == 'namespaceless node'
|
249
|
+
end
|
250
|
+
|
251
|
+
context "and an explicit :namespace" do
|
252
|
+
it "should use the explicit namespace" do
|
253
|
+
@instance.no_default_namespace_with_namespaceless_from_and_explicit_namespace.should == 'explicit namespace node'
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context "with :namespace => false" do
|
258
|
+
it "should find the namespace-less node" do
|
259
|
+
@instance.no_default_namespace_with_namespaceless_from_and_namespace_false.should == 'namespaceless node'
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "with a namespacey :from" do
|
265
|
+
it "should use the :from namespace" do
|
266
|
+
@instance.no_default_namespace_with_namespacey_from.should == 'namespacey node'
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative './../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ROXML, "#xml_namespaces" do
|
4
|
+
describe "for reading" do
|
5
|
+
class Tires
|
6
|
+
include ROXML
|
7
|
+
|
8
|
+
xml_namespaces \
|
9
|
+
:bobsbike => 'http://bobsbikes.example.com',
|
10
|
+
:alicesauto => 'http://alicesautosupply.example.com/'
|
11
|
+
|
12
|
+
xml_reader :bike_tires, :as => [], :from => '@name', :in => 'bobsbike:tire'
|
13
|
+
xml_reader :car_tires, :as => [], :from => '@name', :in => 'alicesauto:tire'
|
14
|
+
xml_reader :tires, :as => [], :from => '@name', :in => 'tire', :namespace => '*'
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
@xml = %{<?xml version="1.0"?>
|
19
|
+
<inventory xmlns="http://alicesautosupply.example.com/" xmlns:bike="http://bobsbikes.example.com">
|
20
|
+
<tire name="super slick racing tire" />
|
21
|
+
<tire name="all weather tire" />
|
22
|
+
<bike:tire name="skinny street" />
|
23
|
+
</inventory>
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should remap default namespaces" do
|
28
|
+
Tires.from_xml(@xml).car_tires.should =~ ['super slick racing tire', 'all weather tire']
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should remap prefix namespaces" do
|
32
|
+
Tires.from_xml(@xml).bike_tires.should == ['skinny street']
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with namespace-indifferent option" do
|
36
|
+
it "should return all tires" do
|
37
|
+
Tires.from_xml(@xml).tires.should =~ ['super slick racing tire', 'all weather tire', 'skinny street']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when an included namespace is not defined in the xml" do
|
43
|
+
context "where the missing namespace is the default" do
|
44
|
+
it "should raise"
|
45
|
+
|
46
|
+
context "but the namespace is declared in the body" do
|
47
|
+
it "should succeed"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "where the missing namespace is included in a namespacey from" do
|
52
|
+
it "should raise"
|
53
|
+
|
54
|
+
context "but the namespace is declared in the body" do
|
55
|
+
it "should succeed"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "where the missing namespace is included in an explicit :namespace" do
|
60
|
+
it "should raise"
|
61
|
+
|
62
|
+
context "but the namespace is declared in the body" do
|
63
|
+
it "should succeed"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative './../spec_helper'
|
2
|
+
|
3
|
+
describe ROXML::XMLObjectRef do
|
4
|
+
class SubObject
|
5
|
+
include ROXML
|
6
|
+
|
7
|
+
xml_reader :value, :from => :attr
|
8
|
+
|
9
|
+
def initialize(value = nil)
|
10
|
+
@value = value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
@xml = ROXML::XML.parse_string %(
|
16
|
+
<myxml>
|
17
|
+
<node>
|
18
|
+
<name value="first" />
|
19
|
+
<name value="second" />
|
20
|
+
<name value="third" />
|
21
|
+
</node>
|
22
|
+
</myxml>)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "plain vanilla" do
|
26
|
+
before do
|
27
|
+
@ref = ROXML::XMLObjectRef.new(OpenStruct.new(:name => 'name', :wrapper => 'node', :array? => false, :sought_type => SubObject), RoxmlObject.new)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return one instance" do
|
31
|
+
@ref.value_in(@xml).value.should == "first"
|
32
|
+
end
|
33
|
+
it "should output one instance"
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with :as => []" do
|
37
|
+
before do
|
38
|
+
@ref = ROXML::XMLObjectRef.new(OpenStruct.new(:name => 'name', :wrapper => 'node', :array? => true, :sought_type => SubObject), RoxmlObject.new)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should collect all instances" do
|
42
|
+
@ref.value_in(@xml).map(&:value).should == ["first", "second", "third"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should output all instances" do
|
46
|
+
xml = ROXML::XML.new_node('myxml')
|
47
|
+
@ref.update_xml(xml, ["first", "second", "third"].map {|value| SubObject.new(value) })
|
48
|
+
xml.to_s.squeeze(' ').should == @xml.root.to_s.squeeze(' ')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when the namespaces are different" do
|
53
|
+
before do
|
54
|
+
@xml = ROXML::XML.parse_string %(
|
55
|
+
<myxml xmlns="http://example.com/three" xmlns:one="http://example.com/one" xmlns:two="http://example.com/two">
|
56
|
+
<node>
|
57
|
+
<one:name>first</one:name>
|
58
|
+
<two:name>second</two:name>
|
59
|
+
<name>third</name>
|
60
|
+
</node>
|
61
|
+
</myxml>)
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with :namespace => '*'" do
|
65
|
+
before do
|
66
|
+
@ref = ROXML::XMLObjectRef.new(OpenStruct.new(:name => 'name', :wrapper => 'node', :array? => true, :namespace => '*', :sought_type => SubObject), RoxmlObject.new)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should collect all instances" do
|
70
|
+
pending "Test bug?"
|
71
|
+
@ref.value_in(@xml).map(&:value).should == ["first", "second", "third"]
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should output all instances with namespaces" do
|
75
|
+
pending "Full namespace write support"
|
76
|
+
xml = ROXML::XML.new_node('myxml')
|
77
|
+
@ref.update_xml(xml, ["first", "second", "third"].map {|value| SubObject.new(value) })
|
78
|
+
xml.should == @xml.root
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|