#!/usr/bin/env python from __future__ import unicode_literals # Allow direct execution import os import sys import copy 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.jsinterp import JSInterpreter from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.tstream import ( _OPERATORS, _ASSIGN_OPERATORS, _LOGICAL_OPERATORS, _UNARY_OPERATORS, _RELATIONS ) def traverse(node, tree_types=(list, tuple)): if type(node) == zip: node = list(copy.deepcopy(node)) if isinstance(node, tree_types): for value in node: for subvalue in traverse(value, tree_types): yield subvalue else: yield node class TestJSInterpreterParser(unittest.TestCase): def test_basic(self): jsi = JSInterpreter(';') ast = [None] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter('return 42;') ast = [(Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 42), None, None)]), None) ]) )] self.assertEqual(list(jsi.statements()), ast) def test_calc(self): jsi = JSInterpreter('return 2*a+1;') ast = [(Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ # Reverse Polish Notation! (Token.MEMBER, (Token.INT, 2), None, None), (Token.MEMBER, (Token.ID, 'a'), None, None), (Token.OP, _OPERATORS['*'][1]), (Token.MEMBER, (Token.INT, 1), None, None), (Token.OP, _OPERATORS['+'][1]) ]), None) ]) )] self.assertEqual(list(jsi.statements()), ast) def test_empty_return(self): jsi = JSInterpreter('return; y()') ast = [(Token.RETURN, None), (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'y'), None, (Token.CALL, [], None) ) ]), None) ])] self.assertEqual(list(jsi.statements()), ast) def test_morespace(self): jsi = JSInterpreter('x = 2 ; return x;') 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) ]) )] self.assertEqual(list(jsi.statements()), ast) def test_strange_chars(self): jsi = JSInterpreter('var $_axY2 = $_axY1 + 1; return $_axY2;') ast = [(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)] ) )] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) def test_operators(self): jsi = JSInterpreter('return 1 << 5;') 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) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter('return 19 & 21;') 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) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter('return 11 >> 2;') 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) ])) ] self.assertEqual(list(jsi.statements()), ast) def test_array_access(self): jsi = JSInterpreter('var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2] = 7; return x;') 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) ]), 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) ]) ) ] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) def test_parens(self): jsi = JSInterpreter('return (1 + 2) * 3;') 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) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter('return (1) + (2) * ((( (( (((((3)))))) )) ));') 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) ]), 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.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), (Token.OP, _OPERATORS['*'][1]), (Token.OP, _OPERATORS['+'][1]) ]), None) ])) ] self.assertEqual(list(jsi.statements()), ast) def test_assignments(self): jsi = JSInterpreter('var x = 20; x = 30 + 1; return x;') 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.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None) ]), None) ])) ] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) jsi = JSInterpreter('var x = 20; x += 30 + 1; return x;') ast[1] = (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)) ]) self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) jsi = JSInterpreter('var x = 20; x -= 30 + 1; return x;') ast[1] = (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)) ]) self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) def test_comments(self): # var x = 2; var y = 50; return x + y; jsi = JSInterpreter('var x = /* 1 + */ 2; var y = /* 30 * 40 */ 50; return x + y;') 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) ])) ] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) # var x = "/*"; var y = 1 + 2; return y; jsi = JSInterpreter('var x = "/*"; var y = 1 /* comment */ + 2; return y;') 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) ])) ] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) def test_precedence(self): jsi = JSInterpreter(' var a = [10, 20, 30, 40, 50]; var b = 6; a[0]=a[b%a.length]; return a;') 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'), 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) ]) ) ] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) def test_call(self): jsi = JSInterpreter(''' function x() { return 2; } function y(a) { return x() + a; } function z() { return y(3); } ''') ast = [ (Token.FUNC, 'x', [], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 2), None, None)]), None) ]) ) ])), (Token.FUNC, 'y', ['a'], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, (Token.CALL, [], None)), (Token.MEMBER, (Token.ID, 'a'), None, None), (Token.OP, _OPERATORS['+'][1]) ]), None) ]) ) ])), (Token.FUNC, 'z', [], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'y'), None, (Token.CALL, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 3), None, None)]), None) ], None)) ]), None) ]) ) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter('function x(a) { return a.split(""); }', variables={'a': 'abc'}) ast = [ (Token.FUNC, 'x', ['a'], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'a'), None, (Token.FIELD, 'split', (Token.CALL, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.STR, ''), None, None)]), None) ], None)) )]), None) ]) ) ])) ] self.assertEqual(list(jsi.statements()), ast) def test_complex_call(self): jsi = JSInterpreter(''' function a(x) { return x; } function b(x) { return x; } function c() { return [a, b][0](0); } ''') ast = [ (Token.FUNC, 'a', ['x'], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), None) ]) ) ])), (Token.FUNC, 'b', ['x'], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.ID, 'x'), None, None)]), None) ]) ) ])), (Token.FUNC, 'c', [], (Token.BLOCK, [ (Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ARRAY, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'a'), None, None)]), None), (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'b'), None, None)]), None) ]), None, (Token.ELEM, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), None) ]), (Token.CALL, [ (Token.ASSIGN, None, (Token.OPEXPR, [(Token.MEMBER, (Token.INT, 0), None, None)]), None) ], None))) ]), None) ]) ) ])), ] self.assertEqual(list(jsi.statements()), ast) def test_getfield(self): jsi = JSInterpreter('return a.var;', variables={'a': {'var': 3}}) ast = [(Token.RETURN, (Token.EXPR, [ (Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'a'), None, (Token.FIELD, 'var', None)), ]), None) ])) ] self.assertEqual(list(jsi.statements()), ast) def test_if(self): jsi = JSInterpreter( ''' function a(x) { if (x > 0) return true; else return false; } ''' ) ast = [ (Token.FUNC, 'a', ['x'], (Token.BLOCK, [ (Token.IF, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None), (Token.MEMBER, (Token.INT, 0), None, None), (Token.REL, _RELATIONS['>'][1]) ]), None)]), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.BOOL, True), None, None)]), None)])), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.BOOL, False), None, None)]), None)]))) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter( ''' function a(x) { if (x > 0) return true; return false; } ''' ) ast = [ (Token.FUNC, 'a', ['x'], (Token.BLOCK, [ (Token.IF, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None), (Token.MEMBER, (Token.INT, 0), None, None), (Token.REL, _RELATIONS['>'][1]) ]), None)]), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.BOOL, True), None, None)]), None)])), None), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.BOOL, False), None, None)]), None)])) ])) ] self.assertEqual(list(jsi.statements()), ast) jsi = JSInterpreter( ''' function a(x) { if (x > 0) { x--; return x; } else { x++; return x; } } ''' ) ast = [ (Token.FUNC, 'a', ['x'], (Token.BLOCK, [ (Token.IF, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None), (Token.MEMBER, (Token.INT, 0), None, None), (Token.REL, _RELATIONS['>'][1]) ]), None)]), (Token.BLOCK, [ (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None), (Token.UOP, _UNARY_OPERATORS['--'][1]) ]), None)]), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None)]), None)])) ]), (Token.BLOCK, [ (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None), (Token.UOP, _UNARY_OPERATORS['++'][1]) ]), None)]), (Token.RETURN, (Token.EXPR, [(Token.ASSIGN, None, (Token.OPEXPR, [ (Token.MEMBER, (Token.ID, 'x'), None, None)]), None)])) ])) ])) ] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_switch(self): # ASAP switch statement test jsi = JSInterpreter( ''' function a(x) { switch (x) { case 6: break; case 5: x++; case 8: x--; break; default: x = 0; } return x; } ''' ) ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_for(self): # ASAP for statement test jsi = JSInterpreter(''' function f(x){ for (var h = 0; h <= x; ++h) { a = h; } return a } ''') ast = [] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) @unittest.skip('Test not yet implemented: missing ast') def test_for_empty(self): # ASAP for empty statement test jsi = JSInterpreter(''' function f(x){ var h = 0 for (; h <= x; ++h) { a = h; } return a } ''') ast = [] self.assertEqual(list(traverse(list(jsi.statements()))), list(traverse(ast))) @unittest.skip('Test not yet implemented: missing ast') def test_for_in(self): # ASAP for in statement test jsi = JSInterpreter(''' function f(z){ for (h in z) { a = h; } return a } ''') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_do(self): # ASAP do statement test jsi = JSInterpreter(''' function f(x){ i = 1 do{ i++; } while (i < x) return i; } ''') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_while(self): # ASAP while statement test jsi = JSInterpreter(''' function f(x){ i = 1 while (i < x) { i++; } return i; } ''') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing code and ast') def test_label(self): # TODO label (break, continue) statement test # might be combined with another jsi = JSInterpreter('') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_funct_expr(self): # ASAP function expression test jsi = JSInterpreter(''' function f() { var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); return add(); } ''') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing ast') def test_object(self): # ASAP object literal test jsi = JSInterpreter(''' function f() { var o = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2; } }; return o; } ''') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing code and ast') def test_try(self): # TODO try statement test jsi = JSInterpreter('') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing code and ast') def test_throw(self): # TODO throw statement test # might be combined with another jsi = JSInterpreter('') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing code and ast') def test_with(self): # TODO with statement test jsi = JSInterpreter('') ast = [] self.assertEqual(list(jsi.statements()), ast) @unittest.skip('Test not yet implemented: missing code and ast') def test_debug(self): # TODO debugger statement test # might be combined with another jsi = JSInterpreter('') ast = [] self.assertEqual(list(jsi.statements()), ast) def test_unshift(self): # https://hg.mozilla.org/mozilla-central/file/tip/js/src/tests/ecma_5/Array/unshift-01.js jsi = JSInterpreter( '''var MAX_LENGTH = 0xffffffff; var a = {}; a.length = MAX_LENGTH + 1; assertEq([].unshift.call(a), MAX_LENGTH); assertEq(a.length, MAX_LENGTH); function testGetSet(len, expected) { var newlen; var a = { get length() { return len; }, set length(v) { newlen = v; } }; var res = [].unshift.call(a); assertEq(res, expected); assertEq(newlen, expected); } testGetSet(0, 0); testGetSet(10, 10); testGetSet("1", 1); testGetSet(null, 0); testGetSet(MAX_LENGTH + 2, MAX_LENGTH); testGetSet(-5, 0);''') jsi.statements() if __name__ == '__main__': unittest.main()