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
@@ -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)
|