def test_global_and_nonlocal(self): assert py2js('nonlocal foo;foo = 3').strip() == 'foo = 3;' assert py2js('global foo;foo = 3').strip() == 'foo = 3;' def func1(): def inner(): x = 3 x = 2 inner() return x def func2(): def inner(): global x x = 3 x = 2 inner() return x def func3(): def inner(): nonlocal x x = 3 x = 2 inner() return x assert evaljs(py2js(func1)+'func1()') == '2' assert evaljs(py2js(func2)+'func2()') == '3' assert evaljs(py2js(func3)+'func3()') == '3'
def test_calling_method_from_init(self): # Note that all class names inside a module need to be unique # for js() to find the correct source. class MyClass11: def __init__(self): self._res = self.m1() + self.m2() + self.m3() def m1(self): return 100 def m2(self): return 10 class MyClass12(MyClass11): def m2(self): return 20 def m3(self): return 2 code = py2js(MyClass11) + py2js(MyClass12) assert evaljs(code + 'm = new MyClass12(); m._res') == '122' assert evaljs(code + 'm = new MyClass12(); m.m1()') == '100'
def test_bound_methods(self): class MyClass14: def __init__(self): self.a = 1 def add2(self): self.a += 2 class MyClass15(MyClass14): def add3(self): self.a += 3 code = py2js(MyClass14) + py2js(MyClass15) assert evaljs( code + 'var m = new MyClass14(); m.add2(); m.add2(); m.a') == '5' assert evaljs( code + 'var m = new MyClass14(); var f = m.add2; f(); f(); m.a') == '5' assert evaljs( code + 'var m = new MyClass15(); var f = m.add3; f(); f(); m.a') == '7' assert evaljs( code + 'var m = new MyClass15(); var f2 = m.add2, f3 = m.add3; f2(); f3(); m.a' ) == '6'
def test_bound_funcs_in_methods(self): class MyClass16: def foo1(self): self.a = 3 f = lambda i: self.a return f() def foo2(self): self.a = 3 def bar(): return self.a return bar() def foo3(self): self.a = 3 def bar(self): return self.a return bar() code = py2js(MyClass16) assert evaljs(code + 'var m = new MyClass16(); m.foo1()') == '3' assert evaljs(code + 'var m = new MyClass16(); m.foo2()') == '3' assert evaljs( code + 'var m = new MyClass16(); try {m.foo3();} catch (err) {"ok"}' ) == 'ok'
def test_global_and_nonlocal(self): assert py2js('nonlocal foo;foo = 3').strip() == 'foo = 3;' assert py2js('global foo;foo = 3').strip() == 'foo = 3;' def func1(): def inner(): x = 3 x = 2 inner() return x def func2(): def inner(): global x x = 3 x = 2 inner() return x def func3(): def inner(): nonlocal x x = 3 x = 2 inner() return x assert evaljs(py2js(func1) + 'func1()') == '2' assert evaljs(py2js(func2) + 'func2()') == '3' assert evaljs(py2js(func3) + 'func3()') == '3'
def test_py2s_rename_function(): code = py2js(foo1, 'bar') assert 'foo' not in code.lower() assert evaljs(code + 'bar()') == '42' code = py2js(foo1, 'xx.bar') assert 'foo' not in code.lower() assert evaljs('var xx={};\n' + code + 'xx.bar();') == '42'
def test_py2js_rename_class(): code = py2js(Foo2, 'Bar') assert 'foo' not in code.lower() assert evaljs(code + 'var m=new Bar(); [m.res1(), m.res2()];') == '[ 42, 7 ]' code = py2js(Foo2, 'xx.Bar') assert 'foo' not in code.lower() assert evaljs('var xx={};\n' + code + 'var m=new xx.Bar(); [m.res1(), m.res2()];') == '[ 42, 7 ]'
def test_module(self): code = BaseParser('foo=3;bar=4;_priv=0;', 'mymodule').dump() # Test that global variables exist assert evaljs(code+'mymodule.foo+mymodule.bar') == '7' # And privates do not assert evaljs(code+'mymodule._priv===undefined') == 'true'
def test_assert(self): assert 'throw' in py2js('assert True') evalpy('assert true; 7') == '7' evalpy('assert true, "msg"; 7') == '7' catcher = 'try { %s } catch(err) { console.log(err); }' assert evaljs(catcher % py2js('assert false')).count('AssertionError') assert evaljs(catcher % py2js('assert false, "foo"')).count('foo')
def test_funcion_call(self): jscode = 'var foo = function (x, y) {return x+y;};' assert evaljs(jscode + py2js('foo(2,2)')) == '4' assert evaljs(jscode + py2js('foo("so ", True)')) == 'so true' assert evaljs(jscode + py2js('a=[1,2]; foo(*a)')) == '3' # Test super (is tested for real in test_parser3.py assert evalpy('d={"_base_class": console};d._base_class.log(4)') == '4' assert evalpy('d={"_base_class": console};d._base_class.log()') == ''
def test_ensure_use_new(self): class MyClass13: def __init__(self): pass code = py2js(MyClass13) err = 'Class constructor is called as a function.' assert evaljs(code + 'try { var m = new MyClass13(); "ok"} catch (err) { err; }') == 'ok' assert evaljs(code + 'try { var m = MyClass13();} catch (err) { err; }') == err assert evaljs(code + 'try { MyClass13.apply(root);} catch (err) { err; }') == err assert evaljs(code + 'var window = root;try { MyClass13.apply(window);} catch (err) { err; }') == err
def test_raw_js(): def func(a, b): """ var c = 3; return a + b + c; """ code = py2js(func) assert evaljs(code + "func(100, 10)") == "113" assert evaljs(code + 'func("x", 10)') == "x103"
def test_raw_js(): def func(a, b): """ var c = 3; return a + b + c; """ code = py2js(func) assert evaljs(code + 'func(100, 10)') == '113' assert evaljs(code + 'func("x", 10)') == 'x103'
def test_ensure_use_new(self): class MyClass13: def __init__(self): pass code = py2js(MyClass13) err = 'Class constructor is called as a function.' assert evaljs(code + 'try { var m = new MyClass13(); "ok"} catch (err) { err; }') == 'ok' assert evaljs(code + 'try { var m = MyClass13();} catch (err) { err; }') == err assert evaljs(code + 'try { MyClass13.apply(global);} catch (err) { err; }') == err assert evaljs(code + 'var window = global;try { MyClass13.apply(window);} catch (err) { err; }') == err
def test_raise(self): assert 'throw' in py2js('raise MyException("foo")') assert 'MyException' in py2js('raise MyException("foo")') assert 'foo' in py2js('raise MyException("foo")') catcher = 'try { %s } catch(err) { console.log(err); }' assert evaljs(catcher % py2js('raise "foo"')) == 'foo' assert evaljs(catcher % py2js('raise 42')) == '42' assert evaljs(catcher % py2js('raise ValueError')).count('ValueError') assert evaljs(catcher % py2js('raise ValueError("foo")')).count('foo')
def test_isinstance(self): # The resulting code is not particularly pretty, so we just # test outcome assert evalpy('isinstance(3.0, list) == True') == 'false' assert evalpy('isinstance(3.0, float) == True') == 'true' assert evalpy('x={}; isinstance(x.foo, "undefined")') == 'true' assert evalpy('isinstance(None, "null")') == 'true' assert evalpy('isinstance(undefined, "undefined")') == 'true' # assert evalpy('isinstance(None, "undefined")') == 'false' assert evalpy('isinstance(undefined, "null")') == 'false' assert evalpy('isinstance(3, float)') == 'true' assert evalpy('isinstance(3, (int, float))') == 'true' assert evalpy('isinstance(3, "number")') == 'true' # #assert evalpy('isinstance(3, int)') == 'false' # int is not defined assert evalpy('isinstance("", str)') == 'true' assert evalpy('isinstance("", "string")') == 'true' # assert evalpy('isinstance("", list)') == 'false' assert evalpy('isinstance(True, bool)') == 'true' assert evalpy('isinstance(True, "boolean")') == 'true' # assert evalpy('isinstance(True, float)') == 'false' assert evalpy('isinstance([], list)') == 'true' assert evalpy('isinstance([], "array")') == 'true' # assert evalpy('isinstance([], "object")') == 'false' assert evalpy('isinstance([], "Object")') == 'false' assert evalpy('isinstance([], dict)') == 'false' assert evalpy('isinstance({}, dict)') == 'true' assert evalpy('isinstance({}, "object")') == 'true' # assert evalpy('isinstance({}, list)') == 'false' assert evalpy('isinstance({}, "array")') == 'false' assert evalpy('isinstance(eval, types.FunctionType)') == 'true' assert evalpy('isinstance(eval, FunctionType)') == 'true' assert evalpy('isinstance(3, types.FunctionType)') == 'false' # own class code = 'function MyClass () {return this;}\nx = new MyClass();\n' assert evaljs(code + py2js('isinstance(x, "object")')) == 'true' assert evaljs(code + py2js('isinstance(x, "Object")')) == 'true' assert evaljs(code + py2js('isinstance(x, "MyClass")')) == 'true' assert evaljs(code + py2js('isinstance(x, MyClass)')) == 'true'
def test_raw_js(self): def func(a, b): """ var c = 3; return a + b + c; """ code = py2js(func) assert evaljs(code + 'func(100, 10)') == '113' assert evaljs(code + 'func("x", 10)') == 'x103'
def test_isinstance(self): # The resulting code is not particularly pretty, so we just # test outcome assert evalpy('isinstance(3.0, list) == True') == 'false' assert evalpy('isinstance(3.0, float) == True') == 'true' assert evalpy('x={}; isinstance(x.foo, "undefined")') == 'true' assert evalpy('isinstance(None, "null")') == 'true' assert evalpy('isinstance(undefined, "undefined")') == 'true' # assert evalpy('isinstance(None, "undefined")') == 'false' assert evalpy('isinstance(undefined, "null")') == 'false' assert evalpy('isinstance(3, float)') == 'true' assert evalpy('isinstance(3, (int, float))') == 'true' assert evalpy('isinstance(3, "number")') == 'true' # #assert evalpy('isinstance(3, int)') == 'false' # int is not defined assert evalpy('isinstance("", str)') == 'true' assert evalpy('isinstance("", "string")') == 'true' # assert evalpy('isinstance("", list)') == 'false' assert evalpy('isinstance(True, bool)') == 'true' assert evalpy('isinstance(True, "boolean")') == 'true' # assert evalpy('isinstance(True, float)') == 'false' assert evalpy('isinstance([], list)') == 'true' assert evalpy('isinstance([], "array")') == 'true' # assert evalpy('isinstance([], "object")') == 'false' assert evalpy('isinstance([], "Object")') == 'false' assert evalpy('isinstance([], dict)') == 'false' assert evalpy('isinstance({}, dict)') == 'true' assert evalpy('isinstance({}, "object")') == 'true' # assert evalpy('isinstance({}, list)') == 'false' assert evalpy('isinstance({}, "array")') == 'false' assert evalpy('isinstance(eval, types.FunctionType)') == 'true' assert evalpy('isinstance(eval, FunctionType)') == 'true' assert evalpy('isinstance(3, types.FunctionType)') == 'false' # own class code = 'function MyClass () {return this;}\nvar x = new MyClass();\n' assert evaljs(code + py2js('isinstance(x, "object")')) == 'true' assert evaljs(code + py2js('isinstance(x, "Object")')) == 'true' assert evaljs(code + py2js('isinstance(x, "MyClass")')) == 'true' assert evaljs(code + py2js('isinstance(x, MyClass)')) == 'true'
def test_raw_js(): @js def func(a, b): """ var c = 3; return a + b + c; """ code = 'var x = ' + func.jscode assert evaljs(code + 'x(100, 10)') == '113' assert evaljs(code + 'x("x", 10)') == 'x103'
def test_module(self): code = Parser('"docstring"\nfoo=3;bar=4;_priv=0;', "mymodule").dump() # Has docstring assert code.count("// docstring") == 1 # Test that global variables exist assert evaljs(code + "mymodule.foo+mymodule.bar") == "7" # And privates do not assert evaljs(code + "mymodule._priv===undefined") == "true"
def test_docstring(self): # And that its not interpreted as raw js def func(a, b): """ docstring """ return a + b code = py2js(func) assert evaljs(code + 'func(100, 10)') == '110' assert evaljs(code + 'func("x", 10)') == 'x10' assert code.count('// docstring') == 1
def test_raw_js(self): @js def func(a, b): """ var c = 3; return a + b + c; """ code = 'var x = ' + func.jscode assert evaljs(code + 'x(100, 10)') == '113' assert evaljs(code + 'x("x", 10)') == 'x103'
def test_module(self): code = Parser('"docstring"\nfoo=3;bar=4;_priv=0;', 'mymodule').dump() # Has docstring assert code.count('// docstring') == 1 # Test that global variables exist assert evaljs(code+'mymodule.foo+mymodule.bar') == '7' # And privates do not assert evaljs(code+'mymodule._priv===undefined') == 'true'
def test_default_args(self): def func(self, foo, bar=4): return foo + bar code = py2js(func) lines = [line for line in code.split('\n') if line] assert lines[1] == 'func = function (foo, bar) {' assert '4' in code assert evaljs(code + 'func(2)') == '6' assert evaljs(code + 'func(2, 2)') == '4' assert evaljs(code + 'func(0, 0)') == '0'
def test_docstring(self): # And that its not interpreted as raw js @js def func(a, b): """ docstring """ return a + b code = 'var x = ' + func.jscode assert evaljs(code + 'x(100, 10)') == '110' assert evaljs(code + 'x("x", 10)') == 'x10' assert code.count('// docstring') == 1
def test_docstring(self): # And that its not interpreted as raw js @js def func(a, b): """ a docstring """ return a + b code = 'var x = ' + func.jscode assert evaljs(code + 'x(100, 10)') == '110' assert evaljs(code + 'x("x", 10)') == 'x10' assert code.count('// a docstring') == 1
def test_default_args(self): @js def func(self, foo, bar=4): return foo + bar code = func.jscode lines = [line for line in code.split('\n') if line] assert lines[0] == 'function (foo, bar) {' assert '4' in code assert evaljs('x=' + code + 'x(2)') == '6' assert evaljs('x=' + code + 'x(2, 2)') == '4' assert evaljs('x=' + code + 'x(0, 0)') == '0'
def test_var_args2(self): def func(self, foo, *args): return args code1 = py2js(func) #lines = [line for line in code1.split('\n') if line] code2 = py2js('func(0, 2, 3)') assert evaljs(code1 + code2, False) == '[2,3]' code2 = py2js('func(0)') assert evaljs(code1 + code2, False) == '[]' code2 = py2js('a=[0,2,3]\nfunc(*a)') assert evaljs(code1 + code2, False) == '[2,3]' code2 = py2js('a=[2,3]\nfunc(0,1,2,*a)') assert evaljs(code1 + code2, False) == '[1,2,2,3]'
def test_scope(self): @js def func(self): def foo(z): y = 2 stub = False only_here = 1 return x + y + z x = 1 y = 0 y = 1 z = 1 res = foo(3) stub = True return res + y # should return 1+2+3+1 == 7 code = 'var x = ' + func.jscode vars1 = code.splitlines()[1] vars2 = code.splitlines()[3] assert vars1.strip().startswith('var ') assert vars2.strip().startswith('var ') assert 'y' in vars1 and 'y' in vars2 assert 'stub' in vars1 and 'stub' in vars2 assert 'only_here' in vars2 and 'only_here' not in vars1 assert evaljs(code + 'x()') == '7'
def test_py2s_rename_function_to_method(): code1 = py2js(Foo2, 'Bar') code = code1 + py2js(foo2, 'Bar.prototype.bar') assert 'foo' not in code.lower() assert evaljs(code + 'var m=new Bar(); m.bar();') == '49' code1 = py2js(Foo2, 'Bar') code = code1 + '\nvar $Bar = Bar.prototype;\n' + py2js(foo2, '$Bar.bar') assert 'foo' not in code.lower() assert evaljs(code + 'var m=new Bar(); m.bar();') == '49' code1 = py2js(Foo2, 'xx.Bar') code = code1 + py2js(foo2, 'xx.Bar.prototype.bar') assert 'foo' not in code.lower() assert evaljs('var xx={};\n' + code + 'var m=new xx.Bar(); m.bar();') == '49'
def test_scope(self): def func(self): def foo(z): y = 2 stub = False # noqa only_here = 1 # noqa return x + y + z x = 1 y = 0 y = 1 # noqa z = 1 # noqa res = foo(3) stub = True # noqa return res + y # should return 1+2+3+1 == 7 # Find function start code = py2js(func) i = code.splitlines().index('var func;') assert i >= 0 # Find first lines of functions, where the vars are defined vars1 = code.splitlines()[i+2] vars2 = code.splitlines()[i+4] assert vars1.strip().startswith('var ') assert vars2.strip().startswith('var ') assert 'y' in vars1 and 'y' in vars2 assert 'stub' in vars1 and 'stub' in vars2 assert 'only_here' in vars2 and 'only_here' not in vars1 assert evaljs(code + 'func()') == '7'
def test_scope(self): def func(self): def foo(z): y = 2 stub = False # noqa only_here = 1 # noqa return x + y + z x = 1 y = 0 y = 1 # noqa z = 1 # noqa res = foo(3) stub = True # noqa return res + y # should return 1+2+3+1 == 7 code = py2js(func) vars1 = code.splitlines()[2] vars2 = code.splitlines()[4] assert vars1.strip().startswith('var ') assert vars2.strip().startswith('var ') assert 'y' in vars1 and 'y' in vars2 assert 'stub' in vars1 and 'stub' in vars2 assert 'only_here' in vars2 and 'only_here' not in vars1 assert evaljs(code + 'func()') == '7'
def test_bound_methods(self): class MyClass14: def __init__(self): self.a = 1 def add2(self): self.a += 2 class MyClass15(MyClass14): def add3(self): self.a += 3 code = py2js(MyClass14) + py2js(MyClass15) assert evaljs(code + 'var m = new MyClass14(); m.add2(); m.add2(); m.a') == '5' assert evaljs(code + 'var m = new MyClass14(); var f = m.add2; f(); f(); m.a') == '5' assert evaljs(code + 'var m = new MyClass15(); var f = m.add3; f(); f(); m.a') == '7' assert evaljs(code + 'var m = new MyClass15(); var f2 = m.add2, f3 = m.add3; f2(); f3(); m.a') == '6'
def test_var_args2(self): @js def func(self, foo, *args): return args code1 = 'var x = ' + func.jscode lines = [line for line in code1.split('\n') if line] code2 = py2js('x(0, 2, 3)') assert evaljs(code1 + code2, False) == '[2,3]' code2 = py2js('x(0)') assert evaljs(code1 + code2, False) == '[]' code2 = py2js('a=[0,2,3]\nx(*a)') assert evaljs(code1 + code2, False) == '[2,3]' code2 = py2js('a=[2,3]\nx(0,1,2,*a)') assert evaljs(code1 + code2, False) == '[1,2,2,3]'
def test_catching2(self): def catchtest(x): try: raise ValueError('foo') except Exception as err: print(err.message) assert evaljs(py2js(catchtest, 'f') + 'f(1)').endswith('foo')
def test_catching2(self): def catchtest(x): try: raise ValueError('foo') except Exception as err: print(err.message) return undefined assert evaljs(py2js(catchtest, 'f') + 'f(1)').endswith('foo')
def test_with_exception(self): def contexttest(x): c = dict(__enter__=lambda: print('enter'), __exit__=lambda et, ev, tb: print(et)) try: with c: print(42) if x != 1: raise AttributeError('fooerror') print(43) except Exception as e: print(e.message) print('.') return undefined assert evaljs(py2js(contexttest, 'f') + 'f(1)') == 'enter\n42\n43\nnull\n.' s = 'enter\n42\nAttributeError\nAttributeError: fooerror\n.' assert evaljs(py2js(contexttest, 'f') + 'f(0)') == s
def test_catching2(self): @js def catchtest(x): try: raise ValueError('foo') except Exception as err: print(err.message) assert evaljs('var f = ' + catchtest.jscode + 'f(1)').endswith('foo')
def test_inheritance_super_more(self): class MyClass4: def foo(self): return self class MyClass5(MyClass4): def foo(self, test): return super().foo() def foo(): return super().foo() code = py2js(MyClass4) + py2js(MyClass5) code += py2js(foo).replace('super()', 'MyClass4.prototype') code += 'var m4=new MyClass4(), m5=new MyClass5();' assert evaljs(code + 'm4.foo() === m4') == 'true' assert evaljs(code + 'm4.foo() === m4') == 'true' assert evaljs(code + 'foo.call(m4) === m4') == 'true'
def test_assert_catch(self): def catchtest(x): try: assert False except AssertionError: print('assertion-error') return undefined assert evaljs(py2js(catchtest, 'f') + 'f(1)') == 'assertion-error'
def test_class(self): @js class MyClass: foo = 7 foo = foo + 1 def __init__(self): self.bar = 7 def addOne(self): self.bar += 1 code = MyClass.jscode + 'var m = new MyClass();' assert evaljs(code + 'm.bar;') == '7' assert evaljs(code + 'm.addOne();m.bar;') == '8' # class vars assert evaljs(code + 'm.foo;') == '8'
def test_catching(self): def catchtest(x): try: if x == 1: raise ValueError('foo') elif x == 2: raise RuntimeError('foo') else: raise "oh crap" except ValueError: print('value-error') except RuntimeError: print('runtime-error') except Exception: print('other-error') assert evaljs(py2js(catchtest, 'f') + 'f(1)') == 'value-error' assert evaljs(py2js(catchtest, 'f') + 'f(2)') == 'runtime-error' assert evaljs(py2js(catchtest, 'f') + 'f(3)') == 'other-error'
def test_class(self): class MyClass: """ docstring """ foo = 7 foo = foo + 1 def __init__(self): self.bar = 7 def addOne(self): self.bar += 1 code = py2js(MyClass) + 'var m = new MyClass();' assert code.count('// docstring') == 1 assert evaljs(code + 'm.bar;') == '7' assert evaljs(code + 'm.addOne();m.bar;') == '8' # class vars assert evaljs(code + 'm.foo;') == '8'
def test_nonlocal(self): assert py2js('nonlocal foo;foo = 3').strip() == 'foo = 3;' func3_code = """def func3(): def inner(): nonlocal x x = 3 x = 2 inner() return x """ assert evaljs(py2js(func3_code)+'func3()') == '3'
def test_instantiation(self): # Test creating instances assert 'new' in py2js('a = Foo()') assert 'new' in py2js('a = x.Foo()') assert 'new' not in py2js('a = foo()') assert 'new' not in py2js('a = _foo()') assert 'new' not in py2js('a = _Foo()') assert 'new' not in py2js('a = this.Foo()') assert 'new' not in py2js('a = JSON.stringify(x)') jscode = 'function Foo() {this.x = 3}\nx=1;\n' assert evaljs(jscode + py2js('a=Foo()\nx')) == '1'