瀏覽代碼

Allow playlist test definitions in test_download.

This moves playlist tests where they belong, i.e. to the extractors themselves.
Additionally, all our network interaction configuration for tests in test_download now applies to playlist tests as well.
Philipp Hagemeister 11 年之前
父節點
當前提交
e8ee972c6e
共有 3 個文件被更改,包括 37 次插入8 次删除
  1. 3 2
      test/helper.py
  2. 27 5
      test/test_download.py
  3. 7 1
      youtube_dl/YoutubeDL.py

+ 3 - 2
test/helper.py

@@ -117,8 +117,9 @@ def expect_info_dict(self, expected_dict, got_dict):
                 u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got))
                 u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got))
 
 
     # Check for the presence of mandatory fields
     # Check for the presence of mandatory fields
-    for key in ('id', 'url', 'title', 'ext'):
-        self.assertTrue(got_dict.get(key), 'Missing mandatory field %s' % key)
+    if got_dict.get('_type') != 'playlist':
+        for key in ('id', 'url', 'title', 'ext'):
+            self.assertTrue(got_dict.get(key), 'Missing mandatory field %s' % key)
     # Check for mandatory fields that are automatically set by YoutubeDL
     # Check for mandatory fields that are automatically set by YoutubeDL
     for key in ['webpage_url', 'extractor', 'extractor_key']:
     for key in ['webpage_url', 'extractor', 'extractor_key']:
         self.assertTrue(got_dict.get(key), u'Missing field: %s' % key)
         self.assertTrue(got_dict.get(key), u'Missing field: %s' % key)

+ 27 - 5
test/test_download.py

@@ -63,15 +63,21 @@ def generator(test_case):
     def test_template(self):
     def test_template(self):
         ie = youtube_dl.extractor.get_info_extractor(test_case['name'])
         ie = youtube_dl.extractor.get_info_extractor(test_case['name'])
         other_ies = [get_info_extractor(ie_key) for ie_key in test_case.get('add_ie', [])]
         other_ies = [get_info_extractor(ie_key) for ie_key in test_case.get('add_ie', [])]
+        is_playlist = any(k.startswith('playlist') for k in test_case)
+        test_cases = test_case.get(
+            'playlist', [] if is_playlist else [test_case])
+
         def print_skipping(reason):
         def print_skipping(reason):
             print('Skipping %s: %s' % (test_case['name'], reason))
             print('Skipping %s: %s' % (test_case['name'], reason))
         if not ie.working():
         if not ie.working():
             print_skipping('IE marked as not _WORKING')
             print_skipping('IE marked as not _WORKING')
             return
             return
-        if 'playlist' not in test_case:
-            info_dict = test_case.get('info_dict', {})
-            if not test_case.get('file') and not (info_dict.get('id') and info_dict.get('ext')):
+
+        for tc in test_cases:
+            info_dict = tc.get('info_dict', {})
+            if not tc.get('file') and not (info_dict.get('id') and info_dict.get('ext')):
                 raise Exception('Test definition incorrect. The output file cannot be known. Are both \'id\' and \'ext\' keys present?')
                 raise Exception('Test definition incorrect. The output file cannot be known. Are both \'id\' and \'ext\' keys present?')
+
         if 'skip' in test_case:
         if 'skip' in test_case:
             print_skipping(test_case['skip'])
             print_skipping(test_case['skip'])
             return
             return
@@ -81,6 +87,9 @@ def generator(test_case):
                 return
                 return
 
 
         params = get_params(test_case.get('params', {}))
         params = get_params(test_case.get('params', {}))
+        if is_playlist and 'playlist' not in test_case:
+            params.setdefault('extract_flat', True)
+            params.setdefault('skip_download', True)
 
 
         ydl = YoutubeDL(params)
         ydl = YoutubeDL(params)
         ydl.add_default_info_extractors()
         ydl.add_default_info_extractors()
@@ -93,7 +102,6 @@ def generator(test_case):
         def get_tc_filename(tc):
         def get_tc_filename(tc):
             return tc.get('file') or ydl.prepare_filename(tc.get('info_dict', {}))
             return tc.get('file') or ydl.prepare_filename(tc.get('info_dict', {}))
 
 
-        test_cases = test_case.get('playlist', [test_case])
         def try_rm_tcs_files():
         def try_rm_tcs_files():
             for tc in test_cases:
             for tc in test_cases:
                 tc_filename = get_tc_filename(tc)
                 tc_filename = get_tc_filename(tc)
@@ -105,7 +113,10 @@ def generator(test_case):
             try_num = 1
             try_num = 1
             while True:
             while True:
                 try:
                 try:
-                    ydl.download([test_case['url']])
+                    # We're not using .download here sine that is just a shim
+                    # for outside error handling, and returns the exit code
+                    # instead of the result dict.
+                    res_dict = ydl.extract_info(test_case['url'])
                 except (DownloadError, ExtractorError) as err:
                 except (DownloadError, ExtractorError) as err:
                     # Check if the exception is not a network related one
                     # Check if the exception is not a network related one
                     if not err.exc_info[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError, compat_http_client.BadStatusLine) or (err.exc_info[0] == compat_HTTPError and err.exc_info[1].code == 503):
                     if not err.exc_info[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError, compat_http_client.BadStatusLine) or (err.exc_info[0] == compat_HTTPError and err.exc_info[1].code == 503):
@@ -121,6 +132,17 @@ def generator(test_case):
                 else:
                 else:
                     break
                     break
 
 
+            if is_playlist:
+                self.assertEqual(res_dict['_type'], 'playlist')
+                expect_info_dict(self, test_case.get('info_dict', {}), res_dict)
+            if 'playlist_mincount' in test_case:
+                self.assertGreaterEqual(
+                    len(res_dict['entries']),
+                    test_case['playlist_mincount'],
+                    'Expected at least %d in playlist %s, but got only %d' % (
+                        test_case['playlist_mincount'], test_case['url'],
+                        len(res_dict['entries'])))
+
             for tc in test_cases:
             for tc in test_cases:
                 tc_filename = get_tc_filename(tc)
                 tc_filename = get_tc_filename(tc)
                 if not test_case.get('params', {}).get('skip_download', False):
                 if not test_case.get('params', {}).get('skip_download', False):

+ 7 - 1
youtube_dl/YoutubeDL.py

@@ -162,6 +162,7 @@ class YoutubeDL(object):
     default_search:    Prepend this string if an input url is not valid.
     default_search:    Prepend this string if an input url is not valid.
                        'auto' for elaborate guessing
                        'auto' for elaborate guessing
     encoding:          Use this encoding instead of the system-specified.
     encoding:          Use this encoding instead of the system-specified.
+    extract_flat:      Do not resolve URLs, return the immediate result.
 
 
     The following parameters are not used by YoutubeDL itself, they are used by
     The following parameters are not used by YoutubeDL itself, they are used by
     the FileDownloader:
     the FileDownloader:
@@ -558,7 +559,12 @@ class YoutubeDL(object):
         Returns the resolved ie_result.
         Returns the resolved ie_result.
         """
         """
 
 
-        result_type = ie_result.get('_type', 'video') # If not given we suppose it's a video, support the default old system
+        result_type = ie_result.get('_type', 'video')
+
+        if self.params.get('extract_flat', False):
+            if result_type in ('url', 'url_transparent'):
+                return ie_result
+
         if result_type == 'video':
         if result_type == 'video':
             self.add_extra_info(ie_result, extra_info)
             self.add_extra_info(ie_result, extra_info)
             return self.process_video_result(ie_result, download=download)
             return self.process_video_result(ie_result, download=download)