voorhees 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,335 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe User do
4
+
5
+ before :each do
6
+ load_json
7
+ end
8
+
9
+ describe "ClassMethods" do
10
+ describe "new_from_json" do
11
+
12
+ it "Should create a new User" do
13
+ User.should_receive(:new).once.and_return(mock(:user, :null_object => true))
14
+ user_from_json
15
+ end
16
+
17
+ it "should assign the JSON to User#raw_json" do
18
+ mock_user = mock(:user, :null_object => true)
19
+ User.stub!(:new).and_return(mock_user)
20
+ mock_user.should_receive(:raw_json=).with(@json)
21
+ user_from_json
22
+ end
23
+
24
+ it "should assign the hierarchy to User#json_hierarchy" do
25
+ mock_user = mock(:user, :null_object => true)
26
+ User.stub!(:new).and_return(mock_user)
27
+ mock_user.should_receive(:json_hierarchy=).with(@hierarchy)
28
+ user_from_json
29
+ end
30
+
31
+ it "should return the new user" do
32
+ user_from_json.should be_an_instance_of(User)
33
+ end
34
+ end
35
+
36
+ describe "json_request" do
37
+
38
+ before :each do
39
+ @json_string= "{}"
40
+ @json_hash = {}
41
+
42
+ @request = mock(:request, :null_object => true)
43
+ @response = mock(:response, :null_object => true)
44
+ @objects = [mock(:object)]
45
+
46
+ Voorhees::Request.stub!(:new).and_return(@request)
47
+ @request.stub!(:perform).and_return(@response)
48
+
49
+ @response.stub!(:to_objects).and_return(@objects)
50
+ @response.stub!(:json).and_return(@json_hash)
51
+ @response.stub!(:body).and_return(@json_string)
52
+ end
53
+
54
+ def perform_request
55
+ User.json_request{}
56
+ end
57
+
58
+
59
+ it "should call Request.new with the current class if no class is passed" do
60
+ Voorhees::Request.should_receive(:new).with(User).and_return(@request)
61
+ perform_request
62
+ end
63
+
64
+ it "should call Request.new with the specified class if a class is passed" do
65
+ Voorhees::Request.should_receive(:new).with(Message).and_return(@request)
66
+ User.json_request(:class => Message) do |request|
67
+ # ...
68
+ end
69
+ end
70
+
71
+
72
+ it "should yeild a request" do
73
+ User.json_request do |r|
74
+ r.should == @request
75
+ end
76
+ end
77
+
78
+ it "should raise a LocalJumpError exception if a block is not given" do
79
+ lambda{
80
+ User.json_request
81
+ }.should raise_error(LocalJumpError)
82
+ end
83
+
84
+ it "should implicitly call Request#perform" do
85
+ @request.should_receive(:perform).once
86
+ perform_request
87
+ end
88
+
89
+ it "should return the result of Response#to_objects if :returning is not set" do
90
+ perform_request.should == @objects
91
+ end
92
+
93
+ it "should return the JSON string if :returning is set to :raw" do
94
+ User.json_request(:returning => :raw){}.should == @json_string
95
+ end
96
+
97
+ it "should return the JSON hash if :returning is set to :json" do
98
+ User.json_request(:returning => :json){}.should == @json_hash
99
+ end
100
+
101
+ it "should return the objects string if :returning is set to :objects" do
102
+ User.json_request(:returning => :objects){}.should == @objects
103
+ end
104
+
105
+ it "should return the response if :returning is set to :response" do
106
+ User.json_request(:returning => :response){}.should == @response
107
+ end
108
+
109
+ end
110
+
111
+ describe "json_service" do
112
+
113
+ before :each do
114
+ @service_name = :list
115
+ @service_attrs = {
116
+ :timeout => 100,
117
+ :required => [:monkeys]
118
+ }
119
+ end
120
+
121
+ def define_service
122
+ User.json_service @service_name, @service_attrs
123
+ end
124
+
125
+ it "should define a method with the same name as the service" do
126
+ User.should_not respond_to(@service_name)
127
+ define_service
128
+ User.should respond_to(@service_name)
129
+ end
130
+
131
+ describe "calling the defined method" do
132
+
133
+ before :each do
134
+ define_service
135
+
136
+ @request = mock(:request, :null_object => true)
137
+ @response = mock(:response, :null_object => true)
138
+ @objects = [mock(:object)]
139
+
140
+ Voorhees::Request.stub!(:new).and_return(@request)
141
+ @request.stub!(:perform).and_return(@response)
142
+ end
143
+
144
+ it "should call User#json_request" do
145
+ User.should_receive(:json_request).and_return(@response)
146
+ User.list
147
+ end
148
+
149
+ it "should pass service attributes onto the request" do
150
+ @service_attrs.each do |key, value|
151
+ @request.should_receive("#{key}=").with(value)
152
+ end
153
+ User.list
154
+ end
155
+
156
+ it "should use any hash passed in to set the request parameters" do
157
+ params = {:monkeys => true}
158
+ @request.should_receive(:parameters=).with(params)
159
+ User.list(params)
160
+ end
161
+
162
+ it "should return the result of Response#to_objects" do
163
+ @response.should_receive(:to_objects).and_return(@objects)
164
+ User.list.should == @objects
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "InstanceMethods" do
171
+
172
+ describe "#raw_json" do
173
+ it "should contain the raw json" do
174
+ user_from_json.raw_json.should == @json
175
+ end
176
+ end
177
+
178
+ describe "#json_attributes" do
179
+ it "should contain symbols of the keys of the attributes available as underscored" do
180
+ user_from_json.json_attributes.sort.should == [:address, :camel_case, :email, :id, :messages, :name, :pet, :username]
181
+ end
182
+ end
183
+
184
+ describe "#json_request" do
185
+
186
+ before :each do
187
+ @request = mock(:request, :null_object => true)
188
+ @response = mock(:response, :null_object => true)
189
+
190
+ Voorhees::Request.stub!(:new).and_return(@request)
191
+ @request.stub!(:perform).and_return(@response)
192
+ end
193
+
194
+ def perform_request
195
+ user_from_json.json_request{}
196
+ end
197
+
198
+ it "should pass the request to the class method" do
199
+ User.should_receive(:json_request)
200
+ user_from_json.json_request{}
201
+ end
202
+
203
+ it "should raise a LocalJumpError exception if a block is not given" do
204
+ lambda{
205
+ user_from_json.json_request
206
+ }.should raise_error(LocalJumpError)
207
+ end
208
+
209
+ it "should implicitly call Request#perform" do
210
+ @request.should_receive(:perform).once
211
+ perform_request
212
+ end
213
+
214
+ it "should return the result of Request#perform" do
215
+ perform_request.should == @response
216
+ end
217
+
218
+ end
219
+
220
+ describe "calling assignment method with name of a json attribute" do
221
+
222
+ it "should define an assignment method" do
223
+ user = user_from_json
224
+
225
+ user.should_not respond_to(:email=)
226
+ user.email = "test"
227
+ user.should respond_to(:email=)
228
+ end
229
+
230
+ it "should assign the value" do
231
+ user = user_from_json
232
+ new_email = "a_new_address@example.com"
233
+
234
+ user.email = new_email
235
+ user.email.should == new_email
236
+ end
237
+
238
+ end
239
+
240
+ describe "calling method with the name of a json attribute" do
241
+
242
+ it "should return the correct data from #id" do
243
+ user = user_from_json
244
+ user.id.should == @json["id"]
245
+ end
246
+
247
+ it "should define a method of the same name" do
248
+ user = user_from_json
249
+
250
+ user.should_not respond_to(:email)
251
+ user.email
252
+ user.should respond_to(:email)
253
+ end
254
+
255
+ it "should return the correct data from defined methods" do
256
+ user = user_from_json
257
+
258
+ user.email # first access, now it's defined
259
+ user.email.should == @json["email"]
260
+ end
261
+
262
+ describe "which is a simple value" do
263
+ it "should return the value of the attribute" do
264
+ user_from_json.email.should == @json["email"]
265
+ end
266
+ end
267
+
268
+ describe "which is camelCase in the JSON" do
269
+ it "should return the value of the attribute" do
270
+ user_from_json.camel_case.should == @json["camelCase"]
271
+ end
272
+ end
273
+
274
+ describe "which is a collection" do
275
+ it "should return an array" do
276
+ user_from_json.messages.should be_an_instance_of(Array)
277
+ end
278
+
279
+ it "should infer the type of objects based on the collection name" do
280
+ user_from_json.messages.each do |m|
281
+ m.should be_an_instance_of(Message)
282
+ end
283
+ end
284
+ end
285
+
286
+ describe "which is a sub-object" do
287
+
288
+ it "should return as a Hash if the hierarchy is not defined" do
289
+ @hierarchy = {
290
+ }
291
+ user_from_json.pet.should be_a(Hash)
292
+ end
293
+
294
+ it "should return as the right class if the hierarchy is defined as symbol" do
295
+ @hierarchy = {
296
+ :address => :address
297
+ }
298
+ user_from_json.address.should be_a(Address)
299
+ end
300
+
301
+ it "should return as the right class if the hierarchy is defined as Class" do
302
+ @hierarchy = {
303
+ :address => Address
304
+ }
305
+ user_from_json.address.should be_a(Address)
306
+ end
307
+
308
+ it "should return as the right class for multiple depths" do
309
+ @hierarchy = {
310
+ :address => [Address, {
311
+ :coords => LatLon
312
+ }]
313
+ }
314
+ user_from_json.address.coords.should be_a(LatLon)
315
+ end
316
+
317
+ end
318
+
319
+ end
320
+
321
+ end
322
+ end
323
+
324
+ def load_json
325
+ body = ''
326
+ path = File.expand_path(File.dirname(__FILE__) + '/fixtures/user.json')
327
+ File.open(path, 'r') do |f|
328
+ body = f.read
329
+ end
330
+ @json = JSON.parse(body)
331
+ end
332
+
333
+ def user_from_json
334
+ User.new_from_json(@json, @hierarchy)
335
+ end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Voorhees::Response do
4
+
5
+ before :each do
6
+ User.stub!(:new_from_json).and_return(User.new)
7
+ end
8
+
9
+ describe "to_objects" do
10
+
11
+ describe "with no class set" do
12
+
13
+ before :each do
14
+ @klass = nil
15
+ build_response(:users)
16
+ end
17
+
18
+ it "should return nil" do
19
+ @response.to_objects.should be_nil
20
+ end
21
+
22
+ end
23
+
24
+ describe "with a class which does not have Voorhees::Resource mixed in" do
25
+
26
+ before :each do
27
+ @klass = NotResource
28
+ build_response(:users)
29
+ end
30
+
31
+ it "should raise a Voorhees::NotResourceError exception" do
32
+ lambda{
33
+ @response.to_objects
34
+ }.should raise_error(Voorhees::NotResourceError)
35
+ end
36
+
37
+ end
38
+
39
+ describe "with a class which has Voorhees::Resource mixed in" do
40
+
41
+ before :each do
42
+ @klass = User
43
+ end
44
+
45
+ describe "with JSON containing an array of 2 items" do
46
+
47
+ before :each do
48
+ build_response(:users)
49
+ end
50
+
51
+ it "should return an array of 2 objects of the right class" do
52
+ users = @response.to_objects
53
+ users.length.should == 2
54
+ users.each do |u|
55
+ u.should be_an_instance_of(User)
56
+ end
57
+ end
58
+
59
+ it "should create objects by sending the JSON and hierarchy to Class.new_from_json" do
60
+ User.should_receive(:new_from_json).with(@response.json[0], @hierarchy).ordered
61
+ User.should_receive(:new_from_json).with(@response.json[1], @hierarchy).ordered
62
+ @response.to_objects
63
+ end
64
+ end
65
+
66
+ describe "with JSON containing one item" do
67
+
68
+ before :each do
69
+ build_response(:user)
70
+ end
71
+
72
+ it "should return one object of the right class" do
73
+ user = @response.to_objects
74
+ user.should be_an_instance_of(User)
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def build_response(fixture)
83
+ body = ''
84
+ path = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{fixture}.json")
85
+ File.open(path, 'r') do |f|
86
+ body = f.read
87
+ end
88
+
89
+ @hierarchy = {
90
+ :address => Address
91
+ }
92
+ @response = Voorhees::Response.new(body, @klass, @hierarchy)
93
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec'
2
+ require 'rubygems'
3
+ require 'json'
4
+ require 'active_support'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'voorhees'
9
+
10
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/resources')
11
+
12
+ Spec::Runner.configure do |config|
13
+
14
+ end
15
+
16
+ # allow sorting by symbol
17
+ class Symbol
18
+ def <=>(a)
19
+ self.to_s <=> a.to_s
20
+ end
21
+ end
22
+