nokogiri-happymapper 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -9,112 +9,142 @@ end
|
|
9
9
|
describe HappyMapper::Item do
|
10
10
|
describe 'new instance' do
|
11
11
|
before do
|
12
|
-
@item =
|
12
|
+
@item = described_class.new(:foo, String, tag: 'foobar')
|
13
13
|
end
|
14
14
|
|
15
|
-
it '
|
15
|
+
it 'accepts a name' do
|
16
16
|
expect(@item.name).to eq('foo')
|
17
17
|
end
|
18
18
|
|
19
|
-
it '
|
19
|
+
it 'accepts a type' do
|
20
20
|
expect(@item.type).to eq(String)
|
21
21
|
end
|
22
22
|
|
23
|
-
it '
|
23
|
+
it 'accepts :tag as an option' do
|
24
24
|
expect(@item.tag).to eq('foobar')
|
25
25
|
end
|
26
26
|
|
27
|
-
it '
|
27
|
+
it 'has a method_name' do
|
28
28
|
expect(@item.method_name).to eq('foo')
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
describe '#constant' do
|
33
|
-
it '
|
34
|
-
item =
|
33
|
+
it 'justs use type if constant' do
|
34
|
+
item = described_class.new(:foo, String)
|
35
35
|
expect(item.constant).to eq(String)
|
36
36
|
end
|
37
37
|
|
38
|
-
it '
|
39
|
-
item =
|
38
|
+
it 'converts string type to constant' do
|
39
|
+
item = described_class.new(:foo, 'String')
|
40
40
|
expect(item.constant).to eq(String)
|
41
41
|
end
|
42
42
|
|
43
|
-
it '
|
44
|
-
item =
|
43
|
+
it 'converts string with :: to constant' do
|
44
|
+
item = described_class.new(:foo, 'Foo::Bar')
|
45
45
|
expect(item.constant).to eq(Foo::Bar)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
describe '#method_name' do
|
50
|
-
it '
|
51
|
-
item =
|
50
|
+
it 'converts dashes to underscores' do
|
51
|
+
item = described_class.new(:'foo-bar', String, tag: 'foobar')
|
52
52
|
expect(item.method_name).to eq('foo_bar')
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
describe '#xpath' do
|
57
|
-
it '
|
58
|
-
item =
|
57
|
+
it 'defaults to tag' do
|
58
|
+
item = described_class.new(:foo, String, tag: 'foobar')
|
59
59
|
expect(item.xpath).to eq('foobar')
|
60
60
|
end
|
61
61
|
|
62
|
-
it '
|
63
|
-
item =
|
62
|
+
it 'prepends with .// if options[:deep] true' do
|
63
|
+
item = described_class.new(:foo, String, tag: 'foobar', deep: true)
|
64
64
|
expect(item.xpath).to eq('.//foobar')
|
65
65
|
end
|
66
66
|
|
67
|
-
it '
|
68
|
-
item =
|
67
|
+
it 'prepends namespace if namespace exists' do
|
68
|
+
item = described_class.new(:foo, String, tag: 'foobar')
|
69
69
|
item.namespace = 'v2'
|
70
70
|
expect(item.xpath).to eq('v2:foobar')
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
describe 'typecasting' do
|
75
|
-
it '
|
76
|
-
item =
|
75
|
+
it 'works with Strings' do
|
76
|
+
item = described_class.new(:foo, String)
|
77
77
|
[21, '21'].each do |a|
|
78
78
|
expect(item.typecast(a)).to eq('21')
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
|
83
|
-
item
|
84
|
-
|
85
|
-
|
82
|
+
context 'with Integers' do
|
83
|
+
let(:item) { described_class.new(:foo, Integer) }
|
84
|
+
|
85
|
+
it 'works with an integer' do
|
86
|
+
expect(item.typecast(21)).to eq 21
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'works with a float' do
|
90
|
+
expect(item.typecast(21.0)).to eq 21
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'works with a string' do
|
94
|
+
expect(item.typecast('21')).to eq 21
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'works with a string with trailing characters' do
|
98
|
+
expect(item.typecast('21foo')).to eq 21
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'works with a string with zero plus trailing characters' do
|
102
|
+
expect(item.typecast('0foo')).to eq 0
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'handles a non-numeric string' do
|
106
|
+
expect(item.typecast('foo')).to be_nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'handles an empty string' do
|
110
|
+
expect(item.typecast('')).to be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'handles nil' do
|
114
|
+
expect(item.typecast(nil)).to be_nil
|
86
115
|
end
|
87
116
|
end
|
88
117
|
|
89
|
-
it '
|
90
|
-
item =
|
118
|
+
it 'works with Floats' do
|
119
|
+
item = described_class.new(:foo, Float)
|
91
120
|
[21, 21.0, '21'].each do |a|
|
92
|
-
expect(item.typecast(a)).to eq
|
121
|
+
expect(item.typecast(a)).to eq 21.0
|
93
122
|
end
|
94
123
|
end
|
95
124
|
|
96
|
-
it '
|
97
|
-
item =
|
98
|
-
expect(item.typecast('2000-01-01 01:01:01.123456')).to eq(Time.local(2000, 1, 1, 1, 1, 1,
|
125
|
+
it 'works with Times' do
|
126
|
+
item = described_class.new(:foo, Time)
|
127
|
+
expect(item.typecast('2000-01-01 01:01:01.123456')).to eq(Time.local(2000, 1, 1, 1, 1, 1, 123_456))
|
99
128
|
end
|
100
129
|
|
101
|
-
|
102
|
-
item
|
103
|
-
expect(item.typecast('2000-01-01')).to eq(Date.new(2000, 1, 1))
|
104
|
-
end
|
130
|
+
context 'with Date' do
|
131
|
+
let(:item) { described_class.new(:foo, Date) }
|
105
132
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
133
|
+
it 'works with a string' do
|
134
|
+
expect(item.typecast('2000-01-01')).to eq(Date.new(2000, 1, 1))
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'handles nil' do
|
138
|
+
expect(item.typecast(nil)).to be_nil
|
139
|
+
end
|
110
140
|
|
111
|
-
|
112
|
-
|
113
|
-
|
141
|
+
it 'handles empty string' do
|
142
|
+
expect(item.typecast('')).to eq(nil)
|
143
|
+
end
|
114
144
|
end
|
115
145
|
|
116
146
|
context 'with DateTime' do
|
117
|
-
let(:item) {
|
147
|
+
let(:item) { described_class.new(:foo, DateTime) }
|
118
148
|
|
119
149
|
it 'works with a string' do
|
120
150
|
result = item.typecast('2000-01-01 13:42:37')
|
@@ -136,8 +166,8 @@ describe HappyMapper::Item do
|
|
136
166
|
end
|
137
167
|
end
|
138
168
|
|
139
|
-
it '
|
140
|
-
item =
|
169
|
+
it 'works with Boolean' do
|
170
|
+
item = described_class.new(:foo, HappyMapper::Boolean)
|
141
171
|
expect(item.typecast('false')).to eq(false)
|
142
172
|
end
|
143
173
|
end
|
data/spec/happymapper_spec.rb
CHANGED
@@ -551,8 +551,8 @@ end
|
|
551
551
|
|
552
552
|
describe HappyMapper do
|
553
553
|
describe 'being included into another class' do
|
554
|
-
|
555
|
-
|
554
|
+
let(:klass) do
|
555
|
+
Class.new do
|
556
556
|
include HappyMapper
|
557
557
|
|
558
558
|
def self.name
|
@@ -561,66 +561,66 @@ describe HappyMapper do
|
|
561
561
|
end
|
562
562
|
end
|
563
563
|
|
564
|
-
it '
|
565
|
-
expect(
|
564
|
+
it 'sets attributes to an array' do
|
565
|
+
expect(klass.attributes).to eq([])
|
566
566
|
end
|
567
567
|
|
568
|
-
it '
|
569
|
-
expect(
|
568
|
+
it 'sets @elements to a hash' do
|
569
|
+
expect(klass.elements).to eq([])
|
570
570
|
end
|
571
571
|
|
572
|
-
it '
|
572
|
+
it 'allows adding an attribute' do
|
573
573
|
expect do
|
574
|
-
|
575
|
-
end.to change(
|
574
|
+
klass.attribute :name, String
|
575
|
+
end.to change(klass, :attributes)
|
576
576
|
end
|
577
577
|
|
578
|
-
it '
|
578
|
+
it 'allows adding an attribute containing a dash' do
|
579
579
|
expect do
|
580
|
-
|
581
|
-
end.to change(
|
580
|
+
klass.attribute :'bar-baz', String
|
581
|
+
end.to change(klass, :attributes)
|
582
582
|
end
|
583
583
|
|
584
|
-
it '
|
585
|
-
|
586
|
-
expect(
|
584
|
+
it 'is able to get all attributes in array' do
|
585
|
+
klass.attribute :name, String
|
586
|
+
expect(klass.attributes.size).to eq(1)
|
587
587
|
end
|
588
588
|
|
589
|
-
it '
|
589
|
+
it 'allows adding an element' do
|
590
590
|
expect do
|
591
|
-
|
592
|
-
end.to change(
|
591
|
+
klass.element :name, String
|
592
|
+
end.to change(klass, :elements)
|
593
593
|
end
|
594
594
|
|
595
|
-
it '
|
595
|
+
it 'allows adding an element containing a dash' do
|
596
596
|
expect do
|
597
|
-
|
598
|
-
end.to change(
|
597
|
+
klass.element :'bar-baz', String
|
598
|
+
end.to change(klass, :elements)
|
599
599
|
end
|
600
600
|
|
601
|
-
it '
|
602
|
-
|
603
|
-
expect(
|
601
|
+
it 'is able to get all elements in array' do
|
602
|
+
klass.element(:name, String)
|
603
|
+
expect(klass.elements.size).to eq(1)
|
604
604
|
end
|
605
605
|
|
606
|
-
it '
|
607
|
-
|
608
|
-
element =
|
606
|
+
it 'allows has one association' do
|
607
|
+
klass.has_one(:user, User)
|
608
|
+
element = klass.elements.first
|
609
609
|
expect(element.name).to eq('user')
|
610
610
|
expect(element.type).to eq(User)
|
611
611
|
expect(element.options[:single]).to eq(true)
|
612
612
|
end
|
613
613
|
|
614
|
-
it '
|
615
|
-
|
616
|
-
element =
|
614
|
+
it 'allows has many association' do
|
615
|
+
klass.has_many(:users, User)
|
616
|
+
element = klass.elements.first
|
617
617
|
expect(element.name).to eq('users')
|
618
618
|
expect(element.type).to eq(User)
|
619
619
|
expect(element.options[:single]).to eq(false)
|
620
620
|
end
|
621
621
|
|
622
|
-
it '
|
623
|
-
expect(
|
622
|
+
it 'defaults tag name to lowercase class' do
|
623
|
+
expect(klass.tag_name).to eq('boo')
|
624
624
|
end
|
625
625
|
|
626
626
|
it 'generates no tag name for anonymous class' do
|
@@ -628,49 +628,49 @@ describe HappyMapper do
|
|
628
628
|
expect(@anon.tag_name).to be_nil
|
629
629
|
end
|
630
630
|
|
631
|
-
it '
|
631
|
+
it 'defaults tag name of class in modules to the last constant lowercase' do
|
632
632
|
module Bar; class Baz; include HappyMapper; end; end
|
633
633
|
expect(Bar::Baz.tag_name).to eq('baz')
|
634
634
|
end
|
635
635
|
|
636
|
-
it '
|
637
|
-
|
638
|
-
expect(
|
636
|
+
it 'allows setting tag name' do
|
637
|
+
klass.tag('FooBar')
|
638
|
+
expect(klass.tag_name).to eq('FooBar')
|
639
639
|
end
|
640
640
|
|
641
|
-
it '
|
642
|
-
|
643
|
-
expect(
|
641
|
+
it 'allows setting a namespace' do
|
642
|
+
klass.namespace(namespace = 'boo')
|
643
|
+
expect(klass.namespace).to eq(namespace)
|
644
644
|
end
|
645
645
|
|
646
|
-
it '
|
647
|
-
expect(
|
646
|
+
it 'provides #parse' do
|
647
|
+
expect(klass).to respond_to(:parse)
|
648
648
|
end
|
649
649
|
end
|
650
650
|
|
651
651
|
describe '#attributes' do
|
652
|
-
it '
|
652
|
+
it 'onlies return attributes for the current class' do
|
653
653
|
expect(Post.attributes.size).to eq(7)
|
654
654
|
expect(Status.attributes.size).to eq(0)
|
655
655
|
end
|
656
656
|
end
|
657
657
|
|
658
658
|
describe '#elements' do
|
659
|
-
it '
|
659
|
+
it 'onlies return elements for the current class' do
|
660
660
|
expect(Post.elements.size).to eq(0)
|
661
661
|
expect(Status.elements.size).to eq(10)
|
662
662
|
end
|
663
663
|
end
|
664
664
|
|
665
665
|
describe '#content' do
|
666
|
-
it '
|
666
|
+
it 'takes String as default argument for type' do
|
667
667
|
State.content :name
|
668
668
|
address = Address.parse(fixture_file('address.xml'))
|
669
669
|
expect(address.state.name).to eq('Lower Saxony')
|
670
670
|
address.state.name.class == String
|
671
671
|
end
|
672
672
|
|
673
|
-
it '
|
673
|
+
it 'works when specific type is provided' do
|
674
674
|
Rate.content :value, Float
|
675
675
|
Product.has_one :rate, Rate
|
676
676
|
product = Product.parse(fixture_file('product_default_namespace.xml'), single: true)
|
@@ -679,7 +679,7 @@ describe HappyMapper do
|
|
679
679
|
end
|
680
680
|
end
|
681
681
|
|
682
|
-
it '
|
682
|
+
it 'parses xml attributes into ruby objects' do
|
683
683
|
posts = Post.parse(fixture_file('posts.xml'))
|
684
684
|
expect(posts.size).to eq(20)
|
685
685
|
first = posts.first
|
@@ -697,16 +697,16 @@ describe HappyMapper do
|
|
697
697
|
' focus on building first-class Ruby classes.')
|
698
698
|
end
|
699
699
|
|
700
|
-
it '
|
700
|
+
it 'parses xml elements to ruby objcts' do
|
701
701
|
statuses = Status.parse(fixture_file('statuses.xml'))
|
702
702
|
expect(statuses.size).to eq(20)
|
703
703
|
first = statuses.first
|
704
|
-
expect(first.id).to eq(
|
704
|
+
expect(first.id).to eq(882_281_424)
|
705
705
|
expect(first.created_at).to eq(Time.utc(2008, 8, 9, 5, 38, 12))
|
706
706
|
expect(first.source).to eq('web')
|
707
707
|
expect(first.truncated).to be_falsey
|
708
708
|
expect(first.in_reply_to_status_id).to eq(1234)
|
709
|
-
expect(first.in_reply_to_user_id).to eq(
|
709
|
+
expect(first.in_reply_to_user_id).to eq(12_345)
|
710
710
|
expect(first.favorited).to be_falsey
|
711
711
|
expect(first.user.id).to eq(4243)
|
712
712
|
expect(first.user.name).to eq('John Nunemaker')
|
@@ -720,7 +720,7 @@ describe HappyMapper do
|
|
720
720
|
expect(first.user.followers_count).to eq(486)
|
721
721
|
end
|
722
722
|
|
723
|
-
it '
|
723
|
+
it 'parses xml containing the desired element as root node' do
|
724
724
|
address = Address.parse(fixture_file('address.xml'), single: true)
|
725
725
|
expect(address.street).to eq('Milchstrasse')
|
726
726
|
expect(address.postcode).to eq('26131')
|
@@ -729,19 +729,19 @@ describe HappyMapper do
|
|
729
729
|
expect(address.country.class).to eq(Country)
|
730
730
|
end
|
731
731
|
|
732
|
-
it '
|
732
|
+
it 'parses text node correctly' do
|
733
733
|
address = Address.parse(fixture_file('address.xml'), single: true)
|
734
734
|
expect(address.country.name).to eq('Germany')
|
735
735
|
expect(address.country.code).to eq('de')
|
736
736
|
end
|
737
737
|
|
738
|
-
it '
|
738
|
+
it 'treats Nokogiri::XML::Document as root' do
|
739
739
|
doc = Nokogiri::XML(fixture_file('address.xml'))
|
740
740
|
address = Address.parse(doc)
|
741
741
|
expect(address.class).to eq(Address)
|
742
742
|
end
|
743
743
|
|
744
|
-
it '
|
744
|
+
it 'parses xml with default namespace (amazon)' do
|
745
745
|
file_contents = fixture_file('pita.xml')
|
746
746
|
items = PITA::Items.parse(file_contents, single: true)
|
747
747
|
expect(items.total_results).to eq(22)
|
@@ -758,7 +758,7 @@ describe HappyMapper do
|
|
758
758
|
expect(second.manufacturer).to eq('Wrox')
|
759
759
|
end
|
760
760
|
|
761
|
-
it '
|
761
|
+
it 'parses xml that has attributes of elements' do
|
762
762
|
items = CurrentWeather.parse(fixture_file('current_weather.xml'))
|
763
763
|
first = items[0]
|
764
764
|
expect(first.temperature).to eq(51)
|
@@ -774,7 +774,7 @@ describe HappyMapper do
|
|
774
774
|
end
|
775
775
|
|
776
776
|
it 'parses xml with optional elements with embedded attributes' do
|
777
|
-
expect { CurrentWeather.parse(fixture_file('current_weather_missing_elements.xml')) }.
|
777
|
+
expect { CurrentWeather.parse(fixture_file('current_weather_missing_elements.xml')) }.not_to raise_error
|
778
778
|
end
|
779
779
|
|
780
780
|
it 'returns nil rather than empty array for absent values when :single => true' do
|
@@ -782,13 +782,13 @@ describe HappyMapper do
|
|
782
782
|
expect(address).to be_nil
|
783
783
|
end
|
784
784
|
|
785
|
-
it '
|
785
|
+
it 'returns same result for absent values when :single => true, regardless of :in_groups_of' do
|
786
786
|
addr1 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', single: true)
|
787
787
|
addr2 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', single: true, in_groups_of: 10)
|
788
788
|
expect(addr1).to eq(addr2)
|
789
789
|
end
|
790
790
|
|
791
|
-
it '
|
791
|
+
it 'parses xml with nested elements' do
|
792
792
|
radars = Radar.parse(fixture_file('radar.xml'))
|
793
793
|
first = radars[0]
|
794
794
|
expect(first.places.size).to eq(1)
|
@@ -801,13 +801,13 @@ describe HappyMapper do
|
|
801
801
|
expect(third.places[1].name).to eq('Home')
|
802
802
|
end
|
803
803
|
|
804
|
-
it '
|
804
|
+
it 'parses xml with element name different to class name' do
|
805
805
|
game = QuarterTest::Game.parse(fixture_file('quarters.xml'))
|
806
806
|
expect(game.q1.start).to eq('4:40:15 PM')
|
807
807
|
expect(game.q2.start).to eq('5:18:53 PM')
|
808
808
|
end
|
809
809
|
|
810
|
-
it '
|
810
|
+
it 'parses xml that has elements with dashes' do
|
811
811
|
commit = GitHub::Commit.parse(fixture_file('commit.xml'))
|
812
812
|
expect(commit.message).to eq('move commands.rb and helpers.rb into commands/ dir')
|
813
813
|
expect(commit.url).to eq('http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b')
|
@@ -816,7 +816,7 @@ describe HappyMapper do
|
|
816
816
|
expect(commit.tree).to eq('28a1a1ca3e663d35ba8bf07d3f1781af71359b76')
|
817
817
|
end
|
818
818
|
|
819
|
-
it '
|
819
|
+
it 'parses xml with no namespace' do
|
820
820
|
product = Product.parse(fixture_file('product_no_namespace.xml'), single: true)
|
821
821
|
expect(product.title).to eq('A Title')
|
822
822
|
expect(product.feature_bullets.bug).to eq('This is a bug')
|
@@ -825,7 +825,7 @@ describe HappyMapper do
|
|
825
825
|
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
826
826
|
end
|
827
827
|
|
828
|
-
it '
|
828
|
+
it 'parses xml with default namespace' do
|
829
829
|
product = Product.parse(fixture_file('product_default_namespace.xml'), single: true)
|
830
830
|
expect(product.title).to eq('A Title')
|
831
831
|
expect(product.feature_bullets.bug).to eq('This is a bug')
|
@@ -834,7 +834,7 @@ describe HappyMapper do
|
|
834
834
|
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
835
835
|
end
|
836
836
|
|
837
|
-
it '
|
837
|
+
it 'parses xml with single namespace' do
|
838
838
|
product = Product.parse(fixture_file('product_single_namespace.xml'), single: true)
|
839
839
|
expect(product.title).to eq('A Title')
|
840
840
|
expect(product.feature_bullets.bug).to eq('This is a bug')
|
@@ -843,7 +843,7 @@ describe HappyMapper do
|
|
843
843
|
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
844
844
|
end
|
845
845
|
|
846
|
-
it '
|
846
|
+
it 'parses xml with multiple namespaces' do
|
847
847
|
track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
|
848
848
|
expect(track.highest_severity).to eq('SUCCESS')
|
849
849
|
expect(track.more_data).to be_falsey
|
@@ -885,7 +885,7 @@ describe HappyMapper do
|
|
885
885
|
expect(track.tran_detail.cust_tran_id).to eq('20090102-111321')
|
886
886
|
end
|
887
887
|
|
888
|
-
it '
|
888
|
+
it 'is able to parse google analytics api xml' do
|
889
889
|
data = Analytics::Feed.parse(fixture_file('analytics.xml'))
|
890
890
|
expect(data.id).to eq('http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com')
|
891
891
|
expect(data.entries.size).to eq(4)
|
@@ -899,7 +899,7 @@ describe HappyMapper do
|
|
899
899
|
expect(property.value).to eq('85301')
|
900
900
|
end
|
901
901
|
|
902
|
-
it '
|
902
|
+
it 'is able to parse google analytics profile xml with manually declared namespace' do
|
903
903
|
data = Analytics::Profile.parse(fixture_file('analytics_profile.xml'))
|
904
904
|
expect(data.entries.size).to eq(6)
|
905
905
|
|
@@ -909,7 +909,7 @@ describe HappyMapper do
|
|
909
909
|
expect(entry.goals.size).to eq(0)
|
910
910
|
end
|
911
911
|
|
912
|
-
it '
|
912
|
+
it 'allows instantiating with a string' do
|
913
913
|
module StringFoo
|
914
914
|
class Bar
|
915
915
|
include HappyMapper
|
@@ -922,7 +922,7 @@ describe HappyMapper do
|
|
922
922
|
end
|
923
923
|
end
|
924
924
|
|
925
|
-
it '
|
925
|
+
it 'parses family search xml' do
|
926
926
|
tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
|
927
927
|
expect(tree.version).to eq('1.0.20071213.942')
|
928
928
|
expect(tree.status_message).to eq('OK')
|
@@ -936,120 +936,115 @@ describe HappyMapper do
|
|
936
936
|
expect(tree.persons.person.first.information.alternateIds.ids.size).to eq(8)
|
937
937
|
end
|
938
938
|
|
939
|
-
it '
|
939
|
+
it 'parses multiple images' do
|
940
940
|
artist = Artist.parse(fixture_file('multiple_primitives.xml'))
|
941
941
|
expect(artist.name).to eq('value')
|
942
942
|
expect(artist.images.size).to eq(2)
|
943
943
|
end
|
944
944
|
|
945
|
-
it '
|
945
|
+
it 'parses lastfm namespaces' do
|
946
946
|
l = Location.parse(fixture_file('lastfm.xml'))
|
947
947
|
expect(l.first.latitude).to eq('51.53469')
|
948
948
|
end
|
949
949
|
|
950
950
|
describe 'Parse optional attributes' do
|
951
|
-
|
952
|
-
|
953
|
-
|
951
|
+
let(:parsed_result) { OptionalAttribute.parse(fixture_file('optional_attributes.xml')) }
|
952
|
+
|
953
|
+
it 'parses an empty String as empty' do
|
954
|
+
expect(parsed_result[0].street).to eq('')
|
954
955
|
end
|
955
956
|
|
956
|
-
it '
|
957
|
-
|
958
|
-
expect(a[1].street).to eq('Milchstrasse')
|
957
|
+
it 'parses a String with value' do
|
958
|
+
expect(parsed_result[1].street).to eq('Milchstrasse')
|
959
959
|
end
|
960
960
|
|
961
|
-
it '
|
962
|
-
|
963
|
-
expect(a[2].street).to be_nil
|
961
|
+
it 'parses an element with no value for the attribute' do
|
962
|
+
expect(parsed_result[2].street).to be_nil
|
964
963
|
end
|
965
964
|
end
|
966
965
|
|
967
966
|
describe 'Default namespace combi' do
|
968
|
-
|
969
|
-
|
970
|
-
@book = DefaultNamespaceCombi.parse(file_contents, single: true)
|
971
|
-
end
|
967
|
+
let(:file_contents) { fixture_file('default_namespace_combi.xml') }
|
968
|
+
let(:book) { DefaultNamespaceCombi.parse(file_contents, single: true) }
|
972
969
|
|
973
|
-
it '
|
974
|
-
expect(
|
970
|
+
it 'parses author' do
|
971
|
+
expect(book.author).to eq('Frank Gilbreth')
|
975
972
|
end
|
976
973
|
|
977
|
-
it '
|
978
|
-
expect(
|
974
|
+
it 'parses title' do
|
975
|
+
expect(book.title).to eq('Cheaper by the Dozen')
|
979
976
|
end
|
980
977
|
|
981
|
-
it '
|
982
|
-
expect(
|
978
|
+
it 'parses number' do
|
979
|
+
expect(book.number).to eq('1568491379')
|
983
980
|
end
|
984
981
|
end
|
985
982
|
|
986
983
|
describe 'Xml Content' do
|
987
|
-
|
988
|
-
file_contents = fixture_file('dictionary.xml')
|
989
|
-
@records = Dictionary::Record.parse(file_contents)
|
990
|
-
end
|
984
|
+
let(:records) { Dictionary::Record.parse fixture_file('dictionary.xml') }
|
991
985
|
|
992
|
-
it '
|
993
|
-
expect(
|
986
|
+
it 'parses XmlContent' do
|
987
|
+
expect(records.first.definitions.first.text).
|
994
988
|
to eq('a large common parrot, <bn>Cacatua galerita</bn>, predominantly' \
|
995
989
|
' white, with yellow on the undersides of wings and tail and a' \
|
996
990
|
' forward curving yellow crest, found in Australia, New Guinea' \
|
997
991
|
' and nearby islands.')
|
998
992
|
end
|
999
993
|
|
1000
|
-
it "
|
1001
|
-
expect(
|
994
|
+
it "saves object's xml content" do
|
995
|
+
expect(records.first.variants.first.xml_content).to eq(
|
1002
996
|
'white <tag>cockatoo</tag>'
|
1003
997
|
)
|
1004
|
-
expect(
|
998
|
+
expect(records.first.variants.last.to_html).to eq(
|
1005
999
|
'<em>white</em> cockatoo'
|
1006
1000
|
)
|
1007
1001
|
end
|
1008
1002
|
end
|
1009
1003
|
|
1010
|
-
it '
|
1004
|
+
it 'parses ambigous items' do
|
1011
1005
|
items = AmbigousItems::Item.parse(fixture_file('ambigous_items.xml'), xpath: '/ambigous/my-items')
|
1012
1006
|
expect(items.map(&:name)).to eq(%w(first second third).map { |s| "My #{s} item" })
|
1013
1007
|
end
|
1014
1008
|
|
1015
1009
|
context Article do
|
1016
|
-
|
1017
|
-
expect(@article.title).not_to be_nil
|
1018
|
-
expect(@article.text).not_to be_nil
|
1019
|
-
expect(@article.photos).not_to be_nil
|
1020
|
-
expect(@article.photos.first.title).not_to be_nil
|
1021
|
-
end
|
1010
|
+
let(:article) { Article.parse(fixture_file('subclass_namespace.xml')) }
|
1022
1011
|
|
1023
|
-
it '
|
1024
|
-
expect(
|
1012
|
+
it 'parses the publish options for Article and Photo' do
|
1013
|
+
expect(article.title).not_to be_nil
|
1014
|
+
expect(article.text).not_to be_nil
|
1015
|
+
expect(article.photos).not_to be_nil
|
1016
|
+
expect(article.photos.first.title).not_to be_nil
|
1025
1017
|
end
|
1026
1018
|
|
1027
|
-
it '
|
1028
|
-
expect(
|
1019
|
+
it 'parses the publish options for Article' do
|
1020
|
+
expect(article.publish_options).not_to be_nil
|
1029
1021
|
end
|
1030
1022
|
|
1031
|
-
it '
|
1032
|
-
expect(
|
1023
|
+
it 'parses the publish options for Photo' do
|
1024
|
+
expect(article.photos.first.publish_options).not_to be_nil
|
1033
1025
|
end
|
1034
1026
|
|
1035
|
-
|
1036
|
-
|
1027
|
+
it 'onlies find only items at the parent level' do
|
1028
|
+
expect(article.photos.length).to eq(1)
|
1037
1029
|
end
|
1038
1030
|
end
|
1039
1031
|
|
1040
|
-
|
1041
|
-
it '
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1032
|
+
describe 'Namespace is missing because an optional element that uses it is not present' do
|
1033
|
+
it 'parses successfully' do
|
1034
|
+
article = PartiallyBadArticle.parse(fixture_file('subclass_namespace.xml'))
|
1035
|
+
|
1036
|
+
aggregate_failures do
|
1037
|
+
expect(article).not_to be_nil
|
1038
|
+
expect(article.title).not_to be_nil
|
1039
|
+
expect(article.text).not_to be_nil
|
1040
|
+
expect(article.photos).not_to be_nil
|
1041
|
+
expect(article.photos.first.title).not_to be_nil
|
1042
|
+
end
|
1048
1043
|
end
|
1049
1044
|
end
|
1050
1045
|
|
1051
1046
|
describe 'with limit option' do
|
1052
|
-
it '
|
1047
|
+
it 'returns results with limited size: 6' do
|
1053
1048
|
sizes = []
|
1054
1049
|
Post.parse(fixture_file('posts.xml'), in_groups_of: 6) do |a|
|
1055
1050
|
sizes << a.size
|
@@ -1057,7 +1052,7 @@ describe HappyMapper do
|
|
1057
1052
|
expect(sizes).to eq([6, 6, 6, 2])
|
1058
1053
|
end
|
1059
1054
|
|
1060
|
-
it '
|
1055
|
+
it 'returns results with limited size: 10' do
|
1061
1056
|
sizes = []
|
1062
1057
|
Post.parse(fixture_file('posts.xml'), in_groups_of: 10) do |a|
|
1063
1058
|
sizes << a.size
|
@@ -1095,7 +1090,7 @@ describe HappyMapper do
|
|
1095
1090
|
end
|
1096
1091
|
|
1097
1092
|
it 'parses according to @nokogiri_config_callback' do
|
1098
|
-
expect { custom.parse(fixture_file('set_config_options.xml')) }.
|
1093
|
+
expect { custom.parse(fixture_file('set_config_options.xml')) }.not_to raise_error
|
1099
1094
|
end
|
1100
1095
|
|
1101
1096
|
it 'can clear @nokogiri_config_callback' do
|
@@ -1105,7 +1100,7 @@ describe HappyMapper do
|
|
1105
1100
|
end
|
1106
1101
|
end
|
1107
1102
|
|
1108
|
-
|
1103
|
+
describe '#xml_value' do
|
1109
1104
|
it 'does not reformat the xml' do
|
1110
1105
|
xml = fixture_file('unformatted_address.xml')
|
1111
1106
|
address = Address.parse(xml, single: true)
|
@@ -1115,7 +1110,7 @@ describe HappyMapper do
|
|
1115
1110
|
end
|
1116
1111
|
end
|
1117
1112
|
|
1118
|
-
|
1113
|
+
describe '#xml_content' do
|
1119
1114
|
it 'does not reformat the xml' do
|
1120
1115
|
xml = fixture_file('unformatted_address.xml')
|
1121
1116
|
address = Address.parse(xml)
|