]>
Commit | Line | Data |
---|---|---|
f4aac741 | 1 | import errno |
112da0a0 | 2 | import io |
44a5f171 | 3 | import hashlib |
112da0a0 PH |
4 | import json |
5 | import os.path | |
00fcc17a FV |
6 | import re |
7 | import types | |
dd508b7c | 8 | import sys |
112da0a0 | 9 | |
fc2c063e | 10 | import youtube_dl.extractor |
44a5f171 | 11 | from youtube_dl import YoutubeDL |
257cfebf PH |
12 | from youtube_dl.utils import ( |
13 | compat_str, | |
14 | preferredencoding, | |
15 | ) | |
112da0a0 | 16 | |
112da0a0 | 17 | |
44a5f171 PH |
18 | def get_params(override=None): |
19 | PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), | |
20 | "parameters.json") | |
21 | with io.open(PARAMETERS_FILE, encoding='utf-8') as pf: | |
22 | parameters = json.load(pf) | |
23 | if override: | |
24 | parameters.update(override) | |
25 | return parameters | |
112da0a0 | 26 | |
f4aac741 PH |
27 | |
28 | def try_rm(filename): | |
29 | """ Remove a file if it exists """ | |
30 | try: | |
31 | os.remove(filename) | |
32 | except OSError as ose: | |
33 | if ose.errno != errno.ENOENT: | |
34 | raise | |
35 | ||
36 | ||
dd508b7c FV |
37 | def report_warning(message): |
38 | ''' | |
39 | Print the message to stderr, it will be prefixed with 'WARNING:' | |
40 | If stderr is a tty file the 'WARNING:' will be colored | |
41 | ''' | |
42 | if sys.stderr.isatty() and os.name != 'nt': | |
43 | _msg_header = u'\033[0;33mWARNING:\033[0m' | |
44 | else: | |
45 | _msg_header = u'WARNING:' | |
46 | output = u'%s %s\n' % (_msg_header, message) | |
47 | if 'b' in getattr(sys.stderr, 'mode', '') or sys.version_info[0] < 3: | |
48 | output = output.encode(preferredencoding()) | |
49 | sys.stderr.write(output) | |
50 | ||
51 | ||
112da0a0 | 52 | class FakeYDL(YoutubeDL): |
f4d96df0 | 53 | def __init__(self, override=None): |
112da0a0 PH |
54 | # Different instances of the downloader can't share the same dictionary |
55 | # some test set the "sublang" parameter, which would break the md5 checks. | |
f4d96df0 | 56 | params = get_params(override=override) |
f4aac741 PH |
57 | super(FakeYDL, self).__init__(params) |
58 | self.result = [] | |
59 | ||
60 | def to_screen(self, s, skip_eol=None): | |
112da0a0 | 61 | print(s) |
f4aac741 | 62 | |
112da0a0 PH |
63 | def trouble(self, s, tb=None): |
64 | raise Exception(s) | |
f4aac741 | 65 | |
112da0a0 | 66 | def download(self, x): |
fc2c063e | 67 | self.result.append(x) |
f4aac741 | 68 | |
00fcc17a FV |
69 | def expect_warning(self, regex): |
70 | # Silence an expected warning matching a regex | |
71 | old_report_warning = self.report_warning | |
72 | def report_warning(self, message): | |
73 | if re.match(regex, message): return | |
74 | old_report_warning(message) | |
75 | self.report_warning = types.MethodType(report_warning, self) | |
fc2c063e | 76 | |
ff14fc49 | 77 | def gettestcases(): |
fc2c063e PH |
78 | for ie in youtube_dl.extractor.gen_extractors(): |
79 | t = getattr(ie, '_TEST', None) | |
80 | if t: | |
81 | t['name'] = type(ie).__name__[:-len('IE')] | |
82 | yield t | |
83 | for t in getattr(ie, '_TESTS', []): | |
84 | t['name'] = type(ie).__name__[:-len('IE')] | |
85 | yield t | |
44a5f171 PH |
86 | |
87 | ||
88 | md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest() | |
257cfebf PH |
89 | |
90 | ||
91 | def expect_info_dict(self, expected_dict, got_dict): | |
92 | for info_field, expected in expected_dict.items(): | |
93 | if isinstance(expected, compat_str) and expected.startswith('re:'): | |
94 | got = got_dict.get(info_field) | |
95 | match_str = expected[len('re:'):] | |
96 | match_rex = re.compile(match_str) | |
97 | ||
98 | self.assertTrue( | |
99 | isinstance(got, compat_str) and match_rex.match(got), | |
100 | u'field %s (value: %r) should match %r' % (info_field, got, match_str)) | |
101 | elif isinstance(expected, type): | |
102 | got = got_dict.get(info_field) | |
103 | self.assertTrue(isinstance(got, expected), | |
104 | u'Expected type %r, but got value %r of type %r' % (expected, got, type(got))) | |
105 | else: | |
106 | if isinstance(expected, compat_str) and expected.startswith('md5:'): | |
107 | got = 'md5:' + md5(got_dict.get(info_field)) | |
108 | else: | |
109 | got = got_dict.get(info_field) | |
110 | self.assertEqual(expected, got, | |
111 | u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) | |
112 | ||
ea38e55f PH |
113 | # Check for the presence of mandatory fields |
114 | for key in ('id', 'url', 'title', 'ext'): | |
115 | self.assertTrue(got_dict.get(key), 'Missing mandatory field %s' % key) | |
116 | # Check for mandatory fields that are automatically set by YoutubeDL | |
117 | for key in ['webpage_url', 'extractor', 'extractor_key']: | |
118 | self.assertTrue(got_dict.get(key), u'Missing field: %s' % key) | |
119 | ||
120 | # Are checkable fields missing from the test case definition? | |
121 | test_info_dict = dict((key, value if not isinstance(value, compat_str) or len(value) < 250 else 'md5:' + md5(value)) | |
122 | for key, value in got_dict.items() | |
123 | if value and key in ('title', 'description', 'uploader', 'upload_date', 'timestamp', 'uploader_id', 'location')) | |
124 | missing_keys = set(test_info_dict.keys()) - set(expected_dict.keys()) | |
125 | if missing_keys: | |
126 | sys.stderr.write(u'\n"info_dict": ' + json.dumps(test_info_dict, ensure_ascii=False, indent=4) + u'\n') | |
127 | self.assertFalse( | |
128 | missing_keys, | |
129 | 'Missing keys in test definition: %s' % ( | |
130 | ', '.join(sorted(missing_keys)))) |