smg 0.1.0 → 0.2.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.
- data/README.rdoc +6 -62
- data/examples/discogs/label.rb +62 -0
- data/examples/discogs/search.rb +60 -0
- data/examples/plant.rb +1 -2
- data/examples/twitter.rb +8 -5
- data/examples/weather.rb +146 -0
- data/lib/smg.rb +4 -0
- data/lib/smg/document.rb +25 -8
- data/lib/smg/http.rb +66 -0
- data/lib/smg/http/exceptions.rb +37 -0
- data/lib/smg/http/request.rb +126 -0
- data/lib/smg/mapping.rb +11 -1
- data/lib/smg/mapping/element.rb +29 -13
- data/lib/smg/mapping/typecasts.rb +2 -1
- data/lib/smg/model.rb +9 -3
- data/lib/smg/resource.rb +5 -1
- data/spec/collect_spec.rb +254 -0
- data/spec/context_spec.rb +189 -0
- data/spec/extract_spec.rb +200 -0
- data/spec/filtering_spec.rb +164 -0
- data/spec/fixtures/discogs/948224.xml +1 -0
- data/spec/fixtures/discogs/Enzyme+Records.xml +9 -0
- data/spec/fixtures/discogs/Genosha+Recordings.xml +13 -0
- data/spec/fixtures/discogs/Ophidian.xml +6 -0
- data/spec/fixtures/fake/malus.xml +18 -0
- data/spec/fixtures/fake/valve.xml +8 -0
- data/spec/fixtures/twitter/pipopolam.xml +46 -0
- data/spec/fixtures/yahoo.weather.com.xml +50 -0
- data/spec/http/request_spec.rb +186 -0
- data/spec/http/shared/automatic.rb +43 -0
- data/spec/http/shared/non_automatic.rb +36 -0
- data/spec/http/shared/redirectable.rb +30 -0
- data/spec/http_spec.rb +76 -0
- data/spec/lib/helpers/http_helpers.rb +27 -0
- data/spec/lib/matchers/instance_methods.rb +38 -0
- data/spec/mapping/element_spec.rb +241 -0
- data/spec/mapping/typecasts_spec.rb +52 -0
- data/spec/resource_spec.rb +30 -0
- data/spec/root_spec.rb +26 -0
- data/spec/spec_helper.rb +23 -0
- metadata +53 -10
- data/examples/discogs.rb +0 -39
@@ -0,0 +1,189 @@
|
|
1
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe SMG::Model do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@klass = Class.new { include SMG::Resource }
|
7
|
+
@data = data = File.read(FIXTURES_DIR + 'fake/malus.xml')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".extract with context" do
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
@data = File.read(FIXTURES_DIR + 'fake/malus.xml')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "does not extract data with the custom :context, when no context passed" do
|
17
|
+
|
18
|
+
@klass.root 'spec'
|
19
|
+
|
20
|
+
@klass.extract :genus
|
21
|
+
@klass.extract :binomial
|
22
|
+
@klass.extract :conservation , :context => [:conservation]
|
23
|
+
|
24
|
+
malus = @klass.parse(@data)
|
25
|
+
malus.genus.should == "Malus"
|
26
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
27
|
+
malus.conservation.should be_nil
|
28
|
+
|
29
|
+
malus = @klass.parse(@data, :conservation)
|
30
|
+
malus.genus.should == "Malus"
|
31
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
32
|
+
malus.conservation.should == "Vulnerable (IUCN 2.3)"
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
it "respects the :context of elements and attributes" do
|
37
|
+
|
38
|
+
@klass.root 'spec'
|
39
|
+
|
40
|
+
@klass.extract :genus , :context => [:classification]
|
41
|
+
@klass.extract :binomial , :context => [:conservation, :classification]
|
42
|
+
@klass.extract :conservation , :context => [:conservation], :as => :status
|
43
|
+
@klass.extract :conservation , :context => [:conservation], :at => :code
|
44
|
+
|
45
|
+
malus = @klass.parse(@data,:conservation)
|
46
|
+
malus.genus.should be_nil
|
47
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
48
|
+
malus.status.should == "Vulnerable (IUCN 2.3)"
|
49
|
+
malus.code.should == "VU"
|
50
|
+
|
51
|
+
malus = @klass.parse(@data,:classification)
|
52
|
+
malus.genus.should == "Malus"
|
53
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
54
|
+
malus.status.should be_nil
|
55
|
+
malus.code.should be_nil
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
it "respects the :context of nested resources" do
|
60
|
+
|
61
|
+
cclass = Class.new { include SMG::Resource }
|
62
|
+
cclass.extract :conservation , :at => :code
|
63
|
+
cclass.extract :conservation , :as => :status
|
64
|
+
|
65
|
+
@klass.root 'spec'
|
66
|
+
|
67
|
+
@klass.extract :genus , :context => [:classification]
|
68
|
+
@klass.extract :binomial , :context => [:conservation, :classification]
|
69
|
+
@klass.extract :conservation , :context => [:conservation], :class => cclass
|
70
|
+
|
71
|
+
malus = @klass.parse(@data,:classification)
|
72
|
+
malus.genus.should == "Malus"
|
73
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
74
|
+
malus.conservation.should be_nil
|
75
|
+
|
76
|
+
malus = @klass.parse(@data,:conservation)
|
77
|
+
malus.genus.should be_nil
|
78
|
+
malus.binomial.should == "Malus sieversii (Ledeb.) M.Roem."
|
79
|
+
|
80
|
+
malus.conservation.should be_an_instance_of cclass
|
81
|
+
malus.conservation.status.should == "Vulnerable (IUCN 2.3)"
|
82
|
+
malus.conservation.code.should == "VU"
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
it "respects the :context IN nested resources" do
|
87
|
+
|
88
|
+
cclass = Class.new { include SMG::Resource }
|
89
|
+
cclass.extract :conservation , :at => :code , :context => [:conservation]
|
90
|
+
cclass.extract :conservation , :as => :status , :context => [:conservation, :info]
|
91
|
+
|
92
|
+
@klass.root 'spec'
|
93
|
+
@klass.extract :conservation , :class => cclass
|
94
|
+
|
95
|
+
malus = @klass.parse(@data,:conservation)
|
96
|
+
malus.conservation.should be_an_instance_of cclass
|
97
|
+
malus.conservation.status.should == "Vulnerable (IUCN 2.3)"
|
98
|
+
malus.conservation.code.should == "VU"
|
99
|
+
|
100
|
+
malus = @klass.parse(@data,:info)
|
101
|
+
malus.conservation.should be_an_instance_of cclass
|
102
|
+
malus.conservation.status.should == "Vulnerable (IUCN 2.3)"
|
103
|
+
malus.conservation.code.should be_nil
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
describe ".collect with context" do
|
110
|
+
|
111
|
+
before :each do
|
112
|
+
@data = File.read(FIXTURES_DIR + 'discogs/Ophidian.xml')
|
113
|
+
end
|
114
|
+
|
115
|
+
it "does not collect data with the custom :context, when no context passed" do
|
116
|
+
|
117
|
+
@klass.root 'resp/artist'
|
118
|
+
@klass.collect 'namevariations/name' , :as => :namevariations
|
119
|
+
@klass.collect 'aliases/name' , :as => :aliases, :context => [:aliases]
|
120
|
+
|
121
|
+
ophidian = @klass.parse(@data)
|
122
|
+
ophidian.namevariations.should == ["Ohidian", "Ophidian as Raziel", "Ophidian [C. Hoyer]", "Ophidiom"]
|
123
|
+
ophidian.aliases.should be_an ::Array
|
124
|
+
ophidian.aliases.should be_empty
|
125
|
+
|
126
|
+
ophidian = @klass.parse(@data, :aliases)
|
127
|
+
ophidian.namevariations.should == ["Ohidian", "Ophidian as Raziel", "Ophidian [C. Hoyer]", "Ophidiom"]
|
128
|
+
ophidian.aliases.should == ["Conrad Hoyer", "Cubist Boy", "Meander", "Trypticon"]
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
it "respects the :context of collections" do
|
133
|
+
|
134
|
+
@klass.root 'resp/artist'
|
135
|
+
@klass.collect 'namevariations/name' , :context => [:namevariations] , :as => :namevariations
|
136
|
+
@klass.collect 'aliases/name' , :context => [:aliases] , :as => :aliases
|
137
|
+
|
138
|
+
ophidian = @klass.parse(@data,:namevariations)
|
139
|
+
ophidian.namevariations.should == ["Ohidian", "Ophidian as Raziel", "Ophidian [C. Hoyer]", "Ophidiom"]
|
140
|
+
ophidian.aliases.should be_an ::Array
|
141
|
+
ophidian.aliases.should be_empty
|
142
|
+
|
143
|
+
ophidian = @klass.parse(@data,:aliases)
|
144
|
+
ophidian.namevariations.should be_an ::Array
|
145
|
+
ophidian.namevariations.should be_empty
|
146
|
+
ophidian.aliases.should == ["Conrad Hoyer", "Cubist Boy", "Meander", "Trypticon"]
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
it "respects the :context IN collections" do
|
151
|
+
|
152
|
+
imgclass = Class.new { include SMG::Resource }
|
153
|
+
imgclass.extract :image , :at => :uri150 , :as => :preview
|
154
|
+
imgclass.extract :image , :at => :uri , :as => :fullsize , :context => [:everything]
|
155
|
+
imgclass.extract :image , :at => :height , :context => [:everything]
|
156
|
+
imgclass.extract :image , :at => :width , :context => [:everything]
|
157
|
+
|
158
|
+
@klass.root 'resp/artist'
|
159
|
+
@klass.collect 'images/image', :as => :images, :class => imgclass
|
160
|
+
|
161
|
+
ophidian = @klass.parse(@data)
|
162
|
+
ophidian.images.should be_an ::Array
|
163
|
+
ophidian.images.size.should == 5
|
164
|
+
|
165
|
+
image = ophidian.images[2]
|
166
|
+
image.should be_an_instance_of imgclass
|
167
|
+
image.height.should be_nil
|
168
|
+
image.width.should be_nil
|
169
|
+
image.fullsize.should be_nil
|
170
|
+
image.preview.should == "http://www.discogs.com/image/A-150-15203-1172410732.jpeg"
|
171
|
+
|
172
|
+
ophidian = @klass.parse(@data, :everything)
|
173
|
+
ophidian.images.should be_an ::Array
|
174
|
+
ophidian.images.size.should == 5
|
175
|
+
|
176
|
+
image = ophidian.images[2]
|
177
|
+
image.should be_an_instance_of imgclass
|
178
|
+
image.height.should == "399"
|
179
|
+
image.width.should == "598"
|
180
|
+
image.fullsize.should == "http://www.discogs.com/image/A-15203-1172410732.jpeg"
|
181
|
+
image.preview.should == "http://www.discogs.com/image/A-150-15203-1172410732.jpeg"
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
# EOF
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe SMG::Model, ".extract" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@klass = Class.new { include SMG::Resource }
|
7
|
+
@data = File.read(FIXTURES_DIR + 'fake/malus.xml')
|
8
|
+
end
|
9
|
+
|
10
|
+
include Spec::Matchers::HaveInstanceMethodMixin
|
11
|
+
|
12
|
+
it "defines appropriate reader and writer" do
|
13
|
+
@klass.extract :whatever
|
14
|
+
@klass.should have_instance_method :whatever
|
15
|
+
@klass.should have_instance_method :whatever=
|
16
|
+
end
|
17
|
+
|
18
|
+
it "never overrides readers" do
|
19
|
+
@klass.class_eval "def kingdom; return @kingdom.to_s.upcase; end"
|
20
|
+
@klass.root 'spec'
|
21
|
+
@klass.extract :kingdom
|
22
|
+
malus = @klass.parse(@data)
|
23
|
+
malus.kingdom.should == "PLANTAE"
|
24
|
+
malus.instance_variable_get(:@kingdom).should == "Plantae"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "never overrides writers" do
|
28
|
+
@klass.class_eval "def kingdom=(value); @kingdom = value.to_s.upcase; end"
|
29
|
+
@klass.root 'spec'
|
30
|
+
@klass.extract :kingdom
|
31
|
+
malus = @klass.parse(@data)
|
32
|
+
malus.kingdom.should == "PLANTAE"
|
33
|
+
malus.instance_variable_get(:@kingdom).should == "PLANTAE"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "extracts an empty String if there's an empty element" do
|
37
|
+
@klass.root 'spec'
|
38
|
+
@klass.extract :additional
|
39
|
+
malus = @klass.parse(@data)
|
40
|
+
malus.additional.should == ""
|
41
|
+
end
|
42
|
+
|
43
|
+
it "extracts nothing if there's no appropriate element" do
|
44
|
+
@klass.root 'spec'
|
45
|
+
@klass.extract :bogus
|
46
|
+
malus = @klass.parse(@data)
|
47
|
+
malus.bogus.should == nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "extracts the text of an element otherwise" do
|
51
|
+
@klass.root 'spec'
|
52
|
+
@klass.extract :genus
|
53
|
+
malus = @klass.parse(@data)
|
54
|
+
malus.should respond_to :genus
|
55
|
+
malus.should respond_to :genus=
|
56
|
+
malus.genus.should == 'Malus'
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "using :at option" do
|
60
|
+
|
61
|
+
it "extracts the appropriate attribute" do
|
62
|
+
@klass.extract 'spec/conservation', :as => :conservation_code, :at => :code
|
63
|
+
malus = @klass.parse(@data)
|
64
|
+
malus.conservation_code.should == 'VU'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "extracts nothing if there'no appropriate attribute" do
|
68
|
+
@klass.extract 'spec/conservation', :as => :conservation_code, :at => :bogus
|
69
|
+
malus = @klass.parse(@data)
|
70
|
+
malus.conservation_code.should == nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "extracts nothing if there'no appropriate element" do
|
74
|
+
@klass.extract 'spec/whatever', :as => :whatever, :at => :bogus
|
75
|
+
malus = @klass.parse(@data)
|
76
|
+
malus.whatever.should == nil
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "using :as option" do
|
82
|
+
|
83
|
+
it "defines appropriate reader and writer" do
|
84
|
+
@klass.extract 'spec/conservation', :as => :conservation_status
|
85
|
+
malus = @klass.parse(@data)
|
86
|
+
malus.should respond_to :conservation_status
|
87
|
+
malus.should respond_to :conservation_status=
|
88
|
+
end
|
89
|
+
|
90
|
+
it "extracts data from an element using the 'as' accessor" do
|
91
|
+
@klass.extract 'spec/conservation', :as => :conservation_status
|
92
|
+
malus = @klass.parse(@data)
|
93
|
+
malus.conservation_status.should == 'Vulnerable (IUCN 2.3)'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "extracts nothing if there's no appropriate element" do
|
97
|
+
@klass.extract 'spec/bogus', :as => :conservation_code, :at => :bogus
|
98
|
+
malus = @klass.parse(@data)
|
99
|
+
malus.conservation_code.should == nil
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "using :class option" do
|
105
|
+
|
106
|
+
describe "when :class represents an SMG::Resource" do
|
107
|
+
|
108
|
+
it "extracts data into the class (AKA has_one)" do
|
109
|
+
@foo = Class.new
|
110
|
+
@foo.send(:include, SMG::Resource)
|
111
|
+
@foo.root 'description'
|
112
|
+
@foo.extract :common
|
113
|
+
@foo.extract :described_by
|
114
|
+
@foo.extract :described_as
|
115
|
+
@foo.extract :described_at
|
116
|
+
@klass.extract 'spec/description' , :as => :description, :class => @foo
|
117
|
+
malus = @klass.parse(@data)
|
118
|
+
malus.description.should be_an_instance_of @foo
|
119
|
+
malus.description.common.should == "Asian Wild Apple"
|
120
|
+
malus.description.described_at.should == "1983"
|
121
|
+
malus.description.described_by.should == "Carl Friedrich von Ledebour"
|
122
|
+
malus.description.described_as.should == "Pyrus sieversii"
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "when :class represents a built-in typecast" do
|
128
|
+
|
129
|
+
it "makes an attempt to perform a typecast" do
|
130
|
+
Class.new { include SMG::Resource }
|
131
|
+
@klass.root 'spec'
|
132
|
+
@klass.extract :conservation, :at => :year, :class => :integer, :as => :year_of_conservation_check
|
133
|
+
malus = @klass.parse(@data)
|
134
|
+
malus.year_of_conservation_check.should == 2007
|
135
|
+
end
|
136
|
+
|
137
|
+
it "raises an ArgumentError if typecasting fails" do
|
138
|
+
Class.new { include SMG::Resource }
|
139
|
+
@klass.root 'spec'
|
140
|
+
@klass.extract :conservation, :at => :year, :class => :datetime, :as => :year_of_conservation_check
|
141
|
+
lambda { @klass.parse(@data) }.
|
142
|
+
should raise_error ArgumentError, %r{"2007" is not a valid source for :datetime}
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
describe SMG::Model, ".extract" do
|
152
|
+
|
153
|
+
describe "when XML contains two or more suitable elements" do
|
154
|
+
|
155
|
+
before :each do
|
156
|
+
@klass = Class.new { include SMG::Resource }
|
157
|
+
@data = File.read(FIXTURES_DIR + 'fake/valve.xml')
|
158
|
+
end
|
159
|
+
|
160
|
+
it "ignores everything except the first one suitable thing" do
|
161
|
+
@klass.extract "games/game", :as => :title
|
162
|
+
parsed = @klass.parse(@data)
|
163
|
+
parsed.title.should == "Half-Life 2"
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "using :at option" do
|
167
|
+
|
168
|
+
it "ignores everything except the first one suitable thing" do
|
169
|
+
@klass.extract "games/game", :at => :AppID, :as => :steam_application_id, :class => :integer
|
170
|
+
parsed = @klass.parse(@data)
|
171
|
+
parsed.steam_application_id.should == 220
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "using :class option, when :class option represents an SMG::Resource" do
|
177
|
+
|
178
|
+
it "ignores everything except the first one suitable thing" do
|
179
|
+
@game = Class.new { include SMG::Resource }
|
180
|
+
@game.extract :game, :at => "AppID", :as => :steam_application_id, :class => :integer
|
181
|
+
@game.extract :game, :at => "date"
|
182
|
+
@game.extract :game, :at => "type", :as => :content
|
183
|
+
@game.extract :game, :as => :title
|
184
|
+
|
185
|
+
@klass.extract 'games/game', :class => @game
|
186
|
+
parsed = @klass.parse(@data)
|
187
|
+
parsed.game.should_not be_nil
|
188
|
+
parsed.game.title.should == "Half-Life 2"
|
189
|
+
parsed.game.content.should == "fullprice"
|
190
|
+
parsed.game.steam_application_id.should == 220
|
191
|
+
parsed.game.date.should == "2004-11-16"
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
# EOF
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe SMG::Model, ".extract" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@klass = Class.new { include SMG::Resource }
|
7
|
+
@data = File.read(FIXTURES_DIR + 'fake/valve.xml')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "using :with option" do
|
11
|
+
|
12
|
+
it "extracts the text of an element if conditions are OK" do
|
13
|
+
@klass.extract 'games/game', :as => :title, :with => {:type => "episodic", :AppID => 420}
|
14
|
+
game = @klass.parse(@data)
|
15
|
+
game.title.should == "Half-Life 2: Episode Two"
|
16
|
+
|
17
|
+
@klass.extract 'games/game', :as => :title, :with => {:type => "episodic", :date => "To be announced"}
|
18
|
+
game = @klass.parse(@data)
|
19
|
+
game.title.should == "Half-Life 2: Episode Three"
|
20
|
+
|
21
|
+
@klass.extract 'games/game', :as => :title, :with => {:type => "episodic", :AppID => nil} # i.e. without @AppID attribute
|
22
|
+
game = @klass.parse(@data)
|
23
|
+
game.title.should == "Half-Life 2: Episode Three"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "extracts nothing otherwise" do
|
27
|
+
@klass.extract 'games/game', :as => :title, :with => {:type => "episodic", :AppID => "malformed"}
|
28
|
+
game = @klass.parse(@data)
|
29
|
+
game.title.should == nil
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "using :with and :at options together" do
|
35
|
+
|
36
|
+
it "extracts the text of an element if conditions are OK" do
|
37
|
+
conditions = {:type => "modification", :date => "2007-10-06"}
|
38
|
+
@klass.extract 'games/game', :as => :steam_application_id, :with => conditions, :at => "AppID", :class => :integer
|
39
|
+
@klass.extract 'games/game', :as => :title, :with => conditions
|
40
|
+
game = @klass.parse(@data)
|
41
|
+
game.steam_application_id.should == 380
|
42
|
+
game.title.should == "Minerva: Metastasis"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "extracts nothing otherwise" do
|
46
|
+
conditions = {:type => "modification", :date => "fake"}
|
47
|
+
@klass.extract 'games/game', :as => :steam_application_id, :with => conditions, :at => "AppID", :class => :integer
|
48
|
+
@klass.extract 'games/game', :as => :title, :with => conditions
|
49
|
+
game = @klass.parse(@data)
|
50
|
+
game.steam_application_id.should == nil
|
51
|
+
game.title.should == nil
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "using :with and :class options together" do
|
57
|
+
|
58
|
+
before :each do
|
59
|
+
@game = Class.new { include SMG::Resource }
|
60
|
+
@game.extract :game, :at => "AppID", :as => :steam_application_id, :class => :integer
|
61
|
+
@game.extract :game, :at => "date"
|
62
|
+
@game.extract :game, :at => "type", :as => :content
|
63
|
+
@game.extract :game, :as => :title
|
64
|
+
end
|
65
|
+
|
66
|
+
it "extracts the text of an element if conditions are OK" do
|
67
|
+
conditions = {:type => "modification", :date => "2007-10-06"}
|
68
|
+
@klass.extract 'games/game', :class => @game, :with => conditions
|
69
|
+
parsed = @klass.parse(@data)
|
70
|
+
parsed.game.should_not be_nil
|
71
|
+
parsed.game.title.should == "Minerva: Metastasis"
|
72
|
+
parsed.game.content.should == "modification"
|
73
|
+
parsed.game.steam_application_id.should == 380
|
74
|
+
parsed.game.date.should == "2007-10-06"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "extracts nothing otherwise" do
|
78
|
+
conditions = {:type => "modification", :date => "malformed"}
|
79
|
+
@klass.extract 'games/game', :class => @game, :with => conditions
|
80
|
+
parsed = @klass.parse(@data)
|
81
|
+
parsed.game.should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
describe SMG::Model, ".collect" do
|
89
|
+
|
90
|
+
before :each do
|
91
|
+
@klass = Class.new { include SMG::Resource }
|
92
|
+
@data = File.read(FIXTURES_DIR + 'fake/valve.xml')
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "using :with option" do
|
96
|
+
|
97
|
+
it "collects texts, if conditions are OK" do
|
98
|
+
@klass.collect 'games/game', :with => {"type" => "episodic"}, :as => :titles
|
99
|
+
parsed = @klass.parse(@data)
|
100
|
+
parsed.titles.should == ["Half-Life 2: Episode One", "Half-Life 2: Episode Two", "Half-Life 2: Episode Three"]
|
101
|
+
end
|
102
|
+
|
103
|
+
it "collects texts, if conditions are OK" do
|
104
|
+
@klass.collect 'games/game', :with => {"type" => "unknowb"}, :as => :titles
|
105
|
+
parsed = @klass.parse(@data)
|
106
|
+
parsed.titles.should be_empty
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "using :with and :at options together" do
|
112
|
+
|
113
|
+
it "collects attributes, if conditions are OK" do
|
114
|
+
@klass.collect 'games/game', :with => {"type" => "episodic"}, :at => :date, :as => :dates
|
115
|
+
parsed = @klass.parse(@data)
|
116
|
+
parsed.dates.should == ["2006-06-01", "2007-10-10", "To be announced"]
|
117
|
+
end
|
118
|
+
|
119
|
+
it "collects nothing otherwise" do
|
120
|
+
@klass.collect 'games/game', :with => {"type" => "unknown"}, :at => :date, :as => :dates
|
121
|
+
parsed = @klass.parse(@data)
|
122
|
+
parsed.dates.should be_empty
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "using :with and :class options together" do
|
128
|
+
|
129
|
+
before :each do
|
130
|
+
@game = Class.new { include SMG::Resource }
|
131
|
+
@game.extract :game, :at => "AppID", :as => :steam_application_id, :class => :integer
|
132
|
+
@game.extract :game, :at => "date"
|
133
|
+
@game.extract :game, :as => :title
|
134
|
+
end
|
135
|
+
|
136
|
+
it "collects resources if conditions are OK" do
|
137
|
+
conditions = {:type => "modification"}
|
138
|
+
@klass.collect 'games/game', :class => @game, :with => conditions, :as => :games
|
139
|
+
collection = @klass.parse(@data)
|
140
|
+
|
141
|
+
collection.games.should_not be_empty
|
142
|
+
collection.games.size.should == 2
|
143
|
+
|
144
|
+
collection.games[0].title.should == "Minerva: Metastasis"
|
145
|
+
collection.games[0].steam_application_id.should == 380
|
146
|
+
collection.games[0].date.should == "2007-10-06"
|
147
|
+
|
148
|
+
collection.games[1].title.should == "Black Mesa"
|
149
|
+
collection.games[1].steam_application_id.should == nil
|
150
|
+
collection.games[1].date.should == "To be announced"
|
151
|
+
end
|
152
|
+
|
153
|
+
it "collects nothing otherwise" do
|
154
|
+
conditions = {:type => "unknown"}
|
155
|
+
@klass.collect 'games/game', :class => @game, :with => conditions, :as => :games
|
156
|
+
collection = @klass.parse(@data)
|
157
|
+
collection.games.should be_empty
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
# EOF
|