smg 0.2.0 → 0.2.1

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.
@@ -19,7 +19,8 @@ http://github.com/SSDany/smg/tree/master/examples
19
19
 
20
20
  == REQUIREMENTS:
21
21
 
22
- nokogiri (>=1.3)
22
+ * nokogiri (>=1.3)
23
+ * addressable (>=2.1.1)
23
24
 
24
25
  == LICENSE:
25
26
 
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class A
4
+ include SMG::Resource
5
+ extract "a" , :as => :href , :at => :href
6
+ extract "a" , :as => :content
7
+ end
8
+
9
+ class P
10
+ include SMG::Resource
11
+ extract "p" , :as => :raw
12
+ collect "p/a" , :as => :links , :class => A
13
+ end
14
+
15
+ class Requirements
16
+ include SMG::Resource
17
+ root "div"
18
+ extract "p" , :as => :raw
19
+ extract "p" , :as => :p , :class => P
20
+ collect "p/a" , :as => :links , :class => A
21
+ end
22
+
23
+ data = <<-HTML
24
+ <div><p>Requirements: <a href="http://github.com/tenderlove/nokogiri">nokogiri</a> and <a href="http://github.com/sporkmonger/addressable">addressable</a>.</p></div>
25
+ HTML
26
+
27
+ parsed = Requirements.parse(data)
28
+
29
+ puts parsed.raw #=> "Requirements: nokogiri and addressable."
30
+ puts parsed.links.map { |a| a.href } #=> ["http://github.com/tenderlove/nokogiri", "http://github.com/sporkmonger/addressable"]
31
+ puts parsed.links.map { |a| a.content } #=> ["nokogiri", "addressable"]
32
+
33
+ puts parsed.p.raw #=> "Requirements: nokogiri and addressable."
34
+ puts parsed.p.links.map { |a| a.href } #=> ["http://github.com/tenderlove/nokogiri", "http://github.com/sporkmonger/addressable"]
35
+ puts parsed.p.links.map { |a| a.content } #=> ["nokogiri", "addressable"]
36
+
37
+ # EOF
@@ -132,9 +132,10 @@ class YWeather
132
132
 
133
133
  root 'rss/channel/item'
134
134
 
135
+ extract "title"
136
+ extract "description"
135
137
  extract "geo:lat" , :as => :latitude
136
138
  extract "geo:long" , :as => :longitude
137
- extract "title" , :as => :title
138
139
  extract "yweather:condition" , :as => :current , :class => Condition
139
140
  collect "yweather:forecast" , :as => :forecasts , :class => Forecast
140
141
 
@@ -8,11 +8,10 @@ module SMG #:nodoc:
8
8
  @mapping = object.class.mapping
9
9
  @stack = []
10
10
  @docs = []
11
+ @elements = []
11
12
  @thing = thing
12
13
  @context = context
13
- @chars = ""
14
-
15
- @mapping.refresh!
14
+ @parsed = []
16
15
  end
17
16
 
18
17
  def start_element(name, attrs)
@@ -20,55 +19,49 @@ module SMG #:nodoc:
20
19
  @stack << name
21
20
  ahash = nil
22
21
 
23
- if doc = @docs.last
24
- doc.start_element(name, attrs)
25
- elsif (thing = @mapping.nested[@stack]) &&
26
- !@mapping.parsed.include?(thing.object_id) &&
27
- thing.in_context_of?(@context) &&
28
- thing.with?(ahash ||= Hash[*attrs])
29
-
30
- @docs << doc = Document.new(thing.data_class.new,@context,thing)
31
- doc.start_element(name, attrs)
22
+ if thing = @mapping.nested[@stack] and
23
+ !@parsed.include?(thing.object_id) &&
24
+ thing.in_context_of?(@context) &&
25
+ thing.with?(ahash ||= Hash[*attrs])
26
+ @docs << Document.new(thing.data_class.new,@context,thing)
32
27
  end
33
28
 
29
+ @docs.each { |doc| doc.start_element(name,attrs) }
30
+
34
31
  if !attrs.empty? && maps = @mapping.attributes[@stack]
35
32
  maps.values_at(*(ahash ||= Hash[*attrs]).keys).compact.each do |m|
36
- if !@mapping.parsed.include?(m.object_id) &&
37
- m.in_context_of?(@context) &&
38
- m.with?(ahash)
39
-
33
+ if !@parsed.include?(m.object_id) &&
34
+ m.in_context_of?(@context) &&
35
+ m.with?(ahash)
40
36
  @object.__send__(m.accessor, m.cast(ahash[m.at]))
41
- @mapping.parsed << m.object_id unless m.collection?
37
+ @parsed << m.object_id unless m.collection?
42
38
  end
43
39
  end
44
40
  end
45
41
 
46
- if (e = @mapping.elements[@stack]) &&
47
- !@mapping.parsed.include?(e.object_id) &&
48
- e.in_context_of?(@context) &&
49
- e.with?(ahash ||= Hash[*attrs])
50
- @element = e
51
- @chars = ""
42
+ if e = @mapping.elements[@stack] and
43
+ !@parsed.include?(e.object_id) &&
44
+ e.in_context_of?(@context) &&
45
+ e.with?(ahash ||= Hash[*attrs])
46
+ @elements << [e,""]
52
47
  end
53
48
 
54
49
  end
55
50
 
56
51
  def end_element(name)
57
52
 
58
- if @element
59
- @object.__send__(@element.accessor, @element.cast(@chars))
60
- @mapping.parsed << @element.object_id unless @element.collection?
61
- @chars = ""
62
- @element = nil
53
+ if e = @elements.last and e.first.path == @stack
54
+ e,chars = *@elements.pop
55
+ @object.__send__(e.accessor, e.cast(chars))
56
+ @parsed << e.object_id unless e.collection?
63
57
  end
64
58
 
65
- if doc = @docs.last
66
- doc.end_element(name)
67
- if (t = doc.thing).path == @stack
68
- @object.__send__(t.accessor, doc.object)
69
- @docs.pop
70
- @mapping.parsed << t.object_id unless t.collection?
71
- end
59
+ @docs.each { |doc| doc.end_element(name) }
60
+
61
+ if doc = @docs.last and doc.thing.path == @stack
62
+ @object.__send__(doc.thing.accessor, doc.object)
63
+ @parsed << doc.thing.object_id unless doc.thing.collection?
64
+ @docs.pop
72
65
  end
73
66
 
74
67
  @stack.pop
@@ -76,12 +69,12 @@ module SMG #:nodoc:
76
69
  end
77
70
 
78
71
  def characters(string)
79
- if doc = @docs.last
80
- doc.characters(string)
81
- @chars << string
82
- elsif @element
83
- @chars << string
84
- end
72
+ @docs.each { |doc| doc.characters(string) }
73
+ @elements.each { |e| e.last << string }
74
+ end
75
+
76
+ def cdata_block(string)
77
+ characters(string)
85
78
  end
86
79
 
87
80
  end
@@ -34,12 +34,6 @@ module SMG #:nodoc:
34
34
  @root = normalize_path(path)
35
35
  end
36
36
 
37
- def refresh!
38
- @parsed ||= []
39
- @parsed.clear
40
- nil
41
- end
42
-
43
37
  private
44
38
 
45
39
  def normalize_path(path)
@@ -1,5 +1,5 @@
1
1
  module SMG
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
4
4
 
5
5
  # EOF
@@ -116,7 +116,7 @@ describe SMG::Model, ".collect", "when :class option represents SMG::Resource" d
116
116
  @data = data = File.read(FIXTURES_DIR + 'discogs/Genosha+Recordings.xml')
117
117
  end
118
118
 
119
- before :all do
119
+ before :each do
120
120
  @release_class = Class.new { include SMG::Resource }
121
121
  @release_class.extract 'release' , :at => :id , :as => :discogs_id
122
122
  @release_class.extract 'release' , :at => :status
@@ -206,7 +206,7 @@ describe SMG::Model, ".collect", "with nested collections" do
206
206
  @data = data = File.read(FIXTURES_DIR + 'discogs/948224.xml')
207
207
  end
208
208
 
209
- before :all do
209
+ before :each do
210
210
  @artist_class = Class.new { include SMG::Resource }
211
211
  @artist_class.root 'artist'
212
212
  @artist_class.extract :name
@@ -217,38 +217,56 @@ describe SMG::Model, ".collect", "with nested collections" do
217
217
  @track_class.extract :position
218
218
  @track_class.extract :title
219
219
  @track_class.extract :duration
220
- @track_class.collect 'extraartists/artist/name', :as => :extra_artist_names
221
220
  @track_class.collect 'extraartists/artist', :as => :extra_artists, :class => @artist_class
222
221
  end
223
222
 
224
- it "supports nested collections" do
225
- @klass.root 'resp/release'
226
- @klass.collect 'tracklist/track' , :as => :tracks, :class => @track_class
227
- @klass.collect 'tracklist/track/title' , :as => :tracklist
228
- release = @klass.parse(@data)
229
-
230
- release.tracklist.should be_an_instance_of ::Array
231
- release.tracklist.size.should == 6
232
- 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)"]
223
+ after :each do
224
+ @release.tracks.should be_an_instance_of ::Array
225
+ @release.tracks.size.should == 6
233
226
 
234
- release.tracks.should be_an_instance_of ::Array
235
- release.tracks.size.should == 6
236
-
237
- track = release.tracks[1]
227
+ track = @release.tracks[1]
238
228
  track.position.should == 'A2'
239
229
  track.title.should == 'Butterfly V.I.P. (Interlude By Cubist Boy & Tapage)'
240
230
  track.duration.should == '1:24'
241
231
 
242
- track.extra_artist_names.should be_an_instance_of ::Array
243
- track.extra_artist_names.size.should == 2
244
- track.extra_artist_names.should == ['Cubist Boy', 'Tapage']
245
-
246
232
  track.extra_artists.should be_an_instance_of ::Array
247
233
  track.extra_artists.size.should == 2
248
234
  track.extra_artists[1].name.should == 'Tapage'
249
235
  track.extra_artists[1].role.should == 'Co-producer'
250
236
  end
251
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
+
252
270
  end
253
271
 
254
272
  # EOF
@@ -197,4 +197,23 @@ describe SMG::Model, ".extract" do
197
197
 
198
198
  end
199
199
 
200
+ describe SMG::Model, ".extract" do
201
+
202
+ before :each do
203
+ @klass = Class.new { include SMG::Resource }
204
+ @data = "<thing>just<another>yetanother</another>spec</thing>"
205
+ end
206
+
207
+ it "handles each element independently" do
208
+ @klass.extract :thing
209
+ parsed = @klass.parse(@data)
210
+ parsed.thing.should == "justyetanotherspec"
211
+
212
+ @klass.extract "thing/another"
213
+ parsed = @klass.parse(@data)
214
+ parsed.thing.should == "justyetanotherspec" # NOT "justspec"
215
+ parsed.another.should == "yetanother"
216
+ end
217
+
218
+ end
200
219
  # EOF
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - SSDany
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-13 00:00:00 +04:00
17
+ date: 2010-06-14 00:00:00 +04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -69,6 +69,7 @@ files:
69
69
  - lib/smg/resource.rb
70
70
  - lib/smg/version.rb
71
71
  - lib/smg.rb
72
+ - examples/crazy.rb
72
73
  - examples/discogs/label.rb
73
74
  - examples/discogs/search.rb
74
75
  - examples/helper.rb