thounds 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,93 @@
1
+ require 'faraday'
2
+ require File.expand_path('../version', __FILE__)
3
+
4
+ module Thounds
5
+ # Defines constants and methods related to configuration
6
+ module Configuration
7
+ # An array of valid keys in the options hash when configuring a {Thounds::API}
8
+ VALID_OPTIONS_KEYS = [
9
+ :adapter,
10
+ :consumer_key,
11
+ :consumer_secret,
12
+ :endpoint,
13
+ :format,
14
+ :oauth_token,
15
+ :oauth_token_secret,
16
+ :proxy,
17
+ :user_agent].freeze
18
+
19
+ # An array of valid request/response formats
20
+ #
21
+ # @note Not all methods support the XML format.
22
+ VALID_FORMATS = [
23
+ :json,
24
+ :xml].freeze
25
+
26
+ # The adapter that will be used to connect if none is set
27
+ #
28
+ # @note The default faraday adapter is Net::HTTP.
29
+ DEFAULT_ADAPTER = Faraday.default_adapter
30
+
31
+ # By default, don't set an application key
32
+ DEFAULT_CONSUMER_KEY = nil
33
+
34
+ # By default, don't set an application secret
35
+ DEFAULT_CONSUMER_SECRET = nil
36
+
37
+ # The endpoint that will be used to connect if none is set
38
+ #
39
+ # @note This is configurable in case you want to use HTTP instead of HTTPS, specify a different API version, or use a Thounds-compatible endpoint.
40
+ DEFAULT_ENDPOINT = 'http://thounds.local:3000/'.freeze
41
+
42
+ # The response format appended to the path and sent in the 'Accept' header if none is set
43
+ #
44
+ # @note JSON is preferred over XML because it is more concise and faster to parse.
45
+ DEFAULT_FORMAT = :json
46
+
47
+ # By default, don't set a user oauth token
48
+ DEFAULT_OAUTH_TOKEN = nil
49
+
50
+ # By default, don't set a user oauth secret
51
+ DEFAULT_OAUTH_TOKEN_SECRET = nil
52
+
53
+ # By default, don't use a proxy server
54
+ DEFAULT_PROXY = nil
55
+
56
+ # The user agent that will be sent to the API endpoint if none is set
57
+ DEFAULT_USER_AGENT = "Thounds Ruby Gem #{Thounds::VERSION}".freeze
58
+
59
+ # @private
60
+ attr_accessor *VALID_OPTIONS_KEYS
61
+
62
+ # When this module is extended, set all configuration options to their default values
63
+ def self.extended(base)
64
+ base.reset
65
+ end
66
+
67
+ # Convenience method to allow configuration options to be set in a block
68
+ def configure
69
+ yield self
70
+ end
71
+
72
+ # Create a hash of options and their values
73
+ def options
74
+ VALID_OPTIONS_KEYS.inject({}) do |option, key|
75
+ option.merge!(key => send(key))
76
+ end
77
+ end
78
+
79
+ # Reset all configuration options to defaults
80
+ def reset
81
+ self.adapter = DEFAULT_ADAPTER
82
+ self.consumer_key = DEFAULT_CONSUMER_KEY
83
+ self.consumer_secret = DEFAULT_CONSUMER_SECRET
84
+ self.endpoint = DEFAULT_ENDPOINT
85
+ self.format = DEFAULT_FORMAT
86
+ self.oauth_token = DEFAULT_OAUTH_TOKEN
87
+ self.oauth_token_secret = DEFAULT_OAUTH_TOKEN_SECRET
88
+ self.proxy = DEFAULT_PROXY
89
+ self.user_agent = DEFAULT_USER_AGENT
90
+ self
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday_middleware'
2
+ Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each{|f| require f}
3
+
4
+ module Thounds
5
+ # @private
6
+ module Connection
7
+ private
8
+
9
+ def connection(raw=false)
10
+ options = {
11
+ :headers => {'Accept' => "application/#{format}", 'User-Agent' => user_agent},
12
+ :proxy => proxy,
13
+ :ssl => {:verify => false},
14
+ :url => api_endpoint,
15
+ }
16
+
17
+ Faraday::Connection.new(options) do |connection|
18
+ connection.use Faraday::Request::Multipart
19
+ connection.use Faraday::Request::OAuth, authentication if authenticated?
20
+ connection.adapter(adapter)
21
+ connection.use Faraday::Response::RaiseHttp5xx
22
+ unless raw
23
+ case format.to_s.downcase
24
+ when 'json' then connection.use Faraday::Response::ParseJson
25
+ when 'xml' then connection.use Faraday::Response::ParseXml
26
+ end
27
+ end
28
+ connection.use Faraday::Response::RaiseHttp4xx
29
+ connection.use Faraday::Response::Mashify unless raw
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module Thounds
2
+ # Custom error class for rescuing from all Thounds errors
3
+ class Error < StandardError; end
4
+
5
+ # Raised when Thounds returns the HTTP status code 400
6
+ class BadRequest < Error; end
7
+
8
+ # Raised when Thounds returns the HTTP status code 401
9
+ class Unauthorized < Error; end
10
+
11
+ # Raised when Thounds returns the HTTP status code 403
12
+ class Forbidden < Error; end
13
+
14
+ # Raised when Thounds returns the HTTP status code 404
15
+ class NotFound < Error; end
16
+
17
+ # Raised when Thounds returns the HTTP status code 406
18
+ class NotAcceptable < Error; end
19
+
20
+ # Raised when Thounds returns the HTTP status code 500
21
+ class InternalServerError < Error; end
22
+
23
+ # Raised when Thounds returns the HTTP status code 502
24
+ class BadGateway < Error; end
25
+
26
+ # Raised when Thounds returns the HTTP status code 503
27
+ class ServiceUnavailable < Error; end
28
+ end
@@ -0,0 +1,24 @@
1
+ module Thounds
2
+ # Defines HTTP request methods
3
+ module Request
4
+ # Perform an HTTP request
5
+ def request(method, path, options={}, raw=false)
6
+ response = connection(raw).send(method) do |request|
7
+ case method
8
+ when :get, :delete
9
+ request.url(formatted_path(path), options)
10
+ when :post, :put
11
+ request.path = formatted_path(path)
12
+ request.body = options unless options.empty?
13
+ end
14
+ end
15
+ raw ? response : response.body
16
+ end
17
+
18
+ private
19
+
20
+ def formatted_path(path)
21
+ path
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Thounds
2
+ # The version of the gem
3
+ VERSION = '0.0.1'.freeze unless defined?(::Thounds::VERSION)
4
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Faraday::Response do
4
+ before do
5
+ @client = Thounds::Client.new
6
+ end
7
+
8
+ {
9
+ 400 => Thounds::BadRequest,
10
+ 401 => Thounds::Unauthorized,
11
+ 403 => Thounds::Forbidden,
12
+ 404 => Thounds::NotFound,
13
+ 406 => Thounds::NotAcceptable,
14
+ 500 => Thounds::InternalServerError,
15
+ 502 => Thounds::BadGateway,
16
+ 503 => Thounds::ServiceUnavailable,
17
+ }.each do |status, exception|
18
+ context "when HTTP status is #{status}" do
19
+
20
+ before do
21
+ stub_get('users/171').to_return(:status => status)
22
+ end
23
+
24
+ it "should raise #{exception.name} error" do
25
+ lambda do
26
+ @client.users(171) {|user| user}
27
+ end.should raise_error(exception)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1 @@
1
+ {"friend_of_mine":true,"blog_url":null,"created_at":"2009-06-30T09:52:15Z","city":"30027","friendship_id":2914,"profile_url":"smashing","about":null,"avatar":"http://gravatar.com/avatar/8e6e5c47e1d1b87a322fd2bac7f09d2e.png?d=http%3A%2F%2Fthounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Italy","default_thound":{"privacy":"contacts","public_url":"http://thounds.local:3000/t/6245c9","created_at":"2009-07-24T13:08:08Z","bpm":60,"video":false,"lead_track_id":961,"comments_count":0,"mix_url":"http://thounds.local:3000/thounds/611/stream","user_id":31,"plays_count":6,"mix_duration":0,"tracks":[{"title":"Smash Vs. Fraioli from http://www.randomthink.net/labs/html5drums/","duration":0,"created_at":"2009-07-24T13:08:08Z","privacy":"contacts","offset":0,"path":"thounds/611/tracks/961.mp3","uri":"http://thounds.local:3000/tracks/961/stream","youtube_id":null,"thound_id":611,"lat":null,"user_id":31,"host":"s3","lng":null,"delay":0,"cover":null,"id":961,"user":{"city":"30027","avatar":"http://gravatar.com/avatar/8e6e5c47e1d1b87a322fd2bac7f09d2e.png?d=http%3A%2F%2Fwww.thounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Italy","name":"Smash","id":31},"tags":"drum"},{"title":"yo!","duration":0,"created_at":"2010-04-01T08:17:49Z","privacy":"contacts","offset":133,"path":"/mp3/thound_user_171_mix_thound_611_1270109855794.mp3","uri":"http://stage.thounds.astrails.com//mp3/thound_user_171_mix_thound_611_1270109855794.mp3","youtube_id":null,"thound_id":611,"lat":null,"user_id":171,"host":"stage.thounds.astrails.com","lng":null,"delay":0,"cover":null,"id":2223,"user":{"city":"Treviso","avatar":"http://gravatar.com/avatar/5420033d57945e871b468e1a225cb079.png?d=http%3A%2F%2Fwww.thounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Guinea","name":"Giovanni \u3072\u3089\u304c\u306a","id":171},"tags":"ciao"}],"id":611,"tags":"drum ciao","public_id":"6245c9"},"is_new_user":false,"name":"Smash","id":31,"site_url":null,"tags":[]}
@@ -0,0 +1,54 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_group 'Thounds', 'lib/thounds'
4
+ add_group 'Faraday Middleware', 'lib/faraday'
5
+ add_group 'Specs', 'spec'
6
+ end
7
+
8
+ require File.expand_path('../../lib/thounds', __FILE__)
9
+
10
+ require 'rspec'
11
+ require 'webmock/rspec'
12
+ RSpec.configure do |config|
13
+ config.include WebMock::API
14
+ end
15
+
16
+ def a_delete(path)
17
+ a_request(:delete, Thounds.endpoint + path)
18
+ end
19
+
20
+ def a_get(path)
21
+ a_request(:get, Thounds.endpoint + path)
22
+ end
23
+
24
+ def a_post(path)
25
+ a_request(:post, Thounds.endpoint + path)
26
+ end
27
+
28
+ def a_put(path)
29
+ a_request(:put, Thounds.endpoint + path)
30
+ end
31
+
32
+ def stub_delete(path)
33
+ stub_request(:delete, Thounds.endpoint + path)
34
+ end
35
+
36
+ def stub_get(path)
37
+ stub_request(:get, Thounds.endpoint + path)
38
+ end
39
+
40
+ def stub_post(path)
41
+ stub_request(:post, Thounds.endpoint + path)
42
+ end
43
+
44
+ def stub_put(path)
45
+ stub_request(:put, Thounds.endpoint + path)
46
+ end
47
+
48
+ def fixture_path
49
+ File.expand_path("../fixtures", __FILE__)
50
+ end
51
+
52
+ def fixture(file)
53
+ File.new(fixture_path + '/' + file)
54
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Thounds::API do
4
+ before do
5
+ @keys = Thounds::Configuration::VALID_OPTIONS_KEYS
6
+ end
7
+
8
+ context "with module configuration" do
9
+
10
+ before do
11
+ Thounds.configure do |config|
12
+ @keys.each do |key|
13
+ config.send("#{key}=", key)
14
+ end
15
+ end
16
+ end
17
+
18
+ after do
19
+ Thounds.reset
20
+ end
21
+
22
+ it "should inherit module configuration" do
23
+ api = Thounds::API.new
24
+ @keys.each do |key|
25
+ api.send(key).should == key
26
+ end
27
+ end
28
+
29
+ context "with class configuration" do
30
+
31
+ before do
32
+ @configuration = {
33
+ :consumer_key => 'CK',
34
+ :consumer_secret => 'CS',
35
+ :oauth_token => 'OT',
36
+ :oauth_token_secret => 'OS',
37
+ :adapter => :typhoeus,
38
+ :endpoint => 'http://tumblr.com/',
39
+ :format => :xml,
40
+ :proxy => 'http://giovanni:secret@proxy.example.com:8080',
41
+ :user_agent => 'Custom User Agent',
42
+ }
43
+ end
44
+
45
+ context "during initialization"
46
+
47
+ it "should override module configuration" do
48
+ api = Thounds::API.new(@configuration)
49
+ @keys.each do |key|
50
+ api.send(key).should == @configuration[key]
51
+ end
52
+ end
53
+
54
+ context "after initilization" do
55
+
56
+ it "should override module configuration after initialization" do
57
+ api = Thounds::API.new
58
+ @configuration.each do |key, value|
59
+ api.send("#{key}=", value)
60
+ end
61
+ @keys.each do |key|
62
+ api.send(key).should == @configuration[key]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Thounds::Client do
4
+ it "should connect using the endpoint configuration" do
5
+ client = Thounds::Client.new
6
+ endpoint = URI.parse(client.api_endpoint)
7
+ connection = client.send(:connection).build_url(nil).to_s
8
+ connection.should == endpoint.to_s
9
+ end
10
+ end
@@ -0,0 +1,358 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Thounds do
4
+ after do
5
+ Thounds.reset
6
+ end
7
+
8
+ context "when delegating to a client" do
9
+
10
+ before do
11
+ stub_get("users/31").
12
+ to_return(:body => fixture("user_31.js"), :headers => {:content_type => "application/json; charset=utf-8"})
13
+ end
14
+
15
+ it "should get the correct resource" do
16
+ Thounds.users(31) {|user| user}
17
+ a_get("users/31").
18
+ should have_been_made
19
+ end
20
+
21
+ it "should return the same results as a client" do
22
+ class_obj = nil
23
+ client_obj = nil
24
+
25
+ Thounds.users(31) {|user| class_obj = user}
26
+ Thounds::Client.new.users(31) {|user| client_obj = user}
27
+
28
+ class_obj.should == client_obj
29
+ end
30
+
31
+ end
32
+
33
+ context "when making a request to" do
34
+
35
+ # http://developers.thounds.com/API/HomeStream
36
+ describe "GET home" do
37
+ before do
38
+ stub_get("home")
39
+ end
40
+
41
+ it "should use 'home' request path" do
42
+ Thounds.home {|r| r}.proxy.path.should == "home"
43
+ end
44
+ end
45
+
46
+ # http://developers.thounds.com/API/UserMetadata
47
+ describe "GET profile" do
48
+ before do
49
+ stub_get("profile")
50
+ end
51
+
52
+ it "should use 'profile' request path" do
53
+ Thounds.profile {|r| r}.proxy.path.should == "profile"
54
+ end
55
+ end
56
+
57
+ # http://developers.thounds.com/API/UserMetadata
58
+ describe "GET users/123" do
59
+ before do
60
+ stub_get("users/123")
61
+ end
62
+
63
+ it "should use 'users/123' request path" do
64
+ Thounds.users(123) {|r| r}.proxy.path.should == "users/123"
65
+ end
66
+ end
67
+
68
+ # http://developers.thounds.com/API/UserBand
69
+ # http://developers.thounds.com/API/UserLibrary
70
+ # http://developers.thounds.com/API/UserNotifications
71
+ ["band", "library", "notifications"].each do |member|
72
+ describe "GET profile/#{member}" do
73
+ before do
74
+ stub_get("profile/#{member}")
75
+ end
76
+
77
+ it "should use 'profile/#{member}' request path" do
78
+ Thounds.profile.send(member) {|r| r}.proxy.path.should == "profile/#{member}"
79
+ end
80
+ end
81
+ end
82
+
83
+ # http://developers.thounds.com/API/UserBand
84
+ # http://developers.thounds.com/API/UserLibrary
85
+ ["band", "library"].each do |member|
86
+ describe "GET users/123/#{member}" do
87
+ before do
88
+ stub_get("users/123/#{member}")
89
+ end
90
+
91
+ it "should use 'users/123/#{member}' request path" do
92
+ Thounds.users(123).send(member) {|r| r}.proxy.path.should == "users/123/#{member}"
93
+ end
94
+ end
95
+ end
96
+
97
+ # http://developers.thounds.com/API/UserRegistration
98
+ describe "POST users" do
99
+ before do
100
+ stub_post("users")
101
+
102
+ @options = {
103
+ :user => {
104
+ :name => "John Doe",
105
+ :email => "john@doe.com",
106
+ :country => "Italy",
107
+ :city => "Roma",
108
+ :tags => "jazz vocal"
109
+ }
110
+ }
111
+ @request = Thounds.users.post(@options) {|r| r}
112
+ end
113
+
114
+ it "should use 'users' request path" do
115
+ @request.proxy.path.should == "users"
116
+ end
117
+
118
+ it "should use POST request verb" do
119
+ @request.proxy.verb.should == :post
120
+ end
121
+
122
+ it "should include new user parameters into request" do
123
+ @request.proxy.options.should == @options
124
+ end
125
+ end
126
+
127
+ # http://developers.thounds.com/API/FriendshipRequest
128
+ describe "POST users/123/friendships" do
129
+ before do
130
+ stub_post("users/123/friendships")
131
+
132
+ @request = Thounds.users(123).friendships.post {|r| r}
133
+ end
134
+
135
+ it "should use 'users/123/friendships' request path" do
136
+ @request.proxy.path.should == "users/123/friendships"
137
+ end
138
+
139
+ it "should use POST request verb" do
140
+ @request.proxy.verb.should == :post
141
+ end
142
+ end
143
+
144
+ # http://developers.thounds.com/API/FriendshipAcceptRefuse
145
+ # http://developers.thounds.com/API/FriendshipDelete
146
+ [:put, :delete].each do |verb|
147
+ describe "#{verb.to_s.upcase} profile/friendships/123" do
148
+ before do
149
+ send("stub_#{verb}", "profile/friendships/123")
150
+
151
+ @request = Thounds.profile.friendships(123).send(verb) {|r| r}
152
+ end
153
+
154
+ it "should use 'profile/friendships/123' request path" do
155
+ @request.proxy.path.should == "profile/friendships/123"
156
+ end
157
+
158
+ it "should use #{verb.to_s.upcase} request verb" do
159
+ @request.proxy.verb.should == verb
160
+ end
161
+ end
162
+ end
163
+
164
+ # http://developers.thounds.com/API/ThoundMetadata
165
+ # http://developers.thounds.com/API/ThoundDelete
166
+ [:get, :delete].each do |verb|
167
+ describe "#{verb.to_s.upcase} thounds/123" do
168
+ before do
169
+ send("stub_#{verb}", "thounds/123")
170
+
171
+ @request = Thounds.thounds(123).send(verb) {|r| r}
172
+ end
173
+
174
+ it "should use 'thounds/123' request path" do
175
+ @request.proxy.path.should == "thounds/123"
176
+ end
177
+
178
+ it "should use #{verb.to_s.upcase} request verb" do
179
+ @request.proxy.verb.should == verb
180
+ end
181
+ end
182
+ end
183
+
184
+ # http://developers.thounds.com/API/ThoundPublicStream
185
+ describe "GET thounds/public_stream" do
186
+ before do
187
+ stub_get("thounds/public_stream")
188
+ end
189
+
190
+ it "should use 'thounds/public_stream' request path" do
191
+ Thounds.thounds.public_stream {|r| r}.proxy.path.should == "thounds/public_stream"
192
+ end
193
+ end
194
+
195
+ # http://developers.thounds.com/API/ThoundSearch
196
+ describe "GET thounds/search" do
197
+ before do
198
+ stub_get("thounds/search?q=query")
199
+
200
+ @options = {:q => "query"}
201
+ @request = Thounds.thounds.search(@options) {|r| r}
202
+ end
203
+
204
+ it "should use 'thounds/search' request path" do
205
+ @request.proxy.path.should == "thounds/search"
206
+ end
207
+
208
+ it "should include new user parameters into request" do
209
+ @request.proxy.options.should == @options
210
+ end
211
+ end
212
+
213
+ # http://developers.thounds.com/API/TrackCreate
214
+ # http://developers.thounds.com/API/ThoundCreate
215
+ describe "POST tracks" do
216
+ before do
217
+ stub_post("tracks")
218
+
219
+ @options = {
220
+ :track => {
221
+ :delay => 0,
222
+ :offset => 0,
223
+ :duration => 0,
224
+ :lat => 45.4375,
225
+ :lng => 12.3358,
226
+ :title => "My new default thound!",
227
+ :privacy => "contacts",
228
+ :thound_attributes => {
229
+ :bpm => 90
230
+ },
231
+ :tag_list => "vocal jazz",
232
+ :thoundfile => "SUQzB...",
233
+ :coverfile => "iVBOR..."
234
+ }
235
+ }
236
+ @request = Thounds.tracks.post(@options) {|r| r}
237
+ end
238
+
239
+ it "should use 'tracks' request path" do
240
+ @request.proxy.path.should == "tracks"
241
+ end
242
+
243
+ it "should use POST request verb" do
244
+ @request.proxy.verb.should == :post
245
+ end
246
+
247
+ it "should include new track parameters into request" do
248
+ @request.proxy.options.should == @options
249
+ end
250
+ end
251
+
252
+ # http://developers.thounds.com/API/TrackDelete
253
+ describe "DELETE tracks/123" do
254
+ before do
255
+ stub_delete("tracks/123")
256
+
257
+ @request = Thounds.tracks(123).delete {|r| r}
258
+ end
259
+
260
+ it "should use 'tracks/123' request path" do
261
+ @request.proxy.path.should == "tracks/123"
262
+ end
263
+
264
+ it "should use DELETE request verb" do
265
+ @request.proxy.verb.should == :delete
266
+ end
267
+ end
268
+
269
+ # http://developers.thounds.com/API/TrackNotificationsDelete
270
+ describe "DELETE track_notifications/123" do
271
+ before do
272
+ stub_delete("track_notifications/123")
273
+
274
+ @request = Thounds.track_notifications(123).delete {|r| r}
275
+ end
276
+
277
+ it "should use 'track_notifications/123' request path" do
278
+ @request.proxy.path.should == "track_notifications/123"
279
+ end
280
+
281
+ it "should use DELETE request verb" do
282
+ @request.proxy.verb.should == :delete
283
+ end
284
+ end
285
+
286
+ end
287
+
288
+ describe ".client" do
289
+ it "should be a Thounds::Client" do
290
+ Thounds.client.should be_a Thounds::Client
291
+ end
292
+ end
293
+
294
+ describe ".adapter" do
295
+ it "should return the default adapter" do
296
+ Thounds.adapter.should == Thounds::Configuration::DEFAULT_ADAPTER
297
+ end
298
+ end
299
+
300
+ describe ".adapter=" do
301
+ it "should set the adapter" do
302
+ Thounds.adapter = :typhoeus
303
+ Thounds.adapter.should == :typhoeus
304
+ end
305
+ end
306
+
307
+ describe ".endpoint" do
308
+ it "should return the default endpoint" do
309
+ Thounds.endpoint.should == Thounds::Configuration::DEFAULT_ENDPOINT
310
+ end
311
+ end
312
+
313
+ describe ".endpoint=" do
314
+ it "should set the endpoint" do
315
+ Thounds.endpoint = 'http://tumblr.com/'
316
+ Thounds.endpoint.should == 'http://tumblr.com/'
317
+ end
318
+ end
319
+
320
+ describe ".format" do
321
+ it "should return the default format" do
322
+ Thounds.format.should == Thounds::Configuration::DEFAULT_FORMAT
323
+ end
324
+ end
325
+
326
+ describe ".format=" do
327
+ it "should set the format" do
328
+ Thounds.format = 'xml'
329
+ Thounds.format.should == 'xml'
330
+ end
331
+ end
332
+
333
+ describe ".user_agent" do
334
+ it "should return the default user agent" do
335
+ Thounds.user_agent.should == Thounds::Configuration::DEFAULT_USER_AGENT
336
+ end
337
+ end
338
+
339
+ describe ".user_agent=" do
340
+ it "should set the user_agent" do
341
+ Thounds.user_agent = 'Custom User Agent'
342
+ Thounds.user_agent.should == 'Custom User Agent'
343
+ end
344
+ end
345
+
346
+ describe ".configure" do
347
+
348
+ Thounds::Configuration::VALID_OPTIONS_KEYS.each do |key|
349
+
350
+ it "should set the #{key}" do
351
+ Thounds.configure do |config|
352
+ config.send("#{key}=", key)
353
+ Thounds.send(key).should == key
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end