koala 1.0.0.beta2.1 → 1.0.0.rc

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.
Files changed (50) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG +6 -1
  3. data/Gemfile +3 -0
  4. data/Rakefile +13 -14
  5. data/koala.gemspec +35 -20
  6. data/lib/koala.rb +8 -17
  7. data/lib/koala/graph_api.rb +2 -2
  8. data/lib/koala/http_services.rb +32 -27
  9. data/lib/koala/test_users.rb +4 -4
  10. data/lib/koala/uploadable_io.rb +1 -1
  11. data/spec/cases/api_base_spec.rb +101 -0
  12. data/spec/cases/graph_and_rest_api_spec.rb +31 -0
  13. data/spec/cases/graph_api_spec.rb +25 -0
  14. data/spec/{koala/http_services/http_service_tests.rb → cases/http_services/http_service_spec.rb} +8 -5
  15. data/spec/cases/http_services/net_http_service_spec.rb +350 -0
  16. data/spec/cases/http_services/typhoeus_service_spec.rb +144 -0
  17. data/spec/cases/oauth_spec.rb +374 -0
  18. data/spec/cases/realtime_updates_spec.rb +184 -0
  19. data/spec/cases/rest_api_spec.rb +25 -0
  20. data/spec/{koala/test_users/test_users_tests.rb → cases/test_users_spec.rb} +34 -29
  21. data/spec/cases/uploadable_io_spec.rb +151 -0
  22. data/spec/{koala/assets → fixtures}/beach.jpg +0 -0
  23. data/spec/{facebook_data.yml → fixtures/facebook_data.yml} +5 -5
  24. data/spec/{mock_facebook_responses.yml → fixtures/mock_facebook_responses.yml} +311 -311
  25. data/spec/spec_helper.rb +18 -0
  26. data/spec/support/graph_api_shared_examples.rb +424 -0
  27. data/spec/{koala → support}/live_testing_data_helper.rb +39 -42
  28. data/spec/{mock_http_service.rb → support/mock_http_service.rb} +94 -94
  29. data/spec/{koala/rest_api/rest_api_tests.rb → support/rest_api_shared_examples.rb} +43 -0
  30. data/spec/support/setup_mocks_or_live.rb +52 -0
  31. data/spec/support/uploadable_io_shared_examples.rb +76 -0
  32. metadata +109 -53
  33. data/init.rb +0 -2
  34. data/spec/koala/api_base_tests.rb +0 -102
  35. data/spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb +0 -14
  36. data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +0 -16
  37. data/spec/koala/graph_api/graph_api_no_access_token_tests.rb +0 -65
  38. data/spec/koala/graph_api/graph_api_tests.rb +0 -85
  39. data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +0 -194
  40. data/spec/koala/graph_api/graph_collection_tests.rb +0 -104
  41. data/spec/koala/http_services/net_http_service_tests.rb +0 -339
  42. data/spec/koala/http_services/typhoeus_service_tests.rb +0 -162
  43. data/spec/koala/oauth/oauth_tests.rb +0 -372
  44. data/spec/koala/realtime_updates/realtime_updates_tests.rb +0 -187
  45. data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +0 -25
  46. data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +0 -38
  47. data/spec/koala/uploadable_io/uploadable_io_tests.rb +0 -246
  48. data/spec/koala_spec.rb +0 -18
  49. data/spec/koala_spec_helper.rb +0 -74
  50. data/spec/koala_spec_without_mocks.rb +0 -19
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'although not required, bundler is recommened for running the tests'
5
+ end
6
+
7
+ # load the libraries
8
+ require 'koala'
9
+
10
+ # load testing data libraries
11
+ require 'support/live_testing_data_helper'
12
+ require 'support/mock_http_service'
13
+ require 'support/rest_api_shared_examples'
14
+ require 'support/graph_api_shared_examples'
15
+ require 'support/uploadable_io_shared_examples'
16
+ require 'support/setup_mocks_or_live'
17
+
18
+ BEACH_BALL_PATH = File.join(File.dirname(__FILE__), "fixtures", "beach.jpg")
@@ -0,0 +1,424 @@
1
+ shared_examples_for "Koala GraphAPI" do
2
+ # all Graph API instances should pass these tests, regardless of configuration
3
+
4
+ # API
5
+ it "should never use the rest api server" do
6
+ Koala.should_receive(:make_request).with(
7
+ anything,
8
+ anything,
9
+ anything,
10
+ hash_not_including(:rest_api => true)
11
+ ).and_return(Koala::Response.new(200, "", {}))
12
+
13
+ @api.api("anything")
14
+ end
15
+
16
+ # GRAPH CALL
17
+ describe "graph_call" do
18
+ it "should pass all arguments to the api method" do
19
+ args = ["koppel", {}, "get", {:a => :b}]
20
+
21
+ @api.should_receive(:api).with(*args)
22
+
23
+ @api.graph_call(*args)
24
+ end
25
+
26
+ it "should throw an APIError if the result hash has an error key" do
27
+ Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
28
+ lambda { @api.graph_call("koppel", {}) }.should raise_exception(Koala::Facebook::APIError)
29
+ end
30
+ end
31
+
32
+ # SEARCH
33
+ it "should be able to search" do
34
+ result = @api.search("facebook")
35
+ result.length.should be_an(Integer)
36
+ end
37
+
38
+ # DATA
39
+ # access public info
40
+
41
+ # get_object
42
+ it "should get public data about a user" do
43
+ result = @api.get_object("koppel")
44
+ # the results should have an ID and a name, among other things
45
+ (result["id"] && result["name"]).should_not be_nil
46
+ end
47
+
48
+ it "should get public data about a Page" do
49
+ result = @api.get_object("contextoptional")
50
+ # the results should have an ID and a name, among other things
51
+ (result["id"] && result["name"]).should
52
+ end
53
+
54
+ it "should be able to get multiple objects" do
55
+ results = @api.get_objects(["contextoptional", "naitik"])
56
+ results.length.should == 2
57
+ end
58
+
59
+ it "should be able to access a user's picture" do
60
+ @api.get_picture("chris.baclig").should =~ /http\:\/\//
61
+ end
62
+
63
+ it "should be able to access a user's picture, given a picture type" do
64
+ @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
65
+ end
66
+
67
+ it "should be able to access connections from public Pages" do
68
+ result = @api.get_connections("contextoptional", "photos")
69
+ result.should be_a(Array)
70
+ end
71
+
72
+ # SEARCH
73
+ it "should be able to search" do
74
+ result = @api.search("facebook")
75
+ result.length.should be_an(Integer)
76
+ end
77
+
78
+ # PAGING THROUGH COLLECTIONS
79
+ # see also graph_collection_tests
80
+ it "should make a request for a page when provided a specific set of page params" do
81
+ query = [1, 2]
82
+ @api.should_receive(:graph_call).with(*query)
83
+ @api.get_page(query)
84
+ end
85
+ end
86
+
87
+
88
+ shared_examples_for "Koala GraphAPI with an access token" do
89
+
90
+ it "should get private data about a user" do
91
+ result = @api.get_object("koppel")
92
+ # updated_time should be a pretty fixed test case
93
+ result["updated_time"].should_not be_nil
94
+ end
95
+
96
+ it "should get data about 'me'" do
97
+ result = @api.get_object("me")
98
+ result["updated_time"].should
99
+ end
100
+
101
+ it "should be able to get multiple objects" do
102
+ result = @api.get_objects(["contextoptional", "naitik"])
103
+ result.length.should == 2
104
+ end
105
+ it "should be able to access connections from users" do
106
+ result = @api.get_connections("lukeshepard", "likes")
107
+ result.length.should > 0
108
+ end
109
+
110
+ # PUT
111
+ it "should be able to write an object to the graph" do
112
+ result = @api.put_wall_post("Hello, world, from the test suite!")
113
+ @temporary_object_id = result["id"]
114
+ @temporary_object_id.should_not be_nil
115
+ end
116
+
117
+ # DELETE
118
+ it "should be able to delete posts" do
119
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
120
+ object_id_to_delete = result["id"]
121
+ delete_result = @api.delete_object(object_id_to_delete)
122
+ delete_result.should == true
123
+ end
124
+
125
+ it "should be able to delete likes" do
126
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
127
+ @temporary_object_id = result["id"]
128
+ @api.put_like(@temporary_object_id)
129
+ delete_like_result = @api.delete_like(@temporary_object_id)
130
+ delete_like_result.should == true
131
+ end
132
+
133
+ # additional put tests
134
+ it "should be able to verify messages posted to a wall" do
135
+ message = "the cats are asleep"
136
+ put_result = @api.put_wall_post(message)
137
+ @temporary_object_id = put_result["id"]
138
+ get_result = @api.get_object(@temporary_object_id)
139
+
140
+ # make sure the message we sent is the message that got posted
141
+ get_result["message"].should == message
142
+ end
143
+
144
+ it "should be able to post a message with an attachment to a feed" do
145
+ result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"})
146
+ @temporary_object_id = result["id"]
147
+ @temporary_object_id.should_not be_nil
148
+ end
149
+
150
+ it "should be able to post photos to the user's wall with an open file object" do
151
+ content_type = "image/jpg"
152
+ file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
153
+
154
+ result = @api.put_picture(file, content_type)
155
+ @temporary_object_id = result["id"]
156
+ @temporary_object_id.should_not be_nil
157
+ end
158
+
159
+ it "should be able to post photos to the user's wall without an open file object" do
160
+ content_type = "image/jpg",
161
+ file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
162
+
163
+ result = @api.put_picture(file_path, content_type)
164
+ @temporary_object_id = result["id"]
165
+ @temporary_object_id.should_not be_nil
166
+ end
167
+
168
+ it "should be able to verify a photo posted to a user's wall" do
169
+ content_type = "image/jpg",
170
+ file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
171
+
172
+ expected_message = "This is the test message"
173
+
174
+ result = @api.put_picture(file_path, content_type, :message => expected_message)
175
+ @temporary_object_id = result["id"]
176
+ @temporary_object_id.should_not be_nil
177
+
178
+ get_result = @api.get_object(@temporary_object_id)
179
+ get_result["name"].should == expected_message
180
+ end
181
+
182
+ it "should be able to verify a message with an attachment posted to a feed" do
183
+ attachment = {"name" => "OAuth Playground", "link" => "http://oauth.twoalex.com/"}
184
+ result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
185
+ @temporary_object_id = result["id"]
186
+ get_result = @api.get_object(@temporary_object_id)
187
+
188
+ # make sure the result we fetch includes all the parameters we sent
189
+ it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
190
+ it_matches.should == true
191
+ end
192
+
193
+ it "should be able to comment on an object" do
194
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
195
+ @temporary_object_id = result["id"]
196
+
197
+ # this will be deleted when the post gets deleted
198
+ comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
199
+ comment_result.should_not be_nil
200
+ end
201
+
202
+ it "should be able to verify a comment posted about an object" do
203
+ message_text = "Hello, world, from the test suite, testing comments!"
204
+ result = @api.put_wall_post(message_text)
205
+ @temporary_object_id = result["id"]
206
+
207
+ # this will be deleted when the post gets deleted
208
+ comment_text = "it's my comment!"
209
+ comment_result = @api.put_comment(@temporary_object_id, comment_text)
210
+ get_result = @api.get_object(comment_result["id"])
211
+
212
+ # make sure the text of the comment matches what we sent
213
+ get_result["message"].should == comment_text
214
+ end
215
+
216
+ it "should be able to like an object" do
217
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
218
+ @temporary_object_id = result["id"]
219
+ like_result = @api.put_like(@temporary_object_id)
220
+ like_result.should be_true
221
+ end
222
+
223
+
224
+ # test all methods to make sure they pass data through to the API
225
+ # we run the tests here (rather than in the common shared example group)
226
+ # since some require access tokens
227
+ describe "HTTP options" do
228
+ # Each of the below methods should take an options hash as their last argument
229
+ # ideally we'd use introspection to determine how many arguments a method has
230
+ # but some methods require specially formatted arguments for processing
231
+ # (and anyway, Ruby 1.8's arity method fails (for this) for methods w/ 2+ optional arguments)
232
+ # (Ruby 1.9's parameters method is perfect, but only in 1.9)
233
+ # so we have to double-document
234
+ {
235
+ :get_object => 3, :put_object => 4, :delete_object => 2,
236
+ :get_connections => 4, :put_connections => 4, :delete_connections => 4,
237
+ :put_wall_post => 4,
238
+ :put_comment => 3,
239
+ :put_like => 2, :delete_like => 2,
240
+ :search => 3,
241
+ # methods that have special arguments
242
+ :put_picture => ["x.jpg", "image/jpg", {}, "me"],
243
+ :get_objects => [["x"], {}]
244
+ }.each_pair do |method_name, params|
245
+ it "should pass http options through for #{method_name}" do
246
+ options = {:a => 2}
247
+ # graph call should ultimately receive options as the fourth argument
248
+ @api.should_receive(:graph_call).with(anything, anything, anything, options)
249
+
250
+ # if we supply args, use them (since some methods process params)
251
+ # the method should receive as args n-1 anythings and then options
252
+ args = (params.is_a?(Integer) ? ([{}] * (params - 1)) : params) + [options]
253
+
254
+ @api.send(method_name, *args)
255
+ end
256
+ end
257
+
258
+ # also test get_picture, which merges a parameter into options
259
+ it "should pass http options through for get_picture" do
260
+ options = {:a => 2}
261
+ # graph call should ultimately receive options as the fourth argument
262
+ @api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options)).and_return({})
263
+ @api.send(:get_picture, "x", {}, options)
264
+ end
265
+ end
266
+ end
267
+
268
+
269
+ # GraphCollection
270
+ shared_examples_for "Koala GraphAPI with GraphCollection" do
271
+
272
+ it "should create an array-like object" do
273
+ call = @api.graph_call("contextoptional/photos")
274
+ Koala::Facebook::GraphCollection.new(call, @api).should be_an(Array)
275
+ end
276
+
277
+ describe "when getting a collection" do
278
+ # GraphCollection methods
279
+ it "should get a GraphCollection when getting connections" do
280
+ @result = @api.get_connections("contextoptional", "photos")
281
+ @result.should be_a(Koala::Facebook::GraphCollection)
282
+ end
283
+
284
+ it "should return nil if the get_collections call fails with nil" do
285
+ # this happens sometimes
286
+ @api.should_receive(:graph_call).and_return(nil)
287
+ @api.get_connections("contextoptional", "photos").should be_nil
288
+ end
289
+
290
+ it "should get a GraphCollection when searching" do
291
+ result = @api.search("facebook")
292
+ result.should be_a(Koala::Facebook::GraphCollection)
293
+ end
294
+
295
+ it "should return nil if the search call fails with nil" do
296
+ # this happens sometimes
297
+ @api.should_receive(:graph_call).and_return(nil)
298
+ @api.search("facebook").should be_nil
299
+ end
300
+
301
+ it "should get a GraphCollection when paging through results" do
302
+ @results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>"2010-09-23T21:17:33+0000"}])
303
+ @results.should be_a(Koala::Facebook::GraphCollection)
304
+ end
305
+
306
+ it "should return nil if the page call fails with nil" do
307
+ # this happens sometimes
308
+ @api.should_receive(:graph_call).and_return(nil)
309
+ @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>"2010-09-23T21:17:33+0000"}]).should be_nil
310
+ end
311
+
312
+ # GraphCollection attributes
313
+ describe "the GraphCollection" do
314
+ before(:each) do
315
+ @result = @api.get_connections("contextoptional", "photos")
316
+ end
317
+
318
+ it "should have a read-only paging attribute" do
319
+ lambda { @result.paging }.should_not raise_error
320
+ lambda { @result.paging = "paging" }.should raise_error(NoMethodError)
321
+ end
322
+
323
+ describe "when getting a whole page" do
324
+ before(:each) do
325
+ @second_page = stub("page of Fb graph results")
326
+ @base = stub("base")
327
+ @args = stub("args")
328
+ @page_of_results = stub("page of results")
329
+ end
330
+
331
+ it "should return the previous page of results" do
332
+ @result.should_receive(:previous_page_params).and_return([@base, @args])
333
+ @api.should_receive(:graph_call).with(@base, @args).and_return(@second_page)
334
+ Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
335
+
336
+ @result.previous_page.should == @page_of_results
337
+ end
338
+
339
+ it "should return the next page of results" do
340
+ @result.should_receive(:next_page_params).and_return([@base, @args])
341
+ @api.should_receive(:graph_call).with(@base, @args).and_return(@second_page)
342
+ Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
343
+
344
+ @result.next_page.should == @page_of_results
345
+ end
346
+
347
+ it "should return nil it there are no other pages" do
348
+ %w{next previous}.each do |this|
349
+ @result.should_receive("#{this}_page_params".to_sym).and_return(nil)
350
+ @result.send("#{this}_page").should == nil
351
+ end
352
+ end
353
+ end
354
+
355
+ describe "when parsing page paramters" do
356
+ before(:each) do
357
+ @graph_collection = Koala::Facebook::GraphCollection.new({"data" => []}, Koala::Facebook::GraphAPI.new)
358
+ end
359
+
360
+ it "should return the base as the first array entry" do
361
+ base = "url_path"
362
+ @graph_collection.parse_page_url("anything.com/#{base}?anything").first.should == base
363
+ end
364
+
365
+ it "should return the arguments as a hash as the last array entry" do
366
+ args_hash = {"one" => "val_one", "two" => "val_two"}
367
+ @graph_collection.parse_page_url("anything.com/anything?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").last.should == args_hash
368
+ end
369
+ end
370
+ end
371
+ end
372
+ end
373
+
374
+
375
+ shared_examples_for "Koala GraphAPI without an access token" do
376
+
377
+ it "should not get private data about a user" do
378
+ result = @api.get_object("koppel")
379
+ # updated_time should be a pretty fixed test case
380
+ result["updated_time"].should be_nil
381
+ end
382
+
383
+ it "should not be able to get data about 'me'" do
384
+ lambda { @api.get_object("me") }.should raise_error(Koala::Facebook::APIError)
385
+ end
386
+
387
+ it "shouldn't be able to access connections from users" do
388
+ lambda { @api.get_connections("lukeshepard", "likes") }.should raise_error(Koala::Facebook::APIError)
389
+ end
390
+
391
+ it "should not be able to put an object" do
392
+ lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
393
+ puts "Error! Object #{@result.inspect} somehow put onto Luke Shepard's wall!" if @result
394
+ end
395
+
396
+ # these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
397
+ it "should not be able to post to a feed" do
398
+ (lambda do
399
+ attachment = {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"}
400
+ @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
401
+ end).should raise_error(Koala::Facebook::APIError)
402
+ puts "Error! Object #{@result.inspect} somehow put onto Context Optional's wall!" if @result
403
+ end
404
+
405
+ it "should not be able to comment on an object" do
406
+ # random public post on the ContextOptional wall
407
+ lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
408
+ puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
409
+ end
410
+
411
+ it "should not be able to like an object" do
412
+ lambda { @api.put_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
413
+ end
414
+
415
+ # DELETE
416
+ it "should not be able to delete posts" do
417
+ # test post on the Ruby SDK Test application
418
+ lambda { @result = @api.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
419
+ end
420
+
421
+ it "should not be able to delete a like" do
422
+ lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
423
+ end
424
+ end
@@ -1,43 +1,40 @@
1
- module LiveTestingDataHelper
2
- # in RSpec 2, included example groups no longer share any hooks or state with outside examples
3
- # even if in the same block
4
- # so we have to use a module to provide setup and teardown hooks for live testing
5
-
6
- def self.included(base)
7
- base.class_eval do
8
- before :each do
9
- @token = $testing_data["oauth_token"]
10
- raise Exception, "Must supply access token to run FacebookWithAccessTokenTests!" unless @token
11
- # track temporary objects created
12
- @temporary_object_ids = []
13
- end
14
-
15
- after :each do
16
- # clean up any temporary objects
17
- @temporary_object_ids << @temporary_object_id if @temporary_object_id
18
- count = @temporary_object_ids.length
19
- errors = []
20
-
21
- if count > 0
22
- print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object (#{@temporary_object_ids.first})"}..."
23
- @temporary_object_ids.each do |id|
24
- # get our API
25
- api = @api || (@test_users ? @test_users.graph_api : nil)
26
- raise "Unable to locate API when passed temporary object to delete!" unless api
27
-
28
- # delete the object
29
- result = (api.delete_object(id) rescue false)
30
- # if we errored out or Facebook returned false, track that
31
- errors << id unless result
32
- end
33
-
34
- if errors.length == 0
35
- puts "done."
36
- else
37
- puts "cleaned up #{count - errors.length} objects, but errored out on the following:\n #{errors.join(", ")}"
38
- end
39
- end
40
- end
41
- end
42
- end
1
+ module LiveTestingDataHelper
2
+ # in RSpec 2, included example groups no longer share any hooks or state with outside examples
3
+ # even if in the same block
4
+ # so we have to use a module to provide setup and teardown hooks for live testing
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ before :each do
9
+ @token = $testing_data["oauth_token"]
10
+ raise Exception, "Must supply access token to run FacebookWithAccessTokenTests!" unless @token
11
+ # track temporary objects created
12
+ @temporary_object_ids = []
13
+ end
14
+
15
+ after :each do
16
+ # clean up any temporary objects
17
+ @temporary_object_ids << @temporary_object_id if @temporary_object_id
18
+ count = @temporary_object_ids.length
19
+ errors = []
20
+
21
+ if count > 0
22
+ @temporary_object_ids.each do |id|
23
+ # get our API
24
+ api = @api || (@test_users ? @test_users.graph_api : nil)
25
+ raise "Unable to locate API when passed temporary object to delete!" unless api
26
+
27
+ # delete the object
28
+ result = (api.delete_object(id) rescue false)
29
+ # if we errored out or Facebook returned false, track that
30
+ errors << id unless result
31
+ end
32
+
33
+ unless errors.length == 0
34
+ puts "cleaned up #{count - errors.length} objects, but errored out on the following:\n #{errors.join(", ")}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
43
40
  end