| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  | import errno | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | import io | 
					
						
							| 
									
										
										
										
											2013-10-15 02:00:53 +02:00
										 |  |  | import hashlib | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | import json | 
					
						
							|  |  |  | import os.path | 
					
						
							| 
									
										
										
										
											2013-10-05 15:55:58 -04:00
										 |  |  | import re | 
					
						
							|  |  |  | import types | 
					
						
							| 
									
										
										
										
											2013-10-28 18:03:26 -04:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-27 21:15:16 +02:00
										 |  |  | import youtube_dl.extractor | 
					
						
							| 
									
										
										
										
											2013-10-15 02:00:53 +02:00
										 |  |  | from youtube_dl import YoutubeDL | 
					
						
							| 
									
										
										
										
											2014-03-23 15:52:21 +01:00
										 |  |  | from youtube_dl.utils import ( | 
					
						
							|  |  |  |     compat_str, | 
					
						
							|  |  |  |     preferredencoding, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 02:00:53 +02:00
										 |  |  | def get_params(override=None): | 
					
						
							|  |  |  |     PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), | 
					
						
							|  |  |  |                                    "parameters.json") | 
					
						
							|  |  |  |     with io.open(PARAMETERS_FILE, encoding='utf-8') as pf: | 
					
						
							|  |  |  |         parameters = json.load(pf) | 
					
						
							|  |  |  |     if override: | 
					
						
							|  |  |  |         parameters.update(override) | 
					
						
							|  |  |  |     return parameters | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | def try_rm(filename): | 
					
						
							|  |  |  |     """ Remove a file if it exists """ | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         os.remove(filename) | 
					
						
							|  |  |  |     except OSError as ose: | 
					
						
							|  |  |  |         if ose.errno != errno.ENOENT: | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-28 18:03:26 -04:00
										 |  |  | def report_warning(message): | 
					
						
							|  |  |  |     '''
 | 
					
						
							|  |  |  |     Print the message to stderr, it will be prefixed with 'WARNING:' | 
					
						
							|  |  |  |     If stderr is a tty file the 'WARNING:' will be colored | 
					
						
							|  |  |  |     '''
 | 
					
						
							|  |  |  |     if sys.stderr.isatty() and os.name != 'nt': | 
					
						
							|  |  |  |         _msg_header = u'\033[0;33mWARNING:\033[0m' | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         _msg_header = u'WARNING:' | 
					
						
							|  |  |  |     output = u'%s %s\n' % (_msg_header, message) | 
					
						
							|  |  |  |     if 'b' in getattr(sys.stderr, 'mode', '') or sys.version_info[0] < 3: | 
					
						
							|  |  |  |         output = output.encode(preferredencoding()) | 
					
						
							|  |  |  |     sys.stderr.write(output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  | class FakeYDL(YoutubeDL): | 
					
						
							| 
									
										
										
										
											2013-10-18 00:46:35 +02:00
										 |  |  |     def __init__(self, override=None): | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  |         # Different instances of the downloader can't share the same dictionary | 
					
						
							|  |  |  |         # some test set the "sublang" parameter, which would break the md5 checks. | 
					
						
							| 
									
										
										
										
											2013-10-18 00:46:35 +02:00
										 |  |  |         params = get_params(override=override) | 
					
						
							| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  |         super(FakeYDL, self).__init__(params) | 
					
						
							|  |  |  |         self.result = [] | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     def to_screen(self, s, skip_eol=None): | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  |         print(s) | 
					
						
							| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  |     def trouble(self, s, tb=None): | 
					
						
							|  |  |  |         raise Exception(s) | 
					
						
							| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-27 00:09:05 +02:00
										 |  |  |     def download(self, x): | 
					
						
							| 
									
										
										
										
											2013-06-27 21:15:16 +02:00
										 |  |  |         self.result.append(x) | 
					
						
							| 
									
										
										
										
											2013-10-06 05:47:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-05 15:55:58 -04:00
										 |  |  |     def expect_warning(self, regex): | 
					
						
							|  |  |  |         # Silence an expected warning matching a regex | 
					
						
							|  |  |  |         old_report_warning = self.report_warning | 
					
						
							|  |  |  |         def report_warning(self, message): | 
					
						
							|  |  |  |             if re.match(regex, message): return | 
					
						
							|  |  |  |             old_report_warning(message) | 
					
						
							|  |  |  |         self.report_warning = types.MethodType(report_warning, self) | 
					
						
							| 
									
										
										
										
											2013-06-27 21:15:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-19 19:41:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | def gettestcases(include_onlymatching=False): | 
					
						
							| 
									
										
										
										
											2013-06-27 21:15:16 +02:00
										 |  |  |     for ie in youtube_dl.extractor.gen_extractors(): | 
					
						
							|  |  |  |         t = getattr(ie, '_TEST', None) | 
					
						
							|  |  |  |         if t: | 
					
						
							| 
									
										
										
										
											2014-04-19 19:41:06 +02:00
										 |  |  |             assert not hasattr(ie, '_TESTS'), \ | 
					
						
							|  |  |  |                 '%s has _TEST and _TESTS' % type(ie).__name__ | 
					
						
							|  |  |  |             tests = [t] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             tests = getattr(ie, '_TESTS', []) | 
					
						
							|  |  |  |         for t in tests: | 
					
						
							| 
									
										
										
										
											2014-04-21 07:56:51 +02:00
										 |  |  |             if not include_onlymatching and t.get('only_matching', False): | 
					
						
							| 
									
										
										
										
											2014-04-19 19:41:06 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2013-06-27 21:15:16 +02:00
										 |  |  |             t['name'] = type(ie).__name__[:-len('IE')] | 
					
						
							|  |  |  |             yield t | 
					
						
							| 
									
										
										
										
											2013-10-15 02:00:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest() | 
					
						
							| 
									
										
										
										
											2014-03-23 15:52:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def expect_info_dict(self, expected_dict, got_dict): | 
					
						
							|  |  |  |     for info_field, expected in expected_dict.items(): | 
					
						
							|  |  |  |         if isinstance(expected, compat_str) and expected.startswith('re:'): | 
					
						
							|  |  |  |             got = got_dict.get(info_field) | 
					
						
							|  |  |  |             match_str = expected[len('re:'):] | 
					
						
							|  |  |  |             match_rex = re.compile(match_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertTrue( | 
					
						
							|  |  |  |                 isinstance(got, compat_str) and match_rex.match(got), | 
					
						
							|  |  |  |                 u'field %s (value: %r) should match %r' % (info_field, got, match_str)) | 
					
						
							|  |  |  |         elif isinstance(expected, type): | 
					
						
							|  |  |  |             got = got_dict.get(info_field) | 
					
						
							|  |  |  |             self.assertTrue(isinstance(got, expected), | 
					
						
							| 
									
										
										
										
											2014-05-13 09:41:36 +02:00
										 |  |  |                 u'Expected type %r for field %s, but got value %r of type %r' % (expected, info_field, got, type(got))) | 
					
						
							| 
									
										
										
										
											2014-03-23 15:52:21 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if isinstance(expected, compat_str) and expected.startswith('md5:'): | 
					
						
							|  |  |  |                 got = 'md5:' + md5(got_dict.get(info_field)) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 got = got_dict.get(info_field) | 
					
						
							|  |  |  |             self.assertEqual(expected, got, | 
					
						
							|  |  |  |                 u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-23 16:06:03 +01:00
										 |  |  |     # 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) | 
					
						
							|  |  |  |     # Check for mandatory fields that are automatically set by YoutubeDL | 
					
						
							|  |  |  |     for key in ['webpage_url', 'extractor', 'extractor_key']: | 
					
						
							|  |  |  |         self.assertTrue(got_dict.get(key), u'Missing field: %s' % key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Are checkable fields missing from the test case definition? | 
					
						
							|  |  |  |     test_info_dict = dict((key, value if not isinstance(value, compat_str) or len(value) < 250 else 'md5:' + md5(value)) | 
					
						
							|  |  |  |         for key, value in got_dict.items() | 
					
						
							|  |  |  |         if value and key in ('title', 'description', 'uploader', 'upload_date', 'timestamp', 'uploader_id', 'location')) | 
					
						
							|  |  |  |     missing_keys = set(test_info_dict.keys()) - set(expected_dict.keys()) | 
					
						
							|  |  |  |     if missing_keys: | 
					
						
							|  |  |  |         sys.stderr.write(u'\n"info_dict": ' + json.dumps(test_info_dict, ensure_ascii=False, indent=4) + u'\n') | 
					
						
							|  |  |  |         self.assertFalse( | 
					
						
							|  |  |  |             missing_keys, | 
					
						
							|  |  |  |             'Missing keys in test definition: %s' % ( | 
					
						
							|  |  |  |                 ', '.join(sorted(missing_keys)))) | 
					
						
							| 
									
										
										
										
											2014-04-30 02:02:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def assertRegexpMatches(self, text, regexp, msg=None): | 
					
						
							|  |  |  |     if hasattr(self, 'assertRegexpMatches'): | 
					
						
							|  |  |  |         return self.assertRegexpMatches(text, regexp, msg) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         m = re.match(regexp, text) | 
					
						
							|  |  |  |         if not m: | 
					
						
							|  |  |  |             note = 'Regexp didn\'t match: %r not found in %r' % (regexp, text) | 
					
						
							|  |  |  |             if msg is None: | 
					
						
							|  |  |  |                 msg = note | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 msg = note + ', ' + msg | 
					
						
							|  |  |  |             self.assertTrue(m, msg) |