nokogiri-happymapper 0.5.9 → 0.6.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 +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
|