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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -5
  3. data/README.md +85 -69
  4. data/lib/happymapper.rb +27 -22
  5. data/lib/happymapper/anonymous_mapper.rb +35 -30
  6. data/lib/happymapper/item.rb +1 -1
  7. data/lib/happymapper/supported_types.rb +2 -7
  8. data/lib/happymapper/version.rb +1 -1
  9. data/spec/features/after_parse_callbacks_spec.rb +29 -0
  10. data/spec/{attribute_default_value_spec.rb → features/attribute_default_value_spec.rb} +3 -3
  11. data/spec/{attributes_spec.rb → features/attributes_spec.rb} +6 -6
  12. data/spec/{has_many_empty_array_spec.rb → features/has_many_empty_array_spec.rb} +1 -1
  13. data/spec/{ignay_spec.rb → features/ignay_spec.rb} +10 -19
  14. data/spec/{inheritance_spec.rb → features/inheritance_spec.rb} +1 -1
  15. data/spec/{mixed_namespaces_spec.rb → features/mixed_namespaces_spec.rb} +17 -17
  16. data/spec/{parse_with_object_to_update_spec.rb → features/parse_with_object_to_update_spec.rb} +0 -0
  17. data/spec/features/same_tag_different_meaning_spec.rb +44 -0
  18. data/spec/{to_xml_spec.rb → features/to_xml_spec.rb} +2 -2
  19. data/spec/{to_xml_with_namespaces_spec.rb → features/to_xml_with_namespaces_spec.rb} +0 -0
  20. data/spec/{wilcard_tag_name_spec.rb → features/wildcard_tag_name_spec.rb} +5 -5
  21. data/spec/{wrap_spec.rb → features/wrap_spec.rb} +4 -4
  22. data/spec/{xpath_spec.rb → features/xpath_spec.rb} +17 -23
  23. data/spec/happymapper/anonymous_mapper_spec.rb +158 -0
  24. data/spec/happymapper/element_spec.rb +1 -1
  25. data/spec/happymapper/item_spec.rb +75 -45
  26. data/spec/happymapper_spec.rb +120 -125
  27. metadata +32 -28
  28. data/spec/happymapper_parse_spec.rb +0 -131
@@ -28,7 +28,7 @@ module HappyMapper
28
28
  end
29
29
 
30
30
  #
31
- # @param [XMLNode] node the xml node that is being parsed
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 != '0'
130
- value_to_s = value.to_s
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HappyMapper
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -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).to_not eq default_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
@@ -38,7 +38,7 @@ describe 'emptyness' do
38
38
  expect(navigator.items_with_a_different_name).to be_empty
39
39
  end
40
40
 
41
- it 'returns an empty array' do
41
+ it 'looks for items based on the element tag, not the element name' do
42
42
  expect(navigator.items).to be_empty
43
43
  end
44
44
  end
@@ -39,25 +39,29 @@ class CatalogNode
39
39
  end
40
40
 
41
41
  describe HappyMapper do
42
- it 'should not be nil' do
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 'should have the attribute code' do
48
+ it 'has the attribute code' do
47
49
  expect(catalog_tree.code).to eq('NLD')
48
50
  end
49
51
 
50
- it 'should have many nodes' do
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
- it 'should have a name' do
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 'should have translations' do
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 'should have subnodes' do
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 'should be possible to deserialize XML into a Child class instance' do
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
@@ -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
@@ -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 'should map different elements to same class' do
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 'should filter on xpath appropriately' do
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 'should parse correct values onto generic class' do
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 'should #to_xml using parent element tag name' do
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 "should properly respect child HappyMapper tags if tag isn't provided on the element defintion" do
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 12345
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 are created so nil class values does not occur' do
46
- expect { subject.description = 'anything' }.to_not raise_error
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 = 12345
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(:subject) { Item.parse(xml_string, single: true) }
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 'should have a title' do
54
- expect(subject.title).to eq 'Test XML'
53
+ it 'has a title' do
54
+ expect(parsed_result.title).to eq 'Test XML'
55
55
  end
56
56
 
57
- it 'should find the link href value' do
58
- expect(subject.link).to eq 'link_to_resources'
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 'should find the link href value' do
62
- expect(subject.different_link).to eq 'different_link'
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 'should find this subitem based on the xpath' do
66
- expect(subject.detail).to eq 'I want to parse this'
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 'should find the subitems based on the xpath' do
70
- expect(subject.more_details_text.size).to eq(2)
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 'should find the subitems based on the xpath' do
76
- expect(subject.more_details.size).to eq(2)
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 'should find the subitems based on the xpath' do
82
- expect(subject.more_details_alternative.size).to eq(2)
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 'should have a baby name' do
88
- expect(subject.baby.name).to eq 'Jumbo'
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