async def test_component_id_uniqueness(): """ JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js 3 6 3 ---------- JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js """ # Test uniqueness of component id's c1, s1 = launch(JsComponentB) c2, s2 = launch(JsComponentB) with c1: c11 = CreatingJsComponent2() # JsComponent that has local JsComponent c11.create_sub() c11.create_sub() with c2: c22 = CreatingJsComponent2() # JsComponent that has local JsComponent c22.create_sub() c22.create_sub() await roundtrip(s1, s2) cc = [c1, c11, c11.sub, c2, c22, c22.sub] for c in cc: print(c.id) c.session.send_command('EVAL', c.id, 'id') await roundtrip(s1, s2) # That was not very unique though s = set() for c in cc: s.add(c.id) print(len(s)) # But this is s = set() for c in cc: s.add(c.uid) print(len(s)) # And this should be too s = set() for c in [c1, c11, c11.sub]: s.add(c.id.split('_')[-1]) print(len(s))
async def test_component_id_uniqueness(): """ JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js 3 6 3 ---------- JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js JsComponentB_1 CreatingJsComponent2_2 CreatingJsComponent2_2js """ # Test uniqueness of component id's c1, s1 = launch(JsComponentB) c2, s2 = launch(JsComponentB) with c1: c11 = CreatingJsComponent2() # JsComponent that has local JsComponent c11.create_sub() c11.create_sub() with c2: c22 = CreatingJsComponent2() # JsComponent that has local JsComponent c22.create_sub() c22.create_sub() await roundtrip(s1, s2) cc = [c1, c11, c11.sub, c2, c22, c22.sub] for c in cc: print(c.id) c.session.send_command('EVAL', c.id, 'id') await roundtrip(s1, s2) # That was not very unique though s = set() for c in cc: s.add(c.id) print(len(s)) # But this is s = set() for c in cc: s.add(c.uid) print(len(s)) # And this should be too s = set() for c in [c1, c11, c11.sub]: s.add(c.id.split('_')[-1]) print(len(s))
async def test_proxy_binding21(): """ 14 None 24 None 24 24 ---------- 14 ? JsComponentA undefined ? JsComponentA undefined """ # Test multiple sessions, and sharing objects c1, s1 = launch(JsComponentB) c2, s2 = launch(JsComponentB) with c1: c11 = JsComponentA() # JsComponent that has local JsComponent c1.set_sub1(c11) with c2: c22 = JsComponentA() # JsComponent that has local JsComponent c2.set_sub1(c22) await roundtrip(s1, s2) c11.set_foo(14) c22.set_foo(24) await roundtrip(s1, s2) print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2) # So far, not much news, now break the universe ... c1.set_sub1(c2.sub1) await roundtrip(s1, s2) print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) # In JS, c1.sub1 will be a stub s1.send_command('EVAL', c1.id, 'sub1.id') s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2) # But we can still "handle" it c1.sub1_to_sub2() await roundtrip(s1, s2) # And now c1.sub2.foo has the value of c2.sub1.foo print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) s1.send_command('EVAL', c1.id, 'sub1.id') s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2)
async def test_proxy_binding21(): """ 14 None 24 None 24 24 ---------- 14 ? JsComponentA undefined ? JsComponentA undefined """ # Test multiple sessions, and sharing objects c1, s1 = launch(JsComponentB) c2, s2 = launch(JsComponentB) with c1: c11 = JsComponentA() # JsComponent that has local JsComponent c1.set_sub1(c11) with c2: c22 = JsComponentA() # JsComponent that has local JsComponent c2.set_sub1(c22) await roundtrip(s1, s2) c11.set_foo(14) c22.set_foo(24) await roundtrip(s1, s2) print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2) # So far, not much news, now break the universe ... c1.set_sub1(c2.sub1) await roundtrip(s1, s2) print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) # In JS, c1.sub1 will be a stub s1.send_command('EVAL', c1.id, 'sub1.id') s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2) # But we can still "handle" it c1.sub1_to_sub2() await roundtrip(s1, s2) # And now c1.sub2.foo has the value of c2.sub1.foo print(c1.sub1 and c1.sub1.foo, c1.sub2 and c1.sub2.foo) s1.send_command('EVAL', c1.id, 'sub1.id') s1.send_command('EVAL', c1.id, 'sub1.foo') await roundtrip(s1, s2)
async def test_jscomponent_prop1(): """ 0 0 3 ---------- 0 3 """ c, s = launch(JsComponentA) # Note: set_foo() immediately sends an INVOKE command. If the # subsequent (now commented) EVAL command is not handled in the same # event loop iter, the value will already have been updated. s.send_command('EVAL', c.id, 'foo') c.set_foo(3) print(c.foo) # s.send_command('EVAL', c.id, 'foo') loop.iter() print(c.foo) # still not set await roundtrip(s) print(c.foo) s.send_command('EVAL', c.id, 'foo') await roundtrip(s)
async def test_jscomponent_reaction2(): """ 0 0 3 ---------- sub foo changed 0 sub foo changed 3 """ c1, s = launch(JsComponentA) with c1: c2 = JsComponentA() # JsComponent sub c1.set_sub(c2) print(c2.foo) await roundtrip(s) c2.set_foo(3) print(c2.foo) await roundtrip(s) print(c2.foo) await roundtrip(s)
async def test_jscomponent_emitter1(): """ ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ---------- got bar event 16 got bar event 17 got bar event 18 got bar event 19 """ c, s = launch(JsComponentA) c.bar_event(6) c.bar_event(7) await roundtrip(s) c.bar_event(8) c.bar_event(9) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [16]) s.send_command('INVOKE', c.id, 'bar_event', [17]) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [18]) s.send_command('INVOKE', c.id, 'bar_event', [19]) await roundtrip(s)
async def test_jscomponent_init1(): """ 0 0 0 10 20 20 ---------- init init """ # This test is important. We have plenty of tests that ensure that the init # args and kwargs work in both Python and JS variants of Component, but # instantiating a JsComponent in Python will have to communicate these! c1, s = launch(app.PyComponent) with c1: c2 = JsComponentA(foo=10) c3 = JsComponentC(20) c4 = JsComponentC(20, foo=10) # What happens in init takes preference # Data is not yet synced print(c2.foo) print(c3.foo) print(c4.foo) await roundtrip(s) print(c2.foo) print(c3.foo) print(c4.foo)
async def test_pycomponent_reaction1(): """ 0 sub foo changed 0 0 sub foo changed 3 3 ---------- """ c1, s = launch(PyComponentA) with c1: c2 = PyComponentA() # PyComponent sub c1.set_sub(c2) print(c2.foo) loop.iter() c2.set_foo(3) print(c2.foo) loop.iter() print(c2.foo) await roundtrip(s)
async def test_jscomponent_emitter1(): """ ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ---------- got bar event 16 got bar event 17 got bar event 18 got bar event 19 """ c, s = launch(JsComponentA) c.bar_event(6) c.bar_event(7) await roundtrip(s) c.bar_event(8) c.bar_event(9) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [16]) s.send_command('INVOKE', c.id, 'bar_event', [17]) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [18]) s.send_command('INVOKE', c.id, 'bar_event', [19]) await roundtrip(s)
async def test_jscomponent_reaction2(): """ 0 0 3 ---------- sub foo changed 0 sub foo changed 3 """ c1, s = launch(JsComponentA) with c1: c2 = JsComponentA() # JsComponent sub c1.set_sub(c2) print(c2.foo) await roundtrip(s) c2.set_foo(3) print(c2.foo) await roundtrip(s) print(c2.foo) await roundtrip(s)
async def test_jscomponent_prop1(): """ 0 0 3 ---------- 0 3 """ c, s = launch(JsComponentA) # Note: set_foo() immediately sends an INVOKE command. If the # subsequent (now commented) EVAL command is not handled in the same # event loop iter, the value will already have been updated. s.send_command('EVAL', c.id, 'foo') c.set_foo(3) print(c.foo) # s.send_command('EVAL', c.id, 'foo') loop.iter() print(c.foo) # still not set await roundtrip(s) print(c.foo) s.send_command('EVAL', c.id, 'foo') await roundtrip(s)
async def test_pycomponent_emitter1(): """ got bar event [6, 7] got bar event [8, 9] ---------- ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter """ c, s = launch(PyComponentA) c.bar_event(6) c.bar_event(7) await roundtrip(s) c.bar_event(8) c.bar_event(9) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [16]) s.send_command('INVOKE', c.id, 'bar_event', [17]) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [18]) s.send_command('INVOKE', c.id, 'bar_event', [19]) await roundtrip(s)
async def test_pycomponent_reaction1(): """ 0 sub foo changed 0 0 sub foo changed 3 3 ---------- """ c1, s = launch(PyComponentA) with c1: c2 = PyComponentA() # PyComponent sub c1.set_sub(c2) print(c2.foo) loop.iter() c2.set_foo(3) print(c2.foo) loop.iter() print(c2.foo) await roundtrip(s)
async def test_dispose_PyComponent3(): """ done disposing MyPyComponent_2 disposing MyPyComponent_3 ---------- ? Cannot dispose a PyComponent from JS ? Cannot dispose a PyComponent from JS done """ # Cannot dispose from JS # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) # Try to dispose s.send_command('INVOKE', c1.id, 'dispose', []) s.send_command('INVOKE', c2.id, 'dispose', []) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_jscomponent_init1(): """ 0 0 0 10 20 20 ---------- init init """ # This test is important. We have plenty of tests that ensure that the init # args and kwargs work in both Python and JS variants of Component, but # instantiating a JsComponent in Python will have to communicate these! c1, s = launch(app.PyComponent) with c1: c2 = JsComponentA(foo=10) c3 = JsComponentC(20) c4 = JsComponentC(20, foo=10) # What happens in init takes preference # Data is not yet synced print(c2.foo) print(c3.foo) print(c4.foo) await roundtrip(s) print(c2.foo) print(c3.foo) print(c4.foo)
async def test_pycomponent_emitter1(): """ got bar event [6, 7] got bar event [8, 9] ---------- ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter ? Cannot use emitter """ c, s = launch(PyComponentA) c.bar_event(6) c.bar_event(7) await roundtrip(s) c.bar_event(8) c.bar_event(9) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [16]) s.send_command('INVOKE', c.id, 'bar_event', [17]) await roundtrip(s) s.send_command('INVOKE', c.id, 'bar_event', [18]) s.send_command('INVOKE', c.id, 'bar_event', [19]) await roundtrip(s)
async def test_dispose_PyComponent3(): """ done disposing MyPyComponent_2 disposing MyPyComponent_3 ---------- ? Cannot dispose a PyComponent from JS ? Cannot dispose a PyComponent from JS done """ # Cannot dispose from JS # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) # Try to dispose s.send_command('INVOKE', c1.id, 'dispose', []) s.send_command('INVOKE', c2.id, 'dispose', []) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_pycomponent_action_chained(): """ hi foo hi bar hi xx ---------- """ c, s = launch(PyComponentA) c.greet('foo').greet('bar').greet('xx') await roundtrip(s)
async def test_pycomponent_action_chained(): """ hi foo hi bar hi xx ---------- """ c, s = launch(PyComponentA) c.greet('foo').greet('bar').greet('xx') await roundtrip(s)
async def test_pycomponent_action1(): """ hi foo hi bar hi spam ---------- """ c, s = launch(PyComponentA) c.greet('foo') c.greet('bar') s.send_command('INVOKE', c.id, 'greet', ["spam"]) await roundtrip(s)
async def test_pycomponent_action1(): """ hi foo hi bar hi spam ---------- """ c, s = launch(PyComponentA) c.greet('foo') c.greet('bar') s.send_command('INVOKE', c.id, 'greet', ["spam"]) await roundtrip(s)
async def test_proxy_binding3(): """ sub foo changed 0 sub foo changed 3 sub foo changed 6 sub foo changed 7 ? Using stub component ? session does not know it ---------- """ # Test that local components only send events when there is a proxy, # and that when events are send anyway, warnings are shown c1, s = launch(PyComponentA) with c1: c2 = JsComponentA() # JsComponent that has local JsComponent c1.set_sub(c2) id2 = c2.id # Change foo of c2 c2.set_foo(3) await roundtrip(s) # Now, we're pretend that to drop the instance s.send_command('INVOKE', c2.id, '_flx_set_has_proxy', [False]) await roundtrip(s) # We don't get the events anymore c2.set_foo(4) c2.set_foo(5) await roundtrip(s) # Re-establish s.send_command('INVOKE', c2.id, '_flx_set_has_proxy', [True]) await roundtrip(s) # We get these c2.set_foo(6) s.send_command('INVOKE', id2, 'set_foo', [7]) # same thing, really await roundtrip(s) # Now, we simulate destroying the proxy without JS knowing s._component_instances.pop(id2) # And then ... invoking an event will raise one error for not being able # to invoke in Python, and one for not being able to decode the "source" # of the event. s.send_command('INVOKE', id2, 'set_foo', [9]) await roundtrip(s)
async def test_proxy_binding2(): """ 7 7 ---------- sub foo changed 7 sub foo changed 7 """ # Get ref to JsComponent instantiated by a JsComponent, # drop that ref, re-get the proxy instance, and verify that its # a different instance representing the same object in JS c1, s = launch(app.PyComponent) with c1: c2 = CreatingJsComponent() # JsComponent that has local JsComponent await roundtrip(s) assert c2.sub is None # Get access to the sub component c2.apply_sub() await roundtrip(s) await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) print(c3.foo) # Get id of c3 and get rid of any references id3 = id(c3) c3_ref = weakref.ref(c3) c3_id = c3.id c2.set_sub(None) for i in range(5): # need a few roundtrips for session to drop c3 await roundtrip(s) del c3 for i in range(5): await roundtrip(s) gc.collect() assert c3_ref() is None # Python dropped it, but JS still has the object! # Get access to the sub component again (proxy thereof, really) c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) assert c3.id == c3_id print(c3.foo)
async def test_proxy_binding2(): """ 7 7 ---------- sub foo changed 7 sub foo changed 7 """ # Get ref to JsComponent instantiated by a JsComponent, # drop that ref, re-get the proxy instance, and verify that its # a different instance representing the same object in JS c1, s = launch(app.PyComponent) with c1: c2 = CreatingJsComponent() # JsComponent that has local JsComponent await roundtrip(s) assert c2.sub is None # Get access to the sub component c2.apply_sub() await roundtrip(s) await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) print(c3.foo) # Get id of c3 and get rid of any references id3 = id(c3) c3_ref = weakref.ref(c3) c3_id = c3.id c2.set_sub(None) for i in range(5): # need a few roundtrips for session to drop c3 await roundtrip(s) del c3 for i in range(5): await roundtrip(s) gc.collect() assert c3_ref() is None # Python dropped it, but JS still has the object! # Get access to the sub component again (proxy thereof, really) c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) assert c3.id == c3_id print(c3.foo)
async def test_proxy_binding3(): """ sub foo changed 0 sub foo changed 3 sub foo changed 6 sub foo changed 7 ? Using stub component ? session does not know it ---------- """ # Test that local components only send events when there is a proxy, # and that when events are send anyway, warnings are shown c1, s = launch(PyComponentA) with c1: c2 = JsComponentA() # JsComponent that has local JsComponent c1.set_sub(c2) id2 = c2.id # Change foo of c2 c2.set_foo(3) await roundtrip(s) # Now, we're pretend that to drop the instance s.send_command('INVOKE', c2.id, '_flx_set_has_proxy', [False]) await roundtrip(s) # We don't get the events anymore c2.set_foo(4) c2.set_foo(5) await roundtrip(s) # Re-establish s.send_command('INVOKE', c2.id, '_flx_set_has_proxy', [True]) await roundtrip(s) # We get these c2.set_foo(6) s.send_command('INVOKE', id2, 'set_foo', [7]) # same thing, really await roundtrip(s) # Now, we simulate destroying the proxy without JS knowing s._component_instances.pop(id2) # And then ... invoking an event will raise one error for not being able # to invoke in Python, and one for not being able to decode the "source" # of the event. s.send_command('INVOKE', id2, 'set_foo', [9]) await roundtrip(s)
async def test_pycomponent_action2(): """ hi foo hi bar hi spam ---------- """ c1, s = launch(PyComponentA) with c1: c = PyComponentA() assert c.session is s c.greet('foo') c.greet('bar') s.send_command('INVOKE', c.id, 'greet', ["spam"]) await roundtrip(s)
async def test_proxy_binding1(): """ sub foo changed 7 7 sub foo changed 7 7 ---------- """ # Get ref to JsComponent instantiated by a PyComponent c1, s = launch(app.PyComponent) with c1: c2 = CreatingPyComponent() # PyComponent that has local JsComponent await roundtrip(s) assert c2.sub is None # Get access to the sub component c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) print(c3.foo) # Get id of c3 and get rid of any references c3_id = c3.id c3_ref = weakref.ref(c3) c2.set_sub(None) for i in range(5): await roundtrip(s) del c3 for i in range(5): await roundtrip(s) assert c3_ref() is not None # because PyComponent has it # Get access to the sub component again (proxy thereof, really) c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) assert c3.id == c3_id print(c3.foo)
async def test_proxy_binding1(): """ sub foo changed 7 7 sub foo changed 7 7 ---------- """ # Get ref to JsComponent instantiated by a PyComponent c1, s = launch(app.PyComponent) with c1: c2 = CreatingPyComponent() # PyComponent that has local JsComponent await roundtrip(s) assert c2.sub is None # Get access to the sub component c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) print(c3.foo) # Get id of c3 and get rid of any references c3_id = c3.id c3_ref = weakref.ref(c3) c2.set_sub(None) for i in range(5): await roundtrip(s) del c3 for i in range(5): await roundtrip(s) assert c3_ref() is not None # because PyComponent has it # Get access to the sub component again (proxy thereof, really) c2.apply_sub() await roundtrip(s) c3 = c2.sub assert isinstance(c3, JsComponentA) assert c3.id == c3_id print(c3.foo)
async def test_jscomponent_action2(): """ ---------- hi foo hi bar hi spam """ c1, s = launch(JsComponentA) with c1: c = JsComponentA() assert c.session is s c.greet('foo') c.greet('bar') s.send_command('INVOKE', c.id, 'greet', ["spam"]) await roundtrip(s) await roundtrip(s)
async def test_dispose_PyComponent1(): """ MyPyComponent_2 MyPyComponent_3 disposing MyPyComponent_2 disposing MyPyComponent_3 None None done ---------- MyPyComponent_2 MyPyComponent_3 null null done """ # Explicit call to dispose() # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() await roundtrip(s) c1_id, c2_id = c1.id, c2.id check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose c1.dispose() c2.dispose() await roundtrip(s) await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_dispose_PyComponent1(): """ MyPyComponent_2 MyPyComponent_3 disposing MyPyComponent_2 disposing MyPyComponent_3 None None done ---------- MyPyComponent_2 MyPyComponent_3 null null done """ # Explicit call to dispose() # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() await roundtrip(s) c1_id, c2_id = c1.id, c2.id check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose c1.dispose() c2.dispose() await roundtrip(s) await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_pycomponent_prop1(): """ 0 3 3 ---------- 0 3 """ c, s = launch(PyComponentA) c.set_foo(3) print(c.foo) s.send_command('EVAL', c.id, 'foo') loop.iter() print(c.foo) # this will mutate foo await roundtrip(s) print(c.foo) s.send_command('EVAL', c.id, 'foo') await roundtrip(s)
async def test_pycomponent_prop1(): """ 0 3 3 ---------- 0 3 """ c, s = launch(PyComponentA) c.set_foo(3) print(c.foo) s.send_command('EVAL', c.id, 'foo') loop.iter() print(c.foo) # this will mutate foo await roundtrip(s) print(c.foo) s.send_command('EVAL', c.id, 'foo') await roundtrip(s)
async def test_dispose_JsComponent3(): """ MyJsComponent_2 MyJsComponent_3 None None done ---------- MyJsComponent_2 MyJsComponent_3 disposing MyJsComponent_2 disposing MyJsComponent_3 null null done """ # Dispose from JS # Init c, s = launch(PyComponent) with c: c1 = MyJsComponent() c2 = MyJsComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose from JS s.send_command('INVOKE', c1.id, 'dispose', []) s.send_command('INVOKE', c2.id, 'dispose', []) await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_dispose_JsComponent3(): """ MyJsComponent_2 MyJsComponent_3 None None done ---------- MyJsComponent_2 MyJsComponent_3 disposing MyJsComponent_2 disposing MyJsComponent_3 null null done """ # Dispose from JS # Init c, s = launch(PyComponent) with c: c1 = MyJsComponent() c2 = MyJsComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose from JS s.send_command('INVOKE', c1.id, 'dispose', []) s.send_command('INVOKE', c2.id, 'dispose', []) await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_dispose_PyComponent2(): """ MyPyComponent_2 MyPyComponent_3 disposing MyPyComponent_2 disposing MyPyComponent_3 None None done ---------- MyPyComponent_2 MyPyComponent_3 null null done """ # Dispose by losing the reference # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose via Python gc del c1, c2 gc.collect() # will schedule call to _dispose await roundtrip(s) # which we will handle here check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_dispose_PyComponent2(): """ MyPyComponent_2 MyPyComponent_3 disposing MyPyComponent_2 disposing MyPyComponent_3 None None done ---------- MyPyComponent_2 MyPyComponent_3 null null done """ # Dispose by losing the reference # Init c, s = launch(PyComponent) with c: c1 = MyPyComponent() c2 = MyPyComponent() c1_id, c2_id = c1.id, c2.id await roundtrip(s) check_alive(s, c1_id, c2_id) await roundtrip(s) # Dispose via Python gc del c1, c2 gc.collect() # will schedule call to _dispose await roundtrip(s) # which we will handle here check_alive(s, c1_id, c2_id) await roundtrip(s) # End print('done') s.send_command('EVAL', '"done"') await roundtrip(s)
async def test_pycomponent_init1(): """ init init 10 20 20 ---------- """ c1, s = launch(app.PyComponent) with c1: c2 = PyComponentA(foo=10) c3 = PyComponentC(20) c4 = PyComponentC(20, foo=10) # What happens in init takes preference await roundtrip(s) print(c2.foo) print(c3.foo) print(c4.foo)
async def test_pycomponent_init1(): """ init init 10 20 20 ---------- """ c1, s = launch(app.PyComponent) with c1: c2 = PyComponentA(foo=10) c3 = PyComponentC(20) c4 = PyComponentC(20, foo=10) # What happens in init takes preference await roundtrip(s) print(c2.foo) print(c3.foo) print(c4.foo)