smg 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.rdoc +1 -1
  2. data/lib/smg/http.rb +23 -24
  3. data/lib/smg/http/exceptions.rb +5 -9
  4. data/lib/smg/http/hooks.rb +43 -0
  5. data/lib/smg/http/request.rb +23 -2
  6. data/lib/smg/mapping.rb +1 -3
  7. data/lib/smg/mapping/element.rb +1 -5
  8. data/lib/smg/mapping/typecasts.rb +1 -1
  9. data/lib/smg/model.rb +4 -4
  10. data/lib/smg/version.rb +1 -1
  11. metadata +32 -37
  12. data/examples/crazy.rb +0 -37
  13. data/examples/discogs/label.rb +0 -62
  14. data/examples/discogs/search.rb +0 -60
  15. data/examples/helper.rb +0 -10
  16. data/examples/plant.rb +0 -88
  17. data/examples/twitter.rb +0 -38
  18. data/examples/weather.rb +0 -147
  19. data/spec/collect_spec.rb +0 -272
  20. data/spec/context_spec.rb +0 -189
  21. data/spec/extract_spec.rb +0 -219
  22. data/spec/filtering_spec.rb +0 -164
  23. data/spec/fixtures/discogs/948224.xml +0 -1
  24. data/spec/fixtures/discogs/Enzyme+Records.xml +0 -9
  25. data/spec/fixtures/discogs/Genosha+Recordings.xml +0 -13
  26. data/spec/fixtures/discogs/Ophidian.xml +0 -6
  27. data/spec/fixtures/fake/malus.xml +0 -18
  28. data/spec/fixtures/fake/valve.xml +0 -8
  29. data/spec/fixtures/twitter/pipopolam.xml +0 -46
  30. data/spec/fixtures/yahoo.weather.com.xml +0 -50
  31. data/spec/http/request_spec.rb +0 -186
  32. data/spec/http/shared/automatic.rb +0 -43
  33. data/spec/http/shared/non_automatic.rb +0 -36
  34. data/spec/http/shared/redirectable.rb +0 -30
  35. data/spec/http_spec.rb +0 -76
  36. data/spec/lib/helpers/http_helpers.rb +0 -27
  37. data/spec/lib/matchers/instance_methods.rb +0 -38
  38. data/spec/mapping/element_spec.rb +0 -241
  39. data/spec/mapping/typecasts_spec.rb +0 -52
  40. data/spec/resource_spec.rb +0 -30
  41. data/spec/root_spec.rb +0 -26
  42. data/spec/spec_helper.rb +0 -23
@@ -1,62 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
2
-
3
- module Discogs
4
- class Label
5
-
6
- class Release
7
-
8
- include SMG::Resource
9
-
10
- extract 'release' , :at => :id, :as => :discogs_id, :class => :integer
11
- extract 'release' , :at => :status
12
-
13
- extract 'release/title'
14
- extract 'release/catno'
15
- extract 'release/artist'
16
- extract 'release/format'
17
-
18
- end
19
-
20
- include SMG::Resource
21
-
22
- root 'resp/label'
23
-
24
- extract 'name'
25
- extract 'contactinfo' , :as => :contacts
26
- extract 'profile'
27
- extract 'parentLabel' , :as => :parent
28
- collect 'urls/url' , :as => :links
29
- collect 'sublabels/label' , :as => :sublabels
30
- collect 'releases/release' , :as => :releases, :class => Release , :context => [:releases], :with => {"status" => "Accepted"}
31
-
32
- def name_with_parent
33
- "#{name}#{" @ #{parent}" if parent}"
34
- end
35
-
36
- end
37
- end
38
-
39
- data = File.read(ROOT.join('spec/fixtures/discogs/Enzyme+Records.xml'))
40
-
41
- template = <<-TEMPLATE
42
- <%= label.name_with_parent %>
43
-
44
- %label.sublabels.each do |sublabel|
45
- * <%= sublabel %>
46
- %end
47
-
48
- %label.releases.each do |release|
49
- * [<%= release.catno %>] <%= release.artist %> - <%= release.title %>
50
- %end
51
-
52
- TEMPLATE
53
-
54
- require 'erb'
55
-
56
- label = Discogs::Label.parse(data,:releases)
57
- $stdout << ERB.new(template, nil, "%").result(binding)
58
-
59
- label = Discogs::Label.parse(data)
60
- $stdout << ERB.new(template, nil, "%").result(binding)
61
-
62
- # EOF
@@ -1,60 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
2
-
3
- require 'zlib'
4
-
5
- module Discogs
6
-
7
- def self.search(t,q)
8
- Discogs::Search.get("search",
9
- :query => {"type" => t, "q" => q},
10
- :headers => {"Accept-Encoding" => "gzip,*;q=0"}) do |response|
11
- Zlib::GzipReader.new(StringIO.new(response.body)).read
12
- end
13
- end
14
-
15
- class Search
16
-
17
- include SMG::Resource
18
- include SMG::HTTP
19
-
20
- class ExactResult
21
- include SMG::Resource
22
- extract 'result', :at => 'type', :as => :resource_type
23
- extract 'result/title'
24
- extract 'result/uri'
25
- end
26
-
27
- class Result
28
- include SMG::Resource
29
- extract 'result', :at => 'type', :as => :resource_type
30
- extract 'result/title'
31
- extract 'result/uri'
32
- extract 'result/summary'
33
- end
34
-
35
- site "http://www.discogs.com"
36
- params "f" => "xml", "api_key" => "API_KEY"
37
-
38
- root 'resp'
39
- collect 'exactresults/result', :as => :exactresults, :class => ExactResult
40
- collect 'searchresults/result', :as => :results, :class => Result
41
-
42
- end
43
-
44
- end
45
-
46
- search = Discogs.search("all", "Genosha Recordings")
47
-
48
- puts <<-RESULT
49
- type: #{search.exactresults.first.resource_type}
50
- title: #{search.exactresults.first.title}
51
- URI: #{search.exactresults.first.uri}
52
- total: #{search.results.size}
53
- RESULT
54
-
55
- # type: label
56
- # title: Genosha Recordings
57
- # URI: http://www.discogs.com/label/Genosha+Recordings
58
- # total: 20
59
-
60
- # EOF
@@ -1,10 +0,0 @@
1
- require 'pathname'
2
-
3
- ROOT = Pathname(__FILE__).dirname.expand_path.parent
4
-
5
- dir = ROOT.join('lib').to_s
6
- $:.unshift(dir) unless $:.include?(dir)
7
-
8
- require 'smg'
9
-
10
- # EOF
@@ -1,88 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
-
3
- class Conservation
4
-
5
- include SMG::Resource
6
-
7
- extract :conservation , :at => :code
8
- extract :conservation , :at => :year , :context => [:conservation]
9
- extract :conservation , :as => :status , :context => [:conservation]
10
-
11
- end
12
-
13
- class Plant
14
-
15
- include SMG::Resource
16
-
17
- root 'spec'
18
-
19
- extract 'family' , :context => [:classification]
20
- extract 'genus' , :context => [:classification]
21
- extract 'binomial'
22
- extract 'conservation' , :context => [:conservation, :info], :class => Conservation
23
- collect 'synonims/binomial' , :context => [:synonims], :as => :synonims
24
-
25
- end
26
-
27
- data = <<-XML
28
- <?xml version="1.0" encoding="UTF-8"?>
29
- <spec>
30
- <family>Rosaceae</family>
31
- <genus>Malus</genus>
32
- <conservation code="NE" year="2007">Not Evaluated</conservation>
33
- <binomial>Malus pumila Mill.</binomial>
34
- <synonims>
35
- <binomial>Malus communis Poir.</binomial>
36
- <binomial>Malus domestica auct. non Borkh.</binomial>
37
- <binomial>Malus praecox (Pall.) Borkh.</binomial>
38
- <binomial>Malus pumila Mill. var. niedzwetzkyana (Dieck) C.K. Schneid.</binomial>
39
- <binomial>Malus sylvestris Amer. auth., non (L.) Mill.</binomial>
40
- <binomial>Malus sylvestris (L.) Mill. var. praecox (Pall.) Ponomar.</binomial>
41
- <binomial>Pyrus pumila (Mill.) K. Koch</binomial>
42
- </synonims>
43
- </spec>
44
- XML
45
-
46
- plant = Plant.parse(data,:classification)
47
-
48
- puts plant.family #=> "Rosaceae"
49
- puts plant.genus #=> "Malus"
50
- puts plant.binomial #=> "Malus pumila Mill."
51
- puts plant.conservation #=> nil
52
- puts plant.synonims #=> []
53
-
54
- plant = Plant.parse(data,:synonims)
55
-
56
- puts plant.family #=> nil
57
- puts plant.genus #=> nil
58
- puts plant.binomial #=> "Malus pumila Mill."
59
- puts plant.conservation #=> nil
60
- puts plant.synonims #=> [ "Malus communis Poir.",
61
- # "Malus domestica auct. non Borkh.",
62
- # "Malus praecox (Pall.) Borkh.",
63
- # "Malus pumila Mill. var. niedzwetzkyana (Dieck) C.K. Schneid.",
64
- # "Malus sylvestris Amer. auth., non (L.) Mill.",
65
- # "Malus sylvestris (L.) Mill. var. praecox (Pall.) Ponomar.",
66
- # "Pyrus pumila (Mill.) K. Koch" ]
67
-
68
- plant = Plant.parse(data,:conservation)
69
-
70
- puts plant.family #=> nil
71
- puts plant.genus #=> nil
72
- puts plant.binomial #=> "Malus pumila Mill."
73
- puts plant.conservation.status #=> "Not Evaluated"
74
- puts plant.conservation.code #=> "NE"
75
- puts plant.conservation.year #=> "2007"
76
- puts plant.synonims #=> []
77
-
78
- plant = Plant.parse(data,:info)
79
-
80
- puts plant.family #=> nil
81
- puts plant.genus #=> nil
82
- puts plant.binomial #=> "Malus pumila Mill."
83
- puts plant.conservation.status #=> nil
84
- puts plant.conservation.code #=> "NE"
85
- puts plant.conservation.status #=> nil
86
- puts plant.synonims #=> []
87
-
88
- # EOF
@@ -1,38 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
-
3
- class Status
4
- include SMG::Resource
5
-
6
- root 'status'
7
-
8
- extract :id , :class => :integer, :as => :status_id
9
- extract :created_at , :class => :datetime
10
- extract :text
11
-
12
- end
13
-
14
- class User
15
- include SMG::Resource
16
-
17
- root 'user'
18
-
19
- extract :id , :class => :integer, :as => :twitter_id
20
- extract :location , :class => :string
21
- extract :status , :class => Status
22
- extract :created_at , :class => :datetime
23
- extract :name
24
- extract :screen_name
25
-
26
- end
27
-
28
- data = File.read(ROOT.join('spec/fixtures/twitter/pipopolam.xml'))
29
- user = User.parse(data)
30
-
31
- puts <<-EOS
32
- ID: #{user.twitter_id}
33
- #{user.screen_name} (#{user.name}), since #{user.created_at.strftime('%Y.%m.%d')}
34
- location: #{user.location}
35
- status: #{user.status.text}
36
- EOS
37
-
38
- # EOF
@@ -1,147 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
-
3
- class YWeather
4
-
5
- CONDITION_CODES = {
6
- 1 => "tornado",
7
- 2 => "tropical storm",
8
- 3 => "hurricane",
9
- 4 => "severe thunderstorms",
10
- 4 => "thunderstorms",
11
- 5 => "mixed rain and snow",
12
- 6 => "mixed rain and sleet",
13
- 7 => "mixed snow and sleet",
14
- 8 => "freezing drizzle",
15
- 9 => "drizzle",
16
- 10 => "freezing rain",
17
- 11 => "showers",
18
- 12 => "showers",
19
- 13 => "snow flurries",
20
- 14 => "light snow showers",
21
- 15 => "blowing snow",
22
- 16 => "snow",
23
- 17 => "hail",
24
- 18 => "sleet",
25
- 19 => "dust",
26
- 20 => "foggy",
27
- 21 => "haze",
28
- 22 => "smoky",
29
- 23 => "blustery",
30
- 24 => "windy",
31
- 25 => "cold",
32
- 26 => "cloudy",
33
- 27 => "mostly cloudy (night)",
34
- 28 => "mostly cloudy (day)",
35
- 29 => "partly cloudy (night)",
36
- 30 => "partly cloudy (day)",
37
- 31 => "clear (night)",
38
- 32 => "sunny",
39
- 33 => "fair (night)",
40
- 34 => "fair (day)",
41
- 35 => "mixed rain and hail",
42
- 36 => "hot",
43
- 37 => "isolated thunderstorms",
44
- 38 => "scattered thunderstorms",
45
- 39 => "scattered thunderstorms",
46
- 40 => "scattered showers",
47
- 41 => "heavy snow",
48
- 42 => "scattered snow showers",
49
- 43 => "heavy snow",
50
- 44 => "partly cloudy",
51
- 45 => "thundershowers",
52
- 46 => "snow showers",
53
- 47 => "isolated thundershowers",
54
- 3200 => "not available"
55
- }
56
-
57
- class Forecast
58
- include SMG::Resource
59
-
60
- extract "yweather:forecast" , :at => :low
61
- extract "yweather:forecast" , :at => :high
62
- extract "yweather:forecast" , :at => :day
63
- extract "yweather:forecast" , :at => :date , :class => :datetime
64
- extract "yweather:forecast" , :at => :code , :class => :integer
65
- extract "yweather:forecast" , :at => :text
66
-
67
- def condition
68
- CONDITION_CODES[code]
69
- end
70
-
71
- end
72
-
73
- class Condition
74
- include SMG::Resource
75
-
76
- extract "yweather:condition" , :at => :temp
77
- extract "yweather:condition" , :at => :date
78
- extract "yweather:condition" , :at => :text
79
- extract "yweather:condition" , :at => :code , :class => :integer
80
-
81
- def condition
82
- CONDITION_CODES[code]
83
- end
84
-
85
- end
86
-
87
- class Units
88
- include SMG::Resource
89
-
90
- extract "yweather:units" , :at => :temperature
91
- extract "yweather:units" , :at => :distance
92
- extract "yweather:units" , :at => :pressure
93
- extract "yweather:units" , :at => :speed
94
- end
95
-
96
- class Atmosphere
97
- include SMG::Resource
98
-
99
- extract "yweather:atmosphere" , :at => :humidity
100
- extract "yweather:atmosphere" , :at => :visibility
101
- extract "yweather:atmosphere" , :at => :pressure
102
- extract "yweather:atmosphere" , :at => :rising
103
- end
104
-
105
- class Location
106
- include SMG::Resource
107
-
108
- extract "yweather:location" , :at => :city
109
- extract "yweather:location" , :at => :region
110
- extract "yweather:location" , :at => :country
111
- end
112
-
113
- class Wind
114
- include SMG::Resource
115
-
116
- extract "yweather:wind" , :at => :chill
117
- extract "yweather:wind" , :at => :direction
118
- extract "yweather:wind" , :at => :speed
119
- end
120
-
121
- include SMG::Resource
122
-
123
- root 'rss/channel'
124
-
125
- extract "lastBuildDate" , :as => :built_at
126
- extract "yweather:astronomy" , :at => :sunrise
127
- extract "yweather:astronomy" , :at => :sunset
128
- extract "yweather:location" , :as => :wind , :class => Location
129
- extract "yweather:units" , :as => :units , :class => Units
130
- extract "yweather:atmosphere" , :as => :atmosphere , :class => Atmosphere
131
- extract "yweather:wind" , :as => :wind , :class => Wind
132
-
133
- root 'rss/channel/item'
134
-
135
- extract "title"
136
- extract "description"
137
- extract "geo:lat" , :as => :latitude
138
- extract "geo:long" , :as => :longitude
139
- extract "yweather:condition" , :as => :current , :class => Condition
140
- collect "yweather:forecast" , :as => :forecasts , :class => Forecast
141
-
142
- end
143
-
144
- data = File.read(ROOT.join('spec/fixtures/yahoo.weather.com.xml'))
145
- yweather = YWeather.parse(data)
146
-
147
- # EOF
@@ -1,272 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
4
-
5
- describe SMG::Model, ".collect" do
6
-
7
- include Spec::Matchers::HaveInstanceMethodMixin
8
-
9
- before :each do
10
- @klass = Class.new { include SMG::Resource }
11
- @data = data = File.read(FIXTURES_DIR + 'discogs/Genosha+Recordings.xml')
12
- end
13
-
14
- it "defines appropriate reader and writer" do
15
- @klass.root 'resp/label'
16
- @klass.collect 'releases/release/catno', :as => :catalogue_numbers
17
- @klass.should have_instance_method 'catalogue_numbers'
18
- @klass.should have_instance_method 'append_to_catalogue_numbers'
19
- end
20
-
21
- it "never overrides readers" do
22
- @klass.root 'resp/label'
23
- @klass.collect 'urls/url', :as => :urls
24
- @klass.class_eval <<-CODE
25
- def urls
26
- unless @urls.nil?
27
- @urls.map{|u| u.empty? ? nil : u.strip}.compact.join(', ')
28
- end
29
- end
30
- CODE
31
- label = @klass.parse(@data)
32
- label.urls.should == 'http://www.genosharecordings.com/, http://www.myspace.com/genosharecordings'
33
- end
34
-
35
- it "never overrides writers" do
36
- @klass.root 'resp/label'
37
- @klass.collect 'urls/url', :as => :urls
38
- @klass.class_eval <<-CODE
39
- def append_to_urls(value)
40
- unless value.nil? || value.empty?
41
- @urls ||= []
42
- @urls << URI.parse(value)
43
- end
44
- end
45
- CODE
46
- label = @klass.parse(@data)
47
- label.urls.should be_an_instance_of ::Array
48
- label.urls.should == [
49
- URI.parse('http://www.genosharecordings.com/'),
50
- URI.parse('http://www.myspace.com/genosharecordings')
51
- ]
52
- end
53
-
54
- end
55
-
56
- describe SMG::Model, ".collect", "without :class option" do
57
-
58
- before :each do
59
- @klass = Class.new { include SMG::Resource }
60
- @data = data = File.read(FIXTURES_DIR + 'discogs/Genosha+Recordings.xml')
61
- end
62
-
63
- it "collects texts" do
64
- @klass.root 'resp/label'
65
- @klass.collect 'releases/release/catno', :as => :catalogue_numbers
66
- label = @klass.parse(@data)
67
- label.catalogue_numbers.should be_an_instance_of ::Array
68
- label.catalogue_numbers.should == ["GEN 001", "GEN 001", "GEN 002", "GEN 003", "GEN 006", "GEN 008", "GEN 008", "GEN 009", "GEN 012", "GEN 013", "GEN 015", "GEN004", "GEN005", "GEN006½", "GEN007", "GEN009", "GEN010", "GEN011", "GEN012", "GEN014", "GEN016", "GEN017", "GENCD01", "GENOSHA 018"]
69
- end
70
-
71
- it "collects attributes" do
72
- @klass.root 'resp/label'
73
- @klass.collect 'releases/release', :at => :id , :as => :release_ids
74
- @klass.collect 'releases/release', :at => :status , :as => :release_statuses
75
- label = @klass.parse(@data)
76
- label.release_ids.should be_an_instance_of ::Array
77
- label.release_statuses.should be_an_instance_of ::Array
78
- label.release_ids.should == ["183713", "1099277", "183735", "225253", "354681", "1079143", "448035", "1083336", "1079145", "814757", "964449", "254166", "341855", "387611", "396345", "448709", "529057", "662611", "683859", "915651", "1021944", "1494949", "354683", "1825580"]
79
- label.release_statuses.should == ["Accepted"]*24
80
- end
81
-
82
- it "is able to build multiple datasets" do
83
- custom_xml = <<-XML
84
- <releases>
85
- <release id="2259548" status="Accepted" type="TrackAppearance">Signal Flow Podcast 03</release>
86
- <release id="2283715" status="Accepted" type="TrackAppearance">United Hardcore Forces</release>
87
- <release id="2283652" status="Accepted" type="TrackAppearance">Warp Madness</release>
88
- <release id="1775742" status="Accepted" type="UnofficialRelease">Stalker 2.9 Level 3 Compilation</release>
89
- </release>
90
- XML
91
-
92
- @klass.collect 'releases/release', :at => :id, :as => :ids
93
- @klass.collect 'releases/release', :at => :type, :as => :types
94
- @klass.collect 'releases/release', :as => :titles
95
-
96
- collection = @klass.parse(custom_xml)
97
- collection.ids.should == ["2259548", "2283715", "2283652", "1775742"]
98
- collection.types.should == ["TrackAppearance", "TrackAppearance", "TrackAppearance", "UnofficialRelease"]
99
- collection.titles.should == ["Signal Flow Podcast 03", "United Hardcore Forces", "Warp Madness", "Stalker 2.9 Level 3 Compilation"]
100
- end
101
-
102
- it "collects nothing when there's no matching elements" do
103
- @klass.root 'resp/label'
104
- @klass.collect 'releases/release', :at => :bogus, :as => :release_ids
105
- label = @klass.parse(@data)
106
- label.release_ids.should be_an_instance_of ::Array
107
- label.release_ids.should be_empty
108
- end
109
-
110
- end
111
-
112
- describe SMG::Model, ".collect", "when :class option represents SMG::Resource" do
113
-
114
- before :each do
115
- @klass = Class.new { include SMG::Resource }
116
- @data = data = File.read(FIXTURES_DIR + 'discogs/Genosha+Recordings.xml')
117
- end
118
-
119
- before :each do
120
- @release_class = Class.new { include SMG::Resource }
121
- @release_class.extract 'release' , :at => :id , :as => :discogs_id
122
- @release_class.extract 'release' , :at => :status
123
- @release_class.extract 'release/title'
124
-
125
- @image_class = Class.new { include SMG::Resource }
126
- @image_class.extract 'image', :at => :uri
127
- @image_class.extract 'image', :at => :uri150, :as => :preview
128
- @image_class.extract 'image', :at => :width
129
- @image_class.extract 'image', :at => :height
130
- end
131
-
132
- it "collects resources" do
133
- @klass.root 'resp/label'
134
- @klass.collect 'releases/release', :as => :releases, :class => @release_class
135
- label = @klass.parse(@data)
136
- label.releases.should be_an_instance_of ::Array
137
- label.releases.size.should == 24
138
- label.releases[8].title.should == "No, We Don't Want You To Clap Your Fucking Hands"
139
- label.releases[8].discogs_id.should == "1079145"
140
- label.releases[8].status.should == "Accepted"
141
- end
142
-
143
- it "is able to build multiple collections" do
144
- @klass.root 'resp/label'
145
- @klass.collect 'releases/release' , :as => :releases , :class => @release_class
146
- @klass.collect 'images/image' , :as => :images , :class => @image_class
147
- @klass.collect 'releases/release' , :as => :release_ids , :at => :id
148
- label = @klass.parse(@data)
149
-
150
- label.releases.should be_an_instance_of ::Array
151
- label.releases.size.should == 24
152
- label.releases[8].should be_an_instance_of @release_class
153
- label.releases[8].title.should == "No, We Don't Want You To Clap Your Fucking Hands"
154
- label.releases[8].discogs_id.should == "1079145"
155
-
156
- label.images.should be_an_instance_of ::Array
157
- label.images.size.should == 2
158
- label.images[1].should be_an_instance_of @image_class
159
- label.images[1].width.should == '600'
160
- label.images[1].height.should == '159'
161
- label.images[1].uri.should == 'http://www.discogs.com/image/L-16366-1165574398.jpeg'
162
- label.images[1].preview.should == 'http://www.discogs.com/image/L-150-16366-1165574398.jpeg'
163
-
164
- label.release_ids.should == ["183713", "1099277", "183735", "225253", "354681", "1079143", "448035", "1083336", "1079145", "814757", "964449", "254166", "341855", "387611", "396345", "448709", "529057", "662611", "683859", "915651", "1021944", "1494949", "354683", "1825580"]
165
- end
166
-
167
- it "collects nothing when there's no matching elements" do
168
- @klass.root 'resp/label'
169
- @klass.collect 'releases/bogus', :as => :releases, :class => @release_class
170
- label = @klass.parse(@data)
171
- label.releases.should be_an_instance_of ::Array
172
- label.releases.should be_empty
173
- end
174
-
175
- end
176
-
177
- describe SMG::Model, ".collect", "when :class option represents built-in typecast" do
178
-
179
- before :each do
180
- @klass = Class.new { include SMG::Resource }
181
- @data = data = File.read(FIXTURES_DIR + 'discogs/Genosha+Recordings.xml')
182
- end
183
-
184
- it "makes an attempt to perform a typecast" do
185
- Class.new { include SMG::Resource }
186
- @klass.root 'resp/label'
187
- @klass.collect 'releases/release', :at => :id, :class => :integer, :as => :release_ids
188
- label = @klass.parse(@data)
189
- label.release_ids.should == [183713, 1099277, 183735, 225253, 354681, 1079143, 448035, 1083336, 1079145, 814757, 964449, 254166, 341855, 387611, 396345, 448709, 529057, 662611, 683859, 915651, 1021944, 1494949, 354683, 1825580]
190
- end
191
-
192
- it "raises an ArgumentError if typecasting fails" do
193
- Class.new { include SMG::Resource }
194
- @klass.root 'resp/label'
195
- @klass.collect 'releases/release', :at => :id, :class => :datetime, :as => :release_ids
196
- lambda { @klass.parse(@data) }.
197
- should raise_error ArgumentError, %r{"183713" is not a valid source for :datetime}
198
- end
199
-
200
- end
201
-
202
- describe SMG::Model, ".collect", "with nested collections" do
203
-
204
- before :each do
205
- @klass = Class.new { include SMG::Resource }
206
- @data = data = File.read(FIXTURES_DIR + 'discogs/948224.xml')
207
- end
208
-
209
- before :each do
210
- @artist_class = Class.new { include SMG::Resource }
211
- @artist_class.root 'artist'
212
- @artist_class.extract :name
213
- @artist_class.extract :role
214
-
215
- @track_class = Class.new { include SMG::Resource }
216
- @track_class.root 'track'
217
- @track_class.extract :position
218
- @track_class.extract :title
219
- @track_class.extract :duration
220
- @track_class.collect 'extraartists/artist', :as => :extra_artists, :class => @artist_class
221
- end
222
-
223
- after :each do
224
- @release.tracks.should be_an_instance_of ::Array
225
- @release.tracks.size.should == 6
226
-
227
- track = @release.tracks[1]
228
- track.position.should == 'A2'
229
- track.title.should == 'Butterfly V.I.P. (Interlude By Cubist Boy & Tapage)'
230
- track.duration.should == '1:24'
231
-
232
- track.extra_artists.should be_an_instance_of ::Array
233
- track.extra_artists.size.should == 2
234
- track.extra_artists[1].name.should == 'Tapage'
235
- track.extra_artists[1].role.should == 'Co-producer'
236
- end
237
-
238
- it "supports nested collections" do
239
- @klass.root 'resp/release'
240
- @klass.collect 'tracklist/track', :as => :tracks, :class => @track_class
241
-
242
- @release = @klass.parse(@data)
243
- end
244
-
245
- it "handles each collection independently" do
246
-
247
- @track_class.collect 'extraartists/artist/name', :as => :extra_artist_names
248
-
249
- @klass.root 'resp/release/tracklist'
250
- @klass.collect 'track' , :as => :tracks, :class => @track_class
251
- @klass.collect 'track/title' , :as => :tracklist
252
- @klass.collect 'track/extraartists/artist' , :as => :extra_artists, :class => @artist_class
253
-
254
- @release = @klass.parse(@data)
255
-
256
- @release.tracklist.should be_an_instance_of ::Array
257
- @release.tracklist.size.should == 6
258
- @release.tracklist.should == ["Butterfly V.I.P. (VIP Edit By Ophidian)", "Butterfly V.I.P. (Interlude By Cubist Boy & Tapage)", "Butterfly V.I.P. (Original Version)", "Hammerhead V.I.P. (VIP Edit By Ophidian)", "Hammerhead V.I.P. (Interlude By Cubist Boy & Tapage)", "Hammerhead V.I.P. (Original Version)"]
259
-
260
- @release.tracks.should be_an_instance_of ::Array
261
- @release.tracks.size.should == 6
262
-
263
- @release.extra_artists.should be_an_instance_of ::Array
264
- @release.extra_artists.size.should == 6
265
- @release.extra_artists[2].name.should == 'Tapage'
266
- @release.extra_artists[2].role.should == 'Co-producer'
267
-
268
- end
269
-
270
- end
271
-
272
- # EOF