diff --git a/test/js2tests/array_access.py b/test/js2tests/array_access.py index 3c933c916..7f0a4e61c 100644 --- a/test/js2tests/array_access.py +++ b/test/js2tests/array_access.py @@ -4,75 +4,79 @@ from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS tests = [ - {'code': 'var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x;', - 'asserts': [{'value': [5, 2, 7]}], - 'ast': [(Token.VAR, - zip(['x'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ARRAY, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 1), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 2), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 3), None, None)]), None) - ]), None, None), - ]), - None) - ]) - ), - (Token.EXPR, [ - (Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'x'), - None, - (Token.ELEM, - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), - None) + {'code': 'function f() { var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x; }', + 'asserts': [{'value': [5, 2, 7], 'call': ('f',)}], + 'ast': [ + (Token.FUNC, 'f', [], [ + (Token.VAR, + zip(['x'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ARRAY, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 1), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 2), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 3), None, None)]), None) + ]), None, None), ]), - None)) - ]), - (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 4), None, None)]), None) + None) + ]) + ), + (Token.EXPR, [ + (Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'x'), + None, + (Token.ELEM, + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), + None) + ]), + None)) + ]), + (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 4), None, None)]), None) + ) + ]), + (Token.EXPR, [ + (Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), + None, + (Token.ELEM, (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), + None) + ]), None)) + ]), + (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 5), None, None)]), None)) + ]), + (Token.EXPR, [ + (Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), + None, + (Token.ELEM, (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), + None) + ]), None)) + ]), + (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 7), None, None)]), None)) + ]), + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), None) + ]) ) - ]), - (Token.EXPR, [ - (Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), - None, - (Token.ELEM, (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), - None) - ]), None)) - ]), - (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 5), None, None)]), None)) - ]), - (Token.EXPR, [ - (Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), - None, - (Token.ELEM, (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), - None) - ]), None)) - ]), - (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 7), None, None)]), None)) - ]), - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), None) - ]) - )] + ]) + ] } ] diff --git a/test/js2tests/assignments.py b/test/js2tests/assignments.py index 13783425a..ef9ccf8d0 100644 --- a/test/js2tests/assignments.py +++ b/test/js2tests/assignments.py @@ -5,40 +5,42 @@ from youtube_dl.jsinterp2.tstream import _OPERATORS, _ASSIGN_OPERATORS tests = [ { - 'code': 'var x = 20; x = 30 + 1; return x;', - 'asserts': [{'value': 31}], + 'code': 'function f() { var x = 20; x = 30 + 1; return x; }', + 'asserts': [{'value': 31, 'call': ('f',)}], 'ast': [ - (Token.VAR, zip( - ['x'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 20), None, None)]), - None)] - )), - (Token.EXPR, [ - (Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 30), None, None), - (Token.MEMBER, (Token.INT, 1), None, None), - (Token.OP, _OPERATORS['+'][1])]), - None)) - ]), + (Token.FUNC, 'f', [], [ + (Token.VAR, zip( + ['x'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 20), None, None)]), + None)] + )), + (Token.EXPR, [ + (Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 30), None, None), + (Token.MEMBER, (Token.INT, 1), None, None), + (Token.OP, _OPERATORS['+'][1])]), + None)) + ]), - (Token.RETURN, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'x'), None, None) - ]), None) - ])) + (Token.RETURN, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'x'), None, None) + ]), None) + ])) + ]) ] }, { - 'code': 'var x = 20; x += 30 + 1; return x;', - 'asserts': [{'value': 51}], + 'code': 'function f() { var x = 20; x += 30 + 1; return x;}', + 'asserts': [{'value': 51, 'call': ('f',)}], }, { - 'code': 'var x = 20; x -= 30 + 1; return x;', - 'asserts': [{'value': -11}], + 'code': 'function f() { var x = 20; x -= 30 + 1; return x;}', + 'asserts': [{'value': -11, 'call': ('f',)}], } ] diff --git a/test/js2tests/basic.py b/test/js2tests/basic.py index 97baf352b..888a62a37 100644 --- a/test/js2tests/basic.py +++ b/test/js2tests/basic.py @@ -4,23 +4,29 @@ from youtube_dl.jsinterp2.jsgrammar import Token tests = [ { - 'code': 'return 42;', - 'asserts': [{'value': 42}], - 'ast': [(Token.RETURN, + 'code': 'function f() { return 42; }', + 'asserts': [{'value': 42, 'call': ('f',)}], + 'ast': [ + (Token.FUNC, 'f', [], [ + (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 42), None, None)]), None) - ]))] + ])) + ]) + ] }, { - 'code': ';', - 'asserts': [{'value': None}], - 'ast': [None] + 'code': 'function x() {;}', + 'asserts': [{'value': None, 'call': ('x',)}], + 'ast': [(Token.FUNC, 'x', [], [None])] }, { - 'code': 'var x5 = function(){return 42;}', + # FIXME: function expresiion needs to be implemented + 'exclude': ('jsinterp2',), + 'code': 'var x5 = function x5(){return 42;}', 'asserts': [{'value': 42, 'call': ('x5',)}] } ] diff --git a/test/js2tests/branch.py b/test/js2tests/branch.py index effa52740..535159f84 100644 --- a/test/js2tests/branch.py +++ b/test/js2tests/branch.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _RELATIONS -skip = {'interpret': 'Interpreting if statement not yet implemented'} +skip = { + 'jsinterp': 'Branching is not supported', + 'interpret': 'Interpreting if statement not yet implemented' +} tests = [ { diff --git a/test/js2tests/calc.py b/test/js2tests/calc.py index 2289002d2..54aed2db2 100644 --- a/test/js2tests/calc.py +++ b/test/js2tests/calc.py @@ -4,10 +4,11 @@ from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _OPERATORS tests = [ - {'code': 'return 2*a+1;', - 'globals': {'a': 3}, - 'asserts': [{'value': 7}], - 'ast': [(Token.RETURN, + {'code': 'function x4(a){return 2*a+1;}', + 'asserts': [{'value': 7, 'call': ('x4', 3)}], + 'ast': [ + (Token.FUNC, 'x4', ['a'], [ + (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, @@ -21,6 +22,8 @@ tests = [ ]), None) ]) - )] + ) + ]) + ] } ] diff --git a/test/js2tests/call.py b/test/js2tests/call.py index 20078626b..9ce9c34fa 100644 --- a/test/js2tests/call.py +++ b/test/js2tests/call.py @@ -9,9 +9,8 @@ tests = [ function x() { return 2; } function y(a) { return x() + a; } function z() { return y(3); } - z(); ''', - 'asserts': [{'value': 5}], + 'asserts': [{'value': 5, 'call': ('z',)}], 'ast': [ (Token.FUNC, 'x', [], [ (Token.RETURN, (Token.EXPR, [ @@ -37,17 +36,13 @@ tests = [ ]), None) ]) ) - ]), - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'z'), None, (Token.CALL, [], None)) - ]), None) ]) ] }, { - 'code': 'function x(a) { return a.split(""); }', # FIXME built-in functions not yet implemented - # 'asserts': [{'value': ["a", "b", "c"], 'call': ('x',"abc")}], + 'exclude': ('jsinterp2',), + 'code': 'function x(a) { return a.split(""); }', + 'asserts': [{'value': ["a", "b", "c"], 'call': ('x',"abc")}], 'ast': [ (Token.FUNC, 'x', ['a'], [ (Token.RETURN, (Token.EXPR, [ @@ -63,13 +58,13 @@ tests = [ ]) ] }, { + 'exclude': ('jsinterp',), 'code': ''' function a(x) { return x; } function b(x) { return x + 1; } function c() { return [a, b][0](0); } - c(); ''', - 'asserts': [{'value': 0}], + 'asserts': [{'value': 0, 'call': ('c',)}], 'ast': [ (Token.FUNC, 'a', ['x'], [ (Token.RETURN, (Token.EXPR, [ @@ -100,11 +95,6 @@ tests = [ ], None))) ]), None) ])) - ]), - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'c'), None, (Token.CALL, [], None)) - ]), None) ]) ] } diff --git a/test/js2tests/comments.py b/test/js2tests/comments.py index 9c81638ad..67fe709f1 100644 --- a/test/js2tests/comments.py +++ b/test/js2tests/comments.py @@ -3,69 +3,80 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _OPERATORS +skip = {'jsinterp': 'Not yet fully implemented'} + tests = [ { 'code': ''' - var x = /* 1 + */ 2; - var y = /* 30 - * 40 */ 50; - return x + y;''', - 'asserts': [{'value': 52}], + function x() { + var x = /* 1 + */ 2; + var y = /* 30 + * 40 */ 50; + return x + y; + } + ''', + 'asserts': [{'value': 52, 'call': ('x',)}], 'ast': [ - (Token.VAR, zip( - ['x'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), - None)] - )), - (Token.VAR, zip( - ['y'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 50), None, None)]), - None)] - )), - (Token.RETURN, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'x'), None, None), - (Token.MEMBER, (Token.ID, 'y'), None, None), - (Token.OP, _OPERATORS['+'][1]) - ]), None) - ])) + (Token.FUNC, 'x', [], [ + (Token.VAR, zip( + ['x'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), + None)] + )), + (Token.VAR, zip( + ['y'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 50), None, None)]), + None)] + )), + (Token.RETURN, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'x'), None, None), + (Token.MEMBER, (Token.ID, 'y'), None, None), + (Token.OP, _OPERATORS['+'][1]) + ]), None) + ])) + ]) ] }, { 'code': ''' - var x = "/*"; - var y = 1 /* comment */ + 2; - return y; + function f() { + var x = "/*"; + var y = 1 /* comment */ + 2; + return y; + } ''', - 'asserts': [{'value': 3}], + 'asserts': [{'value': 3, 'call': ('f',)}], 'ast': [ - (Token.VAR, zip( - ['x'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.STR, '/*'), None, None)]), - None)] - )), - (Token.VAR, zip( - ['y'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 1), None, None), - (Token.MEMBER, (Token.INT, 2), None, None), - (Token.OP, _OPERATORS['+'][1]) - ]), - None)] - )), - (Token.RETURN, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'y'), None, None)]), - None) - ])) + (Token.FUNC, 'f', [], [ + (Token.VAR, zip( + ['x'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.STR, '/*'), None, None)]), + None)] + )), + (Token.VAR, zip( + ['y'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 1), None, None), + (Token.MEMBER, (Token.INT, 2), None, None), + (Token.OP, _OPERATORS['+'][1]) + ]), + None)] + )), + (Token.RETURN, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'y'), None, None)]), + None) + ])) + ]) ] } ] diff --git a/test/js2tests/debug.py b/test/js2tests/debug.py index c2697db45..f233176aa 100644 --- a/test/js2tests/debug.py +++ b/test/js2tests/debug.py @@ -2,8 +2,11 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token -skip = {'interpret': 'Interpreting debugger statement not yet implemented', - 'parse': 'Test not yet implemented: missing code and ast'} +skip = { + 'jsinterp': 'Debugger statement is not supported', + 'interpret': 'Interpreting debugger statement not yet implemented', + 'parse': 'Test not yet implemented: missing code and ast' +} tests = [ { diff --git a/test/js2tests/do_loop.py b/test/js2tests/do_loop.py index dadf6b393..30887e081 100644 --- a/test/js2tests/do_loop.py +++ b/test/js2tests/do_loop.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS -skip = {'interpret': 'Interpreting do loop not yet implemented'} +skip = { + 'jsinterp': 'Do loop is not supportted', + 'interpret': 'Interpreting do loop not yet implemented' +} tests = [ { @@ -16,7 +19,7 @@ tests = [ return i; } ''', - 'asserts': [{'value': 5, 'call': 5}], + 'asserts': [{'value': 5, 'call': ('f', 5)}], 'ast': [ (Token.FUNC, 'f', ['x'], [ (Token.EXPR, [ diff --git a/test/js2tests/empty_return.py b/test/js2tests/empty_return.py index 14c84cbe9..49d2c161f 100644 --- a/test/js2tests/empty_return.py +++ b/test/js2tests/empty_return.py @@ -3,21 +3,24 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token tests = [ - {'code': 'return; y()', - 'asserts': [{'value': None}], + {'code': 'function f() { return; y(); }', + 'asserts': [{'value': None, 'call': ('f',)}], 'ast': [ - (Token.RETURN, None), - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, - (Token.ID, 'y'), - None, - (Token.CALL, [], None) - ) - ]), - None) - ])] + (Token.FUNC, 'f', [], [ + (Token.RETURN, None), + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, + (Token.ID, 'y'), + None, + (Token.CALL, [], None) + ) + ]), + None) + ]) + ]) + ] } ] diff --git a/test/js2tests/for_empty.py b/test/js2tests/for_empty.py index 704e99592..4ef5ba1ee 100644 --- a/test/js2tests/for_empty.py +++ b/test/js2tests/for_empty.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS -skip = {'interpret': 'Interpreting for empty loop not yet implemented'} +skip = { + 'jsinterp': 'For loop is not supported', + 'interpret': 'Interpreting for empty loop not yet implemented' +} tests = [ { diff --git a/test/js2tests/for_in.py b/test/js2tests/for_in.py index 2a99e470c..12ad7f672 100644 --- a/test/js2tests/for_in.py +++ b/test/js2tests/for_in.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS -skip = {'interpret': 'Interpreting for in loop not yet implemented'} +skip = { + 'jsinterp': 'For in loop is not supported', + 'interpret': 'Interpreting for in loop not yet implemented' +} tests = [ { diff --git a/test/js2tests/for_loop.py b/test/js2tests/for_loop.py index 99b64148a..6b4d2a876 100644 --- a/test/js2tests/for_loop.py +++ b/test/js2tests/for_loop.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS -skip = {'interpret': 'Interpreting for loop not yet implemented'} +skip = { + 'jsinterp': 'For loop is not supported', + 'interpret': 'Interpreting for loop not yet implemented' +} tests = [ { diff --git a/test/js2tests/func_expr.py b/test/js2tests/func_expr.py index d88d8e823..2071fdac6 100644 --- a/test/js2tests/func_expr.py +++ b/test/js2tests/func_expr.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS -skip = {'interpret': 'Interpreting function expression not yet implemented'} +skip = { + 'jsinterp': 'not supported', + 'interpret': 'Interpreting function expression not yet implemented' +} tests = [ { diff --git a/test/js2tests/getfield.py b/test/js2tests/getfield.py index 86fb79699..c404a0371 100644 --- a/test/js2tests/getfield.py +++ b/test/js2tests/getfield.py @@ -2,24 +2,28 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token +skip = {'jsinterp': 'Field access is not supported'} + tests = [ { - 'code': 'return a.var;', - 'asserts': [{'value': 3}], + 'code': 'function f() { return a.var; }', + 'asserts': [{'value': 3, 'call': ('f',)}], 'globals': {'a': {'var': 3}}, 'ast': [ - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, - (Token.ID, 'a'), - None, - (Token.FIELD, 'var', None)), - ]), - None) - ])) + (Token.FUNC, 'f', [], [ + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, + (Token.ID, 'a'), + None, + (Token.FIELD, 'var', None)), + ]), + None) + ])) + ]) ] } ] diff --git a/test/js2tests/label.py b/test/js2tests/label.py index 011ec9ed6..61fea0720 100644 --- a/test/js2tests/label.py +++ b/test/js2tests/label.py @@ -2,8 +2,11 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token -skip = {'interpret': 'Interpreting label not yet implemented', - 'parse': 'Test not yet implemented: missing code and ast'} +skip = { + 'jsinterp': 'Label statement is not supported', + 'interpret': 'Interpreting label not yet implemented', + 'parse': 'Test not yet implemented: missing code and ast' +} tests = [ { diff --git a/test/js2tests/morespace.py b/test/js2tests/morespace.py index 850a27b73..83c5e6845 100644 --- a/test/js2tests/morespace.py +++ b/test/js2tests/morespace.py @@ -5,27 +5,30 @@ from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS tests = [ { - 'code': 'x = 2 ; return x;', - 'asserts': [{'value': 2}], + 'code': 'function f() { x = 2 ; return x; }', + 'asserts': [{'value': 2, 'call': ('f',)}], 'ast': [ - (Token.EXPR, - [(Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), - None) - )] - ), - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), - None) - ]) - )] + (Token.FUNC, 'f', [], [ + (Token.EXPR, + [(Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), + None) + )] + ), + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), + None) + ]) + ) + ]) + ] }, { 'code': 'function x (a) { return 2 * a + 1 ; }', 'asserts': [{'value': 7, 'call': ('x', 3)}] diff --git a/test/js2tests/operators.py b/test/js2tests/operators.py index f54c8a5f5..29e973389 100644 --- a/test/js2tests/operators.py +++ b/test/js2tests/operators.py @@ -5,41 +5,49 @@ from youtube_dl.jsinterp2.tstream import _OPERATORS tests = [ { - 'code': 'return 1 << 5;', - 'asserts': [{'value': 32}], + 'code': 'function f() { return 1 << 5; }', + 'asserts': [{'value': 32, 'call': ('f',)}], 'ast': [ - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 1), None, None), - (Token.MEMBER, (Token.INT, 5), None, None), - (Token.OP, _OPERATORS['<<'][1]) - ]), None) - ]))] - }, { - 'code': 'return 19 & 21;', - 'asserts': [{'value': 17}], - 'ast': [ - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 19), None, None), - (Token.MEMBER, (Token.INT, 21), None, None), - (Token.OP, _OPERATORS['&'][1]) - ]), None) - ])) + (Token.FUNC, 'f', [], [ + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 1), None, None), + (Token.MEMBER, (Token.INT, 5), None, None), + (Token.OP, _OPERATORS['<<'][1]) + ]), None) + ])) + ]) ] }, { - 'code': 'return 11 >> 2;', - 'asserts': [{'value': 2}], + 'code': 'function f() { return 19 & 21;}', + 'asserts': [{'value': 17, 'call': ('f',)}], 'ast': [ - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 11), None, None), - (Token.MEMBER, (Token.INT, 2), None, None), - (Token.OP, _OPERATORS['>>'][1]) - ]), None) - ]))] + (Token.FUNC, 'f', [], [ + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 19), None, None), + (Token.MEMBER, (Token.INT, 21), None, None), + (Token.OP, _OPERATORS['&'][1]) + ]), None) + ])) + ]) + ] + }, { + 'code': 'function f() { return 11 >> 2;}', + 'asserts': [{'value': 2, 'call': ('f',)}], + 'ast': [ + (Token.FUNC, 'f', [], [ + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 11), None, None), + (Token.MEMBER, (Token.INT, 2), None, None), + (Token.OP, _OPERATORS['>>'][1]) + ]), None) + ])) + ]) + ] } ] diff --git a/test/js2tests/parens.py b/test/js2tests/parens.py index 2f59f661c..38cd094bd 100644 --- a/test/js2tests/parens.py +++ b/test/js2tests/parens.py @@ -5,71 +5,75 @@ from youtube_dl.jsinterp2.tstream import _OPERATORS tests = [ { - 'code': 'return (1 + 2) * 3;', - 'asserts': [{'value': 9}], + 'code': 'function f() { return (1 + 2) * 3; }', + 'asserts': [{'value': 9, 'call': ('f',)}], 'ast': [ - (Token.RETURN, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 1), None, None), - (Token.MEMBER, (Token.INT, 2), None, None), - (Token.OP, _OPERATORS['+'][1]) - ]), None) - ]), None, None), - (Token.MEMBER, (Token.INT, 3), None, None), - (Token.OP, _OPERATORS['*'][1]) - ]), None) - ]))] + (Token.FUNC, 'f', [], [ + (Token.RETURN, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 1), None, None), + (Token.MEMBER, (Token.INT, 2), None, None), + (Token.OP, _OPERATORS['+'][1]) + ]), None) + ]), None, None), + (Token.MEMBER, (Token.INT, 3), None, None), + (Token.OP, _OPERATORS['*'][1]) + ]), None) + ])) + ]) + ] }, { - 'code': 'return (1) + (2) * ((( (( (((((3)))))) )) ));', - 'asserts': [{'value': 7}], + 'code': 'function f() { return (1) + (2) * ((( (( (((((3)))))) )) ));}', + 'asserts': [{'value': 7, 'call': ('f',)}], 'ast': [ + (Token.FUNC, 'f', [], [ + (Token.RETURN, (Token.EXPR, [ + (Token.ASSIGN, None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 1), None, None) + ]), None)]), None, None), - (Token.RETURN, (Token.EXPR, [ - (Token.ASSIGN, None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 1), None, None) - ]), None)]), None, None), + (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 2), None, None) + ]), None)]), None, None), - (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 2), None, None) - ]), None)]), None, None), - - (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, - (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 3), None, None) - ]), None)]), None, None) + (Token.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, + (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 3), None, None) + ]), None)]), None, None) + ]), None)]), None, None) ]), None)]), None, None) ]), None)]), None, None) ]), None)]), None, None) + ]), None)]), None, None) - ]), None)]), None, None) + ]), None)]), None, None) - ]), None)]), None, None) - ]), None)]), None, None) - ]), None)]), None, None), + ]), None)]), None, None), - (Token.OP, _OPERATORS['*'][1]), - (Token.OP, _OPERATORS['+'][1]) - ]), None) - ])) + (Token.OP, _OPERATORS['*'][1]), + (Token.OP, _OPERATORS['+'][1]) + ]), None) + ])) + ]) ] } ] diff --git a/test/js2tests/precedence.py b/test/js2tests/precedence.py index 094fc201c..e80142597 100644 --- a/test/js2tests/precedence.py +++ b/test/js2tests/precedence.py @@ -8,75 +8,79 @@ skip = {'interpret': 'Interpreting built-in fields not yet implemented'} tests = [ { 'code': ''' - var a = [10, 20, 30, 40, 50]; - var b = 6; - a[0]=a[b%a.length]; - return a; + function f() { + var a = [10, 20, 30, 40, 50]; + var b = 6; + a[0]=a[b%a.length]; + return a; + } ''', - 'asserts': [{'value': [20, 20, 30, 40, 50]}], + 'asserts': [{'value': [20, 20, 30, 40, 50], 'call': ('f',)}], 'ast': [ - (Token.VAR, - zip(['a'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ARRAY, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 10), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 20), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 30), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 40), None, None)]), None), - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.INT, 50), None, None)]), None) - ]), None, None), - ]), - None) - ]) - ), - (Token.VAR, - zip(['b'], - [(Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 6), None, None)]), None)] - ) - ), - (Token.EXPR, [ - (Token.ASSIGN, - _ASSIGN_OPERATORS['='][1], - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'a'), - None, - (Token.ELEM, - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), - None) - ]), - None)) - ]), - (Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'a'), + (Token.FUNC, 'f', [], [ + (Token.VAR, + zip(['a'], + [(Token.ASSIGN, None, - (Token.ELEM, (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, 'b'), None, None), - (Token.MEMBER, (Token.ID, 'a'), None, (Token.FIELD, 'length', None)), - (Token.OP, _OPERATORS['%'][1]) - ]), None)]), - None)) - ]), - None) + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ARRAY, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 10), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 20), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 30), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 40), None, None)]), None), + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.INT, 50), None, None)]), None) + ]), None, None), + ]), + None) + ]) + ), + (Token.VAR, + zip(['b'], + [(Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 6), None, None)]), None)] + ) + ), + (Token.EXPR, [ + (Token.ASSIGN, + _ASSIGN_OPERATORS['='][1], + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'a'), + None, + (Token.ELEM, + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), + None) + ]), + None)) + ]), + (Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'a'), + None, + (Token.ELEM, (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, 'b'), None, None), + (Token.MEMBER, (Token.ID, 'a'), None, (Token.FIELD, 'length', None)), + (Token.OP, _OPERATORS['%'][1]) + ]), None)]), + None)) + ]), + None) + ) + ]), + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'a'), None, None)]), None) + ]) ) - ]), - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'a'), None, None)]), None) - ]) - ) + ]) ] } ] diff --git a/test/js2tests/strange_chars.py b/test/js2tests/strange_chars.py index 1ad397782..c4a28c772 100644 --- a/test/js2tests/strange_chars.py +++ b/test/js2tests/strange_chars.py @@ -5,29 +5,31 @@ from youtube_dl.jsinterp2.tstream import _OPERATORS tests = [ { - 'code': 'var $_axY2 = $_xY1 + 1; return $_axY2;', - 'globals': {'$_xY1': 20}, - 'asserts': [{'value': 21}], + 'code': 'function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; }', + 'asserts': [{'value': 21, 'call': ('$_xY1', 20)}], 'ast': [ - (Token.VAR, - zip(['$_axY2'], - [(Token.ASSIGN, - None, - (Token.OPEXPR, [ - (Token.MEMBER, (Token.ID, '$_xY1'), None, None), - (Token.MEMBER, (Token.INT, 1), None, None), - (Token.OP, _OPERATORS['+'][1]) - ]), - None) - ]) - ), - (Token.RETURN, - (Token.EXPR, [ - (Token.ASSIGN, - None, - (Token.OPEXPR, [(Token.MEMBER, (Token.ID, '$_axY2'), None, None)]), - None)] - ) - )] + (Token.FUNC, '$_xY1', ['$_axY1'], [ + (Token.VAR, + zip(['$_axY2'], + [(Token.ASSIGN, + None, + (Token.OPEXPR, [ + (Token.MEMBER, (Token.ID, '$_axY1'), None, None), + (Token.MEMBER, (Token.INT, 1), None, None), + (Token.OP, _OPERATORS['+'][1]) + ]), + None) + ]) + ), + (Token.RETURN, + (Token.EXPR, [ + (Token.ASSIGN, + None, + (Token.OPEXPR, [(Token.MEMBER, (Token.ID, '$_axY2'), None, None)]), + None)] + ) + ) + ]) + ] } ] diff --git a/test/js2tests/stringprototype.py b/test/js2tests/stringprototype.py index 531fcc211..756be2563 100644 --- a/test/js2tests/stringprototype.py +++ b/test/js2tests/stringprototype.py @@ -1,12 +1,16 @@ from __future__ import unicode_literals -skip = {'parse': 'Ast not yet implemented'} +skip = { + 'jsinterp': 'String literals are not supported', + 'parse': 'Ast not yet implemented' +} tests = [ { - 'code': '"hello".split("");', + 'exclude': ('jsinterp2',), + 'code': 'function f() {return "hello".split(""); }', 'globals': {}, - 'asserts': [{'value': ['h', 'e', 'l', 'l', 'o']}], + 'asserts': [{'value': ['h', 'e', 'l', 'l', 'o'], 'call': ('f',)}], 'ast': [] } ] diff --git a/test/js2tests/switch.py b/test/js2tests/switch.py index 7d38e5261..d858e255f 100644 --- a/test/js2tests/switch.py +++ b/test/js2tests/switch.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS -skip = {'interpret': 'Interpreting switch statement not yet implemented'} +skip = { + 'jsinterp': 'Switch statement is not supported', + 'interpret': 'Interpreting switch statement not yet implemented' +} tests = [ { diff --git a/test/js2tests/try_statement.py b/test/js2tests/try_statement.py index b3596a7c6..eb7882517 100644 --- a/test/js2tests/try_statement.py +++ b/test/js2tests/try_statement.py @@ -2,8 +2,11 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token -skip = {'interpret': 'Interpreting try statement not yet implemented', - 'parse': 'Test not yet implemented: missing code and ast'} +skip = { + 'jsinterp': 'Try statement is not supported', + 'interpret': 'Interpreting try statement not yet implemented', + 'parse': 'Test not yet implemented: missing code and ast' +} tests = [ { diff --git a/test/js2tests/unary.py b/test/js2tests/unary.py index a5d4ce3eb..964c64055 100644 --- a/test/js2tests/unary.py +++ b/test/js2tests/unary.py @@ -1,11 +1,14 @@ from __future__ import unicode_literals -skip = {'parse': True} +skip = { + 'jsinterp': 'Unary opertations are not supported', + 'parse': True +} tests = [ { - 'code': 'return -5 + +3;', - 'asserts': [{'value': -2}] + 'code': 'function f() { return -5 + +3; }', + 'asserts': [{'value': -2, 'call': ('f',)}] }, { 'code': 'function f() {return -5 + ++a;}', 'globals': {'a': -3}, diff --git a/test/js2tests/unshift.py b/test/js2tests/unshift.py index 13f4f07fc..b2a4cd34e 100644 --- a/test/js2tests/unshift.py +++ b/test/js2tests/unshift.py @@ -1,5 +1,11 @@ from __future__ import unicode_literals +skip = { + 'jsinterp': 'Test not implemented', + 'parse': 'Test not implemented', + 'interpert': 'Test not implemented' +} + tests = [ { 'code': ''' diff --git a/test/js2tests/while_loop.py b/test/js2tests/while_loop.py index 0ce17a18e..f215cd673 100644 --- a/test/js2tests/while_loop.py +++ b/test/js2tests/while_loop.py @@ -3,7 +3,10 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS -skip = {'interpret': 'Interpreting while loop not yet implemented'} +skip = { + 'jsinterp': 'While loop is not supported', + 'interpret': 'Interpreting while loop not yet implemented' +} tests = [ { diff --git a/test/js2tests/with_statement.py b/test/js2tests/with_statement.py index 5336b4a76..c203e7ce5 100644 --- a/test/js2tests/with_statement.py +++ b/test/js2tests/with_statement.py @@ -2,8 +2,11 @@ from __future__ import unicode_literals from youtube_dl.jsinterp2.jsgrammar import Token -skip = {'interpret': 'Interpreting with statement not yet implemented', - 'parse': 'Test not yet implemented: missing code and ast'} +skip = { + 'jsinterp': 'With statement is not supported', + 'interpret': 'Interpreting with statement not yet implemented', + 'parse': 'Test not yet implemented: missing code and ast' +} tests = [ { diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py index 078075065..282c4a90c 100644 --- a/test/test_jsinterp.py +++ b/test/test_jsinterp.py @@ -17,7 +17,7 @@ else: import unittest sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from youtube_dl.jsinterp2 import JSInterpreter +from youtube_dl.jsinterp import JSInterpreter from .js2tests import gettestcases defs = gettestcases() @@ -33,7 +33,10 @@ class TestJSInterpreter(unittest.TestCase): def generator(test_case, name): def test_template(self): for test in test_case['subtests']: - if 'code' not in test: + excluded = test.get('exclude') + if excluded is not None and 'jsinterp' in excluded: + log_reason = 'jsinterp does not support this subtest:\n%s' % test['code'] + elif 'code' not in test: log_reason = 'No code in subtest, skipping' elif 'asserts' not in test: log_reason = 'No assertion in subtest, skipping' @@ -41,13 +44,20 @@ def generator(test_case, name): log_reason = None if log_reason is None: - jsi = JSInterpreter(test['code'], variables=test.get('globals')) - for a in test['asserts']: - if 'value' in a: - if 'call' in a: - self.assertEqual(jsi.call_function(*a['call']), a['value']) - else: - self.assertEqual(jsi.run(), a['value']) + variables = test.get('globals') + code = test['code'] + call = None + + if variables is not None: + code = 'function f(%s){%s}' % ((''.join(variables.keys())), code) + call = ('f',) + tuple(v for v in variables.values()) + + jsi = JSInterpreter(code, objects=variables) + for assertion in test['asserts']: + if 'value' in assertion: + if call is None: + call = assertion['call'] + self.assertEqual(jsi.call_function(*call), assertion['value']) else: log.debug('No value in assertion, skipping') else: @@ -59,7 +69,7 @@ def generator(test_case, name): # And add them to TestJSInterpreter for n, tc in enumerate(defs): - reason = tc['skip'].get('interpret', False) + reason = tc['skip'].get('jsinterp', False) tname = 'test_' + str(tc['name']) i = 1 while hasattr(TestJSInterpreter, tname): diff --git a/test/test_jsinterp2.py b/test/test_jsinterp2.py new file mode 100644 index 000000000..3a2b9d35f --- /dev/null +++ b/test/test_jsinterp2.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +# """ +# see: `js2tests` +# """ + +from __future__ import unicode_literals + +# Allow direct execution +import os +import sys +import logging + +if sys.version_info < (2, 7): + import unittest2 as unittest +else: + import unittest +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from youtube_dl.jsinterp2 import JSInterpreter +from .js2tests import gettestcases + +defs = gettestcases() +# set level to logging.DEBUG to see messages about missing assertions +logging.basicConfig(stream=sys.stderr, level=logging.WARNING) + + +class TestJSInterpreter(unittest.TestCase): + def setUp(self): + self.defs = defs + + +def generator(test_case, name): + def test_template(self): + for test in test_case['subtests']: + excluded = test.get('exclude') + if excluded is not None and 'jsinterp2' in excluded: + log_reason = 'jsinterp does not support this subtest:\n%s' % test['code'] + elif 'code' not in test: + log_reason = 'No code in subtest, skipping' + elif 'asserts' not in test: + log_reason = 'No assertion in subtest, skipping' + else: + log_reason = None + + if log_reason is None: + jsi = JSInterpreter(test['code'], variables=(test.get('globals'))) + jsi.run() + for assertion in test['asserts']: + if 'value' in assertion: + call = assertion['call'] + self.assertEqual(jsi.call_function(*call), assertion['value']) + else: + log.debug('No value in assertion, skipping') + else: + log.debug(log_reason) + + log = logging.getLogger('TestJSInterpreter.%s' % name) + return test_template + + +# And add them to TestJSInterpreter +for n, tc in enumerate(defs): + reason = tc['skip'].get('interpret', False) + tname = 'test_' + str(tc['name']) + i = 1 + while hasattr(TestJSInterpreter, tname): + tname = 'test_%s_%d' % (tc['name'], i) + i += 1 + + if reason is not True: + log_reason = 'Entirely' + elif not any('asserts' in test for test in tc['subtests']): + log_reason = '''There isn't any assertion''' + else: + log_reason = None + + if log_reason is not None: + test_method = generator(tc, tname) + test_method.__name__ = str(tname) + if reason is not False: + test_method.__unittest_skip__ = True + test_method.__unittest_skip_why__ = reason + setattr(TestJSInterpreter, test_method.__name__, test_method) + del test_method + else: + log = logging.getLogger('TestJSInterpreter') + log.debug('Skipping %s:%s' % (tname, log_reason)) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_jsinterp_parse.py b/test/test_jsinterp2_parse.py similarity index 100% rename from test/test_jsinterp_parse.py rename to test/test_jsinterp2_parse.py diff --git a/test/test_jsinterp_orig.py b/test/test_jsinterp_orig.py new file mode 100644 index 000000000..c24b8ca74 --- /dev/null +++ b/test/test_jsinterp_orig.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python + +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.jsinterp import JSInterpreter + + +class TestJSInterpreter(unittest.TestCase): + def test_basic(self): + jsi = JSInterpreter('function x(){;}') + self.assertEqual(jsi.call_function('x'), None) + + jsi = JSInterpreter('function x3(){return 42;}') + self.assertEqual(jsi.call_function('x3'), 42) + + jsi = JSInterpreter('var x5 = function(){return 42;}') + self.assertEqual(jsi.call_function('x5'), 42) + + def test_calc(self): + jsi = JSInterpreter('function x4(a){return 2*a+1;}') + self.assertEqual(jsi.call_function('x4', 3), 7) + + def test_empty_return(self): + jsi = JSInterpreter('function f(){return; y()}') + self.assertEqual(jsi.call_function('f'), None) + + def test_morespace(self): + jsi = JSInterpreter('function x (a) { return 2 * a + 1 ; }') + self.assertEqual(jsi.call_function('x', 3), 7) + + jsi = JSInterpreter('function f () { x = 2 ; return x; }') + self.assertEqual(jsi.call_function('f'), 2) + + def test_strange_chars(self): + jsi = JSInterpreter('function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; }') + self.assertEqual(jsi.call_function('$_xY1', 20), 21) + + def test_operators(self): + jsi = JSInterpreter('function f(){return 1 << 5;}') + self.assertEqual(jsi.call_function('f'), 32) + + jsi = JSInterpreter('function f(){return 19 & 21;}') + self.assertEqual(jsi.call_function('f'), 17) + + jsi = JSInterpreter('function f(){return 11 >> 2;}') + self.assertEqual(jsi.call_function('f'), 2) + + def test_array_access(self): + jsi = JSInterpreter('function f(){var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x;}') + self.assertEqual(jsi.call_function('f'), [5, 2, 7]) + + def test_parens(self): + jsi = JSInterpreter('function f(){return (1) + (2) * ((( (( (((((3)))))) )) ));}') + self.assertEqual(jsi.call_function('f'), 7) + + jsi = JSInterpreter('function f(){return (1 + 2) * 3;}') + self.assertEqual(jsi.call_function('f'), 9) + + def test_assignments(self): + jsi = JSInterpreter('function f(){var x = 20; x = 30 + 1; return x;}') + self.assertEqual(jsi.call_function('f'), 31) + + jsi = JSInterpreter('function f(){var x = 20; x += 30 + 1; return x;}') + self.assertEqual(jsi.call_function('f'), 51) + + jsi = JSInterpreter('function f(){var x = 20; x -= 30 + 1; return x;}') + self.assertEqual(jsi.call_function('f'), -11) + + def test_comments(self): + 'Skipping: Not yet fully implemented' + return + jsi = JSInterpreter(''' + function x() { + var x = /* 1 + */ 2; + var y = /* 30 + * 40 */ 50; + return x + y; + } + ''') + self.assertEqual(jsi.call_function('x'), 52) + + jsi = JSInterpreter(''' + function f() { + var x = "/*"; + var y = 1 /* comment */ + 2; + return y; + } + ''') + self.assertEqual(jsi.call_function('f'), 3) + + def test_precedence(self): + jsi = JSInterpreter(''' + function x() { + var a = [10, 20, 30, 40, 50]; + var b = 6; + a[0]=a[b%a.length]; + return a; + }''') + self.assertEqual(jsi.call_function('x'), [20, 20, 30, 40, 50]) + + def test_call(self): + jsi = JSInterpreter(''' + function x() { return 2; } + function y(a) { return x() + a; } + function z() { return y(3); } + ''') + self.assertEqual(jsi.call_function('z'), 5) + + +if __name__ == '__main__': + unittest.main() diff --git a/youtube_dl/jsinterp2/jsinterp.py b/youtube_dl/jsinterp2/jsinterp.py index 0a30907da..5e9fe39fc 100644 --- a/youtube_dl/jsinterp2/jsinterp.py +++ b/youtube_dl/jsinterp2/jsinterp.py @@ -284,8 +284,8 @@ class JSInterpreter(object): self._context = self._context_stack.pop() def call_function(self, funcname, *args): - f = (self.this[funcname] if funcname in self.this else - self.global_vars[funcname] if funcname in self.global_vars else + f = (self.this[funcname].getvalue() if funcname in self.this else + self.global_vars[funcname].getvalue() if funcname in self.global_vars else self.extract_function(funcname)) return f(*args)