nokogiri-happymapper 0.5.9 → 0.6.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 +10 -1
- data/License +20 -0
- data/lib/happymapper.rb +63 -34
- data/lib/happymapper/anonymous_mapper.rb +3 -3
- data/lib/happymapper/element.rb +3 -3
- data/lib/happymapper/supported_types.rb +5 -5
- data/lib/happymapper/version.rb +1 -1
- data/spec/fixtures/unformatted_address.xml +1 -0
- data/spec/happymapper/attribute_spec.rb +1 -1
- data/spec/happymapper/item_spec.rb +39 -18
- data/spec/happymapper_parse_spec.rb +41 -15
- data/spec/happymapper_spec.rb +229 -216
- data/spec/has_many_empty_array_spec.rb +2 -2
- data/spec/ignay_spec.rb +12 -12
- data/spec/inheritance_spec.rb +2 -2
- data/spec/parse_with_object_to_update_spec.rb +1 -1
- data/spec/to_xml_spec.rb +2 -1
- data/spec/to_xml_with_namespaces_spec.rb +38 -2
- data/spec/wilcard_tag_name_spec.rb +7 -7
- data/spec/wrap_spec.rb +2 -2
- data/spec/xpath_spec.rb +3 -3
- metadata +21 -17
@@ -9,24 +9,24 @@ describe HappyMapper do
|
|
9
9
|
subject { described_class.parse fixture_file('address.xml') }
|
10
10
|
|
11
11
|
it "should parse child elements" do
|
12
|
-
subject.street.
|
13
|
-
subject.housenumber.
|
14
|
-
subject.postcode.
|
15
|
-
subject.city.
|
12
|
+
expect(subject.street).to eq("Milchstrasse")
|
13
|
+
expect(subject.housenumber).to eq("23")
|
14
|
+
expect(subject.postcode).to eq("26131")
|
15
|
+
expect(subject.city).to eq("Oldenburg")
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should not create a content entry when the xml contents no text content" do
|
19
|
-
subject.
|
19
|
+
expect(subject).not_to respond_to :content
|
20
20
|
end
|
21
21
|
|
22
22
|
context "child elements with attributes" do
|
23
23
|
|
24
24
|
it "should parse the attributes" do
|
25
|
-
subject.country.code.
|
25
|
+
expect(subject.country.code).to eq("de")
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should parse the content" do
|
29
|
-
subject.country.content.
|
29
|
+
expect(subject.country.content).to eq("Germany")
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
@@ -37,7 +37,7 @@ describe HappyMapper do
|
|
37
37
|
subject { described_class.parse fixture_file('ambigous_items.xml') }
|
38
38
|
|
39
39
|
it "should create accessor methods with similar names" do
|
40
|
-
subject.my_items.item.
|
40
|
+
expect(subject.my_items.item).to be_kind_of Array
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -46,9 +46,9 @@ describe HappyMapper do
|
|
46
46
|
subject { described_class.parse fixture_file('subclass_namespace.xml') }
|
47
47
|
|
48
48
|
it "should parse the elements and values correctly" do
|
49
|
-
subject.title.
|
50
|
-
subject.photo.publish_options.author.
|
51
|
-
subject.gallery.photo.title.
|
49
|
+
expect(subject.title).to eq("article title")
|
50
|
+
expect(subject.photo.publish_options.author).to eq("Stephanie")
|
51
|
+
expect(subject.gallery.photo.title).to eq("photo title")
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -56,7 +56,7 @@ describe HappyMapper do
|
|
56
56
|
subject { described_class.parse fixture_file('ambigous_items.xml') }
|
57
57
|
|
58
58
|
it "should parse the entire relationship" do
|
59
|
-
subject.my_items.item.first.item.name.
|
59
|
+
expect(subject.my_items.item.first.item.name).to eq("My first internal item")
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -66,8 +66,8 @@ describe HappyMapper do
|
|
66
66
|
|
67
67
|
it "should parse the elements as it would a 'has_many'" do
|
68
68
|
|
69
|
-
subject.name.
|
70
|
-
subject.image.
|
69
|
+
expect(subject.name).to eq("value")
|
70
|
+
expect(subject.image).to eq([ "image1", "image2" ])
|
71
71
|
|
72
72
|
end
|
73
73
|
|
@@ -78,7 +78,33 @@ describe HappyMapper do
|
|
78
78
|
subject { described_class.parse fixture_file('subclass_namespace.xml') }
|
79
79
|
|
80
80
|
it "should parse the elements an values correctly" do
|
81
|
-
subject.title.
|
81
|
+
expect(subject.title).to eq("article title")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "after_parse callbacks" do
|
86
|
+
module AfterParseSpec
|
87
|
+
class Address
|
88
|
+
include HappyMapper
|
89
|
+
element :street, String
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
after do
|
94
|
+
AfterParseSpec::Address.after_parse_callbacks.clear
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should callback with the newly created object" do
|
98
|
+
from_cb = nil
|
99
|
+
called = false
|
100
|
+
cb1 = proc { |object| from_cb = object }
|
101
|
+
cb2 = proc { called = true }
|
102
|
+
AfterParseSpec::Address.after_parse(&cb1)
|
103
|
+
AfterParseSpec::Address.after_parse(&cb2)
|
104
|
+
|
105
|
+
object = AfterParseSpec::Address.parse fixture_file('address.xml')
|
106
|
+
expect(from_cb).to eq(object)
|
107
|
+
expect(called).to eq(true)
|
82
108
|
end
|
83
109
|
end
|
84
110
|
|
data/spec/happymapper_spec.rb
CHANGED
@@ -86,15 +86,31 @@ module Atom
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
class Country
|
90
|
+
include HappyMapper
|
91
|
+
|
92
|
+
attribute :code, String
|
93
|
+
content :name, String
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
class State
|
98
|
+
include HappyMapper
|
99
|
+
end
|
100
|
+
|
89
101
|
class Address
|
90
102
|
include HappyMapper
|
91
103
|
|
104
|
+
attr_accessor :xml_value
|
105
|
+
attr_accessor :xml_content
|
106
|
+
|
92
107
|
tag 'address'
|
93
108
|
element :street, String
|
94
109
|
element :postcode, String
|
95
110
|
element :housenumber, String
|
96
111
|
element :city, String
|
97
|
-
|
112
|
+
has_one :country, Country
|
113
|
+
has_one :state, State
|
98
114
|
end
|
99
115
|
|
100
116
|
class Feature
|
@@ -305,30 +321,6 @@ class CurrentWeather
|
|
305
321
|
element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
|
306
322
|
end
|
307
323
|
|
308
|
-
class Country
|
309
|
-
include HappyMapper
|
310
|
-
|
311
|
-
attribute :code, String
|
312
|
-
content :name, String
|
313
|
-
end
|
314
|
-
|
315
|
-
|
316
|
-
class State
|
317
|
-
include HappyMapper
|
318
|
-
end
|
319
|
-
|
320
|
-
class Address
|
321
|
-
include HappyMapper
|
322
|
-
|
323
|
-
tag 'address'
|
324
|
-
element :street, String
|
325
|
-
element :postcode, String
|
326
|
-
element :housenumber, String
|
327
|
-
element :city, String
|
328
|
-
has_one :country, Country
|
329
|
-
has_one :state, State
|
330
|
-
end
|
331
|
-
|
332
324
|
# for type coercion
|
333
325
|
class ProductGroup < String; end
|
334
326
|
|
@@ -580,99 +572,99 @@ describe HappyMapper do
|
|
580
572
|
class Boo; include HappyMapper end
|
581
573
|
|
582
574
|
it "should set attributes to an array" do
|
583
|
-
@klass.attributes.
|
575
|
+
expect(@klass.attributes).to eq([])
|
584
576
|
end
|
585
577
|
|
586
578
|
it "should set @elements to a hash" do
|
587
|
-
@klass.elements.
|
579
|
+
expect(@klass.elements).to eq([])
|
588
580
|
end
|
589
581
|
|
590
582
|
it "should allow adding an attribute" do
|
591
|
-
|
583
|
+
expect {
|
592
584
|
@klass.attribute :name, String
|
593
|
-
}.
|
585
|
+
}.to change(@klass, :attributes)
|
594
586
|
end
|
595
587
|
|
596
588
|
it "should allow adding an attribute containing a dash" do
|
597
|
-
|
589
|
+
expect {
|
598
590
|
@klass.attribute :'bar-baz', String
|
599
|
-
}.
|
591
|
+
}.to change(@klass, :attributes)
|
600
592
|
end
|
601
593
|
|
602
594
|
it "should be able to get all attributes in array" do
|
603
595
|
@klass.attribute :name, String
|
604
|
-
@klass.attributes.size.
|
596
|
+
expect(@klass.attributes.size).to eq(1)
|
605
597
|
end
|
606
598
|
|
607
599
|
it "should allow adding an element" do
|
608
|
-
|
600
|
+
expect {
|
609
601
|
@klass.element :name, String
|
610
|
-
}.
|
602
|
+
}.to change(@klass, :elements)
|
611
603
|
end
|
612
604
|
|
613
605
|
it "should allow adding an element containing a dash" do
|
614
|
-
|
606
|
+
expect {
|
615
607
|
@klass.element :'bar-baz', String
|
616
|
-
}.
|
608
|
+
}.to change(@klass, :elements)
|
617
609
|
|
618
610
|
end
|
619
611
|
|
620
612
|
it "should be able to get all elements in array" do
|
621
613
|
@klass.element(:name, String)
|
622
|
-
@klass.elements.size.
|
614
|
+
expect(@klass.elements.size).to eq(1)
|
623
615
|
end
|
624
616
|
|
625
617
|
it "should allow has one association" do
|
626
618
|
@klass.has_one(:user, User)
|
627
619
|
element = @klass.elements.first
|
628
|
-
element.name.
|
629
|
-
element.type.
|
630
|
-
element.options[:single].
|
620
|
+
expect(element.name).to eq('user')
|
621
|
+
expect(element.type).to eq(User)
|
622
|
+
expect(element.options[:single]).to eq(true)
|
631
623
|
end
|
632
624
|
|
633
625
|
it "should allow has many association" do
|
634
626
|
@klass.has_many(:users, User)
|
635
627
|
element = @klass.elements.first
|
636
|
-
element.name.
|
637
|
-
element.type.
|
638
|
-
element.options[:single].
|
628
|
+
expect(element.name).to eq('users')
|
629
|
+
expect(element.type).to eq(User)
|
630
|
+
expect(element.options[:single]).to eq(false)
|
639
631
|
end
|
640
632
|
|
641
633
|
it "should default tag name to lowercase class" do
|
642
|
-
@klass.tag_name.
|
634
|
+
expect(@klass.tag_name).to eq('boo')
|
643
635
|
end
|
644
636
|
|
645
637
|
it "should default tag name of class in modules to the last constant lowercase" do
|
646
638
|
module Bar; class Baz; include HappyMapper; end; end
|
647
|
-
Bar::Baz.tag_name.
|
639
|
+
expect(Bar::Baz.tag_name).to eq('baz')
|
648
640
|
end
|
649
641
|
|
650
642
|
it "should allow setting tag name" do
|
651
643
|
@klass.tag('FooBar')
|
652
|
-
@klass.tag_name.
|
644
|
+
expect(@klass.tag_name).to eq('FooBar')
|
653
645
|
end
|
654
646
|
|
655
647
|
it "should allow setting a namespace" do
|
656
648
|
@klass.namespace(namespace = "boo")
|
657
|
-
@klass.namespace.
|
649
|
+
expect(@klass.namespace).to eq(namespace)
|
658
650
|
end
|
659
651
|
|
660
652
|
it "should provide #parse" do
|
661
|
-
@klass.
|
653
|
+
expect(@klass).to respond_to(:parse)
|
662
654
|
end
|
663
655
|
end
|
664
656
|
|
665
657
|
describe "#attributes" do
|
666
658
|
it "should only return attributes for the current class" do
|
667
|
-
Post.attributes.size.
|
668
|
-
Status.attributes.size.
|
659
|
+
expect(Post.attributes.size).to eq(7)
|
660
|
+
expect(Status.attributes.size).to eq(0)
|
669
661
|
end
|
670
662
|
end
|
671
663
|
|
672
664
|
describe "#elements" do
|
673
665
|
it "should only return elements for the current class" do
|
674
|
-
Post.elements.size.
|
675
|
-
Status.elements.size.
|
666
|
+
expect(Post.elements.size).to eq(0)
|
667
|
+
expect(Status.elements.size).to eq(10)
|
676
668
|
end
|
677
669
|
end
|
678
670
|
|
@@ -680,7 +672,7 @@ describe HappyMapper do
|
|
680
672
|
it "should take String as default argument for type" do
|
681
673
|
State.content :name
|
682
674
|
address = Address.parse(fixture_file('address.xml'))
|
683
|
-
address.state.name.
|
675
|
+
expect(address.state.name).to eq("Lower Saxony")
|
684
676
|
address.state.name.class == String
|
685
677
|
end
|
686
678
|
|
@@ -688,97 +680,97 @@ describe HappyMapper do
|
|
688
680
|
Rate.content :value, Float
|
689
681
|
Product.has_one :rate, Rate
|
690
682
|
product = Product.parse(fixture_file('product_default_namespace.xml'), :single => true)
|
691
|
-
product.rate.value.
|
683
|
+
expect(product.rate.value).to eq(120.25)
|
692
684
|
product.rate.class == Float
|
693
685
|
end
|
694
686
|
end
|
695
687
|
|
696
688
|
it "should parse xml attributes into ruby objects" do
|
697
689
|
posts = Post.parse(fixture_file('posts.xml'))
|
698
|
-
posts.size.
|
690
|
+
expect(posts.size).to eq(20)
|
699
691
|
first = posts.first
|
700
|
-
first.href.
|
701
|
-
first.hash.
|
702
|
-
first.description.
|
703
|
-
first.tag.
|
704
|
-
first.time.
|
705
|
-
first.others.
|
706
|
-
first.extended.
|
692
|
+
expect(first.href).to eq('http://roxml.rubyforge.org/')
|
693
|
+
expect(first.hash).to eq('19bba2ab667be03a19f67fb67dc56917')
|
694
|
+
expect(first.description).to eq('ROXML - Ruby Object to XML Mapping Library')
|
695
|
+
expect(first.tag).to eq('ruby xml gems mapping')
|
696
|
+
expect(first.time).to eq(Time.utc(2008, 8, 9, 5, 24, 20))
|
697
|
+
expect(first.others).to eq(56)
|
698
|
+
expect(first.extended).to eq('ROXML is a Ruby library designed to make it easier for Ruby developers to work with XML. Using simple annotations, it enables Ruby classes to be custom-mapped to XML. ROXML takes care of the marshalling and unmarshalling of mapped attributes so that developers can focus on building first-class Ruby classes.')
|
707
699
|
end
|
708
700
|
|
709
701
|
it "should parse xml elements to ruby objcts" do
|
710
702
|
statuses = Status.parse(fixture_file('statuses.xml'))
|
711
|
-
statuses.size.
|
703
|
+
expect(statuses.size).to eq(20)
|
712
704
|
first = statuses.first
|
713
|
-
first.id.
|
714
|
-
first.created_at.
|
715
|
-
first.source.
|
716
|
-
first.truncated.
|
717
|
-
first.in_reply_to_status_id.
|
718
|
-
first.in_reply_to_user_id.
|
719
|
-
first.favorited.
|
720
|
-
first.user.id.
|
721
|
-
first.user.name.
|
722
|
-
first.user.screen_name.
|
723
|
-
first.user.location.
|
724
|
-
first.user.description.
|
725
|
-
first.user.profile_image_url.
|
726
|
-
first.user.url.
|
727
|
-
first.user.protected.
|
728
|
-
first.user.followers_count.
|
705
|
+
expect(first.id).to eq(882281424)
|
706
|
+
expect(first.created_at).to eq(Time.utc(2008, 8, 9, 5, 38, 12))
|
707
|
+
expect(first.source).to eq('web')
|
708
|
+
expect(first.truncated).to be_falsey
|
709
|
+
expect(first.in_reply_to_status_id).to eq(1234)
|
710
|
+
expect(first.in_reply_to_user_id).to eq(12345)
|
711
|
+
expect(first.favorited).to be_falsey
|
712
|
+
expect(first.user.id).to eq(4243)
|
713
|
+
expect(first.user.name).to eq('John Nunemaker')
|
714
|
+
expect(first.user.screen_name).to eq('jnunemaker')
|
715
|
+
expect(first.user.location).to eq('Mishawaka, IN, US')
|
716
|
+
expect(first.user.description).to eq('Loves his wife, ruby, notre dame football and iu basketball')
|
717
|
+
expect(first.user.profile_image_url).to eq('http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg')
|
718
|
+
expect(first.user.url).to eq('http://addictedtonew.com')
|
719
|
+
expect(first.user.protected).to be_falsey
|
720
|
+
expect(first.user.followers_count).to eq(486)
|
729
721
|
end
|
730
722
|
|
731
723
|
it "should parse xml containing the desired element as root node" do
|
732
724
|
address = Address.parse(fixture_file('address.xml'), :single => true)
|
733
|
-
address.street.
|
734
|
-
address.postcode.
|
735
|
-
address.housenumber.
|
736
|
-
address.city.
|
737
|
-
address.country.class.
|
725
|
+
expect(address.street).to eq('Milchstrasse')
|
726
|
+
expect(address.postcode).to eq('26131')
|
727
|
+
expect(address.housenumber).to eq('23')
|
728
|
+
expect(address.city).to eq('Oldenburg')
|
729
|
+
expect(address.country.class).to eq(Country)
|
738
730
|
end
|
739
731
|
|
740
732
|
it "should parse text node correctly" do
|
741
733
|
address = Address.parse(fixture_file('address.xml'), :single => true)
|
742
|
-
address.country.name.
|
743
|
-
address.country.code.
|
734
|
+
expect(address.country.name).to eq('Germany')
|
735
|
+
expect(address.country.code).to eq('de')
|
744
736
|
end
|
745
737
|
|
746
738
|
it "should treat Nokogiri::XML::Document as root" do
|
747
739
|
doc = Nokogiri::XML(fixture_file('address.xml'))
|
748
740
|
address = Address.parse(doc)
|
749
|
-
address.class.
|
741
|
+
expect(address.class).to eq(Address)
|
750
742
|
end
|
751
743
|
|
752
744
|
it "should parse xml with default namespace (amazon)" do
|
753
745
|
file_contents = fixture_file('pita.xml')
|
754
746
|
items = PITA::Items.parse(file_contents, :single => true)
|
755
|
-
items.total_results.
|
756
|
-
items.total_pages.
|
747
|
+
expect(items.total_results).to eq(22)
|
748
|
+
expect(items.total_pages).to eq(3)
|
757
749
|
first = items.items[0]
|
758
750
|
second = items.items[1]
|
759
|
-
first.asin.
|
760
|
-
first.point.
|
761
|
-
first.detail_page_url.
|
762
|
-
first.detail_page_url.to_s.
|
763
|
-
first.manufacturer.
|
764
|
-
first.product_group.
|
765
|
-
second.asin.
|
766
|
-
second.manufacturer.
|
751
|
+
expect(first.asin).to eq('0321480791')
|
752
|
+
expect(first.point).to eq('38.5351715088 -121.7948684692')
|
753
|
+
expect(first.detail_page_url).to be_a_kind_of(URI)
|
754
|
+
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')
|
755
|
+
expect(first.manufacturer).to eq('Addison-Wesley Professional')
|
756
|
+
expect(first.product_group).to eq('<ProductGroup>Book</ProductGroup>')
|
757
|
+
expect(second.asin).to eq('047022388X')
|
758
|
+
expect(second.manufacturer).to eq('Wrox')
|
767
759
|
end
|
768
760
|
|
769
761
|
it "should parse xml that has attributes of elements" do
|
770
762
|
items = CurrentWeather.parse(fixture_file('current_weather.xml'))
|
771
763
|
first = items[0]
|
772
|
-
first.temperature.
|
773
|
-
first.feels_like.
|
774
|
-
first.current_condition.
|
775
|
-
first.current_condition.icon.
|
764
|
+
expect(first.temperature).to eq(51)
|
765
|
+
expect(first.feels_like).to eq(51)
|
766
|
+
expect(first.current_condition).to eq('Sunny')
|
767
|
+
expect(first.current_condition.icon).to eq('http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif')
|
776
768
|
end
|
777
769
|
|
778
770
|
it "parses xml with attributes of elements that aren't :single => true" do
|
779
771
|
feed = Atom::Feed.parse(fixture_file('atom.xml'))
|
780
|
-
feed.link.first.href.
|
781
|
-
feed.link.last.href.
|
772
|
+
expect(feed.link.first.href).to eq('http://www.example.com')
|
773
|
+
expect(feed.link.last.href).to eq('http://www.example.com/tv_shows.atom')
|
782
774
|
end
|
783
775
|
|
784
776
|
it "parses xml with optional elements with embedded attributes" do
|
@@ -787,134 +779,134 @@ describe HappyMapper do
|
|
787
779
|
|
788
780
|
it "returns nil rather than empty array for absent values when :single => true" do
|
789
781
|
address = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true)
|
790
|
-
address.
|
782
|
+
expect(address).to be_nil
|
791
783
|
end
|
792
784
|
|
793
785
|
it "should return same result for absent values when :single => true, regardless of :in_groups_of" do
|
794
786
|
addr1 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true)
|
795
787
|
addr2 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true, :in_groups_of => 10)
|
796
|
-
addr1.
|
788
|
+
expect(addr1).to eq(addr2)
|
797
789
|
end
|
798
790
|
|
799
791
|
it "should parse xml with nested elements" do
|
800
792
|
radars = Radar.parse(fixture_file('radar.xml'))
|
801
793
|
first = radars[0]
|
802
|
-
first.places.size.
|
803
|
-
first.places[0].name.
|
794
|
+
expect(first.places.size).to eq(1)
|
795
|
+
expect(first.places[0].name).to eq('Store')
|
804
796
|
second = radars[1]
|
805
|
-
second.places.size.
|
797
|
+
expect(second.places.size).to eq(0)
|
806
798
|
third = radars[2]
|
807
|
-
third.places.size.
|
808
|
-
third.places[0].name.
|
809
|
-
third.places[1].name.
|
799
|
+
expect(third.places.size).to eq(2)
|
800
|
+
expect(third.places[0].name).to eq('Work')
|
801
|
+
expect(third.places[1].name).to eq('Home')
|
810
802
|
end
|
811
803
|
|
812
804
|
it "should parse xml with element name different to class name" do
|
813
805
|
game = QuarterTest::Game.parse(fixture_file('quarters.xml'))
|
814
|
-
game.q1.start.
|
815
|
-
game.q2.start.
|
806
|
+
expect(game.q1.start).to eq('4:40:15 PM')
|
807
|
+
expect(game.q2.start).to eq('5:18:53 PM')
|
816
808
|
end
|
817
809
|
|
818
810
|
it "should parse xml that has elements with dashes" do
|
819
811
|
commit = GitHub::Commit.parse(fixture_file('commit.xml'))
|
820
|
-
commit.message.
|
821
|
-
commit.url.
|
822
|
-
commit.id.
|
823
|
-
commit.committed_date.
|
824
|
-
commit.tree.
|
812
|
+
expect(commit.message).to eq("move commands.rb and helpers.rb into commands/ dir")
|
813
|
+
expect(commit.url).to eq("http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b")
|
814
|
+
expect(commit.id).to eq("c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b")
|
815
|
+
expect(commit.committed_date).to eq(Date.parse("2008-03-02T16:45:41-08:00"))
|
816
|
+
expect(commit.tree).to eq("28a1a1ca3e663d35ba8bf07d3f1781af71359b76")
|
825
817
|
end
|
826
818
|
|
827
819
|
it "should parse xml with no namespace" do
|
828
820
|
product = Product.parse(fixture_file('product_no_namespace.xml'), :single => true)
|
829
|
-
product.title.
|
830
|
-
product.feature_bullets.bug.
|
831
|
-
product.feature_bullets.features.size.
|
832
|
-
product.feature_bullets.features[0].name.
|
833
|
-
product.feature_bullets.features[1].name.
|
821
|
+
expect(product.title).to eq("A Title")
|
822
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
823
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
824
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
825
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
834
826
|
end
|
835
827
|
|
836
828
|
it "should parse xml with default namespace" do
|
837
829
|
product = Product.parse(fixture_file('product_default_namespace.xml'), :single => true)
|
838
|
-
product.title.
|
839
|
-
product.feature_bullets.bug.
|
840
|
-
product.feature_bullets.features.size.
|
841
|
-
product.feature_bullets.features[0].name.
|
842
|
-
product.feature_bullets.features[1].name.
|
830
|
+
expect(product.title).to eq("A Title")
|
831
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
832
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
833
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
834
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
843
835
|
end
|
844
836
|
|
845
837
|
it "should parse xml with single namespace" do
|
846
838
|
product = Product.parse(fixture_file('product_single_namespace.xml'), :single => true)
|
847
|
-
product.title.
|
848
|
-
product.feature_bullets.bug.
|
849
|
-
product.feature_bullets.features.size.
|
850
|
-
product.feature_bullets.features[0].name.
|
851
|
-
product.feature_bullets.features[1].name.
|
839
|
+
expect(product.title).to eq("A Title")
|
840
|
+
expect(product.feature_bullets.bug).to eq('This is a bug')
|
841
|
+
expect(product.feature_bullets.features.size).to eq(2)
|
842
|
+
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
843
|
+
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
852
844
|
end
|
853
845
|
|
854
846
|
it "should parse xml with multiple namespaces" do
|
855
847
|
track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
|
856
|
-
track.highest_severity.
|
857
|
-
track.more_data.
|
848
|
+
expect(track.highest_severity).to eq('SUCCESS')
|
849
|
+
expect(track.more_data).to be_falsey
|
858
850
|
notification = track.notifications.first
|
859
|
-
notification.code.
|
860
|
-
notification.localized_message.
|
861
|
-
notification.message.
|
862
|
-
notification.severity.
|
863
|
-
notification.source.
|
851
|
+
expect(notification.code).to eq(0)
|
852
|
+
expect(notification.localized_message).to eq('Request was successfully processed.')
|
853
|
+
expect(notification.message).to eq('Request was successfully processed.')
|
854
|
+
expect(notification.severity).to eq('SUCCESS')
|
855
|
+
expect(notification.source).to eq('trck')
|
864
856
|
detail = track.trackdetails.first
|
865
|
-
detail.carrier_code.
|
866
|
-
detail.est_delivery.
|
867
|
-
detail.service_info.
|
868
|
-
detail.status_code.
|
869
|
-
detail.status_desc.
|
870
|
-
detail.tracking_number.
|
871
|
-
detail.weight.units.
|
872
|
-
detail.weight.value.
|
857
|
+
expect(detail.carrier_code).to eq('FDXG')
|
858
|
+
expect(detail.est_delivery).to eq('2009-01-02T00:00:00')
|
859
|
+
expect(detail.service_info).to eq('Ground-Package Returns Program-Domestic')
|
860
|
+
expect(detail.status_code).to eq('OD')
|
861
|
+
expect(detail.status_desc).to eq('On FedEx vehicle for delivery')
|
862
|
+
expect(detail.tracking_number).to eq('9611018034267800045212')
|
863
|
+
expect(detail.weight.units).to eq('LB')
|
864
|
+
expect(detail.weight.value).to eq(2)
|
873
865
|
events = detail.events
|
874
|
-
events.size.
|
866
|
+
expect(events.size).to eq(10)
|
875
867
|
first_event = events[0]
|
876
|
-
first_event.eventdescription.
|
877
|
-
first_event.eventtype.
|
878
|
-
first_event.timestamp.
|
879
|
-
first_event.address.city.
|
880
|
-
first_event.address.countrycode.
|
881
|
-
first_event.address.residential.
|
882
|
-
first_event.address.state.
|
883
|
-
first_event.address.zip.
|
868
|
+
expect(first_event.eventdescription).to eq('On FedEx vehicle for delivery')
|
869
|
+
expect(first_event.eventtype).to eq('OD')
|
870
|
+
expect(first_event.timestamp).to eq('2009-01-02T06:00:00')
|
871
|
+
expect(first_event.address.city).to eq('WICHITA')
|
872
|
+
expect(first_event.address.countrycode).to eq('US')
|
873
|
+
expect(first_event.address.residential).to be_falsey
|
874
|
+
expect(first_event.address.state).to eq('KS')
|
875
|
+
expect(first_event.address.zip).to eq('67226')
|
884
876
|
last_event = events[-1]
|
885
|
-
last_event.eventdescription.
|
886
|
-
last_event.eventtype.
|
887
|
-
last_event.timestamp.
|
888
|
-
last_event.address.city.
|
889
|
-
last_event.address.countrycode.
|
890
|
-
last_event.address.residential.
|
891
|
-
last_event.address.state.
|
892
|
-
last_event.address.zip.
|
893
|
-
track.tran_detail.cust_tran_id.
|
877
|
+
expect(last_event.eventdescription).to eq('In FedEx possession')
|
878
|
+
expect(last_event.eventtype).to eq('IP')
|
879
|
+
expect(last_event.timestamp).to eq('2008-12-27T09:40:00')
|
880
|
+
expect(last_event.address.city).to eq('LONGWOOD')
|
881
|
+
expect(last_event.address.countrycode).to eq('US')
|
882
|
+
expect(last_event.address.residential).to be_falsey
|
883
|
+
expect(last_event.address.state).to eq('FL')
|
884
|
+
expect(last_event.address.zip).to eq('327506398')
|
885
|
+
expect(track.tran_detail.cust_tran_id).to eq('20090102-111321')
|
894
886
|
end
|
895
887
|
|
896
888
|
it "should be able to parse google analytics api xml" do
|
897
889
|
data = Analytics::Feed.parse(fixture_file('analytics.xml'))
|
898
|
-
data.id.
|
899
|
-
data.entries.size.
|
890
|
+
expect(data.id).to eq('http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com')
|
891
|
+
expect(data.entries.size).to eq(4)
|
900
892
|
|
901
893
|
entry = data.entries[0]
|
902
|
-
entry.title.
|
903
|
-
entry.properties.size.
|
894
|
+
expect(entry.title).to eq('addictedtonew.com')
|
895
|
+
expect(entry.properties.size).to eq(4)
|
904
896
|
|
905
897
|
property = entry.properties[0]
|
906
|
-
property.name.
|
907
|
-
property.value.
|
898
|
+
expect(property.name).to eq('ga:accountId')
|
899
|
+
expect(property.value).to eq('85301')
|
908
900
|
end
|
909
901
|
|
910
902
|
it "should be able to parse google analytics profile xml with manually declared namespace" do
|
911
903
|
data = Analytics::Profile.parse(fixture_file('analytics_profile.xml'))
|
912
|
-
data.entries.size.
|
904
|
+
expect(data.entries.size).to eq(6)
|
913
905
|
|
914
906
|
entry = data.entries[0]
|
915
|
-
entry.title.
|
916
|
-
entry.properties.size.
|
917
|
-
entry.goals.size.
|
907
|
+
expect(entry.title).to eq('www.homedepot.com')
|
908
|
+
expect(entry.properties.size).to eq(6)
|
909
|
+
expect(entry.goals.size).to eq(0)
|
918
910
|
end
|
919
911
|
|
920
912
|
it "should allow instantiating with a string" do
|
@@ -932,43 +924,43 @@ describe HappyMapper do
|
|
932
924
|
|
933
925
|
it "should parse family search xml" do
|
934
926
|
tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
|
935
|
-
tree.version.
|
936
|
-
tree.status_message.
|
937
|
-
tree.status_code.
|
938
|
-
tree.persons.person.size.
|
939
|
-
tree.persons.person.first.version.
|
940
|
-
tree.persons.person.first.modified.
|
941
|
-
tree.persons.person.first.id.
|
942
|
-
tree.persons.person.first.information.alternateIds.ids.
|
943
|
-
tree.persons.person.first.information.alternateIds.ids.size.
|
927
|
+
expect(tree.version).to eq('1.0.20071213.942')
|
928
|
+
expect(tree.status_message).to eq('OK')
|
929
|
+
expect(tree.status_code).to eq('200')
|
930
|
+
expect(tree.persons.person.size).to eq(1)
|
931
|
+
expect(tree.persons.person.first.version).to eq('1199378491000')
|
932
|
+
expect(tree.persons.person.first.modified).to eq(Time.utc(2008, 1, 3, 16, 41, 31)) # 2008-01-03T09:41:31-07:00
|
933
|
+
expect(tree.persons.person.first.id).to eq('KWQS-BBQ')
|
934
|
+
expect(tree.persons.person.first.information.alternateIds.ids).not_to be_kind_of(String)
|
935
|
+
expect(tree.persons.person.first.information.alternateIds.ids.size).to eq(8)
|
944
936
|
end
|
945
937
|
|
946
938
|
it "should parse multiple images" do
|
947
939
|
artist = Artist.parse(fixture_file('multiple_primitives.xml'))
|
948
|
-
artist.name.
|
949
|
-
artist.images.size.
|
940
|
+
expect(artist.name).to eq("value")
|
941
|
+
expect(artist.images.size).to eq(2)
|
950
942
|
end
|
951
943
|
|
952
944
|
it "should parse lastfm namespaces" do
|
953
945
|
l = Location.parse(fixture_file('lastfm.xml'))
|
954
|
-
l.first.latitude.
|
946
|
+
expect(l.first.latitude).to eq("51.53469")
|
955
947
|
end
|
956
948
|
|
957
949
|
describe "Parse optional attributes" do
|
958
950
|
|
959
951
|
it "should parse an empty String as empty" do
|
960
952
|
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
961
|
-
a[0].street.
|
953
|
+
expect(a[0].street).to eq("")
|
962
954
|
end
|
963
955
|
|
964
956
|
it "should parse a String with value" do
|
965
957
|
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
966
|
-
a[1].street.
|
958
|
+
expect(a[1].street).to eq("Milchstrasse")
|
967
959
|
end
|
968
960
|
|
969
961
|
it "should parse a String with value" do
|
970
962
|
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
971
|
-
a[2].street.
|
963
|
+
expect(a[2].street).to be_nil
|
972
964
|
end
|
973
965
|
|
974
966
|
end
|
@@ -980,15 +972,15 @@ describe HappyMapper do
|
|
980
972
|
end
|
981
973
|
|
982
974
|
it "should parse author" do
|
983
|
-
@book.author.
|
975
|
+
expect(@book.author).to eq("Frank Gilbreth")
|
984
976
|
end
|
985
977
|
|
986
978
|
it "should parse title" do
|
987
|
-
@book.title.
|
979
|
+
expect(@book.title).to eq("Cheaper by the Dozen")
|
988
980
|
end
|
989
981
|
|
990
982
|
it "should parse number" do
|
991
|
-
@book.number.
|
983
|
+
expect(@book.number).to eq("1568491379")
|
992
984
|
end
|
993
985
|
|
994
986
|
end
|
@@ -1000,42 +992,45 @@ describe HappyMapper do
|
|
1000
992
|
end
|
1001
993
|
|
1002
994
|
it "should parse XmlContent" do
|
1003
|
-
@records.first.definitions.first.text.
|
995
|
+
expect(@records.first.definitions.first.text).to eq(
|
1004
996
|
'a large common parrot, <bn>Cacatua galerita</bn>, predominantly white, with yellow on the undersides of wings and tail and a forward curving yellow crest, found in Australia, New Guinea and nearby islands.'
|
997
|
+
)
|
1005
998
|
end
|
1006
999
|
|
1007
1000
|
it "should save object's xml content" do
|
1008
|
-
@records.first.variants.first.xml_content.
|
1001
|
+
expect(@records.first.variants.first.xml_content).to eq(
|
1009
1002
|
'white <tag>cockatoo</tag>'
|
1010
|
-
|
1003
|
+
)
|
1004
|
+
expect(@records.first.variants.last.to_html).to eq(
|
1011
1005
|
'<em>white</em> cockatoo'
|
1006
|
+
)
|
1012
1007
|
end
|
1013
1008
|
end
|
1014
1009
|
|
1015
1010
|
it "should parse ambigous items" do
|
1016
1011
|
items = AmbigousItems::Item.parse(fixture_file('ambigous_items.xml'), :xpath => '/ambigous/my-items')
|
1017
|
-
items.map(&:name).
|
1012
|
+
expect(items.map(&:name)).to eq(%w(first second third).map{|s| "My #{s} item" })
|
1018
1013
|
end
|
1019
1014
|
|
1020
1015
|
|
1021
1016
|
context Article do
|
1022
1017
|
it "should parse the publish options for Article and Photo" do
|
1023
|
-
@article.title.
|
1024
|
-
@article.text.
|
1025
|
-
@article.photos.
|
1026
|
-
@article.photos.first.title.
|
1018
|
+
expect(@article.title).not_to be_nil
|
1019
|
+
expect(@article.text).not_to be_nil
|
1020
|
+
expect(@article.photos).not_to be_nil
|
1021
|
+
expect(@article.photos.first.title).not_to be_nil
|
1027
1022
|
end
|
1028
1023
|
|
1029
1024
|
it "should parse the publish options for Article" do
|
1030
|
-
@article.publish_options.
|
1025
|
+
expect(@article.publish_options).not_to be_nil
|
1031
1026
|
end
|
1032
1027
|
|
1033
1028
|
it "should parse the publish options for Photo" do
|
1034
|
-
@article.photos.first.publish_options.
|
1029
|
+
expect(@article.photos.first.publish_options).not_to be_nil
|
1035
1030
|
end
|
1036
1031
|
|
1037
1032
|
it "should only find only items at the parent level" do
|
1038
|
-
@article.photos.length.
|
1033
|
+
expect(@article.photos.length).to eq(1)
|
1039
1034
|
end
|
1040
1035
|
|
1041
1036
|
before(:all) do
|
@@ -1047,11 +1042,11 @@ describe HappyMapper do
|
|
1047
1042
|
context "Namespace is missing because an optional element that uses it is not present" do
|
1048
1043
|
it "should parse successfully" do
|
1049
1044
|
@article = PartiallyBadArticle.parse(fixture_file('subclass_namespace.xml'))
|
1050
|
-
@article.
|
1051
|
-
@article.title.
|
1052
|
-
@article.text.
|
1053
|
-
@article.photos.
|
1054
|
-
@article.photos.first.title.
|
1045
|
+
expect(@article).not_to be_nil
|
1046
|
+
expect(@article.title).not_to be_nil
|
1047
|
+
expect(@article.text).not_to be_nil
|
1048
|
+
expect(@article.photos).not_to be_nil
|
1049
|
+
expect(@article.photos.first.title).not_to be_nil
|
1055
1050
|
end
|
1056
1051
|
end
|
1057
1052
|
|
@@ -1059,18 +1054,18 @@ describe HappyMapper do
|
|
1059
1054
|
describe "with limit option" do
|
1060
1055
|
it "should return results with limited size: 6" do
|
1061
1056
|
sizes = []
|
1062
|
-
|
1057
|
+
Post.parse(fixture_file('posts.xml'), :in_groups_of => 6) do |a|
|
1063
1058
|
sizes << a.size
|
1064
1059
|
end
|
1065
|
-
sizes.
|
1060
|
+
expect(sizes).to eq([6, 6, 6, 2])
|
1066
1061
|
end
|
1067
1062
|
|
1068
1063
|
it "should return results with limited size: 10" do
|
1069
1064
|
sizes = []
|
1070
|
-
|
1065
|
+
Post.parse(fixture_file('posts.xml'), :in_groups_of => 10) do |a|
|
1071
1066
|
sizes << a.size
|
1072
1067
|
end
|
1073
|
-
sizes.
|
1068
|
+
expect(sizes).to eq([10, 10])
|
1074
1069
|
end
|
1075
1070
|
end
|
1076
1071
|
|
@@ -1092,7 +1087,7 @@ describe HappyMapper do
|
|
1092
1087
|
}
|
1093
1088
|
|
1094
1089
|
it 'initializes @nokogiri_config_callback to nil' do
|
1095
|
-
default.nokogiri_config_callback.
|
1090
|
+
expect(default.nokogiri_config_callback).to be_nil
|
1096
1091
|
end
|
1097
1092
|
|
1098
1093
|
it 'defaults to Nokogiri::XML::ParseOptions::STRICT' do
|
@@ -1100,7 +1095,7 @@ describe HappyMapper do
|
|
1100
1095
|
end
|
1101
1096
|
|
1102
1097
|
it 'accepts .on_config callback' do
|
1103
|
-
custom.nokogiri_config_callback.
|
1098
|
+
expect(custom.nokogiri_config_callback).not_to be_nil
|
1104
1099
|
end
|
1105
1100
|
|
1106
1101
|
it 'parses according to @nokogiri_config_callback' do
|
@@ -1113,4 +1108,22 @@ describe HappyMapper do
|
|
1113
1108
|
end
|
1114
1109
|
end
|
1115
1110
|
|
1111
|
+
context 'xml_value' do
|
1112
|
+
it 'does not reformat the xml' do
|
1113
|
+
xml = fixture_file('unformatted_address.xml')
|
1114
|
+
address = Address.parse(xml, single: true)
|
1115
|
+
|
1116
|
+
expect(address.xml_value).to eq %{<address><street>Milchstrasse</street><housenumber>23</housenumber></address>}
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
context 'xml_content' do
|
1121
|
+
it 'does not reformat the xml' do
|
1122
|
+
xml = fixture_file('unformatted_address.xml')
|
1123
|
+
address = Address.parse(xml)
|
1124
|
+
|
1125
|
+
expect(address.xml_content).to eq %{<street>Milchstrasse</street><housenumber>23</housenumber>}
|
1126
|
+
end
|
1127
|
+
end
|
1128
|
+
|
1116
1129
|
end
|