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,76 +0,0 @@
1
- require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- describe SMG::HTTP::Model, ".uri_for" do
4
-
5
- before :all do
6
- @klass = Class.new { include SMG::Resource, SMG::HTTP }
7
- @klass.site "http://www.example.org"
8
- @klass.params "developer" => "Valve"
9
- end
10
-
11
- it "appends a path to the base URI" do
12
- uri = @klass.send(:uri_for, "search")
13
- uri.host.should == "www.example.org"
14
- uri.path.should == "/search"
15
- uri.query_values.should == {"developer" => "Valve"}
16
- end
17
-
18
- it "appends a query to the base URI" do
19
- uri = @klass.send(:uri_for, "search", {"cake" => "Lie"})
20
- uri.host.should == "www.example.org"
21
- uri.path.should == "/search"
22
- uri.query_values.should == {"developer" => "Valve", "cake" => "Lie"}
23
- end
24
-
25
- end
26
-
27
- describe SMG::HTTP::Model do
28
-
29
- before :all do
30
- @klass = Class.new { include SMG::Resource, SMG::HTTP }
31
- @klass.site "http://www.example.org"
32
- @klass.params "developer" => "Valve"
33
- @klass.extract "game/name"
34
- end
35
-
36
- Hash[[:get, :post, :put, :delete, :head].zip(SMG::HTTP::Request::VERBS)].each do |sym,verb|
37
- describe ".#{sym}" do
38
-
39
- before :each do
40
- @response = Net::HTTPOK.new('1.1', 200, "OK")
41
- @response.stub!(:body).and_return("<game><name>Portal</name></game>")
42
- end
43
-
44
- before :each do
45
- @request = mock('request')
46
- @request.stub!(:perform).and_return(@response)
47
- end
48
-
49
- before :each do
50
- @headers = {"Accept-Encoding" => "gzip,deflate;*;q=0"}
51
- @options = {:query => {"cake" => "LIE"}, :headers => @headers}
52
- SMG::HTTP::Request.should_receive(:new).
53
- with(verb, instance_of(Addressable::URI), {:headers => @headers}).
54
- and_return(@request)
55
- end
56
-
57
- it "performs #{sym.to_s.upcase} request" do
58
- @klass.send(sym, "game", @options)
59
- end
60
-
61
- it "parses response' body when no block given" do
62
- @game = @klass.send(sym, "game", @options)
63
- @game.name.should == "Portal"
64
- end
65
-
66
- it "yields response and parses the block returning value when block given" do
67
- @game = @klass.send(sym, "game", @options) { |response| "<game><name>Portal2</name></game>" }
68
- @game.name.should == "Portal2"
69
- end
70
-
71
- end
72
- end
73
-
74
- end
75
-
76
- # EOF
@@ -1,27 +0,0 @@
1
- module Spec #:nodoc:
2
- module Helpers #:nodoc:
3
- module HTTPHelpers
4
-
5
- def http(uri, proxy = nil)
6
- @http ||= mock('http')
7
- uri = Addressable::URI.parse(uri)
8
- args = (proxy && p = Addressable::URI.parse(proxy)) ?
9
- [uri.host, uri.port, p.host, p.port, p.user, p.password] :
10
- [uri.host, uri.port]
11
-
12
- Net::HTTP.should_receive(:new).with(*args).and_return(@http)
13
- end
14
-
15
- def stub_response(code, message, *args)
16
- response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new('1.1', code, message)
17
- response.initialize_http_header(Hash === args.last ? args.pop : {})
18
- response.stub!(:body).and_return(args.join) unless args.empty?
19
- @http.should_receive(:request).and_return response
20
- response
21
- end
22
-
23
- end
24
- end
25
- end
26
-
27
- # EOF
@@ -1,38 +0,0 @@
1
- module Spec #:nodoc:
2
- module Matchers #:nodoc:
3
-
4
- #http://github.com/rubyspec/mspec/blob/master/lib/mspec/matchers/have_instance_method.rb
5
- class HaveInstanceMethodMatcher
6
-
7
- def initialize(method, include_super)
8
- @method = method.to_sym
9
- @include_super = include_super
10
- end
11
-
12
- def matches?(mod)
13
- @mod = mod
14
- mod.instance_methods(@include_super).include?(@method) ||
15
- mod.instance_methods(@include_super).include?(@method.to_s)
16
- end
17
-
18
- def failure_message
19
- ["Expected #{@mod} to have instance method '#{@method.to_s}'",
20
- "but it does not"]
21
- end
22
-
23
- def negative_failure_message
24
- ["Expected #{@mod} NOT to have instance method '#{@method.to_s}'",
25
- "but it does"]
26
- end
27
- end
28
-
29
- module HaveInstanceMethodMixin
30
- def have_instance_method(method, include_super=true)
31
- HaveInstanceMethodMatcher.new method, include_super
32
- end
33
- end
34
-
35
- end
36
- end
37
-
38
- # EOF
@@ -1,241 +0,0 @@
1
- require File.expand_path File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
-
3
- describe SMG::Mapping::Element do
4
-
5
- describe "#initialize" do
6
-
7
- it "respects path" do
8
- e = SMG::Mapping::Element.new(['node','subnode'])
9
- e.name.should == :subnode
10
- e.accessor.should == :subnode=
11
-
12
- e = SMG::Mapping::Element.new(['node','ns:subnode'])
13
- e.name.should == :ns_subnode
14
- e.accessor.should == :ns_subnode=
15
-
16
- e = SMG::Mapping::Element.new(['node','subnode'], :nested => true)
17
- e.name.should == :subnode
18
- e.accessor.should == :subnode=
19
-
20
- e = SMG::Mapping::Element.new(['node','ns:subnode'], :nested => true)
21
- e.name.should == :ns_subnode
22
- e.accessor.should == :ns_subnode=
23
- end
24
-
25
- it "respects namespaces" do
26
- end
27
-
28
- it "respects :at option" do
29
- e = SMG::Mapping::Element.new(['node','subnode'], :at => :something)
30
- e.name.should == :something
31
- e.accessor.should == :something=
32
-
33
- e = SMG::Mapping::Element.new(['node','ns:subnode'], :at => :something)
34
- e.name.should == :something
35
- e.accessor.should == :something=
36
-
37
- e = SMG::Mapping::Element.new(['node','subnode'], :at => :something, :nested => true)
38
- e.name.should == :something
39
- e.accessor.should == :something=
40
-
41
- e = SMG::Mapping::Element.new(['node','ns:subnode'], :at => :something, :nested => true)
42
- e.name.should == :something
43
- e.accessor.should == :something=
44
- end
45
-
46
- it "respects :as option" do
47
- e = SMG::Mapping::Element.new(['node','subnode'], :at => :whatever, :as => :something)
48
- e.name.should == :something
49
- e.accessor.should == :something=
50
-
51
- e = SMG::Mapping::Element.new(['node','ns:subnode'], :at => :whatever, :as => :something)
52
- e.name.should == :something
53
- e.accessor.should == :something=
54
-
55
- e = SMG::Mapping::Element.new(['node','subnode'], :as => :whatever, :nested => true)
56
- e.name.should == :whatever
57
- e.accessor.should == :whatever=
58
-
59
- e = SMG::Mapping::Element.new(['node','ns:subnode'], :as => :whatever, :nested => true)
60
- e.name.should == :whatever
61
- e.accessor.should == :whatever=
62
- end
63
-
64
- it "respects :collection option" do
65
- e = SMG::Mapping::Element.new(['node','subnodes'], :collection => true)
66
- e.name.should == :subnodes
67
- e.accessor.should == :append_to_subnodes
68
-
69
- e = SMG::Mapping::Element.new(['node','ns:subnodes'], :collection => true)
70
- e.name.should == :ns_subnodes
71
- e.accessor.should == :append_to_ns_subnodes
72
-
73
- e = SMG::Mapping::Element.new(['node','subnodes'], :at => :something, :collection => true)
74
- e.name.should == :something
75
- e.accessor.should == :append_to_something
76
-
77
- e = SMG::Mapping::Element.new(['node','ns:subnodes'], :at => :something, :collection => true)
78
- e.name.should == :something
79
- e.accessor.should == :append_to_something
80
-
81
- e = SMG::Mapping::Element.new(['node','subnodes'], :at => :whatever, :as => :something, :collection => true)
82
- e.name.should == :something
83
- e.accessor.should == :append_to_something
84
-
85
- e = SMG::Mapping::Element.new(['node','ns:subnodes'], :at => :whatever, :as => :something, :collection => true)
86
- e.name.should == :something
87
- e.accessor.should == :append_to_something
88
-
89
- e = SMG::Mapping::Element.new(['node','subnodes'], :as => :something, :collection => true)
90
- e.name.should == :something
91
- e.accessor.should == :append_to_something
92
-
93
- e = SMG::Mapping::Element.new(['node','ns:subnodes'], :as => :something, :collection => true)
94
- e.name.should == :something
95
- e.accessor.should == :append_to_something
96
- end
97
-
98
- it "defaults @context to nil" do
99
- e = SMG::Mapping::Element.new(['node','subnode'])
100
- e.context.should be_nil
101
- end
102
-
103
- describe "with :class option" do
104
-
105
- it "defines the @data_class if :class is an SMG::Model" do
106
- klass = Class.new { include SMG::Resource }
107
- e = SMG::Mapping::Element.new(['node'], :class => klass)
108
- e.data_class.should == klass
109
- end
110
-
111
- it "defines the @cast_to if :class is a valid typecast" do
112
- klass = Class.new { include SMG::Resource }
113
- e = SMG::Mapping::Element.new(['node'], :class => :string)
114
- e.cast_to.should == :string
115
- end
116
-
117
- it "raises an ArgumentError otherwise" do
118
- lambda { SMG::Mapping::Element.new(['node'], :class => "bogus!")}.
119
- should raise_error ArgumentError, %r{should be an SMG::Model or a valid typecast}
120
- end
121
-
122
- end
123
-
124
- describe "with :context option" do
125
-
126
- it "defaults @context to nil, if :context is an empty Array" do
127
- e = SMG::Mapping::Element.new(['node'], :context => [])
128
- e.context.should be_nil
129
- end
130
-
131
- it "removes duplicates from @context" do
132
-
133
- e = SMG::Mapping::Element.new(['node'], :context => [:foo, :bar, :baz])
134
- e.context.should == [:foo, :bar, :baz]
135
-
136
- e = SMG::Mapping::Element.new(['node'], :context => [:foo, :bar, :foo, :bar, :baz, :baz])
137
- e.context.should == [:foo, :bar, :baz]
138
-
139
- # undestructive
140
- cct = [:foo, :foo, :bar]
141
- e = SMG::Mapping::Element.new(['node','subnode'], :context => cct)
142
- cct.should == [:foo, :foo, :bar]
143
-
144
- end
145
-
146
- it "raises an ArgumentError, if :context is not an Array of Symbols" do
147
- lambda { e = SMG::Mapping::Element.new(['node'], :context => "something") }.
148
- should raise_error ArgumentError, %r{should be an Array of Symbols}
149
-
150
- lambda { e = SMG::Mapping::Element.new(['node'], :context => [42]) }.
151
- should raise_error ArgumentError, %r{should be an Array of Symbols}
152
- end
153
-
154
- end
155
-
156
- end
157
-
158
- describe "#collection?" do
159
-
160
- it "returns true if Element is a collection" do
161
- e = SMG::Mapping::Element.new(['node','subnode'], :collection => true)
162
- e.should be_a_collection
163
- end
164
-
165
- it "returns false otherwise" do
166
- e = SMG::Mapping::Element.new(['node','subnode'])
167
- e.should_not be_a_collection
168
- end
169
-
170
- end
171
-
172
- describe "#cast" do
173
-
174
- it "does nothing if there's no @cast_to" do
175
- e = SMG::Mapping::Element.new(['node'])
176
- thing = "42"
177
- e.cast(thing).should be_eql thing
178
- end
179
-
180
- it "performs the typecast otherwise" do
181
- e = SMG::Mapping::Element.new(['node'], :class => :integer)
182
- thing = "42"
183
- SMG::Mapping::TypeCasts.should_receive(:[]).with(:integer, thing).and_return("42 (typecasted)")
184
- e.cast(thing).should == "42 (typecasted)"
185
- end
186
-
187
- it "raises an ArgumentError if typecasting fails" do
188
- e = SMG::Mapping::Element.new(['node'], :class => :datetime)
189
- lambda { e.cast('42') }.
190
- should raise_error ArgumentError, %r{"42" is not a valid source for :datetime}
191
- end
192
-
193
- end
194
-
195
- describe "#in_context_of?" do
196
-
197
- it "returns true if @context of an Element is a nil" do
198
- e = SMG::Mapping::Element.new(['node','subnode'])
199
- e.context.should == nil
200
- e.in_context_of?(:whatever).should == true
201
- end
202
-
203
- it "returns true if @context of an Element includes context" do
204
- e = SMG::Mapping::Element.new(['node','subnode'], :context => [:foo])
205
- e.context.should == [:foo]
206
- e.in_context_of?(:foo).should == true
207
- end
208
-
209
- it "returns false otherwise" do
210
- e = SMG::Mapping::Element.new(['node','subnode'], :context => [:foo])
211
- e.context.should == [:foo]
212
- e.in_context_of?(:bar).should == false
213
- end
214
-
215
- end
216
-
217
- describe "#with?" do
218
-
219
- it "returns true if the Hash passed contains @with" do
220
- e = SMG::Mapping::Element.new(['node'], :with => {"id" => "3", "status" => "accepted"})
221
- e.should be_with("id" => "3", "status" => "accepted")
222
- e.should be_with("id" => "3", "status" => "accepted", "key" => "value")
223
- end
224
-
225
- it "returns true if there are no @with conditions" do
226
- e = SMG::Mapping::Element.new(['node','subnode'])
227
- e.with.should == nil
228
- e.should be_with("key" => "value")
229
- end
230
-
231
- it "returns false otherwise" do
232
- e = SMG::Mapping::Element.new(['node'], :with => {"id" => "3", "status" => "accepted"})
233
- e.should_not be_with("status" => "accepted")
234
- e.should_not be_with({})
235
- end
236
-
237
- end
238
-
239
- end
240
-
241
- # EOF
@@ -1,52 +0,0 @@
1
- require File.expand_path File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
-
3
- describe SMG::Mapping::TypeCasts, "[]" do
4
-
5
- it "raises an ArgumentError when typecast is unknown" do
6
- lambda { SMG::Mapping::TypeCasts[:bogus, "42"] }.should raise_error ArgumentError, %r{Can't typecast to :bogus}
7
- end
8
-
9
- it "is able to typecast (Stringable) into Fixnum" do
10
- SMG::Mapping::TypeCasts[:integer, "42"].should == 42
11
- SMG::Mapping::TypeCasts[:integer, nil ].should == 0
12
- end
13
-
14
- it "is able to typecast (Stringable) into Symbol" do
15
- SMG::Mapping::TypeCasts[:symbol, "something"].should == :something
16
- end
17
-
18
- it "is able to typecast (Stringable) into Time" do
19
- source = 'Thu Apr 15 18:16:23 +0400 2010'
20
- value = SMG::Mapping::TypeCasts[:datetime, source]
21
- value.should == Time.parse(source)
22
- end
23
-
24
- it "is able to typecast (Stringable) into Date" do
25
- source = 'Thu Apr 15 18:16:23 +0400 2010'
26
- value = SMG::Mapping::TypeCasts[:date, source]
27
- value.should == Date.parse(source)
28
- end
29
-
30
- it "is able to typecast (Stringable) into URI" do
31
- source = "http://example.org:4567/foo?bar=baz"
32
- value = SMG::Mapping::TypeCasts[:uri, source]
33
- value.should == URI.parse(source)
34
- end
35
-
36
- it "is able to typecast (Stringable) into Float" do
37
- SMG::Mapping::TypeCasts[ :float , nil ].should == 0.00
38
- SMG::Mapping::TypeCasts[ :float , "42." ].should == 42.00
39
- SMG::Mapping::TypeCasts[ :float , ".42" ].should == 0.42
40
- SMG::Mapping::TypeCasts[ :float , "42" ].should == 42.00
41
- end
42
-
43
- it "is able to typecast (Stringable) into Boolean" do
44
- SMG::Mapping::TypeCasts[ :boolean , nil ].should == nil
45
- SMG::Mapping::TypeCasts[ :boolean , "true" ].should == true
46
- SMG::Mapping::TypeCasts[ :boolean , "something" ].should == true
47
- SMG::Mapping::TypeCasts[ :boolean , "false" ].should == false
48
- end
49
-
50
- end
51
-
52
- # EOF
@@ -1,30 +0,0 @@
1
- require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- describe SMG::Resource do
4
-
5
- before :each do
6
- @klass = Class.new { include SMG::Resource }
7
- end
8
-
9
- describe "when included" do
10
-
11
- it "extends class with the SMG::Model" do
12
- @klass.should be_an SMG::Model
13
- end
14
-
15
- end
16
-
17
- describe "#parsed!" do
18
-
19
- it "marks resource as parsed" do
20
- resource = @klass.new
21
- resource.should_not be_parsed
22
- resource.parsed!
23
- resource.should be_parsed
24
- end
25
-
26
- end
27
-
28
- end
29
-
30
- # EOF