nokogiri-happymapper 0.8.0 → 0.8.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +4 -0
- data/lib/happymapper.rb +2 -0
- data/lib/happymapper/element.rb +2 -0
- data/lib/happymapper/supported_types.rb +2 -4
- data/lib/happymapper/version.rb +1 -1
- data/lib/nokogiri-happymapper.rb +4 -0
- data/spec/features/after_parse_callbacks_spec.rb +6 -3
- data/spec/features/attribute_default_value_spec.rb +5 -6
- data/spec/features/attributes_spec.rb +1 -1
- data/spec/features/has_many_empty_array_spec.rb +1 -1
- data/spec/features/ignay_spec.rb +21 -11
- data/spec/features/inheritance_spec.rb +27 -19
- data/spec/features/mixed_namespaces_spec.rb +1 -1
- data/spec/features/parse_with_object_to_update_spec.rb +19 -13
- data/spec/features/same_tag_different_meaning_spec.rb +1 -1
- data/spec/features/to_xml_spec.rb +21 -18
- data/spec/features/to_xml_with_namespaces_spec.rb +19 -16
- data/spec/features/wildcard_tag_name_spec.rb +26 -16
- data/spec/features/wrap_spec.rb +27 -22
- data/spec/features/xpath_spec.rb +1 -1
- data/spec/happymapper/item_spec.rb +5 -2
- data/spec/happymapper_spec.rb +257 -180
- data/spec/spec_helper.rb +1 -1
- metadata +4 -8
- data/spec/happymapper/element_spec.rb +0 -11
- data/spec/happymapper/text_node_spec.rb +0 -11
@@ -108,9 +108,9 @@ module ToXMLWithNamespaces
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
describe 'Saving #to_xml
|
112
|
-
context '
|
113
|
-
let(:
|
111
|
+
RSpec.describe 'Saving #to_xml with xml namespaces', type: :feature do
|
112
|
+
context 'with namespaces' do
|
113
|
+
let(:xml) do
|
114
114
|
country = ToXMLWithNamespaces::Country.new(name: 'USA', code: 'us')
|
115
115
|
address = ToXMLWithNamespaces::Address.new('street' => 'Mockingbird Lane',
|
116
116
|
'location' => 'Home',
|
@@ -126,37 +126,37 @@ describe 'Saving #to_xml', 'with xml namespaces' do
|
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'sets the namespace specified in the class' do
|
129
|
-
expect(
|
129
|
+
expect(xml.xpath('/').children.first.namespace.prefix).to eq 'address'
|
130
130
|
end
|
131
131
|
|
132
132
|
it 'saves elements' do
|
133
133
|
elements = { 'street' => 'Mockingbird Lane', 'postcode' => '98103', 'city' => 'Seattle' }
|
134
134
|
|
135
135
|
elements.each_pair do |property, value|
|
136
|
-
expect(
|
136
|
+
expect(xml.xpath("address:#{property}").text).to eq value
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
140
|
it 'saves attributes' do
|
141
|
-
expect(
|
141
|
+
expect(xml.xpath('@location').text).to eq 'Home-live'
|
142
142
|
end
|
143
143
|
|
144
144
|
context "when an element has a 'state_when_nil' parameter" do
|
145
145
|
it 'saves an empty element' do
|
146
|
-
expect(
|
146
|
+
expect(xml.xpath('address:description').text).to eq ''
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
150
|
context "when an element has a 'on_save' parameter" do
|
151
151
|
context 'with a symbol which represents a function' do
|
152
152
|
it 'saves the element with the result of a function call and not the value of the ivar' do
|
153
|
-
expect(
|
153
|
+
expect(xml.xpath('address:housenumber').text).to eq '[1313]'
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
157
157
|
context 'with a lambda' do
|
158
158
|
it 'saves the results' do
|
159
|
-
expect(
|
159
|
+
expect(xml.xpath('address:date_created').text).to eq '15:00:00 01/01/11'
|
160
160
|
end
|
161
161
|
end
|
162
162
|
end
|
@@ -164,7 +164,7 @@ describe 'Saving #to_xml', 'with xml namespaces' do
|
|
164
164
|
context "when an attribute has a 'on_save' parameter" do
|
165
165
|
context 'with a lambda' do
|
166
166
|
it 'saves the result' do
|
167
|
-
expect(
|
167
|
+
expect(xml.xpath('@location').text).to eq 'Home-live'
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|
@@ -172,21 +172,24 @@ describe 'Saving #to_xml', 'with xml namespaces' do
|
|
172
172
|
context "when a has_many has a 'on_save' parameter" do
|
173
173
|
context 'with a lambda' do
|
174
174
|
it 'saves the result' do
|
175
|
-
dates_updated =
|
176
|
-
|
177
|
-
|
178
|
-
|
175
|
+
dates_updated = xml.xpath('address:dates_updated')
|
176
|
+
|
177
|
+
aggregate_failures do
|
178
|
+
expect(dates_updated.length).to eq 2
|
179
|
+
expect(dates_updated.first.text).to eq '16:01:00 01/01/11'
|
180
|
+
expect(dates_updated.last.text).to eq '11:30:01 01/02/11'
|
181
|
+
end
|
179
182
|
end
|
180
183
|
end
|
181
184
|
end
|
182
185
|
|
183
186
|
context 'when an element type is a HappyMapper subclass' do
|
184
187
|
it 'saves attributes' do
|
185
|
-
expect(
|
188
|
+
expect(xml.xpath('country:country/@countryCode').text).to eq 'us'
|
186
189
|
end
|
187
190
|
|
188
191
|
it 'saves elements' do
|
189
|
-
expect(
|
192
|
+
expect(xml.xpath('country:country/countryName:countryName').text).to eq 'USA'
|
190
193
|
end
|
191
194
|
end
|
192
195
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe 'Wildcard Root Tag' do
|
5
|
+
RSpec.describe 'Wildcard Root Tag', type: :feature do
|
6
6
|
generic_class_xml = %(
|
7
7
|
<root>
|
8
8
|
<description>some description</description>
|
@@ -33,8 +33,10 @@ describe 'Wildcard Root Tag' do
|
|
33
33
|
def <=>(other)
|
34
34
|
result = name <=> other.name
|
35
35
|
return result unless result == 0
|
36
|
+
|
36
37
|
result = href <=> other.href
|
37
38
|
return result unless result == 0
|
39
|
+
|
38
40
|
self.other <=> other.other
|
39
41
|
end
|
40
42
|
end
|
@@ -55,18 +57,22 @@ describe 'Wildcard Root Tag' do
|
|
55
57
|
end
|
56
58
|
|
57
59
|
describe "can have generic classes using tag '*'" do
|
58
|
-
let(:
|
59
|
-
let(:xml) { Nokogiri::XML(
|
60
|
+
let(:root) { GenericBase::Root.parse(generic_class_xml) }
|
61
|
+
let(:xml) { Nokogiri::XML(root.to_xml) }
|
60
62
|
|
61
63
|
it 'maps different elements to same class' do
|
62
|
-
|
63
|
-
|
64
|
+
aggregate_failures do
|
65
|
+
expect(root.blargs).not_to be_nil
|
66
|
+
expect(root.jellos).not_to be_nil
|
67
|
+
end
|
64
68
|
end
|
65
69
|
|
66
70
|
it 'filters on xpath appropriately' do
|
67
|
-
|
68
|
-
|
69
|
-
|
71
|
+
aggregate_failures do
|
72
|
+
expect(root.blargs.size).to eq(2)
|
73
|
+
expect(root.jellos.size).to eq(1)
|
74
|
+
expect(root.subjellos.size).to eq(1)
|
75
|
+
end
|
70
76
|
end
|
71
77
|
|
72
78
|
def base_with(name, href, other)
|
@@ -74,10 +80,12 @@ describe 'Wildcard Root Tag' do
|
|
74
80
|
end
|
75
81
|
|
76
82
|
it 'parses correct values onto generic class' do
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
83
|
+
aggregate_failures do
|
84
|
+
expect(root.blargs[0]).to eq base_with('blargname1', 'http://blarg.com', nil)
|
85
|
+
expect(root.blargs[1]).to eq base_with('blargname2', 'http://blarg.com', nil)
|
86
|
+
expect(root.jellos[0]).to eq base_with('jelloname', 'http://jello.com', nil)
|
87
|
+
expect(root.subjellos[0]).to eq base_with('subjelloname', 'http://ohnojello.com', 'othertext')
|
88
|
+
end
|
81
89
|
end
|
82
90
|
|
83
91
|
def validate_xpath(xpath, name, href, other)
|
@@ -87,10 +95,12 @@ describe 'Wildcard Root Tag' do
|
|
87
95
|
end
|
88
96
|
|
89
97
|
it '#to_xmls using parent element tag name' do
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
98
|
+
aggregate_failures do
|
99
|
+
expect(xml.xpath('/root/description').text).to eq('some description')
|
100
|
+
validate_xpath('/root/blarg[1]', 'blargname1', 'http://blarg.com', '')
|
101
|
+
validate_xpath('/root/blarg[2]', 'blargname2', 'http://blarg.com', '')
|
102
|
+
validate_xpath('/root/jello[1]', 'jelloname', 'http://jello.com', '')
|
103
|
+
end
|
94
104
|
end
|
95
105
|
|
96
106
|
it "properlies respect child HappyMapper tags if tag isn't provided on the element defintion" do
|
data/spec/features/wrap_spec.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe 'wrap which allows you to specify a wrapper element' do
|
5
|
+
RSpec.describe 'wrap which allows you to specify a wrapper element', type: :feature do
|
6
6
|
module Wrap
|
7
7
|
class SubClass
|
8
8
|
include HappyMapper
|
@@ -25,31 +25,33 @@ describe 'wrap which allows you to specify a wrapper element' do
|
|
25
25
|
|
26
26
|
describe '.parse' do
|
27
27
|
context 'when given valid XML' do
|
28
|
-
let(:
|
28
|
+
let(:root) { Wrap::Root.parse fixture_file('wrapper.xml') }
|
29
29
|
|
30
30
|
it 'sets the values correctly' do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
aggregate_failures do
|
32
|
+
expect(root.attr1).to eq 'somevalue'
|
33
|
+
expect(root.name).to eq 'myname'
|
34
|
+
expect(root.description).to eq 'some description'
|
35
|
+
expect(root.subclass.myattr).to eq 'attrvalue'
|
36
|
+
expect(root.subclass.items.size).to eq(2)
|
37
|
+
expect(root.subclass.items[0]).to eq 'item1'
|
38
|
+
expect(root.subclass.items[1]).to eq 'item2'
|
39
|
+
expect(root.number).to eq 12_345
|
40
|
+
end
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
44
|
context 'when initialized without XML' do
|
43
|
-
let(:
|
45
|
+
let(:root) { Wrap::Root.new }
|
44
46
|
|
45
47
|
it 'creates anonymous classes so nil class values do not occur' do
|
46
|
-
expect {
|
48
|
+
expect { root.description = 'anything' }.not_to raise_error
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
53
|
describe '.to_xml' do
|
52
|
-
let(:
|
54
|
+
let(:root) do
|
53
55
|
root = Wrap::Root.new
|
54
56
|
root.attr1 = 'somevalue'
|
55
57
|
root.name = 'myname'
|
@@ -68,15 +70,18 @@ describe 'wrap which allows you to specify a wrapper element' do
|
|
68
70
|
end
|
69
71
|
|
70
72
|
it 'generates the correct xml' do
|
71
|
-
xml = Nokogiri::XML(
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
xml = Nokogiri::XML(root.to_xml)
|
74
|
+
|
75
|
+
aggregate_failures do
|
76
|
+
expect(xml.xpath('/root/@attr1').text).to eq 'somevalue'
|
77
|
+
expect(xml.xpath('/root/name').text).to eq 'myname'
|
78
|
+
expect(xml.xpath('/root/mywraptag/description').text).to eq 'some description'
|
79
|
+
expect(xml.xpath('/root/mywraptag/subclass/@myattr').text).to eq 'attrvalue'
|
80
|
+
expect(xml.xpath('/root/mywraptag/subclass/item').size).to eq(2)
|
81
|
+
expect(xml.xpath('/root/mywraptag/subclass/item[1]').text).to eq 'item1'
|
82
|
+
expect(xml.xpath('/root/mywraptag/subclass/item[2]').text).to eq 'item2'
|
83
|
+
expect(xml.xpath('/root/number').text).to eq '12345'
|
84
|
+
end
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
data/spec/features/xpath_spec.rb
CHANGED
@@ -153,8 +153,11 @@ describe HappyMapper::Item do
|
|
153
153
|
|
154
154
|
it 'works with a historical date in a string' do
|
155
155
|
result = item.typecast('1616-04-23')
|
156
|
-
|
157
|
-
|
156
|
+
|
157
|
+
aggregate_failures do
|
158
|
+
expect(result.to_time).to eq Time.new(1616, 4, 23, 0, 0, 0, '+00:00')
|
159
|
+
expect(result).to be_gregorian
|
160
|
+
end
|
158
161
|
end
|
159
162
|
|
160
163
|
it 'handles nil' do
|
data/spec/happymapper_spec.rb
CHANGED
@@ -606,17 +606,23 @@ describe HappyMapper do
|
|
606
606
|
it 'allows has one association' do
|
607
607
|
klass.has_one(:user, User)
|
608
608
|
element = klass.elements.first
|
609
|
-
|
610
|
-
|
611
|
-
|
609
|
+
|
610
|
+
aggregate_failures do
|
611
|
+
expect(element.name).to eq('user')
|
612
|
+
expect(element.type).to eq(User)
|
613
|
+
expect(element.options[:single]).to eq(true)
|
614
|
+
end
|
612
615
|
end
|
613
616
|
|
614
617
|
it 'allows has many association' do
|
615
618
|
klass.has_many(:users, User)
|
616
619
|
element = klass.elements.first
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
+
|
621
|
+
aggregate_failures do
|
622
|
+
expect(element.name).to eq('users')
|
623
|
+
expect(element.type).to eq(User)
|
624
|
+
expect(element.options[:single]).to eq(false)
|
625
|
+
end
|
620
626
|
end
|
621
627
|
|
622
628
|
it 'defaults tag name to lowercase class' do
|
@@ -649,16 +655,20 @@ describe HappyMapper do
|
|
649
655
|
end
|
650
656
|
|
651
657
|
describe '#attributes' do
|
652
|
-
it '
|
653
|
-
|
654
|
-
|
658
|
+
it 'returns only attributes for the current class' do
|
659
|
+
aggregate_failures do
|
660
|
+
expect(Post.attributes.size).to eq(7)
|
661
|
+
expect(Status.attributes.size).to eq(0)
|
662
|
+
end
|
655
663
|
end
|
656
664
|
end
|
657
665
|
|
658
666
|
describe '#elements' do
|
659
|
-
it '
|
660
|
-
|
661
|
-
|
667
|
+
it 'returns only elements for the current class' do
|
668
|
+
aggregate_failures do
|
669
|
+
expect(Post.elements.size).to eq(0)
|
670
|
+
expect(Status.elements.size).to eq(10)
|
671
|
+
end
|
662
672
|
end
|
663
673
|
end
|
664
674
|
|
@@ -666,73 +676,93 @@ describe HappyMapper do
|
|
666
676
|
it 'takes String as default argument for type' do
|
667
677
|
State.content :name
|
668
678
|
address = Address.parse(fixture_file('address.xml'))
|
669
|
-
|
670
|
-
|
679
|
+
name = address.state.name
|
680
|
+
|
681
|
+
aggregate_failures do
|
682
|
+
expect(name).to eq 'Lower Saxony'
|
683
|
+
expect(name).to be_a String
|
684
|
+
end
|
671
685
|
end
|
672
686
|
|
673
687
|
it 'works when specific type is provided' do
|
674
688
|
Rate.content :value, Float
|
675
689
|
Product.has_one :rate, Rate
|
676
690
|
product = Product.parse(fixture_file('product_default_namespace.xml'), single: true)
|
677
|
-
|
678
|
-
|
691
|
+
value = product.rate.value
|
692
|
+
|
693
|
+
aggregate_failures do
|
694
|
+
expect(value).to eq(120.25)
|
695
|
+
expect(value).to be_a Float
|
696
|
+
end
|
679
697
|
end
|
680
698
|
end
|
681
699
|
|
682
700
|
it 'parses xml attributes into ruby objects' do
|
683
701
|
posts = Post.parse(fixture_file('posts.xml'))
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
to eq(
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
702
|
+
|
703
|
+
aggregate_failures do
|
704
|
+
expect(posts.size).to eq(20)
|
705
|
+
first = posts.first
|
706
|
+
expect(first.href).to eq('http://roxml.rubyforge.org/')
|
707
|
+
expect(first.hash).to eq('19bba2ab667be03a19f67fb67dc56917')
|
708
|
+
expect(first.description).to eq('ROXML - Ruby Object to XML Mapping Library')
|
709
|
+
expect(first.tag).to eq('ruby xml gems mapping')
|
710
|
+
expect(first.time).to eq(Time.utc(2008, 8, 9, 5, 24, 20))
|
711
|
+
expect(first.others).to eq(56)
|
712
|
+
expect(first.extended).
|
713
|
+
to eq('ROXML is a Ruby library designed to make it easier for Ruby' \
|
714
|
+
' developers to work with XML. Using simple annotations, it enables' \
|
715
|
+
' Ruby classes to be custom-mapped to XML. ROXML takes care of the' \
|
716
|
+
' marshalling and unmarshalling of mapped attributes so that developers can' \
|
717
|
+
' focus on building first-class Ruby classes.')
|
718
|
+
end
|
698
719
|
end
|
699
720
|
|
700
721
|
it 'parses xml elements to ruby objcts' do
|
701
722
|
statuses = Status.parse(fixture_file('statuses.xml'))
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
to eq('
|
718
|
-
|
719
|
-
|
720
|
-
|
723
|
+
|
724
|
+
aggregate_failures do
|
725
|
+
expect(statuses.size).to eq(20)
|
726
|
+
first = statuses.first
|
727
|
+
expect(first.id).to eq(882_281_424)
|
728
|
+
expect(first.created_at).to eq(Time.utc(2008, 8, 9, 5, 38, 12))
|
729
|
+
expect(first.source).to eq('web')
|
730
|
+
expect(first.truncated).to be_falsey
|
731
|
+
expect(first.in_reply_to_status_id).to eq(1234)
|
732
|
+
expect(first.in_reply_to_user_id).to eq(12_345)
|
733
|
+
expect(first.favorited).to be_falsey
|
734
|
+
expect(first.user.id).to eq(4243)
|
735
|
+
expect(first.user.name).to eq('John Nunemaker')
|
736
|
+
expect(first.user.screen_name).to eq('jnunemaker')
|
737
|
+
expect(first.user.location).to eq('Mishawaka, IN, US')
|
738
|
+
expect(first.user.description).to eq('Loves his wife, ruby, notre dame football and iu basketball')
|
739
|
+
expect(first.user.profile_image_url).
|
740
|
+
to eq('http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg')
|
741
|
+
expect(first.user.url).to eq('http://addictedtonew.com')
|
742
|
+
expect(first.user.protected).to be_falsey
|
743
|
+
expect(first.user.followers_count).to eq(486)
|
744
|
+
end
|
721
745
|
end
|
722
746
|
|
723
747
|
it 'parses xml containing the desired element as root node' do
|
724
748
|
address = Address.parse(fixture_file('address.xml'), single: true)
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
749
|
+
|
750
|
+
aggregate_failures do
|
751
|
+
expect(address.street).to eq('Milchstrasse')
|
752
|
+
expect(address.postcode).to eq('26131')
|
753
|
+
expect(address.housenumber).to eq('23')
|
754
|
+
expect(address.city).to eq('Oldenburg')
|
755
|
+
expect(address.country.class).to eq(Country)
|
756
|
+
end
|
730
757
|
end
|
731
758
|
|
732
759
|
it 'parses text node correctly' do
|
733
760
|
address = Address.parse(fixture_file('address.xml'), single: true)
|
734
|
-
|
735
|
-
|
761
|
+
|
762
|
+
aggregate_failures do
|
763
|
+
expect(address.country.name).to eq('Germany')
|
764
|
+
expect(address.country.code).to eq('de')
|
765
|
+
end
|
736
766
|
end
|
737
767
|
|
738
768
|
it 'treats Nokogiri::XML::Document as root' do
|
@@ -744,33 +774,46 @@ describe HappyMapper do
|
|
744
774
|
it 'parses xml with default namespace (amazon)' do
|
745
775
|
file_contents = fixture_file('pita.xml')
|
746
776
|
items = PITA::Items.parse(file_contents, single: true)
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
777
|
+
|
778
|
+
aggregate_failures do
|
779
|
+
expect(items.total_results).to eq(22)
|
780
|
+
expect(items.total_pages).to eq(3)
|
781
|
+
|
782
|
+
first = items.items[0]
|
783
|
+
|
784
|
+
expect(first.asin).to eq('0321480791')
|
785
|
+
expect(first.point).to eq('38.5351715088 -121.7948684692')
|
786
|
+
expect(first.detail_page_url).to be_a_kind_of(URI)
|
787
|
+
expect(first.detail_page_url.to_s).to eq('http://www.amazon.com/gp/redirect.html%3FASIN=0321480791%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/0321480791%253FSubscriptionId=dontbeaswoosh')
|
788
|
+
expect(first.manufacturer).to eq('Addison-Wesley Professional')
|
789
|
+
expect(first.product_group).to eq('<ProductGroup>Book</ProductGroup>')
|
790
|
+
|
791
|
+
second = items.items[1]
|
792
|
+
|
793
|
+
expect(second.asin).to eq('047022388X')
|
794
|
+
expect(second.manufacturer).to eq('Wrox')
|
795
|
+
end
|
759
796
|
end
|
760
797
|
|
761
798
|
it 'parses xml that has attributes of elements' do
|
762
799
|
items = CurrentWeather.parse(fixture_file('current_weather.xml'))
|
763
800
|
first = items[0]
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
801
|
+
|
802
|
+
aggregate_failures do
|
803
|
+
expect(first.temperature).to eq(51)
|
804
|
+
expect(first.feels_like).to eq(51)
|
805
|
+
expect(first.current_condition).to eq('Sunny')
|
806
|
+
expect(first.current_condition.icon).to eq('http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif')
|
807
|
+
end
|
768
808
|
end
|
769
809
|
|
770
810
|
it "parses xml with attributes of elements that aren't :single => true" do
|
771
811
|
feed = Atom::Feed.parse(fixture_file('atom.xml'))
|
772
|
-
|
773
|
-
|
812
|
+
|
813
|
+
aggregate_failures do
|
814
|
+
expect(feed.link.first.href).to eq('http://www.example.com')
|
815
|
+
expect(feed.link.last.href).to eq('http://www.example.com/tv_shows.atom')
|
816
|
+
end
|
774
817
|
end
|
775
818
|
|
776
819
|
it 'parses xml with optional elements with embedded attributes' do
|
@@ -790,123 +833,149 @@ describe HappyMapper do
|
|
790
833
|
|
791
834
|
it 'parses xml with nested elements' do
|
792
835
|
radars = Radar.parse(fixture_file('radar.xml'))
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
836
|
+
|
837
|
+
aggregate_failures do
|
838
|
+
first = radars[0]
|
839
|
+
expect(first.places.size).to eq(1)
|
840
|
+
expect(first.places[0].name).to eq('Store')
|
841
|
+
second = radars[1]
|
842
|
+
expect(second.places.size).to eq(0)
|
843
|
+
third = radars[2]
|
844
|
+
expect(third.places.size).to eq(2)
|
845
|
+
expect(third.places[0].name).to eq('Work')
|
846
|
+
expect(third.places[1].name).to eq('Home')
|
847
|
+
end
|
802
848
|
end
|
803
849
|
|
804
850
|
it 'parses xml with element name different to class name' do
|
805
851
|
game = QuarterTest::Game.parse(fixture_file('quarters.xml'))
|
806
|
-
|
807
|
-
|
852
|
+
|
853
|
+
aggregate_failures do
|
854
|
+
expect(game.q1.start).to eq('4:40:15 PM')
|
855
|
+
expect(game.q2.start).to eq('5:18:53 PM')
|
856
|
+
end
|
808
857
|
end
|
809
858
|
|
810
859
|
it 'parses xml that has elements with dashes' do
|
811
860
|
commit = GitHub::Commit.parse(fixture_file('commit.xml'))
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
861
|
+
|
862
|
+
aggregate_failures do
|
863
|
+
expect(commit.message).to eq('move commands.rb and helpers.rb into commands/ dir')
|
864
|
+
expect(commit.url).to eq('http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b')
|
865
|
+
expect(commit.id).to eq('c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b')
|
866
|
+
expect(commit.committed_date).to eq(Date.parse('2008-03-02T16:45:41-08:00'))
|
867
|
+
expect(commit.tree).to eq('28a1a1ca3e663d35ba8bf07d3f1781af71359b76')
|
868
|
+
end
|
817
869
|
end
|
818
870
|
|
819
871
|
it 'parses xml with no namespace' do
|
820
872
|
product = Product.parse(fixture_file('product_no_namespace.xml'), single: true)
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
873
|
+
|
874
|
+
aggregate_failures do
|
875
|
+
expect(product.title).to eq('A Title')
|
876
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
877
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
878
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
879
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
880
|
+
end
|
826
881
|
end
|
827
882
|
|
828
883
|
it 'parses xml with default namespace' do
|
829
884
|
product = Product.parse(fixture_file('product_default_namespace.xml'), single: true)
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
885
|
+
|
886
|
+
aggregate_failures do
|
887
|
+
expect(product.title).to eq('A Title')
|
888
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
889
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
890
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
891
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
892
|
+
end
|
835
893
|
end
|
836
894
|
|
837
895
|
it 'parses xml with single namespace' do
|
838
896
|
product = Product.parse(fixture_file('product_single_namespace.xml'), single: true)
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
897
|
+
|
898
|
+
aggregate_failures do
|
899
|
+
expect(product.title).to eq('A Title')
|
900
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
901
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
902
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
903
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
904
|
+
end
|
844
905
|
end
|
845
906
|
|
846
907
|
it 'parses xml with multiple namespaces' do
|
847
908
|
track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
909
|
+
|
910
|
+
aggregate_failures do
|
911
|
+
expect(track.highest_severity).to eq('SUCCESS')
|
912
|
+
expect(track.more_data).to be_falsey
|
913
|
+
notification = track.notifications.first
|
914
|
+
expect(notification.code).to eq(0)
|
915
|
+
expect(notification.localized_message).to eq('Request was successfully processed.')
|
916
|
+
expect(notification.message).to eq('Request was successfully processed.')
|
917
|
+
expect(notification.severity).to eq('SUCCESS')
|
918
|
+
expect(notification.source).to eq('trck')
|
919
|
+
detail = track.trackdetails.first
|
920
|
+
expect(detail.carrier_code).to eq('FDXG')
|
921
|
+
expect(detail.est_delivery).to eq('2009-01-02T00:00:00')
|
922
|
+
expect(detail.service_info).to eq('Ground-Package Returns Program-Domestic')
|
923
|
+
expect(detail.status_code).to eq('OD')
|
924
|
+
expect(detail.status_desc).to eq('On FedEx vehicle for delivery')
|
925
|
+
expect(detail.tracking_number).to eq('9611018034267800045212')
|
926
|
+
expect(detail.weight.units).to eq('LB')
|
927
|
+
expect(detail.weight.value).to eq(2)
|
928
|
+
events = detail.events
|
929
|
+
expect(events.size).to eq(10)
|
930
|
+
first_event = events[0]
|
931
|
+
expect(first_event.eventdescription).to eq('On FedEx vehicle for delivery')
|
932
|
+
expect(first_event.eventtype).to eq('OD')
|
933
|
+
expect(first_event.timestamp).to eq('2009-01-02T06:00:00')
|
934
|
+
expect(first_event.address.city).to eq('WICHITA')
|
935
|
+
expect(first_event.address.countrycode).to eq('US')
|
936
|
+
expect(first_event.address.residential).to be_falsey
|
937
|
+
expect(first_event.address.state).to eq('KS')
|
938
|
+
expect(first_event.address.zip).to eq('67226')
|
939
|
+
last_event = events[-1]
|
940
|
+
expect(last_event.eventdescription).to eq('In FedEx possession')
|
941
|
+
expect(last_event.eventtype).to eq('IP')
|
942
|
+
expect(last_event.timestamp).to eq('2008-12-27T09:40:00')
|
943
|
+
expect(last_event.address.city).to eq('LONGWOOD')
|
944
|
+
expect(last_event.address.countrycode).to eq('US')
|
945
|
+
expect(last_event.address.residential).to be_falsey
|
946
|
+
expect(last_event.address.state).to eq('FL')
|
947
|
+
expect(last_event.address.zip).to eq('327506398')
|
948
|
+
expect(track.tran_detail.cust_tran_id).to eq('20090102-111321')
|
949
|
+
end
|
886
950
|
end
|
887
951
|
|
888
952
|
it 'is able to parse google analytics api xml' do
|
889
953
|
data = Analytics::Feed.parse(fixture_file('analytics.xml'))
|
890
|
-
expect(data.id).to eq('http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com')
|
891
|
-
expect(data.entries.size).to eq(4)
|
892
954
|
|
893
|
-
|
894
|
-
|
895
|
-
|
955
|
+
aggregate_failures do
|
956
|
+
expect(data.id).to eq('http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com')
|
957
|
+
expect(data.entries.size).to eq(4)
|
958
|
+
|
959
|
+
entry = data.entries[0]
|
960
|
+
expect(entry.title).to eq('addictedtonew.com')
|
961
|
+
expect(entry.properties.size).to eq(4)
|
896
962
|
|
897
|
-
|
898
|
-
|
899
|
-
|
963
|
+
property = entry.properties[0]
|
964
|
+
expect(property.name).to eq('ga:accountId')
|
965
|
+
expect(property.value).to eq('85301')
|
966
|
+
end
|
900
967
|
end
|
901
968
|
|
902
969
|
it 'is able to parse google analytics profile xml with manually declared namespace' do
|
903
970
|
data = Analytics::Profile.parse(fixture_file('analytics_profile.xml'))
|
904
|
-
expect(data.entries.size).to eq(6)
|
905
971
|
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
972
|
+
aggregate_failures do
|
973
|
+
expect(data.entries.size).to eq(6)
|
974
|
+
entry = data.entries[0]
|
975
|
+
expect(entry.title).to eq('www.homedepot.com')
|
976
|
+
expect(entry.properties.size).to eq(6)
|
977
|
+
expect(entry.goals.size).to eq(0)
|
978
|
+
end
|
910
979
|
end
|
911
980
|
|
912
981
|
it 'allows instantiating with a string' do
|
@@ -924,22 +993,28 @@ describe HappyMapper do
|
|
924
993
|
|
925
994
|
it 'parses family search xml' do
|
926
995
|
tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
to eq(
|
934
|
-
|
935
|
-
|
936
|
-
|
996
|
+
|
997
|
+
aggregate_failures do
|
998
|
+
expect(tree.version).to eq('1.0.20071213.942')
|
999
|
+
expect(tree.status_message).to eq('OK')
|
1000
|
+
expect(tree.status_code).to eq('200')
|
1001
|
+
expect(tree.persons.person.size).to eq(1)
|
1002
|
+
expect(tree.persons.person.first.version).to eq('1199378491000')
|
1003
|
+
expect(tree.persons.person.first.modified).
|
1004
|
+
to eq(Time.utc(2008, 1, 3, 16, 41, 31)) # 2008-01-03T09:41:31-07:00
|
1005
|
+
expect(tree.persons.person.first.id).to eq('KWQS-BBQ')
|
1006
|
+
expect(tree.persons.person.first.information.alternateIds.ids).not_to be_kind_of(String)
|
1007
|
+
expect(tree.persons.person.first.information.alternateIds.ids.size).to eq(8)
|
1008
|
+
end
|
937
1009
|
end
|
938
1010
|
|
939
1011
|
it 'parses multiple images' do
|
940
1012
|
artist = Artist.parse(fixture_file('multiple_primitives.xml'))
|
941
|
-
|
942
|
-
|
1013
|
+
|
1014
|
+
aggregate_failures do
|
1015
|
+
expect(artist.name).to eq('value')
|
1016
|
+
expect(artist.images.size).to eq(2)
|
1017
|
+
end
|
943
1018
|
end
|
944
1019
|
|
945
1020
|
it 'parses lastfm namespaces' do
|
@@ -992,12 +1067,10 @@ describe HappyMapper do
|
|
992
1067
|
end
|
993
1068
|
|
994
1069
|
it "saves object's xml content" do
|
995
|
-
|
996
|
-
'white <tag>cockatoo</tag>'
|
997
|
-
|
998
|
-
|
999
|
-
'<em>white</em> cockatoo'
|
1000
|
-
)
|
1070
|
+
aggregate_failures do
|
1071
|
+
expect(records.first.variants.first.xml_content).to eq 'white <tag>cockatoo</tag>'
|
1072
|
+
expect(records.first.variants.last.to_html).to eq '<em>white</em> cockatoo'
|
1073
|
+
end
|
1001
1074
|
end
|
1002
1075
|
end
|
1003
1076
|
|
@@ -1010,10 +1083,12 @@ describe HappyMapper do
|
|
1010
1083
|
let(:article) { Article.parse(fixture_file('subclass_namespace.xml')) }
|
1011
1084
|
|
1012
1085
|
it 'parses the publish options for Article and Photo' do
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1086
|
+
aggregate_failures do
|
1087
|
+
expect(article.title).not_to be_nil
|
1088
|
+
expect(article.text).not_to be_nil
|
1089
|
+
expect(article.photos).not_to be_nil
|
1090
|
+
expect(article.photos.first.title).not_to be_nil
|
1091
|
+
end
|
1017
1092
|
end
|
1018
1093
|
|
1019
1094
|
it 'parses the publish options for Article' do
|
@@ -1124,8 +1199,10 @@ describe HappyMapper do
|
|
1124
1199
|
let(:parsed) { described_class.parse original }
|
1125
1200
|
|
1126
1201
|
it 'has UTF-8 encoding by default' do
|
1127
|
-
|
1128
|
-
|
1202
|
+
aggregate_failures do
|
1203
|
+
expect(original.encoding).to eq Encoding::UTF_8
|
1204
|
+
expect(parsed.to_xml.encoding).to eq Encoding::UTF_8
|
1205
|
+
end
|
1129
1206
|
end
|
1130
1207
|
end
|
1131
1208
|
end
|