rod-rest 0.0.1.1 → 0.5.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.
@@ -9,7 +9,7 @@ stub_class 'Rod::Rest::ProxyFactory'
9
9
  module Rod
10
10
  module Rest
11
11
  describe Client do
12
- let(:factory_class) { stub!.new([resource1],is_a(Client)) { factory }.subject }
12
+ let(:factory_class) { stub!.new([resource1],is_a(Client),is_a(Hash)) { factory }.subject }
13
13
  let(:factory) { Object.new }
14
14
  let(:metadata) { stub!.resources { [resource1] }.subject }
15
15
  let(:resource1) { resource = stub!.name { resource_name }.subject
@@ -23,9 +23,11 @@ module Rod
23
23
  let(:car_type) { resource_name }
24
24
  let(:response) { stub!.status{ 200 }.subject }
25
25
  let(:web_client) { Object.new }
26
+ let(:proxy_cache) { nil }
26
27
 
27
28
  describe "without metadata provided to the client" do
28
- let(:client) { Client.new(http_client: web_client,metadata_factory: metadata_factory, factory: factory_class) }
29
+ let(:client) { Client.new(http_client: web_client,metadata_factory: metadata_factory, factory: factory_class,
30
+ proxy_cache: proxy_cache) }
29
31
  let(:metadata_factory) { stub!.new(description: metadata_description) { metadata }.subject }
30
32
  let(:metadata_description) { "{}" }
31
33
 
@@ -39,9 +41,9 @@ module Rod
39
41
  end
40
42
 
41
43
  describe "when fetching the data via the API" do
42
- let(:json_cars_count) { { count: 3 }.to_json }
44
+ let(:cars_count_json) { { count: 3 }.to_json }
43
45
  let(:cars_response) { response = stub!.status { 200 }.subject
44
- stub(response).body { json_cars_count }
46
+ stub(response).body { cars_count_json }
45
47
  response
46
48
  }
47
49
 
@@ -56,18 +58,18 @@ module Rod
56
58
  end
57
59
 
58
60
  describe "with metadata provided to the client" do
59
- let(:client) { Client.new(http_client: web_client,metadata: metadata, factory: factory_class) }
61
+ let(:client) { Client.new(http_client: web_client,metadata: metadata, factory: factory_class, proxy_cache: proxy_cache) }
60
62
 
61
63
  let(:invalid_id) { 1000 }
62
64
  let(:invalid_index) { 2000 }
63
65
  let(:invalid_response) { stub!.status{ 404 }.subject }
64
66
 
65
67
  describe "#cars_count" do
66
- let(:json_cars_count) { { count: 3 }.to_json }
68
+ let(:cars_count_json) { { count: 3 }.to_json }
67
69
 
68
70
  before do
69
71
  stub(web_client).get("/cars") { response }
70
- stub(response).body { json_cars_count }
72
+ stub(response).body { cars_count_json }
71
73
  end
72
74
 
73
75
  it "returns the number of cars" do
@@ -75,51 +77,86 @@ module Rod
75
77
  end
76
78
  end
77
79
 
78
- describe "with two cars defined" do
80
+ describe "with three cars defined" do
79
81
  let(:mercedes_300_id) { 1 }
82
+ let(:mercedes_180_id) { 2 }
83
+ let(:audi_a4_id) { 3 }
80
84
  let(:mercedes_300_hash) { {rod_id: mercedes_300_id, type: car_type } }
81
- let(:mercedes_180_hash) { {rod_id: 2, type: car_type } }
82
- let(:mercedes_300_proxy){ Object.new }
83
- let(:mercedes_180_proxy){ Object.new }
84
- let(:factory) { factory = stub!.build(mercedes_300_hash) { mercedes_300_proxy }.subject
85
- stub(factory).build(mercedes_180_hash) { mercedes_180_proxy }
85
+ let(:mercedes_180_hash) { {rod_id: mercedes_180_id, type: car_type } }
86
+ let(:audi_a4_hash) { {rod_id: audi_a4_id, type: car_type } }
87
+ let(:mercedes_300) { mercedes = stub!.rod_id { mercedes_300_id }.subject
88
+ stub(mercedes).type { car_type }
89
+ mercedes
90
+ }
91
+ let(:mercedes_180) { Object.new }
92
+ let(:audi_a4) { Object.new }
93
+ let(:factory) { factory = stub!.build(mercedes_300_hash) { mercedes_300 }.subject
94
+ stub(factory).build(mercedes_180_hash) { mercedes_180 }
95
+ stub(factory).build(audi_a4_hash) { audi_a4 }
86
96
  factory
87
97
  }
88
98
 
89
99
  describe "#find_cars_by_name(name)" do
90
100
  let(:car_name) { "Mercedes" }
91
101
  let(:property_name) { "name" }
92
- let(:json_cars) { [mercedes_300_hash,mercedes_180_hash].to_json }
102
+ let(:cars_json) { [mercedes_300_hash,mercedes_180_hash].to_json }
93
103
  let(:indexed_properties){ [indexed_property] }
94
104
  let(:indexed_property) { stub!.name { property_name }.subject }
95
105
 
96
106
  before do
97
107
  stub(web_client).get("/cars?#{property_name}=#{car_name}") { response }
98
- stub(response).body { json_cars }
108
+ stub(response).body { cars_json }
99
109
  end
100
110
 
101
111
  it "finds the cars by their name" do
102
112
  cars = client.find_cars_by_name(car_name)
103
- expected_cars = [mercedes_300_proxy,mercedes_180_proxy]
104
- cars.size.should == expected_cars.size
105
- cars.zip(expected_cars).each do |result,expected|
106
- result.should == expected
107
- end
113
+ expected_cars = [mercedes_300,mercedes_180]
114
+ cars.should == expected_cars
115
+ end
116
+ end
117
+
118
+ describe "#find_cars(1..3)" do
119
+ let(:cars_json) { [mercedes_300_hash,mercedes_180_hash,audi_a4_hash].to_json }
120
+
121
+ before do
122
+ stub(web_client).get("/cars/#{mercedes_300_id}..#{audi_a4_id}") { response }
123
+ stub(response).body { cars_json }
124
+ end
125
+
126
+ it "returns range of cars" do
127
+ cars = client.find_cars(mercedes_300_id..audi_a4_id)
128
+ expected_cars = [mercedes_300,mercedes_180,audi_a4]
129
+ cars.should == expected_cars
130
+ end
131
+ end
132
+
133
+ describe "#find_cars(1,3)" do
134
+ let(:cars_json) { [mercedes_300_hash,audi_a4_hash].to_json }
135
+
136
+ before do
137
+ stub(web_client).get("/cars/#{mercedes_300_id},#{audi_a4_id}") { response }
138
+ stub(response).body { cars_json }
139
+ end
140
+
141
+ it "returns collection of cars" do
142
+ cars = client.find_cars(mercedes_300_id,audi_a4_id)
143
+ expected_cars = [mercedes_300,audi_a4]
144
+ cars.should == expected_cars
108
145
  end
109
146
  end
110
147
 
111
148
  describe "with car response defined" do
112
- let(:json_mercedes_300) { mercedes_300_hash.to_json }
149
+ let(:mercedes_300_json) { mercedes_300_hash.to_json }
113
150
 
114
151
  before do
115
152
  stub(web_client).get("/cars/#{mercedes_300_id}") { response }
116
153
  stub(web_client).get("/cars/#{invalid_id}") { invalid_response }
117
- stub(response).body { json_mercedes_300 }
154
+ stub(response).body { mercedes_300_json }
118
155
  end
119
156
 
120
157
  describe "#find_car(rod_id)" do
121
158
  it "finds the car by its rod_id" do
122
- client.find_car(mercedes_300_id).should == mercedes_300_proxy
159
+ client.find_car(mercedes_300_id).should == mercedes_300
123
160
  end
124
161
 
125
162
  it "raises MissingResource exception for invalid car rod_id" do
@@ -134,7 +171,7 @@ module Rod
134
171
  let(:invalid_type) { "InvalidType" }
135
172
 
136
173
  it "finds the car by its stub" do
137
- client.fetch_object(car_stub).should == mercedes_300_proxy
174
+ client.fetch_object(car_stub).should == mercedes_300
138
175
  end
139
176
 
140
177
  it "raises MissingResource execption for invalid car rod_id" do
@@ -154,13 +191,13 @@ module Rod
154
191
 
155
192
  describe "#car_drivers_count(rod_id)" do
156
193
  let(:drivers_count) { 3 }
157
- let(:json_driver_count) { { count: drivers_count }.to_json }
194
+ let(:driver_count_json) { { count: drivers_count }.to_json }
158
195
 
159
196
 
160
197
  before do
161
198
  stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}") { response }
162
199
  stub(web_client).get("/cars/#{invalid_id}/#{association_name}") { invalid_response }
163
- stub(response).body { json_driver_count }
200
+ stub(response).body { driver_count_json }
164
201
  end
165
202
 
166
203
  it "returns the number of car drivers" do
@@ -172,24 +209,33 @@ module Rod
172
209
  end
173
210
  end
174
211
 
175
- describe "with reponse defined" do
212
+ describe "with drivers" do
176
213
  let(:schumaher_index) { 0 }
214
+ let(:alonzo_index) { 2 }
177
215
  let(:schumaher_hash) { { rod_id: schumaher_id, name: "Schumaher", type: "Driver" } }
216
+ let(:kubica_hash) { { rod_id: 3, name: "Kubica", type: "Driver" } }
217
+ let(:alonzo_hash) { { rod_id: 4, name: "Alonzo", type: "Driver" } }
178
218
  let(:schumaher_json) { schumaher_hash.to_json }
179
- let(:schumaher_proxy) { Object.new }
219
+ let(:kubica_json) { kubica_hash.to_json }
220
+ let(:alonzo_json) { schumaher_hash.to_json }
221
+ let(:schumaher) { Object.new }
222
+ let(:kubica) { Object.new }
223
+ let(:alonzo) { Object.new }
180
224
  let(:schumaher_id) { 1 }
181
225
 
182
226
  before do
227
+ stub(factory).build(schumaher_hash) { schumaher }
228
+ stub(factory).build(kubica_hash) { kubica }
229
+ stub(factory).build(alonzo_hash) { alonzo }
183
230
  stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{schumaher_index}") { response }
184
231
  stub(web_client).get("/cars/#{invalid_id}/#{association_name}/#{schumaher_index}") { invalid_response }
185
232
  stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{invalid_index}") { invalid_response }
186
233
  stub(response).body { schumaher_json }
187
- stub(factory).build(schumaher_hash) { schumaher_proxy }
188
234
  end
189
235
 
190
236
  describe "#car_driver(rod_id,index)" do
191
237
  it "returns the driver" do
192
- client.car_driver(mercedes_300_id,schumaher_index).should == schumaher_proxy
238
+ client.car_driver(mercedes_300_id,schumaher_index).should == schumaher
193
239
  end
194
240
 
195
241
  it "raises MissingResource exception for invalid car rod_id" do
@@ -201,6 +247,34 @@ module Rod
201
247
  end
202
248
  end
203
249
 
250
+ describe "#car_drivers(subject,relation,0..2)" do
251
+ let(:drivers) { [schumaher,kubica,alonzo] }
252
+ let(:collection_json) { [schumaher_hash,kubica_hash,alonzo_hash].to_json }
253
+
254
+ before do
255
+ stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{schumaher_index}..#{alonzo_index}") { response }
256
+ stub(response).body { collection_json }
257
+ end
258
+
259
+ it "returns the collection of drivers" do
260
+ client.car_drivers(mercedes_300_id,schumaher_index..alonzo_index).should == drivers
261
+ end
262
+ end
263
+
264
+ describe "#car_drivers(subject,relation,0,2)" do
265
+ let(:drivers) { [schumaher,alonzo] }
266
+ let(:collection_json) { [schumaher_hash,alonzo_hash].to_json }
267
+
268
+ before do
269
+ stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{schumaher_index},#{alonzo_index}") { response }
270
+ stub(response).body { collection_json }
271
+ end
272
+
273
+ it "returns the collection of drivers" do
274
+ client.car_drivers(mercedes_300_id,schumaher_index,alonzo_index).should == drivers
275
+ end
276
+ end
277
+
204
278
  describe "#fetch_related_object(subject,relation,index)" do
205
279
  let(:association_name) { "drivers" }
206
280
  let(:invalid_association_name){ "owners" }
@@ -214,13 +288,8 @@ module Rod
214
288
  proxy
215
289
  }
216
290
 
217
- before do
218
- stub(mercedes_300_proxy).rod_id { mercedes_300_id }
219
- stub(mercedes_300_proxy).type { car_type }
220
- end
221
-
222
291
  it "returns the driver" do
223
- client.fetch_related_object(mercedes_300_proxy,association_name,schumaher_index).should == schumaher_proxy
292
+ client.fetch_related_object(mercedes_300,association_name,schumaher_index).should == schumaher
224
293
  end
225
294
 
226
295
  it "raises MissingResource exception for invalid car proxy id" do
@@ -228,7 +297,7 @@ module Rod
228
297
  end
229
298
 
230
299
  it "raises MissingResource exception for invalid index" do
231
- lambda { client.fetch_related_object(mercedes_300_proxy,association_name,invalid_index)}.should raise_exception(MissingResource)
300
+ lambda { client.fetch_related_object(mercedes_300,association_name,invalid_index)}.should raise_exception(MissingResource)
232
301
  end
233
302
 
234
303
  it "raises APIError exception for invalid resource type" do
@@ -236,7 +305,37 @@ module Rod
236
305
  end
237
306
 
238
307
  it "raises APIError exception for invalid association name" do
239
- lambda { client.fetch_related_object(mercedes_300_proxy,invalid_association_name,schumaher_index)}.should raise_exception(APIError)
308
+ lambda { client.fetch_related_object(mercedes_300,invalid_association_name,schumaher_index)}.should raise_exception(APIError)
309
+ end
310
+ end
311
+
312
+ describe "#fetch_related_objects(subject,relation,0..2)" do
313
+ let(:association_name) { "drivers" }
314
+ let(:drivers) { [schumaher,kubica,alonzo] }
315
+ let(:collection_json) { [schumaher_hash,kubica_hash,alonzo_hash].to_json }
316
+
317
+ before do
318
+ stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{schumaher_index}..#{alonzo_index}") { response }
319
+ stub(response).body { collection_json }
320
+ end
321
+
322
+ it "returns drivers collection" do
323
+ client.fetch_related_objects(mercedes_300,association_name,schumaher_index..alonzo_index).should == drivers
324
+ end
325
+ end
326
+
327
+ describe "#fetch_related_objects(subject,relation,0,2)" do
328
+ let(:association_name) { "drivers" }
329
+ let(:drivers) { [schumaher,alonzo] }
330
+ let(:collection_json) { [schumaher_hash,alonzo_hash].to_json }
331
+
332
+ before do
333
+ stub(web_client).get("/cars/#{mercedes_300_id}/#{association_name}/#{schumaher_index},#{alonzo_index}") { response }
334
+ stub(response).body { collection_json }
335
+ end
336
+
337
+ it "returns drivers collection" do
338
+ client.fetch_related_objects(mercedes_300,association_name,schumaher_index,alonzo_index).should == drivers
240
339
  end
241
340
  end
242
341
  end
@@ -11,6 +11,34 @@ module Rod
11
11
  let(:size) { 0 }
12
12
  let(:client) { Object.new }
13
13
 
14
+ describe "#inspect" do
15
+ let(:car_type) { "Car" }
16
+ before do
17
+ stub(mercedes_proxy).type { car_type }
18
+ end
19
+
20
+ it "reports the type of the proxy object" do
21
+ collection.inspect.should match(/#{car_type}/)
22
+ end
23
+
24
+ it "reports the name of the association" do
25
+ collection.inspect.should match(/#{association_name}/)
26
+ end
27
+
28
+ it "reports size of the collection" do
29
+ collection.inspect.should match(/#{size}/)
30
+ end
31
+ end
32
+
33
+ describe "#to_s" do
34
+ it "reports the size of the collection" do
35
+ collection.to_s.should match(/#{size}/)
36
+ end
37
+ end
38
+
39
+ describe "#to_s" do
40
+ end
41
+
14
42
  describe "#empty?" do
15
43
  describe "with 0 elements" do
16
44
  it "is empty" do
@@ -60,6 +88,29 @@ module Rod
60
88
  it "returns nil in case of out of bounds driver" do
61
89
  collection[5].should == nil
62
90
  end
91
+
92
+ it "caches retrieved objects" do
93
+ collection[1]
94
+ collection[1]
95
+ expect(client).to have_received.fetch_related_object(mercedes_proxy,association_name,1) { kubica }.once
96
+ end
97
+ end
98
+
99
+ describe "#[lower..upper]" do
100
+ before do
101
+ stub(client).fetch_related_objects(mercedes_proxy,association_name,0..2) { [schumaher,kubica,alonzo] }
102
+ end
103
+
104
+ it "returns drivers by index range" do
105
+ collection[0..2].should == [schumaher,kubica,alonzo]
106
+ end
107
+
108
+ it "caches retrieved objects" do
109
+ collection[0..2]
110
+ collection[1]
111
+ collection[1]
112
+ expect(client).to have_received.fetch_related_objects(mercedes_proxy,association_name,0..2).once
113
+ end
63
114
  end
64
115
 
65
116
  describe "#first" do
@@ -84,9 +135,7 @@ module Rod
84
135
 
85
136
  describe "#each" do
86
137
  before do
87
- stub(client).fetch_related_object(mercedes_proxy,association_name,0) { schumaher }
88
- stub(client).fetch_related_object(mercedes_proxy,association_name,1) { kubica }
89
- stub(client).fetch_related_object(mercedes_proxy,association_name,2) { alonzo }
138
+ stub(client).fetch_related_objects(mercedes_proxy,association_name,0..2) { [schumaher,kubica,alonzo] }
90
139
  end
91
140
 
92
141
  it "iterates over the drivers" do
@@ -32,6 +32,30 @@ module Rod
32
32
  metadata.resources.first
33
33
  expect(resource_metadata_factory).to have_received.new(resource_name,resource_description)
34
34
  end
35
+
36
+ describe "#inspect" do
37
+ let(:data_description) { "data description" }
38
+
39
+ before do
40
+ stub(description).inspect { data_description }
41
+ end
42
+
43
+ it "returns the description of the data" do
44
+ metadata.inspect.should match(/#{data_description}/)
45
+ end
46
+ end
47
+
48
+ describe "#to_s" do
49
+ let(:data_description) { "data description" }
50
+
51
+ before do
52
+ stub(description).to_s { data_description }
53
+ end
54
+
55
+ it "returns the description of the data" do
56
+ metadata.to_s.should match(/#{data_description}/)
57
+ end
58
+ end
35
59
  end
36
60
  end
37
61
  end
@@ -6,6 +6,8 @@ module Rod
6
6
  module Rest
7
7
  describe PropertyMetadata do
8
8
  let(:property_metadata) { PropertyMetadata.new(name,options) }
9
+ let(:name) { :age }
10
+ let(:options) { { type: :integer } }
9
11
 
10
12
  describe "constructor" do
11
13
  it "forbids to create property without name" do
@@ -14,9 +16,6 @@ module Rod
14
16
  end
15
17
 
16
18
  describe "#name" do
17
- let(:options) { { type: :integer } }
18
- let(:name) { :age }
19
-
20
19
  it "converts its name to string" do
21
20
  property_metadata.name.should be_a(String)
22
21
  end
@@ -27,9 +26,6 @@ module Rod
27
26
  end
28
27
 
29
28
  describe "#symbolic_name" do
30
- let(:options) { { type: :string } }
31
- let(:name) { :name }
32
-
33
29
  it "converts its symbolic name to string" do
34
30
  property_metadata.symbolic_name.should be_a(Symbol)
35
31
  end
@@ -58,6 +54,35 @@ module Rod
58
54
  end
59
55
  end
60
56
  end
57
+
58
+ describe "#inspect" do
59
+ let(:options) { { type: :string, index: index } }
60
+ let(:index) { nil }
61
+
62
+ it "reports the name of the property" do
63
+ property_metadata.inspect.should match(/#{name}/)
64
+ end
65
+
66
+ context "without index" do
67
+ it "doesn't report that it is indexed" do
68
+ property_metadata.inspect.should_not match(/indexed/)
69
+ end
70
+ end
71
+
72
+ context "with index" do
73
+ let(:index) { :hash }
74
+
75
+ it "reports that it is indexed" do
76
+ property_metadata.inspect.should match(/indexed/)
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#to_s" do
82
+ it "reports the name of the property" do
83
+ property_metadata.to_s.should match(/#{name}/)
84
+ end
85
+ end
61
86
  end
62
87
  end
63
88
  end