diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/helper.py | 35 | ||||
-rw-r--r-- | test/swftests/ConstArrayAccess.as | 18 | ||||
-rw-r--r-- | test/swftests/ConstantInt.as | 12 | ||||
-rw-r--r-- | test/swftests/DictCall.as | 10 | ||||
-rw-r--r-- | test/swftests/EqualsOperator.as | 10 | ||||
-rw-r--r-- | test/swftests/MemberAssignment.as | 22 | ||||
-rw-r--r-- | test/swftests/NeOperator.as | 24 | ||||
-rw-r--r-- | test/swftests/PrivateVoidCall.as | 22 | ||||
-rw-r--r-- | test/swftests/StringBasics.as | 11 | ||||
-rw-r--r-- | test/swftests/StringCharCodeAt.as | 11 | ||||
-rw-r--r-- | test/swftests/StringConversion.as | 11 | ||||
-rw-r--r-- | test/test_YoutubeDL.py | 1 | ||||
-rw-r--r-- | test/test_age_restriction.py | 3 | ||||
-rw-r--r-- | test/test_all_urls.py | 34 | ||||
-rw-r--r-- | test/test_compat.py | 46 | ||||
-rw-r--r-- | test/test_download.py | 35 | ||||
-rw-r--r-- | test/test_execution.py | 7 | ||||
-rw-r--r-- | test/test_subtitles.py | 42 | ||||
-rw-r--r-- | test/test_swfinterp.py | 5 | ||||
-rw-r--r-- | test/test_unicode_literals.py | 23 | ||||
-rw-r--r-- | test/test_utils.py | 67 | ||||
-rw-r--r-- | test/test_write_annotations.py | 27 | ||||
-rw-r--r-- | test/test_write_info_json.py | 7 | ||||
-rw-r--r-- | test/test_youtube_lists.py | 7 | ||||
-rw-r--r-- | test/test_youtube_signature.py | 2 |
25 files changed, 385 insertions, 107 deletions
diff --git a/test/helper.py b/test/helper.py index 62cb3ce02..8a820526a 100644 --- a/test/helper.py +++ b/test/helper.py @@ -57,9 +57,9 @@ class FakeYDL(YoutubeDL): # Different instances of the downloader can't share the same dictionary # some test set the "sublang" parameter, which would break the md5 checks. params = get_params(override=override) - super(FakeYDL, self).__init__(params) + super(FakeYDL, self).__init__(params, auto_init=False) self.result = [] - + def to_screen(self, s, skip_eol=None): print(s) @@ -72,8 +72,10 @@ class FakeYDL(YoutubeDL): 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 + if re.match(regex, message): + return old_report_warning(message) self.report_warning = types.MethodType(report_warning, self) @@ -114,14 +116,14 @@ def expect_info_dict(self, expected_dict, got_dict): elif isinstance(expected, type): got = got_dict.get(info_field) self.assertTrue(isinstance(got, expected), - 'Expected type %r for field %s, but got value %r of type %r' % (expected, info_field, got, type(got))) + 'Expected type %r for field %s, but got value %r of type %r' % (expected, info_field, got, type(got))) 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, - 'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) + 'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) # Check for the presence of mandatory fields if got_dict.get('_type') != 'playlist': @@ -133,19 +135,20 @@ def expect_info_dict(self, expected_dict, got_dict): # 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')) + 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: def _repr(v): if isinstance(v, compat_str): - return "'%s'" % v.replace('\\', '\\\\').replace("'", "\\'") + return "'%s'" % v.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n') else: return repr(v) info_dict_str = ''.join( ' %s: %s,\n' % (_repr(k), _repr(v)) for k, v in test_info_dict.items()) - write_string('\n"info_dict": {' + info_dict_str + '}\n', out=sys.stderr) + write_string( + '\n\'info_dict\': {\n' + info_dict_str + '}\n', out=sys.stderr) self.assertFalse( missing_keys, 'Missing keys in test definition: %s' % ( @@ -158,7 +161,9 @@ def assertRegexpMatches(self, text, regexp, msg=None): else: m = re.match(regexp, text) if not m: - note = 'Regexp didn\'t match: %r not found in %r' % (regexp, text) + note = 'Regexp didn\'t match: %r not found' % (regexp) + if len(text) < 1000: + note += ' in %r' % text if msg is None: msg = note else: @@ -171,3 +176,13 @@ def assertGreaterEqual(self, got, expected, msg=None): if msg is None: msg = '%r not greater than or equal to %r' % (got, expected) self.assertTrue(got >= expected, msg) + + +def expect_warnings(ydl, warnings_re): + real_warning = ydl.report_warning + + def _report_warning(w): + if not any(re.search(w_re, w) for w_re in warnings_re): + real_warning(w) + + ydl.report_warning = _report_warning diff --git a/test/swftests/ConstArrayAccess.as b/test/swftests/ConstArrayAccess.as new file mode 100644 index 000000000..07dc3f460 --- /dev/null +++ b/test/swftests/ConstArrayAccess.as @@ -0,0 +1,18 @@ +// input: [] +// output: 4 + +package { +public class ConstArrayAccess { + private static const x:int = 2; + private static const ar:Array = ["42", "3411"]; + + public static function main():int{ + var c:ConstArrayAccess = new ConstArrayAccess(); + return c.f(); + } + + public function f(): int { + return ar[1].length; + } +} +} diff --git a/test/swftests/ConstantInt.as b/test/swftests/ConstantInt.as new file mode 100644 index 000000000..e0bbb6166 --- /dev/null +++ b/test/swftests/ConstantInt.as @@ -0,0 +1,12 @@ +// input: [] +// output: 2 + +package { +public class ConstantInt { + private static const x:int = 2; + + public static function main():int{ + return x; + } +} +} diff --git a/test/swftests/DictCall.as b/test/swftests/DictCall.as new file mode 100644 index 000000000..c2d174cc2 --- /dev/null +++ b/test/swftests/DictCall.as @@ -0,0 +1,10 @@ +// input: [{"x": 1, "y": 2}] +// output: 3 + +package { +public class DictCall { + public static function main(d:Object):int{ + return d.x + d.y; + } +} +} diff --git a/test/swftests/EqualsOperator.as b/test/swftests/EqualsOperator.as new file mode 100644 index 000000000..837a69a46 --- /dev/null +++ b/test/swftests/EqualsOperator.as @@ -0,0 +1,10 @@ +// input: [] +// output: false + +package { +public class EqualsOperator { + public static function main():Boolean{ + return 1 == 2; + } +} +} diff --git a/test/swftests/MemberAssignment.as b/test/swftests/MemberAssignment.as new file mode 100644 index 000000000..dcba5e3ff --- /dev/null +++ b/test/swftests/MemberAssignment.as @@ -0,0 +1,22 @@ +// input: [1] +// output: 2 + +package { +public class MemberAssignment { + public var v:int; + + public function g():int { + return this.v; + } + + public function f(a:int):int{ + this.v = a; + return this.v + this.g(); + } + + public static function main(a:int): int { + var v:MemberAssignment = new MemberAssignment(); + return v.f(a); + } +} +} diff --git a/test/swftests/NeOperator.as b/test/swftests/NeOperator.as new file mode 100644 index 000000000..61dcbc4e9 --- /dev/null +++ b/test/swftests/NeOperator.as @@ -0,0 +1,24 @@ +// input: [] +// output: 123 + +package { +public class NeOperator { + public static function main(): int { + var res:int = 0; + if (1 != 2) { + res += 3; + } else { + res += 4; + } + if (2 != 2) { + res += 10; + } else { + res += 20; + } + if (9 == 9) { + res += 100; + } + return res; + } +} +} diff --git a/test/swftests/PrivateVoidCall.as b/test/swftests/PrivateVoidCall.as new file mode 100644 index 000000000..2cc016797 --- /dev/null +++ b/test/swftests/PrivateVoidCall.as @@ -0,0 +1,22 @@ +// input: [] +// output: 9 + +package { +public class PrivateVoidCall { + public static function main():int{ + var f:OtherClass = new OtherClass(); + f.func(); + return 9; + } +} +} + +class OtherClass { + private function pf():void { + ; + } + + public function func():void { + this.pf(); + } +} diff --git a/test/swftests/StringBasics.as b/test/swftests/StringBasics.as new file mode 100644 index 000000000..d27430b13 --- /dev/null +++ b/test/swftests/StringBasics.as @@ -0,0 +1,11 @@ +// input: [] +// output: 3 + +package { +public class StringBasics { + public static function main():int{ + var s:String = "abc"; + return s.length; + } +} +} diff --git a/test/swftests/StringCharCodeAt.as b/test/swftests/StringCharCodeAt.as new file mode 100644 index 000000000..c20d74d65 --- /dev/null +++ b/test/swftests/StringCharCodeAt.as @@ -0,0 +1,11 @@ +// input: [] +// output: 9897 + +package { +public class StringCharCodeAt { + public static function main():int{ + var s:String = "abc"; + return s.charCodeAt(1) * 100 + s.charCodeAt(); + } +} +} diff --git a/test/swftests/StringConversion.as b/test/swftests/StringConversion.as new file mode 100644 index 000000000..c976f5042 --- /dev/null +++ b/test/swftests/StringConversion.as @@ -0,0 +1,11 @@ +// input: [] +// output: 2 + +package { +public class StringConversion { + public static function main():int{ + var s:String = String(99); + return s.length; + } +} +} diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py index ab61e1976..f8e4f930e 100644 --- a/test/test_YoutubeDL.py +++ b/test/test_YoutubeDL.py @@ -266,6 +266,7 @@ class TestFormatSelection(unittest.TestCase): 'ext': 'mp4', 'width': None, } + def fname(templ): ydl = YoutubeDL({'outtmpl': templ}) return ydl.prepare_filename(info) diff --git a/test/test_age_restriction.py b/test/test_age_restriction.py index 71e80b037..5be065c43 100644 --- a/test/test_age_restriction.py +++ b/test/test_age_restriction.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import unicode_literals # Allow direct execution import os @@ -19,7 +20,7 @@ def _download_restricted(url, filename, age): 'age_limit': age, 'skip_download': True, 'writeinfojson': True, - "outtmpl": "%(id)s.%(ext)s", + 'outtmpl': '%(id)s.%(ext)s', } ydl = YoutubeDL(params) ydl.add_default_info_extractors() diff --git a/test/test_all_urls.py b/test/test_all_urls.py index 84b05da39..bd4fe17bf 100644 --- a/test/test_all_urls.py +++ b/test/test_all_urls.py @@ -14,7 +14,7 @@ from test.helper import gettestcases from youtube_dl.extractor import ( FacebookIE, gen_extractors, - JustinTVIE, + TwitchIE, YoutubeIE, ) @@ -32,19 +32,19 @@ class TestAllURLsMatching(unittest.TestCase): def test_youtube_playlist_matching(self): assertPlaylist = lambda url: self.assertMatch(url, ['youtube:playlist']) assertPlaylist('ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8') - assertPlaylist('UUBABnxM4Ar9ten8Mdjj1j0Q') #585 + assertPlaylist('UUBABnxM4Ar9ten8Mdjj1j0Q') # 585 assertPlaylist('PL63F0C78739B09958') assertPlaylist('https://www.youtube.com/playlist?list=UUBABnxM4Ar9ten8Mdjj1j0Q') assertPlaylist('https://www.youtube.com/course?list=ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8') assertPlaylist('https://www.youtube.com/playlist?list=PLwP_SiAcdui0KVebT0mU9Apz359a4ubsC') - assertPlaylist('https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012') #668 + assertPlaylist('https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012') # 668 self.assertFalse('youtube:playlist' in self.matching_ies('PLtS2H6bU1M')) # Top tracks assertPlaylist('https://www.youtube.com/playlist?list=MCUS.20142101') def test_youtube_matching(self): self.assertTrue(YoutubeIE.suitable('PLtS2H6bU1M')) - self.assertFalse(YoutubeIE.suitable('https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012')) #668 + self.assertFalse(YoutubeIE.suitable('https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012')) # 668 self.assertMatch('http://youtu.be/BaW_jenozKc', ['youtube']) self.assertMatch('http://www.youtube.com/v/BaW_jenozKc', ['youtube']) self.assertMatch('https://youtube.googleapis.com/v/BaW_jenozKc', ['youtube']) @@ -72,21 +72,17 @@ class TestAllURLsMatching(unittest.TestCase): self.assertMatch('http://www.youtube.com/results?search_query=making+mustard', ['youtube:search_url']) self.assertMatch('https://www.youtube.com/results?baz=bar&search_query=youtube-dl+test+video&filters=video&lclk=video', ['youtube:search_url']) - def test_justin_tv_channelid_matching(self): - self.assertTrue(JustinTVIE.suitable('justin.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('twitch.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('www.justin.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('www.twitch.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('http://www.justin.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('http://www.twitch.tv/vanillatv')) - self.assertTrue(JustinTVIE.suitable('http://www.justin.tv/vanillatv/')) - self.assertTrue(JustinTVIE.suitable('http://www.twitch.tv/vanillatv/')) - - def test_justintv_videoid_matching(self): - self.assertTrue(JustinTVIE.suitable('http://www.twitch.tv/vanillatv/b/328087483')) - - def test_justin_tv_chapterid_matching(self): - self.assertTrue(JustinTVIE.suitable('http://www.twitch.tv/tsm_theoddone/c/2349361')) + def test_twitch_channelid_matching(self): + self.assertTrue(TwitchIE.suitable('twitch.tv/vanillatv')) + self.assertTrue(TwitchIE.suitable('www.twitch.tv/vanillatv')) + self.assertTrue(TwitchIE.suitable('http://www.twitch.tv/vanillatv')) + self.assertTrue(TwitchIE.suitable('http://www.twitch.tv/vanillatv/')) + + def test_twitch_videoid_matching(self): + self.assertTrue(TwitchIE.suitable('http://www.twitch.tv/vanillatv/b/328087483')) + + def test_twitch_chapterid_matching(self): + self.assertTrue(TwitchIE.suitable('http://www.twitch.tv/tsm_theoddone/c/2349361')) def test_youtube_extract(self): assertExtractId = lambda url, id: self.assertEqual(YoutubeIE.extract_id(url), id) diff --git a/test/test_compat.py b/test/test_compat.py new file mode 100644 index 000000000..1eb454e06 --- /dev/null +++ b/test/test_compat.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# coding: utf-8 + +from __future__ import unicode_literals + +# Allow direct execution +import os +import sys +import unittest +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + + +from youtube_dl.utils import get_filesystem_encoding +from youtube_dl.compat import ( + compat_getenv, + compat_expanduser, +) + + +class TestCompat(unittest.TestCase): + def test_compat_getenv(self): + test_str = 'тест' + os.environ['YOUTUBE-DL-TEST'] = ( + test_str if sys.version_info >= (3, 0) + else test_str.encode(get_filesystem_encoding())) + self.assertEqual(compat_getenv('YOUTUBE-DL-TEST'), test_str) + + def test_compat_expanduser(self): + old_home = os.environ.get('HOME') + test_str = 'C:\Documents and Settings\тест\Application Data' + os.environ['HOME'] = ( + test_str if sys.version_info >= (3, 0) + else test_str.encode(get_filesystem_encoding())) + self.assertEqual(compat_expanduser('~'), test_str) + os.environ['HOME'] = old_home + + def test_all_present(self): + import youtube_dl.compat + all_names = youtube_dl.compat.__all__ + present_names = set(filter( + lambda c: '_' in c and not c.startswith('_'), + dir(youtube_dl.compat))) - set(['unicode_literals']) + self.assertEqual(all_names, sorted(present_names)) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_download.py b/test/test_download.py index 8178015ea..a009aa475 100644 --- a/test/test_download.py +++ b/test/test_download.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import unicode_literals + # Allow direct execution import os import sys @@ -8,6 +10,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from test.helper import ( assertGreaterEqual, + expect_warnings, get_params, gettestcases, expect_info_dict, @@ -22,10 +25,12 @@ import json import socket import youtube_dl.YoutubeDL -from youtube_dl.utils import ( +from youtube_dl.compat import ( compat_http_client, compat_urllib_error, compat_HTTPError, +) +from youtube_dl.utils import ( DownloadError, ExtractorError, format_bytes, @@ -35,18 +40,22 @@ from youtube_dl.extractor import get_info_extractor RETRIES = 3 + class YoutubeDL(youtube_dl.YoutubeDL): def __init__(self, *args, **kwargs): self.to_stderr = self.to_screen self.processed_info_dicts = [] super(YoutubeDL, self).__init__(*args, **kwargs) + def report_warning(self, message): # Don't accept warnings during tests raise ExtractorError(message) + def process_info(self, info_dict): self.processed_info_dicts.append(info_dict) return super(YoutubeDL, self).process_info(info_dict) + def _file_md5(fn): with open(fn, 'rb') as f: return hashlib.md5(f.read()).hexdigest() @@ -56,10 +65,13 @@ defs = gettestcases() class TestDownload(unittest.TestCase): maxDiff = None + def setUp(self): self.defs = defs -### Dynamically generate tests +# Dynamically generate tests + + def generator(test_case): def test_template(self): @@ -85,7 +97,7 @@ def generator(test_case): return for other_ie in other_ies: if not other_ie.working(): - print_skipping(u'test depends on %sIE, marked as not WORKING' % other_ie.ie_key()) + print_skipping('test depends on %sIE, marked as not WORKING' % other_ie.ie_key()) return params = get_params(test_case.get('params', {})) @@ -93,18 +105,21 @@ def generator(test_case): params.setdefault('extract_flat', True) params.setdefault('skip_download', True) - ydl = YoutubeDL(params) + ydl = YoutubeDL(params, auto_init=False) ydl.add_default_info_extractors() finished_hook_called = set() + def _hook(status): if status['status'] == 'finished': finished_hook_called.add(status['filename']) ydl.add_progress_hook(_hook) + expect_warnings(ydl, test_case.get('expected_warnings', [])) def get_tc_filename(tc): return tc.get('file') or ydl.prepare_filename(tc.get('info_dict', {})) res_dict = None + def try_rm_tcs_files(tcs=None): if tcs is None: tcs = test_cases @@ -128,7 +143,7 @@ def generator(test_case): raise if try_num == RETRIES: - report_warning(u'Failed due to network errors, skipping...') + report_warning('Failed due to network errors, skipping...') return print('Retrying: {0} failed tries\n\n##########\n\n'.format(try_num)) @@ -183,7 +198,9 @@ def generator(test_case): md5_for_file = _file_md5(tc_filename) self.assertEqual(md5_for_file, tc['md5']) info_json_fn = os.path.splitext(tc_filename)[0] + '.info.json' - self.assertTrue(os.path.exists(info_json_fn)) + self.assertTrue( + os.path.exists(info_json_fn), + 'Missing info file %s' % info_json_fn) with io.open(info_json_fn, encoding='utf-8') as infof: info_dict = json.load(infof) @@ -198,15 +215,15 @@ def generator(test_case): return test_template -### And add them to TestDownload +# And add them to TestDownload for n, test_case in enumerate(defs): test_method = generator(test_case) tname = 'test_' + str(test_case['name']) i = 1 while hasattr(TestDownload, tname): - tname = 'test_' + str(test_case['name']) + '_' + str(i) + tname = 'test_%s_%d' % (test_case['name'], i) i += 1 - test_method.__name__ = tname + test_method.__name__ = str(tname) setattr(TestDownload, test_method.__name__, test_method) del test_method diff --git a/test/test_execution.py b/test/test_execution.py index 2b115fb31..60df187de 100644 --- a/test/test_execution.py +++ b/test/test_execution.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +from __future__ import unicode_literals + import unittest import sys @@ -6,17 +9,19 @@ import subprocess rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + try: _DEV_NULL = subprocess.DEVNULL except AttributeError: _DEV_NULL = open(os.devnull, 'wb') + class TestExecution(unittest.TestCase): def test_import(self): subprocess.check_call([sys.executable, '-c', 'import youtube_dl'], cwd=rootDir) def test_module_exec(self): - if sys.version_info >= (2,7): # Python 2.6 doesn't support package execution + if sys.version_info >= (2, 7): # Python 2.6 doesn't support package execution subprocess.check_call([sys.executable, '-m', 'youtube_dl', '--version'], cwd=rootDir, stdout=_DEV_NULL) def test_main_exec(self): diff --git a/test/test_subtitles.py b/test/test_subtitles.py index 8f4602e5f..7c4cd8218 100644 --- a/test/test_subtitles.py +++ b/test/test_subtitles.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import unicode_literals # Allow direct execution import os @@ -22,6 +23,7 @@ from youtube_dl.extractor import ( class BaseTestSubtitles(unittest.TestCase): url = None IE = None + def setUp(self): self.DL = FakeYDL() self.ie = self.IE(self.DL) @@ -74,7 +76,7 @@ class TestYoutubeSubtitles(BaseTestSubtitles): self.assertEqual(md5(subtitles['en']), '3cb210999d3e021bd6c7f0ea751eab06') def test_youtube_list_subtitles(self): - self.DL.expect_warning(u'Video doesn\'t have automatic captions') + self.DL.expect_warning('Video doesn\'t have automatic captions') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) @@ -87,7 +89,7 @@ class TestYoutubeSubtitles(BaseTestSubtitles): self.assertTrue(subtitles['it'] is not None) def test_youtube_nosubtitles(self): - self.DL.expect_warning(u'video doesn\'t have subtitles') + self.DL.expect_warning('video doesn\'t have subtitles') self.url = 'n5BB19UTcdA' self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True @@ -101,7 +103,7 @@ class TestYoutubeSubtitles(BaseTestSubtitles): self.DL.params['subtitleslangs'] = langs subtitles = self.getSubtitles() for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) class TestDailymotionSubtitles(BaseTestSubtitles): @@ -130,20 +132,20 @@ class TestDailymotionSubtitles(BaseTestSubtitles): self.assertEqual(len(subtitles.keys()), 5) def test_list_subtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) def test_automatic_captions(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writeautomaticsub'] = True self.DL.params['subtitleslang'] = ['en'] subtitles = self.getSubtitles() self.assertTrue(len(subtitles.keys()) == 0) def test_nosubtitles(self): - self.DL.expect_warning(u'video doesn\'t have subtitles') + self.DL.expect_warning('video doesn\'t have subtitles') self.url = 'http://www.dailymotion.com/video/x12u166_le-zapping-tele-star-du-08-aout-2013_tv' self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True @@ -156,7 +158,7 @@ class TestDailymotionSubtitles(BaseTestSubtitles): self.DL.params['subtitleslangs'] = langs subtitles = self.getSubtitles() for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) class TestTedSubtitles(BaseTestSubtitles): @@ -185,13 +187,13 @@ class TestTedSubtitles(BaseTestSubtitles): self.assertTrue(len(subtitles.keys()) >= 28) def test_list_subtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) def test_automatic_captions(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writeautomaticsub'] = True self.DL.params['subtitleslang'] = ['en'] subtitles = self.getSubtitles() @@ -203,7 +205,7 @@ class TestTedSubtitles(BaseTestSubtitles): self.DL.params['subtitleslangs'] = langs subtitles = self.getSubtitles() for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) class TestBlipTVSubtitles(BaseTestSubtitles): @@ -211,13 +213,13 @@ class TestBlipTVSubtitles(BaseTestSubtitles): IE = BlipTVIE def test_list_subtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) def test_allsubtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() @@ -236,7 +238,7 @@ class TestVimeoSubtitles(BaseTestSubtitles): def test_subtitles(self): self.DL.params['writesubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['en']), '8062383cf4dec168fc40a088aa6d5888') + self.assertEqual(md5(subtitles['en']), '26399116d23ae3cf2c087cea94bc43b4') def test_subtitles_lang(self): self.DL.params['writesubtitles'] = True @@ -251,20 +253,20 @@ class TestVimeoSubtitles(BaseTestSubtitles): self.assertEqual(set(subtitles.keys()), set(['de', 'en', 'es', 'fr'])) def test_list_subtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) def test_automatic_captions(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writeautomaticsub'] = True self.DL.params['subtitleslang'] = ['en'] subtitles = self.getSubtitles() self.assertTrue(len(subtitles.keys()) == 0) def test_nosubtitles(self): - self.DL.expect_warning(u'video doesn\'t have subtitles') + self.DL.expect_warning('video doesn\'t have subtitles') self.url = 'http://vimeo.com/56015672' self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True @@ -277,7 +279,7 @@ class TestVimeoSubtitles(BaseTestSubtitles): self.DL.params['subtitleslangs'] = langs subtitles = self.getSubtitles() for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) class TestWallaSubtitles(BaseTestSubtitles): @@ -285,13 +287,13 @@ class TestWallaSubtitles(BaseTestSubtitles): IE = WallaIE def test_list_subtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['listsubtitles'] = True info_dict = self.getInfoDict() self.assertEqual(info_dict, None) def test_allsubtitles(self): - self.DL.expect_warning(u'Automatic Captions not supported by this server') + self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() @@ -299,7 +301,7 @@ class TestWallaSubtitles(BaseTestSubtitles): self.assertEqual(md5(subtitles['heb']), 'e758c5d7cb982f6bef14f377ec7a3920') def test_nosubtitles(self): - self.DL.expect_warning(u'video doesn\'t have subtitles') + self.DL.expect_warning('video doesn\'t have subtitles') self.url = 'http://vod.walla.co.il/movie/2642630/one-direction-all-for-one' self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True diff --git a/test/test_swfinterp.py b/test/test_swfinterp.py index b42cd74c7..9f18055e6 100644 --- a/test/test_swfinterp.py +++ b/test/test_swfinterp.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import unicode_literals # Allow direct execution import os @@ -37,7 +38,9 @@ def _make_testfunc(testfile): or os.path.getmtime(swf_file) < os.path.getmtime(as_file)): # Recompile try: - subprocess.check_call(['mxmlc', '-output', swf_file, as_file]) + subprocess.check_call([ + 'mxmlc', '-output', swf_file, + '-static-link-runtime-shared-libraries', as_file]) except OSError as ose: if ose.errno == errno.ENOENT: print('mxmlc not found! Skipping test.') diff --git a/test/test_unicode_literals.py b/test/test_unicode_literals.py index a4ba7bad0..19813e034 100644 --- a/test/test_unicode_literals.py +++ b/test/test_unicode_literals.py @@ -1,5 +1,11 @@ from __future__ import unicode_literals +# Allow direct execution +import os +import sys +import unittest +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + import io import os import re @@ -9,14 +15,16 @@ rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) IGNORED_FILES = [ 'setup.py', # http://bugs.python.org/issue13943 + 'conf.py', + 'buildserver.py', ] +from test.helper import assertRegexpMatches + + class TestUnicodeLiterals(unittest.TestCase): def test_all_files(self): - print('Skipping this test (not yet fully implemented)') - return - for dirpath, _, filenames in os.walk(rootDir): for basename in filenames: if not basename.endswith('.py'): @@ -30,10 +38,11 @@ class TestUnicodeLiterals(unittest.TestCase): if "'" not in code and '"' not in code: continue - imps = 'from __future__ import unicode_literals' - self.assertTrue( - imps in code, - ' %s missing in %s' % (imps, fn)) + assertRegexpMatches( + self, + code, + r'(?:(?:#.*?|\s*)\n)*from __future__ import (?:[a-z_]+,\s*)*unicode_literals', + 'unicode_literals import missing in %s' % fn) m = re.search(r'(?<=\s)u[\'"](?!\)|,|$)', code) if m is not None: diff --git a/test/test_utils.py b/test/test_utils.py index bcca0efea..d42df6d96 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -16,11 +16,11 @@ import json import xml.etree.ElementTree from youtube_dl.utils import ( + clean_html, DateRange, encodeFilename, find_xpath_attr, fix_xml_ampersands, - get_meta_content, orderedSet, OnDemandPagedList, InAdvancePagedList, @@ -45,6 +45,10 @@ from youtube_dl.utils import ( escape_rfc3986, escape_url, js_to_json, + intlist_to_bytes, + args_to_str, + parse_filesize, + version_tuple, ) @@ -117,16 +121,16 @@ class TestUtil(unittest.TestCase): self.assertEqual(orderedSet([1, 1, 2, 3, 4, 4, 5, 6, 7, 3, 5]), [1, 2, 3, 4, 5, 6, 7]) self.assertEqual(orderedSet([]), []) self.assertEqual(orderedSet([1]), [1]) - #keep the list ordered + # keep the list ordered self.assertEqual(orderedSet([135, 1, 1, 1]), [135, 1]) def test_unescape_html(self): self.assertEqual(unescapeHTML('%20;'), '%20;') self.assertEqual( unescapeHTML('é'), 'é') - + def test_daterange(self): - _20century = DateRange("19000101","20000101") + _20century = DateRange("19000101", "20000101") self.assertFalse("17890714" in _20century) _ac = DateRange("00010101") self.assertTrue("19690721" in _ac) @@ -140,6 +144,9 @@ class TestUtil(unittest.TestCase): self.assertEqual(unified_strdate('2012/10/11 01:56:38 +0000'), '20121011') self.assertEqual(unified_strdate('1968-12-10'), '19681210') self.assertEqual(unified_strdate('28/01/2014 21:00:00 +0100'), '20140128') + self.assertEqual( + unified_strdate('11/26/2014 11:30:00 AM PST', day_first=False), + '20141126') def test_find_xpath_attr(self): testxml = '''<root> @@ -154,17 +161,6 @@ class TestUtil(unittest.TestCase): self.assertEqual(find_xpath_attr(doc, './/node', 'x', 'a'), doc[1]) self.assertEqual(find_xpath_attr(doc, './/node', 'y', 'c'), doc[2]) - def test_meta_parser(self): - testhtml = ''' - <head> - <meta name="description" content="foo & bar"> - <meta content='Plato' name='author'/> - </head> - ''' - get_meta = lambda name: get_meta_content(name, testhtml) - self.assertEqual(get_meta('description'), 'foo & bar') - self.assertEqual(get_meta('author'), 'Plato') - def test_xpath_with_ns(self): testxml = '''<root xmlns:media="http://example.com/"> <media:song> @@ -179,7 +175,7 @@ class TestUtil(unittest.TestCase): self.assertEqual(find('media:song/url').text, 'http://server.com/download.mp3') def test_smuggle_url(self): - data = {u"ö": u"ö", u"abc": [3]} + data = {"ö": "ö", "abc": [3]} url = 'https://foo.bar/baz?x=y#a' smug_url = smuggle_url(url, data) unsmug_url, unsmug_data = unsmuggle_url(smug_url) @@ -227,6 +223,10 @@ class TestUtil(unittest.TestCase): self.assertEqual(parse_duration('0m0s'), 0) self.assertEqual(parse_duration('0s'), 0) self.assertEqual(parse_duration('01:02:03.05'), 3723.05) + self.assertEqual(parse_duration('T30M38S'), 1838) + self.assertEqual(parse_duration('5 s'), 5) + self.assertEqual(parse_duration('3 min'), 180) + self.assertEqual(parse_duration('2.5 hours'), 9000) def test_fix_xml_ampersands(self): self.assertEqual( @@ -286,12 +286,17 @@ class TestUtil(unittest.TestCase): self.assertEqual(parse_iso8601('2014-03-23T23:04:26+0100'), 1395612266) self.assertEqual(parse_iso8601('2014-03-23T22:04:26+0000'), 1395612266) self.assertEqual(parse_iso8601('2014-03-23T22:04:26Z'), 1395612266) + self.assertEqual(parse_iso8601('2014-03-23T22:04:26.1234Z'), 1395612266) def test_strip_jsonp(self): stripped = strip_jsonp('cb ([ {"id":"532cb",\n\n\n"x":\n3}\n]\n);') d = json.loads(stripped) self.assertEqual(d, [{"id": "532cb", "x": 3}]) + stripped = strip_jsonp('parseMetadata({"STATUS":"OK"})\n\n\n//epc') + d = json.loads(stripped) + self.assertEqual(d, {'STATUS': 'OK'}) + def test_uppercase_escape(self): self.assertEqual(uppercase_escape('aä'), 'aä') self.assertEqual(uppercase_escape('\\U0001d550'), '𝕐') @@ -355,5 +360,35 @@ class TestUtil(unittest.TestCase): on = js_to_json('{"abc": true}') self.assertEqual(json.loads(on), {'abc': True}) + def test_clean_html(self): + self.assertEqual(clean_html('a:\nb'), 'a: b') + self.assertEqual(clean_html('a:\n "b"'), 'a: "b"') + + def test_intlist_to_bytes(self): + self.assertEqual( + intlist_to_bytes([0, 1, 127, 128, 255]), + b'\x00\x01\x7f\x80\xff') + + def test_args_to_str(self): + self.assertEqual( + args_to_str(['foo', 'ba/r', '-baz', '2 be', '']), + 'foo ba/r -baz \'2 be\' \'\'' + ) + + def test_parse_filesize(self): + self.assertEqual(parse_filesize(None), None) + self.assertEqual(parse_filesize(''), None) + self.assertEqual(parse_filesize('91 B'), 91) + self.assertEqual(parse_filesize('foobar'), None) + self.assertEqual(parse_filesize('2 MiB'), 2097152) + self.assertEqual(parse_filesize('5 GB'), 5000000000) + self.assertEqual(parse_filesize('1.2Tb'), 1200000000000) + self.assertEqual(parse_filesize('1,24 KB'), 1240) + + def test_version_tuple(self): + self.assertEqual(version_tuple('1'), (1,)) + self.assertEqual(version_tuple('10.23.344'), (10, 23, 344)) + self.assertEqual(version_tuple('10.1-6'), (10, 1, 6)) # avconv style + if __name__ == '__main__': unittest.main() diff --git a/test/test_write_annotations.py b/test/test_write_annotations.py index eac53b285..780636c77 100644 --- a/test/test_write_annotations.py +++ b/test/test_write_annotations.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # coding: utf-8 +from __future__ import unicode_literals # Allow direct execution import os @@ -31,19 +32,18 @@ params = get_params({ }) - TEST_ID = 'gr51aVj-mLg' ANNOTATIONS_FILE = TEST_ID + '.flv.annotations.xml' EXPECTED_ANNOTATIONS = ['Speech bubble', 'Note', 'Title', 'Spotlight', 'Label'] + class TestAnnotations(unittest.TestCase): def setUp(self): # Clear old files self.tearDown() - def test_info_json(self): - expected = list(EXPECTED_ANNOTATIONS) #Two annotations could have the same text. + expected = list(EXPECTED_ANNOTATIONS) # Two annotations could have the same text. ie = youtube_dl.extractor.YoutubeIE() ydl = YoutubeDL(params) ydl.add_info_extractor(ie) @@ -51,7 +51,7 @@ class TestAnnotations(unittest.TestCase): self.assertTrue(os.path.exists(ANNOTATIONS_FILE)) annoxml = None with io.open(ANNOTATIONS_FILE, 'r', encoding='utf-8') as annof: - annoxml = xml.etree.ElementTree.parse(annof) + annoxml = xml.etree.ElementTree.parse(annof) self.assertTrue(annoxml is not None, 'Failed to parse annotations XML') root = annoxml.getroot() self.assertEqual(root.tag, 'document') @@ -59,18 +59,17 @@ class TestAnnotations(unittest.TestCase): self.assertEqual(annotationsTag.tag, 'annotations') annotations = annotationsTag.findall('annotation') - #Not all the annotations have TEXT children and the annotations are returned unsorted. + # Not all the annotations have TEXT children and the annotations are returned unsorted. for a in annotations: - self.assertEqual(a.tag, 'annotation') - if a.get('type') == 'text': - textTag = a.find('TEXT') - text = textTag.text - self.assertTrue(text in expected) #assertIn only added in python 2.7 - #remove the first occurance, there could be more than one annotation with the same text - expected.remove(text) - #We should have seen (and removed) all the expected annotation texts. + self.assertEqual(a.tag, 'annotation') + if a.get('type') == 'text': + textTag = a.find('TEXT') + text = textTag.text + self.assertTrue(text in expected) # assertIn only added in python 2.7 + # remove the first occurance, there could be more than one annotation with the same text + expected.remove(text) + # We should have seen (and removed) all the expected annotation texts. self.assertEqual(len(expected), 0, 'Not all expected annotations were found.') - def tearDown(self): try_rm(ANNOTATIONS_FILE) diff --git a/test/test_write_info_json.py b/test/test_write_info_json.py index 90426a559..0396ef262 100644 --- a/test/test_write_info_json.py +++ b/test/test_write_info_json.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # coding: utf-8 +from __future__ import unicode_literals # Allow direct execution import os @@ -32,7 +33,7 @@ params = get_params({ TEST_ID = 'BaW_jenozKc' INFO_JSON_FILE = TEST_ID + '.info.json' DESCRIPTION_FILE = TEST_ID + '.mp4.description' -EXPECTED_DESCRIPTION = u'''test chars: "'/\ä↭𝕐 +EXPECTED_DESCRIPTION = '''test chars: "'/\ä↭𝕐 test URL: https://github.com/rg3/youtube-dl/issues/1892 This is a test video for youtube-dl. @@ -53,11 +54,11 @@ class TestInfoJSON(unittest.TestCase): self.assertTrue(os.path.exists(INFO_JSON_FILE)) with io.open(INFO_JSON_FILE, 'r', encoding='utf-8') as jsonf: jd = json.load(jsonf) - self.assertEqual(jd['upload_date'], u'20121002') + self.assertEqual(jd['upload_date'], '20121002') self.assertEqual(jd['description'], EXPECTED_DESCRIPTION) self.assertEqual(jd['id'], TEST_ID) self.assertEqual(jd['extractor'], 'youtube') - self.assertEqual(jd['title'], u'''youtube-dl test video "'/\ä↭𝕐''') + self.assertEqual(jd['title'], '''youtube-dl test video "'/\ä↭𝕐''') self.assertEqual(jd['uploader'], 'Philipp Hagemeister') self.assertTrue(os.path.exists(DESCRIPTION_FILE)) diff --git a/test/test_youtube_lists.py b/test/test_youtube_lists.py index 410f9edc2..c889b6f15 100644 --- a/test/test_youtube_lists.py +++ b/test/test_youtube_lists.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import unicode_literals # Allow direct execution import os @@ -12,10 +13,6 @@ from test.helper import FakeYDL from youtube_dl.extractor import ( YoutubePlaylistIE, YoutubeIE, - YoutubeChannelIE, - YoutubeShowIE, - YoutubeTopListIE, - YoutubeSearchURLIE, ) @@ -31,7 +28,7 @@ class TestYoutubeLists(unittest.TestCase): result = ie.extract('https://www.youtube.com/watch?v=FXxLjLQi3Fg&list=PLwiyx1dc3P2JR9N8gQaQN_BCvlSlap7re') self.assertEqual(result['_type'], 'url') self.assertEqual(YoutubeIE().extract_id(result['url']), 'FXxLjLQi3Fg') - + def test_youtube_course(self): dl = FakeYDL() ie = YoutubePlaylistIE(dl) diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py index df2cb09f2..13d228cd8 100644 --- a/test/test_youtube_signature.py +++ b/test/test_youtube_signature.py @@ -14,7 +14,7 @@ import re import string from youtube_dl.extractor import YoutubeIE -from youtube_dl.utils import compat_str, compat_urlretrieve +from youtube_dl.compat import compat_str, compat_urlretrieve _TESTS = [ ( |