[jsinterp] Test suit update
- Fixes (at least changes) global variable referencing in `jsinterp2` - Adds test suite based testcase for `jsinterp` - Adds per assertion based skip - Renames `test_jsinterp` (hopefully temporally) to `test_jsinterp_orig` - Adds function declaration to testcases (code & ast)
This commit is contained in:
parent
70ac98a924
commit
1f40e3ef63
@ -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)
|
||||
])
|
||||
)]
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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',)}],
|
||||
}
|
||||
]
|
||||
|
@ -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',)}]
|
||||
}
|
||||
]
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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)
|
||||
])
|
||||
)]
|
||||
)
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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)
|
||||
])
|
||||
]
|
||||
}
|
||||
|
@ -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)
|
||||
]))
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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, [
|
||||
|
@ -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)
|
||||
])
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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)
|
||||
]))
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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)}]
|
||||
|
@ -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)
|
||||
]))
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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)
|
||||
]))
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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)
|
||||
])
|
||||
)
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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)]
|
||||
)
|
||||
)
|
||||
])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -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': []
|
||||
}
|
||||
]
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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},
|
||||
|
@ -1,5 +1,11 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
skip = {
|
||||
'jsinterp': 'Test not implemented',
|
||||
'parse': 'Test not implemented',
|
||||
'interpert': 'Test not implemented'
|
||||
}
|
||||
|
||||
tests = [
|
||||
{
|
||||
'code': '''
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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):
|
||||
|
91
test/test_jsinterp2.py
Normal file
91
test/test_jsinterp2.py
Normal file
@ -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()
|
117
test/test_jsinterp_orig.py
Normal file
117
test/test_jsinterp_orig.py
Normal file
@ -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()
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user