[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
|
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{'code': 'var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x;',
|
{'code': 'function f() { var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x; }',
|
||||||
'asserts': [{'value': [5, 2, 7]}],
|
'asserts': [{'value': [5, 2, 7], 'call': ('f',)}],
|
||||||
'ast': [(Token.VAR,
|
'ast': [
|
||||||
zip(['x'],
|
(Token.FUNC, 'f', [], [
|
||||||
[(Token.ASSIGN,
|
(Token.VAR,
|
||||||
None,
|
zip(['x'],
|
||||||
(Token.OPEXPR, [
|
[(Token.ASSIGN,
|
||||||
(Token.MEMBER, (Token.ARRAY, [
|
None,
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None)]), None),
|
(Token.MEMBER, (Token.ARRAY, [
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 2), None, None)]), None),
|
(Token.MEMBER, (Token.INT, 1), None, None)]), None),
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 3), None, None)]), None)
|
(Token.MEMBER, (Token.INT, 2), None, None)]), 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)
|
|
||||||
]),
|
]),
|
||||||
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, 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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'var x = 20; x = 30 + 1; return x;',
|
'code': 'function f() { var x = 20; x = 30 + 1; return x; }',
|
||||||
'asserts': [{'value': 31}],
|
'asserts': [{'value': 31, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.VAR, zip(
|
(Token.FUNC, 'f', [], [
|
||||||
['x'],
|
(Token.VAR, zip(
|
||||||
[(Token.ASSIGN,
|
['x'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 20), None, None)]),
|
None,
|
||||||
None)]
|
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 20), None, None)]),
|
||||||
)),
|
None)]
|
||||||
(Token.EXPR, [
|
)),
|
||||||
(Token.ASSIGN,
|
(Token.EXPR, [
|
||||||
_ASSIGN_OPERATORS['='][1],
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
_ASSIGN_OPERATORS['='][1],
|
||||||
(Token.ASSIGN, None,
|
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
||||||
(Token.OPEXPR, [
|
(Token.ASSIGN, None,
|
||||||
(Token.MEMBER, (Token.INT, 30), None, None),
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None),
|
(Token.MEMBER, (Token.INT, 30), None, None),
|
||||||
(Token.OP, _OPERATORS['+'][1])]),
|
(Token.MEMBER, (Token.INT, 1), None, None),
|
||||||
None))
|
(Token.OP, _OPERATORS['+'][1])]),
|
||||||
]),
|
None))
|
||||||
|
]),
|
||||||
|
|
||||||
(Token.RETURN, (Token.EXPR, [
|
(Token.RETURN, (Token.EXPR, [
|
||||||
(Token.ASSIGN, None,
|
(Token.ASSIGN, None,
|
||||||
(Token.OPEXPR, [
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.ID, 'x'), None, None)
|
(Token.MEMBER, (Token.ID, 'x'), None, None)
|
||||||
]), None)
|
]), None)
|
||||||
]))
|
]))
|
||||||
|
])
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
'code': 'var x = 20; x += 30 + 1; return x;',
|
'code': 'function f() { var x = 20; x += 30 + 1; return x;}',
|
||||||
'asserts': [{'value': 51}],
|
'asserts': [{'value': 51, 'call': ('f',)}],
|
||||||
}, {
|
}, {
|
||||||
'code': 'var x = 20; x -= 30 + 1; return x;',
|
'code': 'function f() { var x = 20; x -= 30 + 1; return x;}',
|
||||||
'asserts': [{'value': -11}],
|
'asserts': [{'value': -11, 'call': ('f',)}],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -4,23 +4,29 @@ from youtube_dl.jsinterp2.jsgrammar import Token
|
|||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return 42;',
|
'code': 'function f() { return 42; }',
|
||||||
'asserts': [{'value': 42}],
|
'asserts': [{'value': 42, 'call': ('f',)}],
|
||||||
'ast': [(Token.RETURN,
|
'ast': [
|
||||||
|
(Token.FUNC, 'f', [], [
|
||||||
|
(Token.RETURN,
|
||||||
(Token.EXPR, [
|
(Token.EXPR, [
|
||||||
(Token.ASSIGN,
|
(Token.ASSIGN,
|
||||||
None,
|
None,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 42), None, None)]),
|
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 42), None, None)]),
|
||||||
None)
|
None)
|
||||||
]))]
|
]))
|
||||||
|
])
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'code': ';',
|
'code': 'function x() {;}',
|
||||||
'asserts': [{'value': None}],
|
'asserts': [{'value': None, 'call': ('x',)}],
|
||||||
'ast': [None]
|
'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',)}]
|
'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.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _RELATIONS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -4,10 +4,11 @@ from youtube_dl.jsinterp2.jsgrammar import Token
|
|||||||
from youtube_dl.jsinterp2.tstream import _OPERATORS
|
from youtube_dl.jsinterp2.tstream import _OPERATORS
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{'code': 'return 2*a+1;',
|
{'code': 'function x4(a){return 2*a+1;}',
|
||||||
'globals': {'a': 3},
|
'asserts': [{'value': 7, 'call': ('x4', 3)}],
|
||||||
'asserts': [{'value': 7}],
|
'ast': [
|
||||||
'ast': [(Token.RETURN,
|
(Token.FUNC, 'x4', ['a'], [
|
||||||
|
(Token.RETURN,
|
||||||
(Token.EXPR, [
|
(Token.EXPR, [
|
||||||
(Token.ASSIGN,
|
(Token.ASSIGN,
|
||||||
None,
|
None,
|
||||||
@ -21,6 +22,8 @@ tests = [
|
|||||||
]),
|
]),
|
||||||
None)
|
None)
|
||||||
])
|
])
|
||||||
)]
|
)
|
||||||
|
])
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -9,9 +9,8 @@ tests = [
|
|||||||
function x() { return 2; }
|
function x() { return 2; }
|
||||||
function y(a) { return x() + a; }
|
function y(a) { return x() + a; }
|
||||||
function z() { return y(3); }
|
function z() { return y(3); }
|
||||||
z();
|
|
||||||
''',
|
''',
|
||||||
'asserts': [{'value': 5}],
|
'asserts': [{'value': 5, 'call': ('z',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.FUNC, 'x', [], [
|
(Token.FUNC, 'x', [], [
|
||||||
(Token.RETURN, (Token.EXPR, [
|
(Token.RETURN, (Token.EXPR, [
|
||||||
@ -37,17 +36,13 @@ tests = [
|
|||||||
]), None)
|
]), 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
|
# 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': [
|
'ast': [
|
||||||
(Token.FUNC, 'x', ['a'], [
|
(Token.FUNC, 'x', ['a'], [
|
||||||
(Token.RETURN, (Token.EXPR, [
|
(Token.RETURN, (Token.EXPR, [
|
||||||
@ -63,13 +58,13 @@ tests = [
|
|||||||
])
|
])
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
|
'exclude': ('jsinterp',),
|
||||||
'code': '''
|
'code': '''
|
||||||
function a(x) { return x; }
|
function a(x) { return x; }
|
||||||
function b(x) { return x + 1; }
|
function b(x) { return x + 1; }
|
||||||
function c() { return [a, b][0](0); }
|
function c() { return [a, b][0](0); }
|
||||||
c();
|
|
||||||
''',
|
''',
|
||||||
'asserts': [{'value': 0}],
|
'asserts': [{'value': 0, 'call': ('c',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.FUNC, 'a', ['x'], [
|
(Token.FUNC, 'a', ['x'], [
|
||||||
(Token.RETURN, (Token.EXPR, [
|
(Token.RETURN, (Token.EXPR, [
|
||||||
@ -100,11 +95,6 @@ tests = [
|
|||||||
], None)))
|
], None)))
|
||||||
]), 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.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _OPERATORS
|
from youtube_dl.jsinterp2.tstream import _OPERATORS
|
||||||
|
|
||||||
|
skip = {'jsinterp': 'Not yet fully implemented'}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': '''
|
'code': '''
|
||||||
var x = /* 1 + */ 2;
|
function x() {
|
||||||
var y = /* 30
|
var x = /* 1 + */ 2;
|
||||||
* 40 */ 50;
|
var y = /* 30
|
||||||
return x + y;''',
|
* 40 */ 50;
|
||||||
'asserts': [{'value': 52}],
|
return x + y;
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
'asserts': [{'value': 52, 'call': ('x',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.VAR, zip(
|
(Token.FUNC, 'x', [], [
|
||||||
['x'],
|
(Token.VAR, zip(
|
||||||
[(Token.ASSIGN,
|
['x'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]),
|
None,
|
||||||
None)]
|
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]),
|
||||||
)),
|
None)]
|
||||||
(Token.VAR, zip(
|
)),
|
||||||
['y'],
|
(Token.VAR, zip(
|
||||||
[(Token.ASSIGN,
|
['y'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 50), None, None)]),
|
None,
|
||||||
None)]
|
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 50), None, None)]),
|
||||||
)),
|
None)]
|
||||||
(Token.RETURN, (Token.EXPR, [
|
)),
|
||||||
(Token.ASSIGN, None,
|
(Token.RETURN, (Token.EXPR, [
|
||||||
(Token.OPEXPR, [
|
(Token.ASSIGN, None,
|
||||||
(Token.MEMBER, (Token.ID, 'x'), None, None),
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.ID, 'y'), None, None),
|
(Token.MEMBER, (Token.ID, 'x'), None, None),
|
||||||
(Token.OP, _OPERATORS['+'][1])
|
(Token.MEMBER, (Token.ID, 'y'), None, None),
|
||||||
]), None)
|
(Token.OP, _OPERATORS['+'][1])
|
||||||
]))
|
]), None)
|
||||||
|
]))
|
||||||
|
])
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
'code': '''
|
'code': '''
|
||||||
var x = "/*";
|
function f() {
|
||||||
var y = 1 /* comment */ + 2;
|
var x = "/*";
|
||||||
return y;
|
var y = 1 /* comment */ + 2;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
''',
|
''',
|
||||||
'asserts': [{'value': 3}],
|
'asserts': [{'value': 3, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.VAR, zip(
|
(Token.FUNC, 'f', [], [
|
||||||
['x'],
|
(Token.VAR, zip(
|
||||||
[(Token.ASSIGN,
|
['x'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.STR, '/*'), None, None)]),
|
None,
|
||||||
None)]
|
(Token.OPEXPR, [(Token.MEMBER, (Token.STR, '/*'), None, None)]),
|
||||||
)),
|
None)]
|
||||||
(Token.VAR, zip(
|
)),
|
||||||
['y'],
|
(Token.VAR, zip(
|
||||||
[(Token.ASSIGN,
|
['y'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [
|
None,
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None),
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 2), None, None),
|
(Token.MEMBER, (Token.INT, 1), None, None),
|
||||||
(Token.OP, _OPERATORS['+'][1])
|
(Token.MEMBER, (Token.INT, 2), None, None),
|
||||||
]),
|
(Token.OP, _OPERATORS['+'][1])
|
||||||
None)]
|
]),
|
||||||
)),
|
None)]
|
||||||
(Token.RETURN, (Token.EXPR, [
|
)),
|
||||||
(Token.ASSIGN, None,
|
(Token.RETURN, (Token.EXPR, [
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'y'), None, None)]),
|
(Token.ASSIGN, None,
|
||||||
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
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
skip = {'interpret': 'Interpreting debugger statement not yet implemented',
|
skip = {
|
||||||
'parse': 'Test not yet implemented: missing code and ast'}
|
'jsinterp': 'Debugger statement is not supported',
|
||||||
|
'interpret': 'Interpreting debugger statement not yet implemented',
|
||||||
|
'parse': 'Test not yet implemented: missing code and ast'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
@ -16,7 +19,7 @@ tests = [
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
'asserts': [{'value': 5, 'call': 5}],
|
'asserts': [{'value': 5, 'call': ('f', 5)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.FUNC, 'f', ['x'], [
|
(Token.FUNC, 'f', ['x'], [
|
||||||
(Token.EXPR, [
|
(Token.EXPR, [
|
||||||
|
@ -3,21 +3,24 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{'code': 'return; y()',
|
{'code': 'function f() { return; y(); }',
|
||||||
'asserts': [{'value': None}],
|
'asserts': [{'value': None, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.RETURN, None),
|
(Token.FUNC, 'f', [], [
|
||||||
(Token.EXPR, [
|
(Token.RETURN, None),
|
||||||
(Token.ASSIGN,
|
(Token.EXPR, [
|
||||||
None,
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [
|
None,
|
||||||
(Token.MEMBER,
|
(Token.OPEXPR, [
|
||||||
(Token.ID, 'y'),
|
(Token.MEMBER,
|
||||||
None,
|
(Token.ID, 'y'),
|
||||||
(Token.CALL, [], None)
|
None,
|
||||||
)
|
(Token.CALL, [], None)
|
||||||
]),
|
)
|
||||||
None)
|
]),
|
||||||
])]
|
None)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -2,24 +2,28 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
|
skip = {'jsinterp': 'Field access is not supported'}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return a.var;',
|
'code': 'function f() { return a.var; }',
|
||||||
'asserts': [{'value': 3}],
|
'asserts': [{'value': 3, 'call': ('f',)}],
|
||||||
'globals': {'a': {'var': 3}},
|
'globals': {'a': {'var': 3}},
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.RETURN,
|
(Token.FUNC, 'f', [], [
|
||||||
(Token.EXPR, [
|
(Token.RETURN,
|
||||||
(Token.ASSIGN,
|
(Token.EXPR, [
|
||||||
None,
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [
|
None,
|
||||||
(Token.MEMBER,
|
(Token.OPEXPR, [
|
||||||
(Token.ID, 'a'),
|
(Token.MEMBER,
|
||||||
None,
|
(Token.ID, 'a'),
|
||||||
(Token.FIELD, 'var', None)),
|
None,
|
||||||
]),
|
(Token.FIELD, 'var', None)),
|
||||||
None)
|
]),
|
||||||
]))
|
None)
|
||||||
|
]))
|
||||||
|
])
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -2,8 +2,11 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
skip = {'interpret': 'Interpreting label not yet implemented',
|
skip = {
|
||||||
'parse': 'Test not yet implemented: missing code and ast'}
|
'jsinterp': 'Label statement is not supported',
|
||||||
|
'interpret': 'Interpreting label not yet implemented',
|
||||||
|
'parse': 'Test not yet implemented: missing code and ast'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -5,27 +5,30 @@ from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS
|
|||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'x = 2 ; return x;',
|
'code': 'function f() { x = 2 ; return x; }',
|
||||||
'asserts': [{'value': 2}],
|
'asserts': [{'value': 2, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.EXPR,
|
(Token.FUNC, 'f', [], [
|
||||||
[(Token.ASSIGN,
|
(Token.EXPR,
|
||||||
_ASSIGN_OPERATORS['='][1],
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
_ASSIGN_OPERATORS['='][1],
|
||||||
(Token.ASSIGN,
|
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
||||||
None,
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]),
|
None,
|
||||||
None)
|
(Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]),
|
||||||
)]
|
None)
|
||||||
),
|
)]
|
||||||
(Token.RETURN,
|
),
|
||||||
(Token.EXPR, [
|
(Token.RETURN,
|
||||||
(Token.ASSIGN,
|
(Token.EXPR, [
|
||||||
None,
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
None,
|
||||||
None)
|
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]),
|
||||||
])
|
None)
|
||||||
)]
|
])
|
||||||
|
)
|
||||||
|
])
|
||||||
|
]
|
||||||
}, {
|
}, {
|
||||||
'code': 'function x (a) { return 2 * a + 1 ; }',
|
'code': 'function x (a) { return 2 * a + 1 ; }',
|
||||||
'asserts': [{'value': 7, 'call': ('x', 3)}]
|
'asserts': [{'value': 7, 'call': ('x', 3)}]
|
||||||
|
@ -5,41 +5,49 @@ from youtube_dl.jsinterp2.tstream import _OPERATORS
|
|||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return 1 << 5;',
|
'code': 'function f() { return 1 << 5; }',
|
||||||
'asserts': [{'value': 32}],
|
'asserts': [{'value': 32, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.RETURN,
|
(Token.FUNC, 'f', [], [
|
||||||
(Token.EXPR, [
|
(Token.RETURN,
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.EXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None),
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 5), None, None),
|
(Token.MEMBER, (Token.INT, 1), None, None),
|
||||||
(Token.OP, _OPERATORS['<<'][1])
|
(Token.MEMBER, (Token.INT, 5), None, 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)
|
|
||||||
]))
|
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
'code': 'return 11 >> 2;',
|
'code': 'function f() { return 19 & 21;}',
|
||||||
'asserts': [{'value': 2}],
|
'asserts': [{'value': 17, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.RETURN,
|
(Token.FUNC, 'f', [], [
|
||||||
(Token.EXPR, [
|
(Token.RETURN,
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.EXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 11), None, None),
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 2), None, None),
|
(Token.MEMBER, (Token.INT, 19), None, None),
|
||||||
(Token.OP, _OPERATORS['>>'][1])
|
(Token.MEMBER, (Token.INT, 21), None, 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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return (1 + 2) * 3;',
|
'code': 'function f() { return (1 + 2) * 3; }',
|
||||||
'asserts': [{'value': 9}],
|
'asserts': [{'value': 9, 'call': ('f',)}],
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.RETURN, (Token.EXPR, [
|
(Token.FUNC, 'f', [], [
|
||||||
(Token.ASSIGN, None,
|
(Token.RETURN, (Token.EXPR, [
|
||||||
(Token.OPEXPR, [
|
(Token.ASSIGN, None,
|
||||||
(Token.MEMBER, (Token.EXPR, [
|
(Token.OPEXPR, [
|
||||||
(Token.ASSIGN, None,
|
(Token.MEMBER, (Token.EXPR, [
|
||||||
(Token.OPEXPR, [
|
(Token.ASSIGN, None,
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None),
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 2), None, None),
|
(Token.MEMBER, (Token.INT, 1), None, None),
|
||||||
(Token.OP, _OPERATORS['+'][1])
|
(Token.MEMBER, (Token.INT, 2), None, None),
|
||||||
]), None)
|
(Token.OP, _OPERATORS['+'][1])
|
||||||
]), None, None),
|
]), None)
|
||||||
(Token.MEMBER, (Token.INT, 3), None, None),
|
]), None, None),
|
||||||
(Token.OP, _OPERATORS['*'][1])
|
(Token.MEMBER, (Token.INT, 3), None, None),
|
||||||
]), None)
|
(Token.OP, _OPERATORS['*'][1])
|
||||||
]))]
|
]), None)
|
||||||
|
]))
|
||||||
|
])
|
||||||
|
]
|
||||||
}, {
|
}, {
|
||||||
'code': 'return (1) + (2) * ((( (( (((((3)))))) )) ));',
|
'code': 'function f() { return (1) + (2) * ((( (( (((((3)))))) )) ));}',
|
||||||
'asserts': [{'value': 7}],
|
'asserts': [{'value': 7, 'call': ('f',)}],
|
||||||
'ast': [
|
'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.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.ASSIGN, None,
|
(Token.MEMBER, (Token.INT, 2), None, None)
|
||||||
(Token.OPEXPR, [
|
]), None)]), None, None),
|
||||||
(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.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.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.MEMBER, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.MEMBER,
|
||||||
(Token.MEMBER, (Token.INT, 3), None, None)
|
(Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
]), None)]), None, None)
|
(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)
|
||||||
|
|
||||||
]), 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]),
|
||||||
(Token.OP, _OPERATORS['+'][1])
|
(Token.OP, _OPERATORS['+'][1])
|
||||||
]), None)
|
]), None)
|
||||||
]))
|
]))
|
||||||
|
])
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -8,75 +8,79 @@ skip = {'interpret': 'Interpreting built-in fields not yet implemented'}
|
|||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': '''
|
'code': '''
|
||||||
var a = [10, 20, 30, 40, 50];
|
function f() {
|
||||||
var b = 6;
|
var a = [10, 20, 30, 40, 50];
|
||||||
a[0]=a[b%a.length];
|
var b = 6;
|
||||||
return a;
|
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': [
|
'ast': [
|
||||||
(Token.VAR,
|
(Token.FUNC, 'f', [], [
|
||||||
zip(['a'],
|
(Token.VAR,
|
||||||
[(Token.ASSIGN,
|
zip(['a'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(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,
|
None,
|
||||||
(Token.ELEM, (Token.EXPR, [
|
(Token.OPEXPR, [
|
||||||
(Token.ASSIGN, None, (Token.OPEXPR, [
|
(Token.MEMBER, (Token.ARRAY, [
|
||||||
(Token.MEMBER, (Token.ID, 'b'), None, None),
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.ID, 'a'), None, (Token.FIELD, 'length', None)),
|
(Token.MEMBER, (Token.INT, 10), None, None)]), None),
|
||||||
(Token.OP, _OPERATORS['%'][1])
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
]), None)]),
|
(Token.MEMBER, (Token.INT, 20), None, None)]), None),
|
||||||
None))
|
(Token.ASSIGN, None, (Token.OPEXPR, [
|
||||||
]),
|
(Token.MEMBER, (Token.INT, 30), None, 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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'var $_axY2 = $_xY1 + 1; return $_axY2;',
|
'code': 'function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; }',
|
||||||
'globals': {'$_xY1': 20},
|
'asserts': [{'value': 21, 'call': ('$_xY1', 20)}],
|
||||||
'asserts': [{'value': 21}],
|
|
||||||
'ast': [
|
'ast': [
|
||||||
(Token.VAR,
|
(Token.FUNC, '$_xY1', ['$_axY1'], [
|
||||||
zip(['$_axY2'],
|
(Token.VAR,
|
||||||
[(Token.ASSIGN,
|
zip(['$_axY2'],
|
||||||
None,
|
[(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [
|
None,
|
||||||
(Token.MEMBER, (Token.ID, '$_xY1'), None, None),
|
(Token.OPEXPR, [
|
||||||
(Token.MEMBER, (Token.INT, 1), None, None),
|
(Token.MEMBER, (Token.ID, '$_axY1'), None, None),
|
||||||
(Token.OP, _OPERATORS['+'][1])
|
(Token.MEMBER, (Token.INT, 1), None, None),
|
||||||
]),
|
(Token.OP, _OPERATORS['+'][1])
|
||||||
None)
|
]),
|
||||||
])
|
None)
|
||||||
),
|
])
|
||||||
(Token.RETURN,
|
),
|
||||||
(Token.EXPR, [
|
(Token.RETURN,
|
||||||
(Token.ASSIGN,
|
(Token.EXPR, [
|
||||||
None,
|
(Token.ASSIGN,
|
||||||
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, '$_axY2'), None, None)]),
|
None,
|
||||||
None)]
|
(Token.OPEXPR, [(Token.MEMBER, (Token.ID, '$_axY2'), None, None)]),
|
||||||
)
|
None)]
|
||||||
)]
|
)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
skip = {'parse': 'Ast not yet implemented'}
|
skip = {
|
||||||
|
'jsinterp': 'String literals are not supported',
|
||||||
|
'parse': 'Ast not yet implemented'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': '"hello".split("");',
|
'exclude': ('jsinterp2',),
|
||||||
|
'code': 'function f() {return "hello".split(""); }',
|
||||||
'globals': {},
|
'globals': {},
|
||||||
'asserts': [{'value': ['h', 'e', 'l', 'l', 'o']}],
|
'asserts': [{'value': ['h', 'e', 'l', 'l', 'o'], 'call': ('f',)}],
|
||||||
'ast': []
|
'ast': []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -2,8 +2,11 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
skip = {'interpret': 'Interpreting try statement not yet implemented',
|
skip = {
|
||||||
'parse': 'Test not yet implemented: missing code and ast'}
|
'jsinterp': 'Try statement is not supported',
|
||||||
|
'interpret': 'Interpreting try statement not yet implemented',
|
||||||
|
'parse': 'Test not yet implemented: missing code and ast'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
skip = {'parse': True}
|
skip = {
|
||||||
|
'jsinterp': 'Unary opertations are not supported',
|
||||||
|
'parse': True
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return -5 + +3;',
|
'code': 'function f() { return -5 + +3; }',
|
||||||
'asserts': [{'value': -2}]
|
'asserts': [{'value': -2, 'call': ('f',)}]
|
||||||
}, {
|
}, {
|
||||||
'code': 'function f() {return -5 + ++a;}',
|
'code': 'function f() {return -5 + ++a;}',
|
||||||
'globals': {'a': -3},
|
'globals': {'a': -3},
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
skip = {
|
||||||
|
'jsinterp': 'Test not implemented',
|
||||||
|
'parse': 'Test not implemented',
|
||||||
|
'interpert': 'Test not implemented'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': '''
|
'code': '''
|
||||||
|
@ -3,7 +3,10 @@ from __future__ import unicode_literals
|
|||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
from youtube_dl.jsinterp2.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
|
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 = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -2,8 +2,11 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from youtube_dl.jsinterp2.jsgrammar import Token
|
from youtube_dl.jsinterp2.jsgrammar import Token
|
||||||
|
|
||||||
skip = {'interpret': 'Interpreting with statement not yet implemented',
|
skip = {
|
||||||
'parse': 'Test not yet implemented: missing code and ast'}
|
'jsinterp': 'With statement is not supported',
|
||||||
|
'interpret': 'Interpreting with statement not yet implemented',
|
||||||
|
'parse': 'Test not yet implemented: missing code and ast'
|
||||||
|
}
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@ else:
|
|||||||
import unittest
|
import unittest
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
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
|
from .js2tests import gettestcases
|
||||||
|
|
||||||
defs = gettestcases()
|
defs = gettestcases()
|
||||||
@ -33,7 +33,10 @@ class TestJSInterpreter(unittest.TestCase):
|
|||||||
def generator(test_case, name):
|
def generator(test_case, name):
|
||||||
def test_template(self):
|
def test_template(self):
|
||||||
for test in test_case['subtests']:
|
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'
|
log_reason = 'No code in subtest, skipping'
|
||||||
elif 'asserts' not in test:
|
elif 'asserts' not in test:
|
||||||
log_reason = 'No assertion in subtest, skipping'
|
log_reason = 'No assertion in subtest, skipping'
|
||||||
@ -41,13 +44,20 @@ def generator(test_case, name):
|
|||||||
log_reason = None
|
log_reason = None
|
||||||
|
|
||||||
if log_reason is None:
|
if log_reason is None:
|
||||||
jsi = JSInterpreter(test['code'], variables=test.get('globals'))
|
variables = test.get('globals')
|
||||||
for a in test['asserts']:
|
code = test['code']
|
||||||
if 'value' in a:
|
call = None
|
||||||
if 'call' in a:
|
|
||||||
self.assertEqual(jsi.call_function(*a['call']), a['value'])
|
if variables is not None:
|
||||||
else:
|
code = 'function f(%s){%s}' % ((''.join(variables.keys())), code)
|
||||||
self.assertEqual(jsi.run(), a['value'])
|
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:
|
else:
|
||||||
log.debug('No value in assertion, skipping')
|
log.debug('No value in assertion, skipping')
|
||||||
else:
|
else:
|
||||||
@ -59,7 +69,7 @@ def generator(test_case, name):
|
|||||||
|
|
||||||
# And add them to TestJSInterpreter
|
# And add them to TestJSInterpreter
|
||||||
for n, tc in enumerate(defs):
|
for n, tc in enumerate(defs):
|
||||||
reason = tc['skip'].get('interpret', False)
|
reason = tc['skip'].get('jsinterp', False)
|
||||||
tname = 'test_' + str(tc['name'])
|
tname = 'test_' + str(tc['name'])
|
||||||
i = 1
|
i = 1
|
||||||
while hasattr(TestJSInterpreter, tname):
|
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()
|
self._context = self._context_stack.pop()
|
||||||
|
|
||||||
def call_function(self, funcname, *args):
|
def call_function(self, funcname, *args):
|
||||||
f = (self.this[funcname] if funcname in self.this else
|
f = (self.this[funcname].getvalue() if funcname in self.this else
|
||||||
self.global_vars[funcname] if funcname in self.global_vars else
|
self.global_vars[funcname].getvalue() if funcname in self.global_vars else
|
||||||
self.extract_function(funcname))
|
self.extract_function(funcname))
|
||||||
return f(*args)
|
return f(*args)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user