www-delicious 0.1.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.
- data/CHANGELOG +5 -0
- data/MIT-LICENSE +21 -0
- data/README +210 -0
- data/Rakefile +137 -0
- data/lib/www/delicious.rb +868 -0
- data/lib/www/delicious/bundle.rb +54 -0
- data/lib/www/delicious/errors.rb +45 -0
- data/lib/www/delicious/post.rb +113 -0
- data/lib/www/delicious/tag.rb +120 -0
- data/lib/www/delicious/version.rb +28 -0
- data/setup.rb +1585 -0
- data/test/helper.rb +108 -0
- data/test/unit/delicious_bundle_test.rb +90 -0
- data/test/unit/delicious_online_test.rb +143 -0
- data/test/unit/delicious_post_test.rb +102 -0
- data/test/unit/delicious_tag_test.rb +140 -0
- data/test/unit/delicious_test.rb +420 -0
- metadata +90 -0
@@ -0,0 +1,420 @@
|
|
1
|
+
#
|
2
|
+
# = WWW::Delicious
|
3
|
+
#
|
4
|
+
# Ruby client for del.icio.us API.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: WWW
|
8
|
+
# Package:: WWW::Delicious
|
9
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
10
|
+
#
|
11
|
+
#--
|
12
|
+
# SVN: $Id$
|
13
|
+
#++
|
14
|
+
|
15
|
+
|
16
|
+
require File.dirname(__FILE__) + '/../helper'
|
17
|
+
|
18
|
+
|
19
|
+
class DeliciousTest < Test::Unit::TestCase
|
20
|
+
include WWW::Delicious::TestCase
|
21
|
+
|
22
|
+
|
23
|
+
# =========================================================================
|
24
|
+
# Constructor behavior
|
25
|
+
# =========================================================================
|
26
|
+
|
27
|
+
def test_initialize
|
28
|
+
obj = nil
|
29
|
+
assert_nothing_raised() { obj = WWW::Delicious.new(TEST_USERNAME, TEST_PASSWORD) }
|
30
|
+
assert_instance_of(WWW::Delicious, obj)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_initialize_with_block
|
34
|
+
obj = instance do |delicious|
|
35
|
+
assert_instance_of(WWW::Delicious, delicious)
|
36
|
+
end
|
37
|
+
assert_instance_of(WWW::Delicious, obj)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_initialize_with_options
|
41
|
+
obj = nil
|
42
|
+
assert_nothing_raised() { obj = WWW::Delicious.new(TEST_USERNAME, TEST_PASSWORD, {:user_agent => 'ruby/test'}) }
|
43
|
+
assert_instance_of(WWW::Delicious, obj)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_initialize_raises_without_account
|
47
|
+
assert_raise(ArgumentError) { WWW::Delicious.new() }
|
48
|
+
assert_raise(ArgumentError) { WWW::Delicious.new(TEST_USERNAME) }
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# =========================================================================
|
53
|
+
# Constructor options
|
54
|
+
# =========================================================================
|
55
|
+
|
56
|
+
def test_initialize_account
|
57
|
+
obj = instance()
|
58
|
+
assert_equal(@default_username, obj.username)
|
59
|
+
assert_equal(@default_password, obj.password)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_initialize_option_user_agent
|
63
|
+
obj = nil
|
64
|
+
useragent = 'MyClass/1.0 (Foo/Bar +http://foo.com/)'
|
65
|
+
assert_nothing_raised() { obj = instance(:user_agent => useragent) }
|
66
|
+
assert_equal(useragent, obj.user_agent)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_initialize_option_user_agent_default
|
70
|
+
useragent = instance.user_agent
|
71
|
+
assert_match("Ruby/#{RUBY_VERSION}", useragent)
|
72
|
+
assert_match("#{WWW::Delicious::NAME}/#{WWW::Delicious::VERSION}", useragent)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# =========================================================================
|
77
|
+
# These tests check the low level HTTP request workflow
|
78
|
+
# Even if #request is a protected method, it is so important that
|
79
|
+
# we must test it separately as we did for a few other similar methods.
|
80
|
+
# =========================================================================
|
81
|
+
|
82
|
+
def test_request_raises_without_http_client
|
83
|
+
obj = instance
|
84
|
+
obj.http_client = nil
|
85
|
+
assert_raise(WWW::Delicious::Error) { obj.send(:request, '/foo') }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_request_waits_necessary_time_between_requests
|
89
|
+
# use valid_account? as a safe request to prevent tests
|
90
|
+
# run with invalid credential to fail
|
91
|
+
r = File.read(TESTCASE_PATH + '/update_success.xml')
|
92
|
+
|
93
|
+
obj = instance
|
94
|
+
set_response(r)
|
95
|
+
obj.valid_account? # 1st request
|
96
|
+
|
97
|
+
3.times do |time|
|
98
|
+
lr = obj.instance_variable_get(:@last_request)
|
99
|
+
set_response(r)
|
100
|
+
obj.valid_account? # N request
|
101
|
+
nr = obj.instance_variable_get(:@last_request)
|
102
|
+
assert((nr - lr) > WWW::Delicious::SECONDS_BEFORE_NEW_REQUEST)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# =========================================================================
|
108
|
+
# Update
|
109
|
+
# =========================================================================
|
110
|
+
|
111
|
+
def test_update
|
112
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
113
|
+
results = nil
|
114
|
+
assert_nothing_raised() { results = instance.update() }
|
115
|
+
assert_equal(results, Time.parse("2008-03-12T08:41:20Z"))
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_update_raises_without_update_root_node
|
119
|
+
set_response(File.read(TESTCASE_PATH + '/bundles_all_success.xml'))
|
120
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
121
|
+
instance.update()
|
122
|
+
end
|
123
|
+
assert_match(/`update`/, exception.message)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# =========================================================================
|
128
|
+
# Bundles
|
129
|
+
# =========================================================================
|
130
|
+
# Test all bundle calls and related methods.
|
131
|
+
# * bundles_all
|
132
|
+
# * bundles_set
|
133
|
+
# * bundles_delete
|
134
|
+
|
135
|
+
def test_bundles_all
|
136
|
+
set_response(File.read(TESTCASE_PATH + '/bundles_all_success.xml'))
|
137
|
+
results = nil
|
138
|
+
|
139
|
+
assert_nothing_raised() { results = instance.bundles_all() }
|
140
|
+
assert_instance_of(Array, results)
|
141
|
+
assert_equal(2, results.length)
|
142
|
+
|
143
|
+
expected = [
|
144
|
+
['music', %w(ipod mp3 music)],
|
145
|
+
['pc', %w(computer software hardware)],
|
146
|
+
]
|
147
|
+
|
148
|
+
results.each_with_index do |bundle, index|
|
149
|
+
assert_instance_of(WWW::Delicious::Bundle, bundle)
|
150
|
+
name, tags = expected[index]
|
151
|
+
assert_equal(name, bundle.name)
|
152
|
+
assert_equal(tags, bundle.tags)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_bundles_all_empty
|
157
|
+
set_response(File.read(TESTCASE_PATH + '/bundles_all_success_empty.xml'))
|
158
|
+
results = nil
|
159
|
+
assert_nothing_raised() { results = instance.bundles_all() }
|
160
|
+
assert_instance_of(Array, results)
|
161
|
+
assert_equal(0, results.length)
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_bundles_all_raises_without_bundles_root_node
|
165
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
166
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
167
|
+
instance.bundles_all()
|
168
|
+
end
|
169
|
+
assert_match(/`bundles`/, exception.message)
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
def test_bundles_set
|
174
|
+
set_response(File.read(TESTCASE_PATH + '/bundles_set_success.xml'))
|
175
|
+
assert_nothing_raised() { instance.bundles_set('name', %w(foo bar)) }
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_bundles_delete_raises_without_result_root_node
|
179
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
180
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
181
|
+
instance.bundles_set('name', %w(foo bar))
|
182
|
+
end
|
183
|
+
assert_match(/`result`/, exception.message)
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
def test_bundles_delete
|
188
|
+
set_response(File.read(TESTCASE_PATH + '/bundles_delete_success.xml'))
|
189
|
+
assert_nothing_raised() { instance.bundles_delete('name') }
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_bundles_delete_raises_without_result_root_node
|
193
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
194
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
195
|
+
instance.bundles_delete('name')
|
196
|
+
end
|
197
|
+
assert_match(/`result`/, exception.message)
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
# =========================================================================
|
202
|
+
# Tags
|
203
|
+
# =========================================================================
|
204
|
+
# Test all tag calls and related methods.
|
205
|
+
# * tags_get
|
206
|
+
# * tags_rename
|
207
|
+
|
208
|
+
|
209
|
+
def test_tags_get
|
210
|
+
set_response(File.read(TESTCASE_PATH + '/tags_get_success.xml'))
|
211
|
+
results = nil
|
212
|
+
|
213
|
+
assert_nothing_raised() { results = instance.tags_get() }
|
214
|
+
assert_instance_of(Array, results)
|
215
|
+
assert_equal(2, results.length)
|
216
|
+
|
217
|
+
expected = [
|
218
|
+
['activedesktop', 1],
|
219
|
+
['business', 14],
|
220
|
+
]
|
221
|
+
|
222
|
+
results.each_with_index do |tag, index|
|
223
|
+
assert_instance_of(WWW::Delicious::Tag, tag)
|
224
|
+
name, count = expected[index]
|
225
|
+
assert_equal(name, tag.name)
|
226
|
+
assert_equal(count, tag.count)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_tags_get_empty
|
231
|
+
set_response(File.read(TESTCASE_PATH + '/tags_get_success_empty.xml'))
|
232
|
+
results = nil
|
233
|
+
assert_nothing_raised() { results = instance.tags_get() }
|
234
|
+
assert_instance_of(Array, results)
|
235
|
+
assert_equal(0, results.length)
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_tags_get_raises_without_bundles_root_node
|
239
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
240
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
241
|
+
instance.tags_get()
|
242
|
+
end
|
243
|
+
assert_match(/`tags`/, exception.message)
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
def test_tags_rename
|
248
|
+
set_response(File.read(TESTCASE_PATH + '/tags_rename_success.xml'))
|
249
|
+
assert_nothing_raised() { instance.tags_rename('old', 'new') }
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_tags_rename_raises_without_result_root_node
|
253
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
254
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
255
|
+
instance.tags_rename('old', 'new')
|
256
|
+
end
|
257
|
+
assert_match(/`result`/, exception.message)
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
# =========================================================================
|
262
|
+
# These tests check posts_get call and all related methods.
|
263
|
+
# TODO: as soon as a full offline test system is ready,
|
264
|
+
# remove protected methods tests .
|
265
|
+
# =========================================================================
|
266
|
+
|
267
|
+
def test_posts_get
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
# =========================================================================
|
272
|
+
# These tests check posts_recent call and all related methods.
|
273
|
+
# TODO: as soon as a full offline test system is ready,
|
274
|
+
# remove protected methods tests .
|
275
|
+
# =========================================================================
|
276
|
+
|
277
|
+
def test_posts_recent
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
# =========================================================================
|
282
|
+
# These tests check posts_all call and all related methods.
|
283
|
+
# TODO: as soon as a full offline test system is ready,
|
284
|
+
# remove protected methods tests .
|
285
|
+
# =========================================================================
|
286
|
+
|
287
|
+
def test_posts_all
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
# =========================================================================
|
292
|
+
# These tests check posts_dates call and all related methods.
|
293
|
+
# =========================================================================
|
294
|
+
|
295
|
+
def test_posts_dates
|
296
|
+
set_response(File.read(TESTCASE_PATH + '/posts_dates_success.xml'))
|
297
|
+
results = nil
|
298
|
+
assert_nothing_raised() { results = instance.posts_dates() }
|
299
|
+
assert_instance_of(Hash, results)
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_posts_dates_raises_without_dates_root_node
|
303
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
304
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
305
|
+
instance.posts_dates()
|
306
|
+
end
|
307
|
+
assert_match(/`dates`/, exception.message)
|
308
|
+
end
|
309
|
+
|
310
|
+
# =========================================================================
|
311
|
+
# These tests check posts_add call and all related methods.
|
312
|
+
# =========================================================================
|
313
|
+
|
314
|
+
def test_posts_add
|
315
|
+
params = {:url => 'http://localhost', :title => 'Just a test'}
|
316
|
+
|
317
|
+
set_response(File.read(TESTCASE_PATH + '/posts_add_success.xml'))
|
318
|
+
assert_nothing_raised() { instance.posts_add(WWW::Delicious::Post.new(params)) }
|
319
|
+
|
320
|
+
set_response(File.read(TESTCASE_PATH + '/posts_add_success.xml'))
|
321
|
+
assert_nothing_raised() { instance.posts_add(params) }
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
# =========================================================================
|
326
|
+
# These tests check posts_delete call and all related methods.
|
327
|
+
# =========================================================================
|
328
|
+
|
329
|
+
def test_posts_delete
|
330
|
+
set_response(File.read(TESTCASE_PATH + '/posts_delete_success.xml'))
|
331
|
+
assert_nothing_raised() { instance.posts_delete('test') }
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_posts_delete_raises_without_result_root_node
|
335
|
+
set_response(File.read(TESTCASE_PATH + '/update_success.xml'))
|
336
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
337
|
+
instance.posts_delete('test')
|
338
|
+
end
|
339
|
+
assert_match(/`result`/, exception.message)
|
340
|
+
end
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
def test_prepare_posts_params
|
345
|
+
tag = 'foo'
|
346
|
+
count = 30
|
347
|
+
url = 'http://localhost'
|
348
|
+
dt = Time.now
|
349
|
+
|
350
|
+
params = { :tag => tag, :url => url, :dt => dt, :count => count }
|
351
|
+
results = instance.send(:prepare_posts_params, params, [:tag, :count, :url, :dt])
|
352
|
+
|
353
|
+
assert_kind_of(WWW::Delicious::Tag, results[:tag])
|
354
|
+
assert_equal(tag, results[:tag].to_s)
|
355
|
+
assert_equal(count, results[:count])
|
356
|
+
assert_equal(URI.parse(url), results[:url])
|
357
|
+
assert_equal(dt.iso8601(), results[:dt])
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_prepare_posts_params_raises_unless_hash
|
361
|
+
['foo', %w(foo bar)].each do |params|
|
362
|
+
exception = assert_raise(ArgumentError) do
|
363
|
+
instance.send(:prepare_posts_params, params)
|
364
|
+
end
|
365
|
+
assert_match(/`Hash`/, exception.message)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_prepare_posts_params_raises_with_unknown_params
|
370
|
+
params = {:tag => 'foo', :foo => 'bar'}
|
371
|
+
exception = assert_raise(WWW::Delicious::Error) do
|
372
|
+
instance.send(:prepare_posts_params, params, [:tag])
|
373
|
+
end
|
374
|
+
assert_match(/`foo`/, exception.message)
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
def test_parse_posts_response
|
379
|
+
response = instance.send(:parse_posts_response,
|
380
|
+
File.read(TESTCASE_PATH + '/posts_success.xml'))
|
381
|
+
assert_instance_of(Array, response)
|
382
|
+
assert_equal(1, response.length)
|
383
|
+
|
384
|
+
results = [
|
385
|
+
['http://stacktrace.it/articoli/2008/03/i-7-peccati-capitali-del-recruitment-di-hacker/', 'Stacktrace.it: I 7 peccati capitali del recruitment di hacker'],
|
386
|
+
]
|
387
|
+
|
388
|
+
response.each_with_index do |post, index|
|
389
|
+
assert_instance_of(WWW::Delicious::Post, post)
|
390
|
+
url, title = results[index]
|
391
|
+
assert_equal(URI.parse(url), post.url)
|
392
|
+
assert_equal(title, post.title)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_parse_posts_response_empty
|
397
|
+
response = instance.send(:parse_posts_response,
|
398
|
+
File.read(TESTCASE_PATH + '/posts_success_empty.xml'))
|
399
|
+
assert_instance_of(Array, response)
|
400
|
+
assert_equal(0, response.length)
|
401
|
+
end
|
402
|
+
|
403
|
+
def test_parse_posts_response_without_bundles_root_node
|
404
|
+
_test_parse_invalid_node(:parse_posts_response, /`posts`/)
|
405
|
+
end
|
406
|
+
|
407
|
+
|
408
|
+
|
409
|
+
protected
|
410
|
+
#
|
411
|
+
# Tests a typical invalid node response.
|
412
|
+
#
|
413
|
+
def _test_parse_invalid_node(method, match)
|
414
|
+
exception = assert_raise(WWW::Delicious::ResponseError) do
|
415
|
+
instance.send(method, File.read(TESTCASE_PATH + '/invalid_root.xml'))
|
416
|
+
end
|
417
|
+
assert_match(match, exception.message)
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: www-delicious
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Simone Carletti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-11 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.7.3
|
23
|
+
version:
|
24
|
+
description: WWW::Delicious is a del.icio.us API client implemented in Ruby. It provides access to all available del.icio.us API queries and returns the original XML response as a friendly Ruby object.
|
25
|
+
email: weppos@weppos.net
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- CHANGELOG
|
33
|
+
- MIT-LICENSE
|
34
|
+
files:
|
35
|
+
- lib/www/delicious/bundle.rb
|
36
|
+
- lib/www/delicious/errors.rb
|
37
|
+
- lib/www/delicious/post.rb
|
38
|
+
- lib/www/delicious/tag.rb
|
39
|
+
- lib/www/delicious/version.rb
|
40
|
+
- lib/www/delicious.rb
|
41
|
+
- test/helper.rb
|
42
|
+
- test/unit/delicious_bundle_test.rb
|
43
|
+
- test/unit/delicious_online_test.rb
|
44
|
+
- test/unit/delicious_post_test.rb
|
45
|
+
- test/unit/delicious_tag_test.rb
|
46
|
+
- test/unit/delicious_test.rb
|
47
|
+
- README
|
48
|
+
- CHANGELOG
|
49
|
+
- MIT-LICENSE
|
50
|
+
- Rakefile
|
51
|
+
- setup.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://code.simonecarletti.com/www-delicious
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --title
|
57
|
+
- www-delicious -- Ruby client for del.icio.us API.
|
58
|
+
- --inline-source
|
59
|
+
- --line-numbers
|
60
|
+
- --main
|
61
|
+
- README
|
62
|
+
- --charset
|
63
|
+
- utf-8
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.8.6
|
71
|
+
version:
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "0"
|
77
|
+
version:
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project: www-delicious
|
81
|
+
rubygems_version: 1.0.1
|
82
|
+
signing_key:
|
83
|
+
specification_version: 2
|
84
|
+
summary: Ruby client for del.icio.us API.
|
85
|
+
test_files:
|
86
|
+
- test/unit/delicious_bundle_test.rb
|
87
|
+
- test/unit/delicious_online_test.rb
|
88
|
+
- test/unit/delicious_post_test.rb
|
89
|
+
- test/unit/delicious_tag_test.rb
|
90
|
+
- test/unit/delicious_test.rb
|