youtube 0.8.5 → 0.8.6
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 +17 -0
- data/Rakefile +1 -1
- data/TODO +0 -3
- data/lib/youtube.rb +83 -50
- data/test/test_api.rb +131 -54
- metadata +4 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
* 2007/06/12
|
2
|
+
|
3
|
+
- [shaper] Fixed typo in VideoDetails, recoding -> recording
|
4
|
+
- [cardmagic] Changed URI.encode to CGI.escape to properly encode &
|
5
|
+
- [shaper] Test for character encoding
|
6
|
+
- [drummr77] Force XML parsed empty strings to be Strings and not Hashes
|
7
|
+
Discovered by shaper.
|
8
|
+
- [Rob Tsuk] Added paging support to videos_by_user
|
9
|
+
- [Rob Tsuk] Created test YouTube account for running tests
|
10
|
+
- [Thomas Cox] Added support for the embed_status tag
|
11
|
+
|
12
|
+
* 2007/06/11
|
13
|
+
|
14
|
+
- [drummr77] Removed videos_by_category since it was removed by YouTube.
|
15
|
+
- [drummr77] Renamed videos_by_category_and_tag to videos_by_category_id_and_tag.
|
16
|
+
- [drummr77] Added videos_by_category_and_tag taking in a category name and tag
|
17
|
+
|
1
18
|
* 2007/02/12
|
2
19
|
|
3
20
|
- [drummr77] Added fix to check if returned video response contains an
|
data/Rakefile
CHANGED
data/TODO
CHANGED
@@ -6,9 +6,6 @@
|
|
6
6
|
we're doing the Right/Best Thing. It looks like we've got hashes with
|
7
7
|
one key e.g. "comments" that then map to a list of actual comments.
|
8
8
|
|
9
|
-
- look at what we store for fields with no actual value; appears we're
|
10
|
-
storing empty hashes in at least some cases.
|
11
|
-
|
12
9
|
- add unit tests for client.videos_by_tag page and per_page params.
|
13
10
|
|
14
11
|
- add unit tests for specifying alternate api host/path in client
|
data/lib/youtube.rb
CHANGED
@@ -22,11 +22,26 @@
|
|
22
22
|
#++
|
23
23
|
|
24
24
|
require 'net/http'
|
25
|
-
require 'uri'
|
26
25
|
require 'xmlsimple'
|
26
|
+
require 'cgi'
|
27
27
|
|
28
28
|
module YouTube
|
29
29
|
|
30
|
+
class Category
|
31
|
+
FILMS_ANIMATION = 1
|
32
|
+
AUTOS_VEHICLES = 2
|
33
|
+
COMEDY = 23
|
34
|
+
ENTERTAINMENT = 24
|
35
|
+
MUSIC = 10
|
36
|
+
NEWS_POLITICS = 25
|
37
|
+
PEOPLE_BLOGS = 22
|
38
|
+
PETS_ANIMALS = 15
|
39
|
+
HOWTO_DIY = 26
|
40
|
+
SPORTS = 17
|
41
|
+
TRAVEL_PLACES = 19
|
42
|
+
GADGETS_GAMES = 20
|
43
|
+
end
|
44
|
+
|
30
45
|
# Main client class managing all interaction with the YouTube server.
|
31
46
|
# Server communication is handled via method_missing() emulating an
|
32
47
|
# RPC-like call and performing all of the work to send out the HTTP
|
@@ -37,7 +52,7 @@ module YouTube
|
|
37
52
|
DEFAULT_HOST = 'http://www.youtube.com'
|
38
53
|
# the default api path to the YouTube API
|
39
54
|
DEFAULT_API_PATH = '/api2_rest'
|
40
|
-
|
55
|
+
|
41
56
|
def initialize(dev_id = nil, host = DEFAULT_HOST, api_path = DEFAULT_API_PATH)
|
42
57
|
raise "developer id required" unless dev_id
|
43
58
|
|
@@ -79,8 +94,8 @@ module YouTube
|
|
79
94
|
_parse_video_response(response)
|
80
95
|
end
|
81
96
|
|
82
|
-
# Returns a list of YouTube::Video objects that match
|
83
|
-
# specified +tag
|
97
|
+
# Returns a list of YouTube::Video objects that match the
|
98
|
+
# specified +tag+.
|
84
99
|
#
|
85
100
|
# Optional parameters are:
|
86
101
|
# +page+ = the "page" of results to retrieve (e.g. 1, 2, 3)
|
@@ -91,7 +106,7 @@ module YouTube
|
|
91
106
|
end
|
92
107
|
|
93
108
|
# Returns a list of YouTube::Video objects with the specified
|
94
|
-
#
|
109
|
+
# playlist +id+.
|
95
110
|
#
|
96
111
|
# Optional parameters are:
|
97
112
|
# +page+ = the "page" of results to retrieve (e.g. 1, 2, 3)
|
@@ -101,35 +116,52 @@ module YouTube
|
|
101
116
|
_parse_video_response(response)
|
102
117
|
end
|
103
118
|
|
104
|
-
# Returns a list of YouTube::Video objects
|
105
|
-
#
|
119
|
+
# Returns a list of YouTube::Video objects detailing the videos
|
120
|
+
# matching the supplied category +id+ and +tag+.
|
106
121
|
#
|
107
122
|
# Optional parameters are:
|
108
123
|
# +page+ = the "page" of results to retrieve (e.g. 1, 2, 3)
|
109
124
|
# +per_page+ = the number of results per page (default: 20, max 100).
|
110
|
-
def
|
111
|
-
response =
|
125
|
+
def videos_by_category_id_and_tag(id, tag, page = 1, per_page = 20)
|
126
|
+
response = videos_list_by_category_and_tag(:category_id => id, :tag => tag, :page => page, :per_page => per_page)
|
112
127
|
_parse_video_response(response)
|
113
128
|
end
|
114
129
|
|
115
130
|
# Returns a list of YouTube::Video objects detailing the videos
|
116
|
-
# matching the supplied +category
|
131
|
+
# matching the supplied +category+ and +tag+.
|
117
132
|
#
|
133
|
+
# Available categories:
|
134
|
+
# YouTube::Category::FILMS_ANIMATION
|
135
|
+
# YouTube::Category::AUTOS_VEHICLES
|
136
|
+
# YouTube::Category::COMEDY
|
137
|
+
# YouTube::Category::ENTERTAINMENT
|
138
|
+
# YouTube::Category::MUSIC
|
139
|
+
# YouTube::Category::NEWS_POLITICS
|
140
|
+
# YouTube::Category::PEOPLE_BLOGS
|
141
|
+
# YouTube::Category::PETS_ANIMALS
|
142
|
+
# YouTube::Category::HOWTO_DIY
|
143
|
+
# YouTube::Category::SPORTS
|
144
|
+
# YouTube::Category::TRAVEL_PLACES
|
145
|
+
# YouTube::Category::GADGETS_GAMES
|
146
|
+
#
|
118
147
|
# Optional parameters are:
|
119
148
|
# +page+ = the "page" of results to retrieve (e.g. 1, 2, 3)
|
120
149
|
# +per_page+ = the number of results per page (default: 20, max 100).
|
121
|
-
def videos_by_category_and_tag(
|
122
|
-
|
123
|
-
_parse_video_response(response)
|
150
|
+
def videos_by_category_and_tag(category, tag, page = 1, per_page = 20)
|
151
|
+
videos_by_category_id_and_tag(category, tag, page, per_page)
|
124
152
|
end
|
125
153
|
|
126
154
|
# Returns a list of YouTube::Video objects detailing the videos
|
127
155
|
# uploaded by the specified +username+.
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
156
|
+
#
|
157
|
+
# Optional parameters are:
|
158
|
+
# +page+ = the "page" of results to retrieve (e.g. 1, 2, 3)
|
159
|
+
# +per_page+ = the number of results per page (default: 20, max 100).
|
160
|
+
def videos_by_user(username, page = 1, per_page = 20)
|
161
|
+
response = videos_list_by_user(:user => username, :page => page, :per_page => per_page)
|
162
|
+
_parse_video_response(response)
|
163
|
+
end
|
164
|
+
|
133
165
|
# Returns a list of YouTube::Video objects detailing the current
|
134
166
|
# global set of featured videos on YouTube.
|
135
167
|
def featured_videos
|
@@ -157,18 +189,15 @@ module YouTube
|
|
157
189
|
|
158
190
|
def _request(method, *params)
|
159
191
|
url = _request_url(method, *params)
|
160
|
-
response = XmlSimple.xml_in(_http_get(url),
|
161
|
-
|
162
|
-
unless response['status'] == 'ok'
|
163
|
-
raise response['error']['description'] + " : url=#{url}"
|
164
|
-
end
|
192
|
+
response = XmlSimple.xml_in(_http_get(url), { 'ForceArray' => [ 'video', 'friend' ] })
|
193
|
+
raise response['error']['description'] + " : url=#{url}" unless response['status'] == 'ok'
|
165
194
|
response
|
166
195
|
end
|
167
196
|
|
168
197
|
def _request_url(method, *params)
|
169
198
|
param_list = String.new
|
170
199
|
unless params.empty?
|
171
|
-
params.first.each_pair { |k, v| param_list << "&#{k.to_s}=#{
|
200
|
+
params.first.each_pair { |k, v| param_list << "&#{k.to_s}=#{CGI.escape(v.to_s)}" }
|
172
201
|
end
|
173
202
|
url = "#{@host}#{@api_path}?method=youtube.#{method}&dev_id=#{@dev_id}#{param_list}"
|
174
203
|
end
|
@@ -192,7 +221,7 @@ module YouTube
|
|
192
221
|
def initialize(payload)
|
193
222
|
@favorite_count = payload['favorite_count'].to_i
|
194
223
|
@friend_count = payload['friend_count'].to_i
|
195
|
-
@user = payload['user']
|
224
|
+
@user = payload['user'].to_s
|
196
225
|
@video_upload_count = payload['video_upload_count'].to_i
|
197
226
|
end
|
198
227
|
end
|
@@ -220,24 +249,24 @@ module YouTube
|
|
220
249
|
attr_reader :video_watch_count
|
221
250
|
|
222
251
|
def initialize(payload)
|
223
|
-
@about_me = payload['about_me']
|
252
|
+
@about_me = payload['about_me'].to_s
|
224
253
|
@age = payload['age'].to_i
|
225
|
-
@books = payload['books']
|
226
|
-
@city = payload['city']
|
227
|
-
@companies = payload['companies']
|
228
|
-
@country = payload['country']
|
254
|
+
@books = payload['books'].to_s
|
255
|
+
@city = payload['city'].to_s
|
256
|
+
@companies = payload['companies'].to_s
|
257
|
+
@country = payload['country'].to_s
|
229
258
|
@currently_on = YouTube._string_to_boolean(payload['currently_on'])
|
230
259
|
@favorite_video_count = payload['favorite_video_count'].to_i
|
231
|
-
@first_name = payload['first_name']
|
260
|
+
@first_name = payload['first_name'].to_s
|
232
261
|
@friend_count = payload['friend_count'].to_i
|
233
|
-
@gender = payload['gender']
|
234
|
-
@hobbies = payload['hobbies']
|
235
|
-
@homepage = payload['homepage']
|
236
|
-
@hometown = payload['hometown']
|
237
|
-
@last_name = payload['last_name']
|
238
|
-
@movies = payload['movies']
|
239
|
-
@occupations = payload['occupations']
|
240
|
-
@relationship = payload['relationship']
|
262
|
+
@gender = payload['gender'].to_s
|
263
|
+
@hobbies = payload['hobbies'].to_s
|
264
|
+
@homepage = payload['homepage'].to_s
|
265
|
+
@hometown = payload['hometown'].to_s
|
266
|
+
@last_name = payload['last_name'].to_s
|
267
|
+
@movies = payload['movies'].to_s
|
268
|
+
@occupations = payload['occupations'].to_s
|
269
|
+
@relationship = payload['relationship'].to_s
|
241
270
|
@video_upload_count = payload['video_upload_count'].to_i
|
242
271
|
@video_watch_count = payload['video_watch_count'].to_i
|
243
272
|
end
|
@@ -260,16 +289,16 @@ module YouTube
|
|
260
289
|
attr_reader :view_count
|
261
290
|
|
262
291
|
def initialize(payload)
|
263
|
-
@author = payload['author']
|
292
|
+
@author = payload['author'].to_s
|
264
293
|
@comment_count = payload['comment_count'].to_i
|
265
|
-
@description = payload['description']
|
294
|
+
@description = payload['description'].to_s
|
266
295
|
@id = payload['id']
|
267
296
|
@length_seconds = payload['length_seconds'].to_i
|
268
297
|
@rating_avg = payload['rating_avg'].to_f
|
269
298
|
@rating_count = payload['rating_count'].to_i
|
270
299
|
@tags = payload['tags']
|
271
300
|
@thumbnail_url = payload['thumbnail_url']
|
272
|
-
@title = payload['title']
|
301
|
+
@title = payload['title'].to_s
|
273
302
|
@upload_time = YouTube._string_to_time(payload['upload_time'])
|
274
303
|
@url = payload['url']
|
275
304
|
@view_count = payload['view_count'].to_i
|
@@ -303,7 +332,7 @@ edoc
|
|
303
332
|
attr_reader :length_seconds
|
304
333
|
attr_reader :rating_avg
|
305
334
|
attr_reader :rating_count
|
306
|
-
attr_reader :
|
335
|
+
attr_reader :recording_location
|
307
336
|
attr_reader :recording_country
|
308
337
|
attr_reader :recording_date
|
309
338
|
attr_reader :tags
|
@@ -312,24 +341,28 @@ edoc
|
|
312
341
|
attr_reader :update_time
|
313
342
|
attr_reader :upload_time
|
314
343
|
attr_reader :view_count
|
344
|
+
attr_reader :embed_status
|
345
|
+
attr_reader :embed_allowed
|
315
346
|
|
316
347
|
def initialize(payload)
|
317
|
-
@author = payload['author']
|
348
|
+
@author = payload['author'].to_s
|
318
349
|
@channel_list = payload['channel_list']
|
319
350
|
@comment_list = payload['comment_list']
|
320
|
-
@description = payload['description']
|
351
|
+
@description = payload['description'].to_s
|
321
352
|
@length_seconds = payload['length_seconds'].to_i
|
322
353
|
@rating_avg = payload['rating_avg'].to_f
|
323
354
|
@rating_count = payload['rating_count'].to_i
|
324
|
-
@recording_country = payload['recording_country']
|
325
|
-
@recording_date = payload['recording_date']
|
326
|
-
@recording_location = payload['recording_location']
|
355
|
+
@recording_country = payload['recording_country'].to_s
|
356
|
+
@recording_date = payload['recording_date'].to_s
|
357
|
+
@recording_location = payload['recording_location'].to_s
|
327
358
|
@tags = payload['tags']
|
328
359
|
@thumbnail_url = payload['thumbnail_url']
|
329
|
-
@title = payload['title']
|
360
|
+
@title = payload['title'].to_s
|
330
361
|
@update_time = YouTube._string_to_time(payload['update_time'])
|
331
362
|
@upload_time = YouTube._string_to_time(payload['upload_time'])
|
332
363
|
@view_count = payload['view_count'].to_i
|
364
|
+
@embed_status = payload['embed_status']
|
365
|
+
@embed_allowed = ( payload['embed_status'] == "ok" )
|
333
366
|
end
|
334
367
|
end
|
335
368
|
|
@@ -345,5 +378,5 @@ edoc
|
|
345
378
|
# representing seconds since the epoch, or nil if the string is nil.
|
346
379
|
def self._string_to_time(time_str)
|
347
380
|
(time_str) ? Time.at(time_str.to_i) : nil
|
348
|
-
end
|
381
|
+
end
|
349
382
|
end
|
data/test/test_api.rb
CHANGED
@@ -2,15 +2,25 @@ require 'rubygems'
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'youtube'
|
4
4
|
require 'pp'
|
5
|
+
require 'yaml'
|
6
|
+
require 'set'
|
5
7
|
|
6
8
|
# This test class assumes an active internet connection
|
7
9
|
class TestAPI < Test::Unit::TestCase
|
8
|
-
@@DEVELOPER_API_KEY = '
|
10
|
+
@@DEVELOPER_API_KEY = 'RCofu-vAmeY'
|
11
|
+
YOUTUBE_LIB_USERID = 'ytlibtest'
|
9
12
|
|
10
13
|
def setup
|
11
14
|
@client = YouTube::Client.new @@DEVELOPER_API_KEY
|
12
15
|
end
|
13
16
|
|
17
|
+
# test to ensure escaping strange characters like ampersands works
|
18
|
+
# properly as we've been bitten by finding that they don't
|
19
|
+
def test_videos_by_tag_escape
|
20
|
+
videos = @client.videos_by_tag('cindy & margolis')
|
21
|
+
_test_video_list(videos)
|
22
|
+
end
|
23
|
+
|
14
24
|
def test_profile
|
15
25
|
profile = @client.profile('nutria42')
|
16
26
|
|
@@ -70,11 +80,34 @@ class TestAPI < Test::Unit::TestCase
|
|
70
80
|
def test_videos_by_user
|
71
81
|
# test case where videos exist
|
72
82
|
videos = @client.videos_by_user('whytheluckystiff')
|
83
|
+
_test_video_list(videos)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_return_10_videos_for_user
|
87
|
+
videos = @client.videos_by_user(YOUTUBE_LIB_USERID)
|
73
88
|
_test_video_list(videos)
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
89
|
+
|
90
|
+
assert_equal 10, videos.length
|
91
|
+
videos_seen = Set.new
|
92
|
+
videos.each do |video|
|
93
|
+
_validate_test_video(video, videos_seen)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_should_paginate_videos_by_user
|
98
|
+
total_videos = 10
|
99
|
+
expected_page_size = 3
|
100
|
+
videos_seen = Set.new
|
101
|
+
1.upto(4) do |index|
|
102
|
+
videos = @client.videos_by_user(YOUTUBE_LIB_USERID, index, expected_page_size)
|
103
|
+
_test_video_list(videos)
|
104
|
+
expected_video_count = total_videos > expected_page_size ? expected_page_size : total_videos
|
105
|
+
assert_equal expected_video_count, videos.length
|
106
|
+
videos.each do |video|
|
107
|
+
_validate_test_video(video, videos_seen)
|
108
|
+
end
|
109
|
+
total_videos -= expected_page_size
|
110
|
+
end
|
78
111
|
end
|
79
112
|
|
80
113
|
def test_videos_by_related
|
@@ -87,16 +120,27 @@ class TestAPI < Test::Unit::TestCase
|
|
87
120
|
_test_video_list(videos)
|
88
121
|
end
|
89
122
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
123
|
+
def test_videos_by_category_id_and_tag
|
124
|
+
videos = @client.videos_by_category_id_and_tag(17, 'bench')
|
125
|
+
_test_video_list(videos)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_videos_by_category_and_tag
|
129
|
+
videos = @client.videos_by_category_and_tag(YouTube::Category::SPORTS, 'bench')
|
130
|
+
_test_video_list(videos)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_should_not_return_any_videos_for_videos_by_category_and_tag
|
134
|
+
videos = @client.videos_by_category_and_tag(YouTube::Category::SPORTS, 'somerandomtagthatihopedoesntexist')
|
135
|
+
assert_nil videos
|
136
|
+
end
|
99
137
|
|
138
|
+
def test_should_get_comment_count_for_video
|
139
|
+
videos = @client.videos_by_tag('imogen heap hide and seek')
|
140
|
+
video = videos.sort{ |a,b| b.view_count <=> a.view_count }.first
|
141
|
+
assert video.comment_count > 0
|
142
|
+
end
|
143
|
+
|
100
144
|
def test_featured_videos
|
101
145
|
videos = @client.featured_videos
|
102
146
|
_test_video_list(videos)
|
@@ -114,7 +158,9 @@ class TestAPI < Test::Unit::TestCase
|
|
114
158
|
assert (details.author && details.author.length > 0)
|
115
159
|
assert (details.length_seconds > 0)
|
116
160
|
assert (details.title && details.title.length > 0)
|
117
|
-
|
161
|
+
assert_instance_of String, details.description
|
162
|
+
assert details.embed_allowed if details.embed_status == "ok"
|
163
|
+
assert !details.embed_allowed if details.embed_status == "not allowed"
|
118
164
|
end
|
119
165
|
|
120
166
|
# make sure parameter validation is operating correctly
|
@@ -147,48 +193,79 @@ class TestAPI < Test::Unit::TestCase
|
|
147
193
|
end
|
148
194
|
|
149
195
|
private
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
196
|
+
# Returns the number of times +substr+ exists within +text+.
|
197
|
+
def _match_count (substr, text)
|
198
|
+
return 0 if (!text || !substr)
|
199
|
+
|
200
|
+
count = 0
|
201
|
+
offset = 0
|
202
|
+
while (result = text.index(substr, offset))
|
203
|
+
count += 1
|
204
|
+
offset = result + 1
|
205
|
+
end
|
206
|
+
count
|
160
207
|
end
|
161
|
-
count
|
162
|
-
end
|
163
208
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
def _test_video_list (videos)
|
169
|
-
# make sure we got some videos
|
170
|
-
assert_not_nil videos
|
171
|
-
assert (videos.length > 0)
|
172
|
-
|
173
|
-
# make sure all video records look good
|
174
|
-
videos.each { |video| _test_video(video) }
|
175
|
-
end
|
209
|
+
def _assert_youtube_url (url)
|
210
|
+
(url =~ /^http:\/\/www.youtube.com\//)
|
211
|
+
end
|
176
212
|
|
177
|
-
|
178
|
-
|
213
|
+
def _test_video_list (videos)
|
214
|
+
# make sure we got some videos
|
215
|
+
assert_not_nil videos
|
216
|
+
assert (videos.length > 0)
|
179
217
|
|
180
|
-
|
181
|
-
|
182
|
-
|
218
|
+
# make sure all video records look good
|
219
|
+
videos.each { |video| _test_video(video) }
|
220
|
+
end
|
183
221
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
222
|
+
def _test_video (video)
|
223
|
+
assert_kind_of YouTube::Video, video
|
224
|
+
|
225
|
+
# sanity-check embed url to make sure it looks ok
|
226
|
+
assert_not_nil video.embed_url
|
227
|
+
_assert_youtube_url video.embed_url
|
228
|
+
|
229
|
+
# check other attributes
|
230
|
+
assert (video.thumbnail_url =~ /\.jpg$/)
|
231
|
+
assert (video.title && video.title.length > 0)
|
232
|
+
assert (video.length_seconds > 0)
|
233
|
+
# make sure description came through as a string, as a single check
|
234
|
+
# that we feel good about covering other fields since the xml parsing
|
235
|
+
# of empty elements defaults to providing an empty hash but we want
|
236
|
+
# a proper type everywhere.
|
237
|
+
assert_instance_of String, video.description
|
238
|
+
assert (video.upload_time && video.upload_time.is_a?(Time))
|
239
|
+
_assert_youtube_url video.url
|
240
|
+
assert (video.view_count >= 0)
|
241
|
+
assert (video.tags && video.tags.length > 0)
|
242
|
+
assert (video.author && video.author.length > 0)
|
243
|
+
end
|
244
|
+
|
245
|
+
def _validate_test_video(video, videos_seen = nil)
|
246
|
+
values = YAML.load(video.description)
|
247
|
+
index = values["index"]
|
248
|
+
|
249
|
+
# make sure we only see a particular video once
|
250
|
+
# if the particular test cares about that
|
251
|
+
if videos_seen
|
252
|
+
assert !videos_seen.include?(index)
|
253
|
+
videos_seen.add(index)
|
254
|
+
end
|
255
|
+
|
256
|
+
title = sprintf("Test Video %02d", index)
|
257
|
+
assert_equal title, video.title
|
258
|
+
assert_equal values["length"], video.length_seconds
|
259
|
+
|
260
|
+
tags = Set.new(video.tags.split)
|
261
|
+
if index.modulo(2) == 1
|
262
|
+
assert tags.include?("ytlodd")
|
263
|
+
else
|
264
|
+
assert tags.include?("ytleven")
|
265
|
+
end
|
266
|
+
|
267
|
+
if [2,3,5,7].to_set.include?(index)
|
268
|
+
assert tags.include?("ytlprime")
|
269
|
+
end
|
270
|
+
end
|
194
271
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: youtube
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.8.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.8.6
|
7
|
+
date: 2007-06-12 00:00:00 -04:00
|
8
8
|
summary: A Ruby object-oriented interface to the YouTube REST API.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Shane Vitarana
|
30
31
|
files:
|