nokogiri-happymapper 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -5
- data/README.md +85 -69
- data/lib/happymapper.rb +27 -22
- data/lib/happymapper/anonymous_mapper.rb +35 -30
- data/lib/happymapper/item.rb +1 -1
- data/lib/happymapper/supported_types.rb +2 -7
- data/lib/happymapper/version.rb +1 -1
- data/spec/features/after_parse_callbacks_spec.rb +29 -0
- data/spec/{attribute_default_value_spec.rb → features/attribute_default_value_spec.rb} +3 -3
- data/spec/{attributes_spec.rb → features/attributes_spec.rb} +6 -6
- data/spec/{has_many_empty_array_spec.rb → features/has_many_empty_array_spec.rb} +1 -1
- data/spec/{ignay_spec.rb → features/ignay_spec.rb} +10 -19
- data/spec/{inheritance_spec.rb → features/inheritance_spec.rb} +1 -1
- data/spec/{mixed_namespaces_spec.rb → features/mixed_namespaces_spec.rb} +17 -17
- data/spec/{parse_with_object_to_update_spec.rb → features/parse_with_object_to_update_spec.rb} +0 -0
- data/spec/features/same_tag_different_meaning_spec.rb +44 -0
- data/spec/{to_xml_spec.rb → features/to_xml_spec.rb} +2 -2
- data/spec/{to_xml_with_namespaces_spec.rb → features/to_xml_with_namespaces_spec.rb} +0 -0
- data/spec/{wilcard_tag_name_spec.rb → features/wildcard_tag_name_spec.rb} +5 -5
- data/spec/{wrap_spec.rb → features/wrap_spec.rb} +4 -4
- data/spec/{xpath_spec.rb → features/xpath_spec.rb} +17 -23
- data/spec/happymapper/anonymous_mapper_spec.rb +158 -0
- data/spec/happymapper/element_spec.rb +1 -1
- data/spec/happymapper/item_spec.rb +75 -45
- data/spec/happymapper_spec.rb +120 -125
- metadata +32 -28
- data/spec/happymapper_parse_spec.rb +0 -131
data/lib/happymapper/item.rb
CHANGED
@@ -28,7 +28,7 @@ module HappyMapper
|
|
28
28
|
end
|
29
29
|
|
30
30
|
#
|
31
|
-
# @param [
|
31
|
+
# @param [Nokogiri::XML::Element] node the xml node that is being parsed
|
32
32
|
# @param [String] namespace the name of the namespace
|
33
33
|
# @param [Hash] xpath_options additional xpath options
|
34
34
|
#
|
@@ -126,13 +126,8 @@ module HappyMapper
|
|
126
126
|
|
127
127
|
register_type Integer do |value|
|
128
128
|
value_to_i = value.to_i
|
129
|
-
if value_to_i == 0 && value
|
130
|
-
|
131
|
-
begin
|
132
|
-
Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
|
133
|
-
rescue ArgumentError
|
134
|
-
nil
|
135
|
-
end
|
129
|
+
if value_to_i == 0 && !value.to_s.start_with?('0')
|
130
|
+
nil
|
136
131
|
else
|
137
132
|
value_to_i
|
138
133
|
end
|
data/lib/happymapper/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'after_parse callbacks' do
|
6
|
+
module AfterParseSpec
|
7
|
+
class Address
|
8
|
+
include HappyMapper
|
9
|
+
element :street, String
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
AfterParseSpec::Address.after_parse_callbacks.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'callbacks with the newly created object' do
|
18
|
+
from_cb = nil
|
19
|
+
called = false
|
20
|
+
cb1 = proc { |object| from_cb = object }
|
21
|
+
cb2 = proc { called = true }
|
22
|
+
AfterParseSpec::Address.after_parse(&cb1)
|
23
|
+
AfterParseSpec::Address.after_parse(&cb2)
|
24
|
+
|
25
|
+
object = AfterParseSpec::Address.parse fixture_file('address.xml')
|
26
|
+
expect(from_cb).to eq(object)
|
27
|
+
expect(called).to eq(true)
|
28
|
+
end
|
29
|
+
end
|
@@ -30,15 +30,15 @@ describe 'Attribute Default Value' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'when a new, non-nil value has been set' do
|
33
|
+
let(:expected_xml) { %(<?xml version="1.0"?>\n<meal type="kosher"/>\n) }
|
34
|
+
|
33
35
|
it 'returns the new value' do
|
34
36
|
meal = subject.parse('<meal />')
|
35
37
|
meal.type = 'vegan'
|
36
38
|
|
37
|
-
expect(meal.type).
|
39
|
+
expect(meal.type).not_to eq default_meal_type
|
38
40
|
end
|
39
41
|
|
40
|
-
let(:expected_xml) { %(<?xml version="1.0"?>\n<meal type="kosher"/>\n) }
|
41
|
-
|
42
42
|
it 'saves the new value to the xml' do
|
43
43
|
meal = subject.new
|
44
44
|
meal.type = 'kosher'
|
@@ -3,12 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe 'Attribute Method Conversion' do
|
6
|
-
let(:xml_document) do
|
7
|
-
%(<document>
|
8
|
-
<link data-src='http://cooking.com/roastbeef' type='recipe'>Roast Beef</link>
|
9
|
-
</document>)
|
10
|
-
end
|
11
|
-
|
12
6
|
module AttributeMethodConversion
|
13
7
|
class Document
|
14
8
|
include HappyMapper
|
@@ -17,6 +11,12 @@ describe 'Attribute Method Conversion' do
|
|
17
11
|
end
|
18
12
|
end
|
19
13
|
|
14
|
+
let(:xml_document) do
|
15
|
+
%(<document>
|
16
|
+
<link data-src='http://cooking.com/roastbeef' type='recipe'>Roast Beef</link>
|
17
|
+
</document>)
|
18
|
+
end
|
19
|
+
|
20
20
|
let(:document) do
|
21
21
|
AttributeMethodConversion::Document.parse(xml_document, single: true)
|
22
22
|
end
|
@@ -39,25 +39,29 @@ class CatalogNode
|
|
39
39
|
end
|
40
40
|
|
41
41
|
describe HappyMapper do
|
42
|
-
|
42
|
+
let(:catalog_tree) { CatalogTree.parse(fixture_file('inagy.xml'), single: true) }
|
43
|
+
|
44
|
+
it 'is not nil' do
|
43
45
|
expect(catalog_tree).not_to be_nil
|
44
46
|
end
|
45
47
|
|
46
|
-
it '
|
48
|
+
it 'has the attribute code' do
|
47
49
|
expect(catalog_tree.code).to eq('NLD')
|
48
50
|
end
|
49
51
|
|
50
|
-
it '
|
52
|
+
it 'has many nodes' do
|
51
53
|
expect(catalog_tree.nodes).not_to be_empty
|
52
54
|
expect(catalog_tree.nodes.length).to eq(2)
|
53
55
|
end
|
54
56
|
|
55
57
|
context 'first node' do
|
56
|
-
|
58
|
+
let(:first_node) { catalog_tree.nodes.first }
|
59
|
+
|
60
|
+
it 'has a name' do
|
57
61
|
expect(first_node.name).to eq('Parent 1')
|
58
62
|
end
|
59
63
|
|
60
|
-
it '
|
64
|
+
it 'has translations' do
|
61
65
|
expect(first_node.translations.length).to eq(2)
|
62
66
|
|
63
67
|
expect(first_node.translations.first.language).to eq('en-GB')
|
@@ -65,7 +69,7 @@ describe HappyMapper do
|
|
65
69
|
expect(first_node.translations.last.name).to eq('Parent 1 de')
|
66
70
|
end
|
67
71
|
|
68
|
-
it '
|
72
|
+
it 'has subnodes' do
|
69
73
|
expect(first_node.nodes).to be_kind_of(Enumerable)
|
70
74
|
expect(first_node.nodes).not_to be_empty
|
71
75
|
expect(first_node.nodes.length).to eq(1)
|
@@ -74,18 +78,5 @@ describe HappyMapper do
|
|
74
78
|
it 'first node - first node name' do
|
75
79
|
expect(first_node.nodes.first.name).to eq('First')
|
76
80
|
end
|
77
|
-
|
78
|
-
def first_node
|
79
|
-
@first_node = catalog_tree.nodes.first
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def catalog_tree
|
84
|
-
@catalog_tree
|
85
|
-
end
|
86
|
-
|
87
|
-
before(:all) do
|
88
|
-
xml_reference = "#{File.dirname(__FILE__)}/fixtures/inagy.xml"
|
89
|
-
@catalog_tree = CatalogTree.parse(File.read(xml_reference), single: true)
|
90
81
|
end
|
91
82
|
end
|
@@ -79,7 +79,7 @@ describe 'Using inheritance to share elements and attributes' do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
context 'when parsing xml' do
|
82
|
-
it '
|
82
|
+
it 'is possible to deserialize XML into a Child class instance' do
|
83
83
|
expect(subject.love).to eq 99
|
84
84
|
expect(subject.genetics.dna).to eq 'ABBA'
|
85
85
|
expect(subject.naivety).to eq 'trusting'
|
@@ -3,23 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe 'A document with mixed namespaces' do
|
6
|
-
#
|
7
|
-
# Note that the parent element of the xml has the namespacing. The elements
|
8
|
-
# contained within the xml do not share the parent element namespace so a
|
9
|
-
# user of the library would likely need to clear the namespace on each of
|
10
|
-
# these child elements.
|
11
|
-
#
|
12
|
-
let(:xml_document) do
|
13
|
-
%(<prefix:address location='home' xmlns:prefix="http://www.unicornland.com/prefix"
|
14
|
-
xmlns:different="http://www.trollcountry.com/different">
|
15
|
-
<street>Milchstrasse</street>
|
16
|
-
<street>Another Street</street>
|
17
|
-
<housenumber>23</housenumber>
|
18
|
-
<different:postcode>26131</different:postcode>
|
19
|
-
<city>Oldenburg</city>
|
20
|
-
</prefix:address>)
|
21
|
-
end
|
22
|
-
|
23
6
|
module MixedNamespaces
|
24
7
|
class Address
|
25
8
|
include HappyMapper
|
@@ -38,6 +21,23 @@ describe 'A document with mixed namespaces' do
|
|
38
21
|
end
|
39
22
|
end
|
40
23
|
|
24
|
+
#
|
25
|
+
# Note that the parent element of the xml has the namespacing. The elements
|
26
|
+
# contained within the xml do not share the parent element namespace so a
|
27
|
+
# user of the library would likely need to clear the namespace on each of
|
28
|
+
# these child elements.
|
29
|
+
#
|
30
|
+
let(:xml_document) do
|
31
|
+
%(<prefix:address location='home' xmlns:prefix="http://www.unicornland.com/prefix"
|
32
|
+
xmlns:different="http://www.trollcountry.com/different">
|
33
|
+
<street>Milchstrasse</street>
|
34
|
+
<street>Another Street</street>
|
35
|
+
<housenumber>23</housenumber>
|
36
|
+
<different:postcode>26131</different:postcode>
|
37
|
+
<city>Oldenburg</city>
|
38
|
+
</prefix:address>)
|
39
|
+
end
|
40
|
+
|
41
41
|
let(:address) do
|
42
42
|
MixedNamespaces::Address.parse(xml_document, single: true)
|
43
43
|
end
|
data/spec/{parse_with_object_to_update_spec.rb → features/parse_with_object_to_update_spec.rb}
RENAMED
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'parsing the same tag differently in different contexts' do
|
6
|
+
module SameTagSpec
|
7
|
+
class Bar
|
8
|
+
include HappyMapper
|
9
|
+
has_one :baz, String
|
10
|
+
end
|
11
|
+
|
12
|
+
class Baz
|
13
|
+
include HappyMapper
|
14
|
+
has_one :qux, String
|
15
|
+
end
|
16
|
+
|
17
|
+
class Foo
|
18
|
+
include HappyMapper
|
19
|
+
has_one :bar, Bar
|
20
|
+
has_one :baz, Baz, xpath: '.'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:xml) do
|
25
|
+
<<~XML
|
26
|
+
<foo>
|
27
|
+
<bar>
|
28
|
+
<baz>Hello</baz>
|
29
|
+
</bar>
|
30
|
+
<baz>
|
31
|
+
<qux>Hi</qux>
|
32
|
+
</baz>
|
33
|
+
</foo>
|
34
|
+
XML
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'parses both uses correctly if xpath limits recursion' do
|
38
|
+
result = SameTagSpec::Foo.parse xml
|
39
|
+
aggregate_failures do
|
40
|
+
expect(result.bar.baz).to eq 'Hello'
|
41
|
+
expect(result.baz.qux).to eq 'Hi'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -191,11 +191,11 @@ describe 'Saving #to_xml' do
|
|
191
191
|
expect(subject.xpath('country/@countryCode').text).to eq 'us'
|
192
192
|
end
|
193
193
|
|
194
|
-
it 'saves elements' do
|
194
|
+
it 'saves elements with a specified tag' do
|
195
195
|
expect(subject.xpath('country/countryName').text).to eq 'USA'
|
196
196
|
end
|
197
197
|
|
198
|
-
it 'saves elements' do
|
198
|
+
it 'saves elements with content' do
|
199
199
|
expect(subject.xpath('country/description').text).to eq 'A lovely country'
|
200
200
|
end
|
201
201
|
end
|
File without changes
|
@@ -58,12 +58,12 @@ describe 'Wildcard Root Tag' do
|
|
58
58
|
let(:subject) { GenericBase::Root.parse(generic_class_xml) }
|
59
59
|
let(:xml) { Nokogiri::XML(subject.to_xml) }
|
60
60
|
|
61
|
-
it '
|
61
|
+
it 'maps different elements to same class' do
|
62
62
|
expect(subject.blargs).not_to be_nil
|
63
63
|
expect(subject.jellos).not_to be_nil
|
64
64
|
end
|
65
65
|
|
66
|
-
it '
|
66
|
+
it 'filters on xpath appropriately' do
|
67
67
|
expect(subject.blargs.size).to eq(2)
|
68
68
|
expect(subject.jellos.size).to eq(1)
|
69
69
|
expect(subject.subjellos.size).to eq(1)
|
@@ -73,7 +73,7 @@ describe 'Wildcard Root Tag' do
|
|
73
73
|
GenericBase::Base.new(name: name, href: href, other: other)
|
74
74
|
end
|
75
75
|
|
76
|
-
it '
|
76
|
+
it 'parses correct values onto generic class' do
|
77
77
|
expect(subject.blargs[0]).to eq base_with('blargname1', 'http://blarg.com', nil)
|
78
78
|
expect(subject.blargs[1]).to eq base_with('blargname2', 'http://blarg.com', nil)
|
79
79
|
expect(subject.jellos[0]).to eq base_with('jelloname', 'http://jello.com', nil)
|
@@ -86,14 +86,14 @@ describe 'Wildcard Root Tag' do
|
|
86
86
|
expect(xml.xpath("#{xpath}/@other").text).to eq other
|
87
87
|
end
|
88
88
|
|
89
|
-
it '
|
89
|
+
it '#to_xmls using parent element tag name' do
|
90
90
|
expect(xml.xpath('/root/description').text).to eq('some description')
|
91
91
|
validate_xpath('/root/blarg[1]', 'blargname1', 'http://blarg.com', '')
|
92
92
|
validate_xpath('/root/blarg[2]', 'blargname2', 'http://blarg.com', '')
|
93
93
|
validate_xpath('/root/jello[1]', 'jelloname', 'http://jello.com', '')
|
94
94
|
end
|
95
95
|
|
96
|
-
it "
|
96
|
+
it "properlies respect child HappyMapper tags if tag isn't provided on the element defintion" do
|
97
97
|
expect(xml.xpath('root/subelement').size).to eq(1)
|
98
98
|
end
|
99
99
|
end
|
@@ -35,15 +35,15 @@ describe 'wrap which allows you to specify a wrapper element' do
|
|
35
35
|
expect(subject.subclass.items.size).to eq(2)
|
36
36
|
expect(subject.subclass.items[0]).to eq 'item1'
|
37
37
|
expect(subject.subclass.items[1]).to eq 'item2'
|
38
|
-
expect(subject.number).to eq
|
38
|
+
expect(subject.number).to eq 12_345
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'when initialized without XML' do
|
43
43
|
let(:subject) { Wrap::Root.new }
|
44
44
|
|
45
|
-
it 'anonymous classes
|
46
|
-
expect { subject.description = 'anything' }.
|
45
|
+
it 'creates anonymous classes so nil class values do not occur' do
|
46
|
+
expect { subject.description = 'anything' }.not_to raise_error
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -54,7 +54,7 @@ describe 'wrap which allows you to specify a wrapper element' do
|
|
54
54
|
root.attr1 = 'somevalue'
|
55
55
|
root.name = 'myname'
|
56
56
|
root.description = 'some description'
|
57
|
-
root.number =
|
57
|
+
root.number = 12_345
|
58
58
|
|
59
59
|
subclass = Wrap::SubClass.new
|
60
60
|
subclass.myattr = 'attrvalue'
|
@@ -27,7 +27,7 @@ describe 'Specifying elements and attributes with an xpath' do
|
|
27
27
|
has_one :name, String
|
28
28
|
end
|
29
29
|
|
30
|
-
let(:
|
30
|
+
let(:parsed_result) { Item.parse(xml_string, single: true) }
|
31
31
|
|
32
32
|
let(:xml_string) do
|
33
33
|
%(
|
@@ -50,41 +50,35 @@ describe 'Specifying elements and attributes with an xpath' do
|
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
53
|
-
it '
|
54
|
-
expect(
|
53
|
+
it 'has a title' do
|
54
|
+
expect(parsed_result.title).to eq 'Test XML'
|
55
55
|
end
|
56
56
|
|
57
|
-
it '
|
58
|
-
expect(
|
57
|
+
it 'finds the link href value' do
|
58
|
+
expect(parsed_result.link).to eq 'link_to_resources'
|
59
59
|
end
|
60
60
|
|
61
|
-
it '
|
62
|
-
expect(
|
61
|
+
it 'finds the other link href value' do
|
62
|
+
expect(parsed_result.different_link).to eq 'different_link'
|
63
63
|
end
|
64
64
|
|
65
|
-
it '
|
66
|
-
expect(
|
65
|
+
it 'finds this subitem based on the xpath' do
|
66
|
+
expect(parsed_result.detail).to eq 'I want to parse this'
|
67
67
|
end
|
68
68
|
|
69
|
-
it '
|
70
|
-
expect(
|
71
|
-
expect(subject.more_details_text.first).to eq 'more 1'
|
72
|
-
expect(subject.more_details_text.last).to eq 'more 2'
|
69
|
+
it 'finds the subitem texts based on the xpath' do
|
70
|
+
expect(parsed_result.more_details_text).to eq ['more 1', 'more 2']
|
73
71
|
end
|
74
72
|
|
75
|
-
it '
|
76
|
-
expect(
|
77
|
-
expect(subject.more_details.first).to eq 'this one'
|
78
|
-
expect(subject.more_details.last).to eq 'another one'
|
73
|
+
it 'finds the subitem attributes based on the xpath' do
|
74
|
+
expect(parsed_result.more_details).to eq ['this one', 'another one']
|
79
75
|
end
|
80
76
|
|
81
|
-
it '
|
82
|
-
expect(
|
83
|
-
expect(subject.more_details_alternative.first).to eq 'this one'
|
84
|
-
expect(subject.more_details_alternative.last).to eq 'another one'
|
77
|
+
it 'finds the subitem attributes based on the xpath with a wildcard' do
|
78
|
+
expect(parsed_result.more_details_alternative).to eq ['this one', 'another one']
|
85
79
|
end
|
86
80
|
|
87
|
-
it '
|
88
|
-
expect(
|
81
|
+
it 'has a baby name' do
|
82
|
+
expect(parsed_result.baby.name).to eq 'Jumbo'
|
89
83
|
end
|
90
84
|
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe HappyMapper::AnonymousMapper do
|
6
|
+
let(:anonymous_mapper) { described_class.new }
|
7
|
+
|
8
|
+
describe '#parse' do
|
9
|
+
context 'when parsing a single root node' do
|
10
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('address.xml') }
|
11
|
+
|
12
|
+
it 'creates the correct set of child elements on the element class' do
|
13
|
+
elements = parsed_result.class.elements
|
14
|
+
expect(elements.map(&:tag)).to eq %w(street housenumber postcode city country state)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'parses child elements' do
|
18
|
+
aggregate_failures do
|
19
|
+
expect(parsed_result.street).to eq('Milchstrasse')
|
20
|
+
expect(parsed_result.housenumber).to eq('23')
|
21
|
+
expect(parsed_result.postcode).to eq('26131')
|
22
|
+
expect(parsed_result.city).to eq('Oldenburg')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not create a content entry when the xml contents no text content' do
|
27
|
+
expect(parsed_result).not_to respond_to :content
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'parses both the attributes and content when present' do
|
31
|
+
aggregate_failures do
|
32
|
+
expect(parsed_result.country.code).to eq('de')
|
33
|
+
expect(parsed_result.country.content).to eq('Germany')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with element names with special characters' do
|
39
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('ambigous_items.xml') }
|
40
|
+
|
41
|
+
it 'creates accessor methods with similar names' do
|
42
|
+
expect(parsed_result.my_items.item).to be_kind_of Array
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with element names with camelCased elements and Capital Letters' do
|
47
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('subclass_namespace.xml') }
|
48
|
+
|
49
|
+
it 'parses camel-cased child elements correctly' do
|
50
|
+
aggregate_failures do
|
51
|
+
expect(parsed_result.photo.publish_options.author).to eq('Stephanie')
|
52
|
+
expect(parsed_result.gallery.photo.title).to eq('photo title')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'parses camel-cased child properties correctly' do
|
57
|
+
expect(parsed_result.publish_options.created_day).to eq('2011-01-14')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with repeated elements with camel-cased names' do
|
62
|
+
let(:xml) do
|
63
|
+
<<~XML
|
64
|
+
<foo>
|
65
|
+
<fooBar>
|
66
|
+
<baz>Hello</baz>
|
67
|
+
</fooBar>
|
68
|
+
<fooBar>
|
69
|
+
<baz>Hi</baz>
|
70
|
+
</fooBar>
|
71
|
+
</foo>
|
72
|
+
XML
|
73
|
+
end
|
74
|
+
let(:parsed_result) { anonymous_mapper.parse xml }
|
75
|
+
|
76
|
+
it 'parses the repeated elements correctly' do
|
77
|
+
expect(parsed_result.foo_bar.map(&:baz)).to eq %w(Hello Hi)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with elements with camelCased attribute names' do
|
82
|
+
let(:parsed_result) { anonymous_mapper.parse '<foo barBaz="quuz"/>' }
|
83
|
+
|
84
|
+
it 'parses attributes correctly' do
|
85
|
+
expect(parsed_result.bar_baz).to eq('quuz')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with several elements nested deeply' do
|
90
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('ambigous_items.xml') }
|
91
|
+
|
92
|
+
it 'parses the entire relationship' do
|
93
|
+
expect(parsed_result.my_items.item.first.item.name).to eq('My first internal item')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when parsing an that contains multiple elements with the same tag' do
|
98
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('multiple_primitives.xml') }
|
99
|
+
|
100
|
+
it "parses the elements as it would a 'has_many'" do
|
101
|
+
aggregate_failures do
|
102
|
+
expect(parsed_result.name).to eq('value')
|
103
|
+
expect(parsed_result.image).to eq(%w(image1 image2))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when parsing xml with multiple namespaces' do
|
109
|
+
let(:parsed_result) { anonymous_mapper.parse fixture_file('subclass_namespace.xml') }
|
110
|
+
|
111
|
+
it 'parses the elements an values correctly' do
|
112
|
+
expect(parsed_result.title).to eq('article title')
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'parses attribute names correctly' do
|
116
|
+
expect(parsed_result.name).to eq 'title'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when parsing an element with a nested value element with a different namespace' do
|
121
|
+
let(:xml) do
|
122
|
+
<<~XML
|
123
|
+
<a:foo xmlns:a="http://foo.org/a" xmlns:b="http://foo.org/b">
|
124
|
+
<b:bar>Hello</b:bar>
|
125
|
+
</a:foo>
|
126
|
+
XML
|
127
|
+
end
|
128
|
+
let(:result) { anonymous_mapper.parse xml }
|
129
|
+
|
130
|
+
it 'parses the value elements correctly' do
|
131
|
+
expect(result.bar).to eq 'Hello'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when parsing xml that uses the same tag for string and other elements' do
|
136
|
+
let(:xml) do
|
137
|
+
<<~XML
|
138
|
+
<foo>
|
139
|
+
<bar>
|
140
|
+
<baz>Hello</baz>
|
141
|
+
</bar>
|
142
|
+
<baz>
|
143
|
+
<qux>Hi</qux>
|
144
|
+
</baz>
|
145
|
+
</foo>
|
146
|
+
XML
|
147
|
+
end
|
148
|
+
let(:result) { anonymous_mapper.parse xml }
|
149
|
+
|
150
|
+
it 'parses both occurences of the tag correctly' do
|
151
|
+
aggregate_failures do
|
152
|
+
expect(result.bar.baz).to eq 'Hello'
|
153
|
+
expect(result.baz.qux).to eq 'Hi'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|