def test_action_python_only(): m = MyObject() # Action decorator needs proper callable with raises(TypeError): event.action(3) if '__pypy__' in sys.builtin_module_names: pass # skip else: with raises(TypeError): event.action(isinstance) # Check type of the instance attribute assert isinstance(m.set_foo, event._action.Action) # Cannot set or delete an action with raises(AttributeError): m.set_foo = 3 with raises(AttributeError): del m.set_foo # Repr and docs assert 'action' in repr(m.__class__.set_foo).lower() assert 'action' in repr(m.set_foo).lower() assert 'foo' in repr(m.set_foo) # Also for autogenereated action m = MyObject_autoaction() assert 'action' in repr(m.__class__.set_foo).lower() assert 'action' in repr(m.set_foo).lower() assert 'foo' in repr(m.set_foo)
def test_fail_exception(): with raises(AttributeError): func_fail_exception1() with raises(AttributeError): func_fail_exception2() with raises(Exception): # eval_js turns processerror into Exception func_fail_exception3()
def test_js_module_types(): code = create_js_module('baz.js', CODE, ['bb'], 'aa', 'hidden') assert 'define' not in code assert 'require' not in code assert 'bb' not in code assert 'aa' not in code assert 'return' not in code code = create_js_module('baz.js', CODE, ['bb'], 'aa', 'simple') assert 'define' not in code assert 'require' not in code assert 'bb' not in code assert 'return aa' in code code = create_js_module('baz.js', CODE, ['bb'], 'aa', 'amd') assert 'define' in code assert 'require' not in code assert 'bb' in code assert 'return aa' in code code = create_js_module('baz.js', CODE, ['bb'], 'aa', 'umd') assert 'define' in code assert 'require' in code assert 'bb' in code assert 'return aa' in code with raises(ValueError): # type not a str create_js_module('baz.js', CODE, ['bb'], 'aa', 3) with raises(ValueError): # invalid type create_js_module('baz.js', CODE, ['bb'], 'aa', 'not_known')
def test_set_log_level(): with raises(ValueError): set_log_level('notaloglevel') with raises(TypeError): set_log_level([])
def test_iter(): foo = Foo() foo.emit('foo', {}) assert len(foo.r) == 0 event.loop.iter() assert len(foo.r) == 1 assert foo.r[0] == 1 foo = Foo() foo.emit('foo', {}) foo.emit('foo', {}) event.loop.iter() assert len(foo.r) == 1 assert foo.r[0] == 2 # Failing func call res = [] def fail(): res.append(1) 1/0 raises(ZeroDivisionError, fail) assert len(res) == 1 # When handled by the loop, error is printed, but no fail event.loop.call_later(fail) event.loop.iter() assert len(res) == 2
def test_method_handlers(): events1 = [] events2 = [] class Foo(event.HasEvents): @event.connect('x1') def handle1(self, *events): events1.extend(events) @event.connect('x1', 'x2') def handle2(self, *events): events2.extend(events) foo = Foo() with event.loop: foo.emit('x1', {}) foo.emit('x2', {}) assert len(events1) == 1 assert len(events2) == 2 assert isinstance(foo.handle1, event._handler.Handler) assert repr(foo.handle1) assert hasattr(foo.handle1, 'dispose') assert foo.handle1.get_name() == 'handle1' assert foo.handle1.get_connection_info() == [('x1', ['x1', ])] assert foo.handle2.get_connection_info() == [('x1', ['x1', ]), ('x2', ['x2', ])] # Can't touch this with raises(AttributeError): foo.handle1 = 3 with raises(AttributeError): del foo.handle1
def test_signals_on_classes_are_descriptors(): shown = [] class Test(HasSignals): @input def title(v=''): return str(v) @connect('title') def show_title1(v=''): shown.append(v) @connect('title') def show_title2(self, v=''): shown.append(v) assert len(shown) == 0 assert Test.title.not_connected assert Test.show_title1.not_connected assert Test.show_title2.not_connected raises(RuntimeError, Test.show_title1.connect) t = Test() assert len(shown) == 2
def test_emitter_python_only(): m = MyObject() # Emitter decorator needs proper callable with raises(TypeError): event.emitter(3) if '__pypy__' in sys.builtin_module_names: pass # skip else: with raises(TypeError): event.emitter(isinstance) # Check type of the instance attribute assert isinstance(m.foo, event._emitter.Emitter) # Cannot set or delete an emitter with raises(AttributeError): m.foo = 3 with raises(AttributeError): del m.foo # Repr and docs assert 'emitter' in repr(m.__class__.foo).lower() assert 'emitter' in repr(m.foo).lower() assert 'foo' in repr(m.foo)
def test_export(): # Test using some icons over which I have some control B = 'https://bitbucket.org/iep-project/iep/raw/tip/iep/resources/appicons/' for name in ['ieplogo', 'py']: icon = Icon(B + name + '.ico') assert len(icon.image_sizes()) > 0 # Export png filename = os.path.join(tempdir, name + '.png') icon.write(filename) for i in icon.image_sizes(): assert os.path.isfile(os.path.join(tempdir, name + '%i.png' % i)) # Export bmp filename = os.path.join(tempdir, name + '.bmp') icon.write(filename) for i in icon.image_sizes(): assert os.path.isfile(os.path.join(tempdir, name + '%i.bmp' % i)) # Failures .. with raises(TypeError): icon.write(3) with raises(TypeError): icon.write([]) if sys.version_info[0] > 2: with raises(TypeError): icon.write(filename.encode()) with raises(ValueError): icon.write(os.path.join(tempdir, name + '.foo'))
def test_main_funcs(): o_app = dialite._the_app try: # No args dialite._the_app = app = NoopApp() for func in (dialite.inform, dialite.warn, dialite.fail, dialite.ask_ok, dialite.ask_retry, dialite.ask_yesno): func() # assert app.res == ['Info', 'Warning', 'Error', 'Confirm', 'Retry', 'Question'] # With args dialite._the_app = app = NoopApp() for func in (dialite.inform, dialite.warn, dialite.fail, dialite.ask_ok, dialite.ask_retry, dialite.ask_yesno): func(func.__name__, 'meh bla') # assert app.res == ['inform', 'warn', 'fail', 'ask_ok', 'ask_retry', 'ask_yesno'] # Fails for func in (dialite.inform, dialite.warn, dialite.fail, dialite.ask_ok, dialite.ask_retry, dialite.ask_yesno): with raises(TypeError): func(3, 'meh') with raises(TypeError): func('meh', 3) with raises(TypeError): func('meh', 'bla', 'foo') # need exactly two args finally: dialite._the_app = o_app
def test_method_handlers_nodecorator(): events1 = [] events2 = [] class Foo(event.HasEvents): def _handle1(self, *events): events1.extend(events) handle1 = event.connect(_handle1, 'x1') def _handle2(self, *events): events2.extend(events) handle2 = event.connect(_handle2, 'x1', 'x2') foo = Foo() with event.loop: foo.emit('x1', {}) foo.emit('x2', {}) assert len(events1) == 1 assert len(events2) == 2 assert isinstance(foo.handle1, event._handler.Handler) assert repr(foo.handle1) assert hasattr(foo.handle1, 'dispose') assert foo.handle1.get_name() == '_handle1' # note the name ... # Can't touch this with raises(AttributeError): foo.handle1 = 3 with raises(AttributeError): del foo.handle1
def test_emit(): h = event.HasEvents() events = [] @h.connect('foo', 'bar') def handler(*evts): events.extend(evts) h.emit('foo', {}) h.emit('bar', {'x': 1, 'y': 2}) h.emit('spam', {}) # not registered handler.handle_now() assert len(events) == 2 for ev in events: assert isinstance(ev, dict) assert ev.source is h assert len(events[0]) == 2 assert len(events[1]) == 4 assert events[0].type == 'foo' assert events[1].type == 'bar' assert events[1].x == 1 assert events[1]['y'] == 2 # Fail with raises(ValueError): h.emit('foo:a', {}) with raises(TypeError): h.emit('foo', 4) with raises(TypeError): h.emit('foo', 'bla')
def test_selenium(): p = launch(URL, "selenium-firefox") assert p._proc is None assert p.driver time.sleep(0.5) p.close() raises(ValueError, launch, URL, "selenium")
def test_connectors2(): """ test connectors with sub """ x = MyHasEvents() y = MyHasEvents() x.sub = [y] def foo(*events): pass # Warn if no known event with capture_log('warning') as log: h = x.connect(foo, 'sub*.b') assert log y._HasEvents__handlers.pop('b') # Supress warn with capture_log('warning') as log: h = x.connect(foo, '!sub*.b') assert not log y._HasEvents__handlers.pop('b') # Supress warn, with label with capture_log('warning') as log: h = x.connect(foo, '!sub*.b:meh') assert not log y._HasEvents__handlers.pop('b') # Invalid syntax - but fix and warn with capture_log('warning') as log: h = x.connect(foo, 'sub*.!b:meh') assert log assert 'Exclamation mark' in log[0] y._HasEvents__handlers.pop('b') # Position of * with capture_log('warning') as log: h = x.connect(foo, 'sub*.a') assert not log with capture_log('warning') as log: h = x.connect(foo, 'sub.*.a') assert log with raises(ValueError): h = x.connect(foo, 'sub.*a') # fail # No star, no connection, fail! with raises(RuntimeError): h = x.connect(foo, 'sub.b') # Mix it with capture_log('warning') as log: h = x.connect(foo, '!aa*') assert not log with capture_log('warning') as log: h = x.connect(foo, '!aa**') assert not log with capture_log('warning') as log: h = x.connect(foo, '!aa**:meh') # why not assert not log
def test_session_registering_model_classes(): store = AssetStore() s = SessionAssets(store) s._send_command = lambda x: None store.create_module_assets('flexx.ui.layouts') raises(ValueError, s.register_model_class, 4) # must be a Model class s.register_model_class(ui.Slider) assert len(s._known_classes) == 3 # Slider, Widget, and Model s.register_model_class(ui.Slider) # no duplicates! assert len(s._known_classes) == 3 s.register_model_class(ui.BoxLayout) s.register_model_class(ui.Button) # Get result js = s.get_js_only() assert js.count('.Button = function ') == 1 assert js.count('.Slider = function ') == 1 assert js.count('.Widget = function ') == 1 assert js.count('.BoxLayout = function ') == 1 # Check that module indeed only has layout widgets jsmodule = store.load_asset('flexx-ui-layouts.js').decode() assert jsmodule.count('.BoxLayout = function ') == 1 assert jsmodule.count('.Button = function ') == 0 assert jsmodule.count('.Widget = function ') == 0 # Check that page contains the rest page = s.get_page() assert page.count('.BoxLayout = function ') == 0 assert page.count('.Button = function ') == 1 assert page.count('.Widget = function ') == 1 # Check that a single page export has it all export = s.get_page_for_export([], True) assert export.count('.BoxLayout = function ') == 1 assert export.count('.Button = function ') == 1 assert export.count('.Widget = function ') == 1 # Patch - this func is normally provided by the Session subclass commands = [] s._send_command = lambda x: commands.append(x) # Dynamic s.register_model_class(ui.BoxLayout) assert len(commands) == 0 # already known s.register_model_class(ui.FormLayout) assert len(commands) == 0 # already in module asset # s.register_model_class(ui.Label) assert '.Label = function' in commands[0] # JS assert 'flx-' in commands[1] # CSS
def test_js_module_names(): with raises(ValueError): # name not a str create_js_module(3, CODE, ['bb'], 'aa', 'simple') with raises(ValueError): # name empty str create_js_module('', CODE, ['bb'], 'aa', 'simple') code = create_js_module('foo.js', CODE, ['bb'], 'aa', 'simple') assert '.foo =' in code # using safe names
def test_js_module_exports(): with raises(ValueError): # exports not a str or list create_js_module('foo.js', CODE, ['bb'], 3, 'simple') with raises(ValueError): # exports element not a str create_js_module('foo.js', CODE, ['bb'], ['aa', 3], 'simple') code =create_js_module('foo.js', CODE, ['bb'], 'aa', 'simple') assert 'return aa' in code code = create_js_module('foo.js', CODE, ['bb'], ['aa', 'bb'], 'simple') assert 'return {aa: aa, bb: bb}' in code
def test_connecting_disconnected(): @connect('nonexistent1') def s1(v): return v + 1 assert isinstance(s1, Signal) assert s1.not_connected raises(SignalValueError, s1) raises(RuntimeError, s1.connect) assert 'not connected' in repr(s1).lower()
def test_func_name(): # Do not allow weird names, though not recommended # todo: now that we have a metaclass, we can allow it! with raises(RuntimeError): class Test(HasSignals): s1 = Signal(lambda x: x, []) with raises(RuntimeError): class Test(HasSignals): s2 = Signal(float, [])
def test_cannot_instantiate_without_session(): app.manager.remove_default_session() with raises(RuntimeError) as err: PyComponent() assert 'needs a session!' in str(err) with raises(RuntimeError) as err: JsComponent() assert 'needs a session!' in str(err)
def test_flexx_in_thread3(): """ Test starting and creating server when a server is currently running. """ res = [] def main(): # Create fresh ioloop and make flexx use it loop = IOLoop() loop.make_current() app.create_server() app.start() def try_start(): try: app.start() except RuntimeError: res.append('start-fail') def try_create(): try: main() except RuntimeError: res.append('create-fail') t = threading.Thread(target=main) t.start() # With that thread running ... while not app.current_server()._running: time.sleep(0.01) with raises(RuntimeError): app.start() with raises(RuntimeError): app.create_server() t1 = threading.Thread(target=try_start) t1.start() t1.join() t2 = threading.Thread(target=try_create) t2.start() t2.join() # Stop app.stop() # Start does not work, but we can stop it! t.join() # Otherwise it would never join # Note that we cannot start it right after calling stop, because it wont # stop *at once*. We need to join first. assert res == ['start-fail', 'create-fail']
def test_errors(): # Capture stderr errors = [] def _fake_err(msg): errors.append(msg) old_error = sys.stderr.write sys.stderr.write = _fake_err try: reacted = [] @input def s1(v=10): return float(v) # creating a react signal connects it, invalidates it, updates it # -> error to stderr @connect('s1') def s2(v): reacted.append(v) 1/0 assert len(reacted) == 1 # hooray, we got here safely, but there should be printing to stderr assert 'ZeroDivision' in ''.join(errors) # Updating s1 should invoke the same ... errors[:] = [] s1(20) assert len(reacted) == 2 assert 'ZeroDivision' in ''.join(errors) # creating a lazy signal connects it, invalidates it. Stop # -> on calling, it should raise @lazy('s1') def s3(v): reacted.append(v) 1/0 assert len(reacted) == 2 raises(ZeroDivisionError, s3) assert len(reacted) == 3 # Calling it again ... raises again raises(ZeroDivisionError, s3) assert len(reacted) == 4 finally: sys.stderr.write = old_error # Set back
def test_js_module_imports(): with raises(ValueError): # imports not a list create_js_module('foo.js', CODE, 'bb', 'aa', 'simple') with raises(ValueError): # imports element not a str create_js_module('foo.js', CODE, ['bb', 4], 'aa', 'simple') for type in ('amd', 'umd'): code = create_js_module('foo.js', CODE, ['bb as cc', 'dd'], 'aa', type) assert '"bb"' in code assert '"dd"' in code assert '"cc"' not in code assert 'cc, dd' in code
def test_remote_asset(): # Prepare example asset info # Note: use http instead of https to avoid spurious certificate errors bootstrap_url = 'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' jquery_url = 'http://code.jquery.com/jquery-3.1.1.slim.min.js' with open(test_filename + '.js', 'wb') as f: f.write('var blablabla=7;'.encode()) # JS from url asset = app.Asset(jquery_url) assert asset.remote assert asset.source == jquery_url assert 'jQuery v3.1.1' in asset.to_string() assert 'jQuery v3.1.1' in asset.to_html('{}', 0) assert 'jQuery v3.1.1' not in asset.to_html('{}', 1) assert 'jQuery v3.1.1' not in asset.to_html('{}', 2) assert 'jQuery v3.1.1' not in asset.to_html('{}', 3) assert 'src=' not in asset.to_html('{}', 0) assert 'src=' in asset.to_html('{}', 1) assert 'src=' in asset.to_html('{}', 2) assert 'src=' in asset.to_html('{}', 3) assert 'http://' in asset.to_html('{}', 1) assert 'http://' not in asset.to_html('{}', 2) assert 'http://' in asset.to_html('{}', 3) # CSS from url asset = app.Asset(bootstrap_url) assert asset.remote assert asset.source == bootstrap_url assert 'Bootstrap v3.3.7' in asset.to_string() assert 'Bootstrap v3.3.7' in asset.to_html('{}', 0) assert 'Bootstrap v3.3.7' not in asset.to_html('{}', 1) assert 'Bootstrap v3.3.7' not in asset.to_html('{}', 2) assert 'Bootstrap v3.3.7' not in asset.to_html('{}', 3) assert 'href=' not in asset.to_html('{}', 0) assert 'href=' in asset.to_html('{}', 1) assert 'href=' in asset.to_html('{}', 2) assert 'href=' in asset.to_html('{}', 3) assert 'http://' in asset.to_html('{}', 1) assert 'http://' not in asset.to_html('{}', 2) assert 'http://' in asset.to_html('{}', 3) # Falis with raises(TypeError): # JS from file - not allowed app.Asset('file://' + test_filename + '.js') with raises(TypeError): app.Asset(jquery_url, 'foo=3') # no sources for remote asset with raises(TypeError): app.Asset(jquery_url, ['foo=3']) # no sources for remote asset
def test_json_conversion(): from commonast import Node, Assign, Name, BinOp, Bytes, Num # Test json conversion roota = Assign([Name('foo')], BinOp('Add', Name('a'), Num(3))) rootb = Assign([Name('foo')], BinOp('Add', None, Num(3.2))) rootc = Assign([Name('foo')], BinOp('Add', Bytes(b'xx'), Num(4j))) for node1 in (roota, rootb, rootc): js = node1.tojson() node2 = Node.fromjson(js) # assert js.count('BinOp') == 1 assert js.count('Num') == 1 # assert node2.target_nodes[0].name == node1.target_nodes[0].name assert node2.value_node.op == node1.value_node.op assert node2.value_node.left_node == node1.value_node.left_node assert node2.value_node.right_node.value == node1.value_node.right_node.value # In fact, we can do node1 == node2 assert roota != rootb assert roota != rootc with raises(ValueError): roota == 5 assert str(roota) == roota.tojson() assert len(repr(roota)) < 80
def test_read_wrong(): with raises(TypeError): Icon(4) with raises(IOError): Icon('file does not exist') with raises(IOError): Icon('http://url does not exist') with raises(TypeError): Icon(['no', 'lists']) if sys.version_info[0] > 2: with raises(TypeError): Icon(b'not a filename')
def test_session_registering_model_classes(): from flexx import ui store = AssetStore() store.update_modules() s = Session('', store) commands = [] s._send_command = lambda x: commands.append(x) assert not s.present_modules s._register_model_class(ui.Button) assert len(s.present_modules) == 2 assert 'flexx.ui._widget' in s.present_modules assert 'flexx.ui.widgets._button' in s.present_modules assert len(s._present_classes) == 6 # Because a module was loaded that has more widgets assert ui.Button in s._present_classes assert ui.RadioButton in s._present_classes assert ui.CheckBox in s._present_classes assert ui.ToggleButton in s._present_classes assert ui.BaseButton in s._present_classes assert ui.Widget in s._present_classes with raises(TypeError): s._register_model_class(3)
def test_dict_ok(): d = event.Dict(foo=3) assert d.foo == 3 assert d['foo'] == 3 d.foo = 4 assert d.foo == 4 assert d['foo'] == 4 d['foo'] = 5 assert d.foo == 5 assert d['foo'] == 5 d._x = 9 assert d._x == 9 d.__x = 8 assert d.__x == 8 d.x0123 = 7 assert d.x0123 == 7 with raises(AttributeError): d.bladibla
def test_get_event_handlers(): class Foo(event.HasEvents): @event.connect('x') def spam(self, *events): pass @event.connect('x') def eggs(self, *events): pass foo = Foo() @foo.connect('x') def bar(*events): pass # sorted by label name assert foo.get_event_handlers('x') == [bar, foo.eggs, foo.spam] @foo.connect('x') def zz1(*events): pass @foo.connect('x:a') def zz2(*events): pass # sorted by label name assert foo.get_event_handlers('x') == [zz2, bar, foo.eggs, foo.spam, zz1] # Nonexisting event type is ok assert foo.get_event_handlers('y') == [] # No labels allowed with raises(ValueError): foo.get_event_handlers('x:a')
def test_lazy_asset(): side_effect = [] def lazy(): side_effect.append(True) return 'spaaam' asset = app.Asset('foo.js', lazy) assert asset.source is lazy assert not side_effect assert asset.to_string() == 'spaaam' assert side_effect while side_effect: side_effect.pop(0) assert asset.to_string() == 'spaaam' assert not side_effect # Fail def lazy_wrong(): return None asset = app.Asset('foo.js', lazy_wrong) assert asset.source is lazy_wrong with raises(ValueError): asset.to_string()
def test_session_assets(): store = AssetStore() s = SessionAssets(store) s._send_command = lambda x: None assert not s.get_used_asset_names() with open(test_filename, 'wb') as f: f.write(b'bar\n') # Add assets, check mangles name a1 = s.add_asset('foo.css', b'foo\n') a2 = s.add_asset('foo.js', test_filename) assert 'foo' in a1 and s.id in a1 and a1.endswith('.css') assert 'foo' in a2 and s.id in a2 and a2.endswith('.js') assert s.get_used_asset_names() == [a1, a2] # order in which it came # Get the asset raises(IndexError, store.load_asset, 'foo.css') raises(IndexError, store.load_asset, 'foo.js') assert store.load_asset(a1) == b'foo\n' assert store.load_asset(a2) == b'bar\n' # Use asset store.add_asset('spam.js', b'1234\x00') s.use_global_asset('spam.js') assert s.get_used_asset_names()[-1] == 'spam.js' raises(IndexError, s.use_global_asset, 'unknown-asset.js') raises(ValueError, s.add_asset, 3, b'a\n') # Add assets after loading page s.get_page() s.use_global_asset('spam.js') # prints a warning, but it does work # Global assets s.add_global_asset('eggs.js', b'12345\x00') assert s.get_used_asset_names()[-1] == 'eggs.js' assert store.load_asset('eggs.js') == b'12345\x00' raises(ValueError, s.use_global_asset, 3) # Remote assets s.use_remote_asset('http://linked.com/not/verified.js') s.use_remote_asset('http://linked.com/not/verified.css') s.use_remote_asset('http://linked.com/not/verified.css') # twice is ok raises(ValueError, s.use_remote_asset, 3) page = s.get_page() assert 'not/verified.js' in page assert 'not/verified.css' in page
def test_import_project_fail(): raises(Exception, loaded_modules, PROJECT_NAME + '.foobarxx')
def test_property(): class MyObject(event.HasEvents): @event.prop def foo(self, v=1.2): return float(v) @event.prop def bar(self, v=1.3): return float(v) m = MyObject() assert m.foo == 1.2 assert m.bar == 1.3 m = MyObject(foo=3) assert m.foo == 3.0 m.foo = 5.1 m.bar = 5.1 assert m.foo == 5.1 assert m.bar == 5.1 m.foo = '9.3' assert m.foo == 9.3 m = MyObject(foo=3) assert m.foo == 3.0 # Hacky, but works def foo(): pass x = event.prop(foo) assert 'foo' in repr(x) spam = lambda x: None x = event.prop(spam) assert '<lambda>' in repr(x) # fails with raises(ValueError): m.foo = 'bla' with raises(ValueError): MyObject(foo='bla') with raises(TypeError): m._set_prop(3, 3) # Property name must be a string with raises(AttributeError): m._set_prop('spam', 3) # MyObject has not spam property with raises(AttributeError): MyObject(spam='bla') # MyObject has not spam property with raises(TypeError): event.prop(3) # prop decorator needs callable with raises(AttributeError): del m.foo # cannot delete a property class MyObject2(event.HasEvents): @event.prop def foo(self, v): return float(v) #with raises(RuntimeError): # MyObject2() # no default value for foo ob = MyObject2() assert ob.foo is None
def test_js_module_code(): with raises(ValueError): # code not a str create_js_module('foo.js', 4, ['bb'], 'aa', 'simple')
def test_asset(): # Initialization asset1 = app.Asset('foo.js', 'foo=3') assert 'foo.js' in repr(asset1) assert 'foo.js' == asset1.name assert asset1.source == 'foo=3' asset2 = app.Asset('bar.css', 'bar=2') assert 'bar.css' in repr(asset2) assert 'bar.css' == asset2.name assert asset2.source == 'bar=2' with raises(TypeError): app.Asset() # :/ with raises(TypeError): app.Asset('foo.js') # need source with raises(TypeError): app.Asset(3, 'bar=2') # name not a str with raises(ValueError): app.Asset('foo.png', '') # js and css only with raises(TypeError): app.Asset('bar.css', 3) # source not str with raises(TypeError): app.Asset('bar.css', ['a']) # source not str # To html JS asset = app.Asset('foo.js', 'foo=3;bar=3') code = asset.to_html('', 0) assert code.startswith('<script') and code.strip().endswith('</script>') assert 'foo=3' in code assert '\n' not in code # because source had no newlines asset = app.Asset('foo.js', 'foo=3\nbar=3') code = asset.to_html('', 0) assert code.startswith('<script') and code.strip().endswith('</script>') assert '\nfoo=3\nbar=3\n' in code # note the newlines asset = app.Asset('foo.js', 'foo=3\nbar=3') code = asset.to_html() assert code.startswith('<script ') and code.strip().endswith('</script>') assert 'foo=' not in code assert '\n' not in code # because its a link # To html CSS asset = app.Asset('bar.css', 'foo=3;bar=3') code = asset.to_html('', 0) assert code.startswith('<style') and code.strip().endswith('</style>') assert 'foo=' in code assert '\n' not in code # because source had no newlines asset = app.Asset('bar.css', 'foo=3\nbar=3') code = asset.to_html('', 0) assert code.startswith('<style') and code.strip().endswith('</style>') assert '\nfoo=3\nbar=3\n' in code # note the newlines asset = app.Asset('bar.css', 'foo=3\nbar=3') code = asset.to_html() assert code.startswith('<link') and code.strip().endswith('/>') assert 'foo-' not in code assert '\n' not in code # becasue its a link # Test asset via uri with open(test_filename, 'wb') as f: f.write('var blablabla=7;'.encode()) asset = app.Asset('bar.css', 'file://' + test_filename) assert 'blablabla=7' in asset.to_string() asset = app.Asset('bar.css', 'http://code.jquery.com/jquery-3.1.1.slim.min.js') assert 'jQuery v3.1.1' in asset.to_string()
def test_for(self): # Test all possible ranges line = nowhitespace(py2js('for i in range(9): pass', inline_stdlib=False)) assert line == 'vari;for(i=0;i<9;i+=1){}' line = nowhitespace(py2js('for i in range(2, 99): pass', inline_stdlib=False)) assert line == 'vari;for(i=2;i<99;i+=1){}' line = nowhitespace(py2js('for i in range(100, 0, -1): pass', inline_stdlib=False)) assert line == 'vari;for(i=100;i>0;i+=-1){}' # Test enumeration (code) assert ' in ' not in py2js('for i in [1, 2, 3]: pass') assert ' in ' not in py2js('for i in {1:2, 2:3}: pass') # Test declaration of iteration variable assert 'var aa' in py2js('for aa in x: pass') assert 'var aa' in py2js('aa=""\nfor aa in x: pass') assert 'var aa' in py2js('j=aa=""\nfor aa in x: pass') # Test output for range assert evalpy('for i in range(3):\n print(i)') == '0\n1\n2' assert evalpy('for i in range(1,6,2):\n print(i)') == '1\n3\n5' # Range with complex input assert evalpy('for i in range(sum([2, 3])): print(i)') == '0\n1\n2\n3\n4' # Test explicit for-array iteration code = py2js('a=[7,8]\nfor i in range(len(a)):\n print(a[i])') assert ' in ' not in code and evaljs(code) == '7\n8' # Test enumeration over arrays - should use actual for-loop code = py2js('for k in [7, 8]:\n print(k)') assert ' in ' not in code and evaljs(code) == '7\n8' # compile time tests raises(JSError, py2js, 'for i, j in range(10): pass') # Test enumeration over dicts # Python cannot see its a dict, and uses a for-loop code = py2js('d = {3:7, 4:8}\nfor k in d:\n print(k)') assert ' in ' not in code and evaljs(code) == '3\n4' code = py2js('d = {3:7, 4:8}\nfor k in d:\n print(d[k])') assert ' in ' not in code and evaljs(code) == '7\n8' # .keys() code = py2js('d = {3:7, 4:8}\nfor k in d.keys():\n print(d[k])') assert evaljs(code) == '7\n8' # and ' in ' in code # .values() code = py2js('d = {3:7, 4:8}\nfor v in d.values():\n print(v)') assert ' in ' in code and evaljs(code) == '7\n8' # .items() code = py2js('d = {3:7, 4:8}\nfor k,v in d.items():\n print(k)') assert ' in ' in code and evaljs(code) == '3\n4' code = py2js('d = {3:7, 4:8}\nfor k,v in d.items():\n print(v)') assert ' in ' in code and evaljs(code) == '7\n8' # compile time tests raises(JSError, py2js, 'for i, j in x.keys(): pass') raises(JSError, py2js, 'for i, j in x.values(): pass') raises(JSError, py2js, 'for i in x.items(): pass') raises(JSError, py2js, 'for i, j, k in x.items(): pass') # Test iterate over strings code = py2js('for c in "foo":\n print(c)') assert evaljs(code) == 'f\no\no' # Break and continue for9 = 'for i in range(9):\n ' assert evalpy(for9 + 'if i==4:break\n print(i)') == '0\n1\n2\n3' assert evalpy(for9 + 'if i<5:continue\n print(i)') == '5\n6\n7\n8' # Else assert evalpy(for9 + 'if i==3:break\nelse: print(99)\n0') == '0' assert evalpy(for9 + 'if i==30:break\nelse: print(99)\n0') == '99\n0' # Nested loops correct else code = py2js(self.method_for) assert evaljs('%s method_for()' % code) == 'ok\nok\nnull' # Tuple iterators assert evalpy('for i, j in [[1, 2], [3, 4]]: print(i+j)') == '3\n7' assert evalpy('for i, j, k in [[1, 2, 3], [3, 4, 5]]: print(i+j+k)') == '6\n12'
def test_unknown(): raises(ValueError, launch, URL, 'foo')
def test_fails(): import flxtest.foo import flxtest.bar assert JSModule('flxtest.foo', {}) # Wrong init with raises(TypeError): JSModule() with raises(TypeError): JSModule('flxtest.foo') with raises(TypeError): JSModule(3, {}) with raises(TypeError): JSModule('flxtest.foo', 3) with raises(TypeError): JSModule('flxtest.foo', {}, 3) # Name issues with raises(ValueError): JSModule('flxtest.doesnotexist', {}) with raises(ValueError): JSModule('flxtest', {}) # must be flxtest.__init__ with raises(ValueError): JSModule('flxtest.foo.__init__', {}) # only for actual package names! # Cannot create module with same name twice (in same store) store = {} JSModule('flxtest.foo', store) with raises(RuntimeError): JSModule('flxtest.foo', store) JSModule('flxtest.foo', {}) # in alt store its ok though # Untranspilable m = JSModule('flxtest.bar', {}) with raises(ValueError) as err: m.add_variable('cannot_transpile') assert 'cannot transpile' in str(err.value) # Unserializable m = JSModule('flxtest.bar', {}) with raises(ValueError) as err: m.add_variable('cannot_serialize') assert 'cannot serialize' in str(err.value) # Un-anythingable m = JSModule('flxtest.bar', {}) with raises(ValueError) as err: m.add_variable('cannot_do_anything') assert 'cannot convert' in str(err.value)
def test_unknown(): # Suppress dialog temporarily from flexx import dialite with dialite.NoDialogs(): raises(ValueError, launch, URL, 'foo')
def test_Node_creation(): Node = commonast.Node class MyNodeWithoutSlots(Node): pass class MyStubNode(Node): __slots__ = () class MyNode(Node): __slots__ = 'name', 'op', 'foo_node', 'foo_nodes', 'bar' stubnode = MyStubNode() stubnodes = [MyStubNode(), MyStubNode(), MyStubNode()] # Node is an abstract class raises(AssertionError, Node) # Nodes must have slots (and no __dict__ to preserve memory) raises(AssertionError, MyNodeWithoutSlots) # number of names must match raises( AssertionError, MyNode, ) raises(AssertionError, MyStubNode, 1) raises(AssertionError, MyNode, 'a', 'Add', stubnode, stubnodes, 1, 2) # These work node = MyNode('a', 'Add', stubnode, stubnodes, 1) node = MyNode('a', 'Add', None, stubnodes, 1) node = MyNode('a', 'Add', stubnode, [], 1) node = MyNode('a', 'Add', stubnode, stubnodes, 'bla') node = MyNode('a', 'Add', stubnode, stubnodes, [1, 2, 3]) node = MyNode('a', 'Mult', stubnode, stubnodes, 1) node = MyNode('blas asdasd as', 'Mult', stubnode, stubnodes, 1) # Name must be a string raises(AssertionError, MyNode, 1, 'Add', stubnode, stubnodes, 1) # op must be an existing operator raises(AssertionError, MyNode, 'a', 'crap', stubnode, stubnodes, 1) # names ending with _node must be a node, and _nodes must be a list of nodes raises(AssertionError, MyNode, 'a', 'Add', 1, stubnodes, 1) raises(AssertionError, MyNode, 'a', 'Add', 'x', stubnodes, 1) raises(AssertionError, MyNode, 'a', 'Add', stubnode, 'not a node', 1) raises(AssertionError, MyNode, 'a', 'Add', stubnode, [1, 2], 1) # bar can be anything, but not a Node or list of Nodes raises(AssertionError, MyNode, 'a', 'Add', stubnode, stubnodes, stubnode) raises(AssertionError, MyNode, 'a', 'Add', stubnode, stubnodes, stubnodes)
def test_ok234(): assert func_ok2() with raises(StdoutMismatchError): func_ok3() with raises(StdoutMismatchError): func_ok4()
def test_python_wrong(): b = Bar() raises(TypeError, serializer.saves, b)
def test_asset_store_simple(): s = AssetStore() assert len(s.get_asset_names()) == 1 # reset.css assert not s._cache raises(IndexError, s.load_asset, 'foo.js') with open(test_filename, 'wb') as f: f.write(b'bar\n') s.add_asset('foo.css', b'foo\n') s.add_asset('foo.js', test_filename) assert s.get_asset_names() == ['foo.css', 'foo.js', 'reset.css'] # alphabetically assert s.load_asset('foo.css') == b'foo\n' assert s.load_asset('foo.js') == b'bar\n' # Check caching with open(test_filename, 'wb') as f: f.write(b'foo\n') assert s.load_asset('foo.js') == b'bar\n' # Setting same asset s.add_asset('foo.css', b'foo\n') s.add_asset('foo.js', test_filename) raises(ValueError, s.add_asset, 'foo.css', b'fooo\n') raises(ValueError, s.add_asset, 'foo.js', b'foo\n') raises(ValueError, s.add_asset, 'foo.js', b'bar\n') # Fail add_asset raises(ValueError, s.add_asset, 'xxx', 3) # value must be str or bytes raises(ValueError, s.add_asset, 'xxx', 'some file that does not exist') # str means filename raises( RuntimeError, s._cache_get, 'nonexistent.ever') # Runtime error, because this should never happen # Assets from http s.add_asset('webresource.js', 'http://code.jquery.com/jquery.min.js') assert len(s.load_asset('webresource.js')) > 0 # Fail load_asset raises(IndexError, s.load_asset, 'nonexistent.js')
def test_bundle(): try: from flexx import ui except ImportError: skip('no flexx.ui') store = {} m1 = app.JSModule('flexx.ui.widgets._button', store) m1.add_variable('Button') m2 = app.JSModule('flexx.ui.widgets._tree', store) m2.add_variable('TreeWidget') m3 = store['flexx.ui._widget'] # because its a dep of the above # JS bundle bundle = app.Bundle('flexx.ui.js') assert 'flexx.ui' in repr(bundle) bundle.add_module(m1) bundle.add_module(m2) bundle.add_module(m3) # Modules are sorted assert bundle.modules == (m3, m1, m2) # Deps are agregated assert 'flexx.app.js' in bundle.deps assert 'flexx.app._component2.js' in bundle.deps assert not any('flexx.ui' in dep for dep in bundle.deps) # Strings are combined code = bundle.to_string() assert '$Widget =' in code assert '$Button =' in code assert '$TreeWidget =' in code # CSS bundle bundle = app.Bundle('flexx.ui.css') bundle.add_module(m1) bundle.add_module(m2) bundle.add_module(m3) # code = bundle.to_string() assert '.Widget =' not in code assert '.flx-Widget {' in code assert '.flx-TreeWidget {' in code # This works too bundle = app.Bundle('-foo.js') bundle.add_module(m1) # But this does not bundle = app.Bundle('foo.js') with raises(ValueError): bundle.add_module(m1) # Assets can be bundled too bundle = app.Bundle('flexx.ui.css') bundle.add_module(m1) bundle.add_module(m2) a1 = app.Asset('foo.css', 'foo-xxx') a2 = app.Asset('bar.css', 'bar-yyy') bundle.add_asset(a1) bundle.add_asset(a2) assert a1 in bundle.assets assert a2 in bundle.assets code = bundle.to_string() assert 'foo-xxx' in code assert 'bar-yyy' in code with raises(TypeError): bundle.add_asset() with raises(TypeError): bundle.add_asset(3) with raises(TypeError): bundle.add_asset(bundle) # no bundles
def test_py2js_on_wrong_vals(): raises(ValueError, py2js, []) raises(ValueError, py2js, {}) raises(ValueError, py2js, str) # cannot find source for str
def test_asset(): # Initialization asset1 = app.Asset('foo.js', 'foo=3') assert 'foo.js' in repr(asset1) assert 'foo.js' == asset1.name assert asset1.source == 'foo=3' asset2 = app.Asset('bar.css', 'bar=2') assert 'bar.css' in repr(asset2) assert 'bar.css' == asset2.name assert asset2.source == 'bar=2' with raises(TypeError): app.Asset() # :/ with raises(TypeError): app.Asset('foo.js') # need source with raises(TypeError): app.Asset(3, 'bar=2') # name not a str with raises(ValueError): app.Asset('foo.png', '') # js and css only with raises(TypeError): app.Asset('bar.css', 3) # source not str with raises(TypeError): app.Asset('bar.css', ['a']) # source not str # To html JS asset = app.Asset('foo.js', 'foo=3;bar=3') code = asset.to_html('', 0) assert code.startswith('<script') and code.strip().endswith('</script>') assert 'foo=3' in code assert '\n' not in code # because source had no newlines asset = app.Asset('foo.js', 'foo=3\nbar=3') code = asset.to_html('', 0) assert code.startswith('<script') and code.strip().endswith('</script>') assert '\nfoo=3\nbar=3\n' in code # note the newlines asset = app.Asset('foo.js', 'foo=3\nbar=3') code = asset.to_html() assert code.startswith('<script ') and code.strip().endswith('</script>') assert 'foo=' not in code assert '\n' not in code # because its a link # To html CSS asset = app.Asset('bar.css', 'foo=3;bar=3') code = asset.to_html('', 0) assert code.startswith('<style') and code.strip().endswith('</style>') assert 'foo=' in code assert '\n' not in code # because source had no newlines asset = app.Asset('bar.css', 'foo=3\nbar=3') code = asset.to_html('', 0) assert code.startswith('<style') and code.strip().endswith('</style>') assert '\nfoo=3\nbar=3\n' in code # note the newlines asset = app.Asset('bar.css', 'foo=3\nbar=3') code = asset.to_html() assert code.startswith('<link') and code.strip().endswith('/>') assert 'foo-' not in code assert '\n' not in code # becasue its a link # Test asset via uri fname = 'file:///home/xx/foobar.css' with raises(TypeError): app.Asset('bar.css', fname) with raises(TypeError): app.Asset(fname)
def test_connectors2(): """ test connectors with sub """ x = MyComponent() y = MyComponent() x.sub = [y] def foo(*events): pass # Warn if no known event with capture_log('warning') as log: h = x.reaction(foo, 'sub*.b') assert log y._Component__handlers.pop('b') # Supress warn with capture_log('warning') as log: h = x.reaction(foo, '!sub*.b') assert not log y._Component__handlers.pop('b') # Supress warn, with label with capture_log('warning') as log: h = x.reaction(foo, '!sub*.b:meh') assert not log y._Component__handlers.pop('b') # Invalid syntax - but fix and warn with capture_log('warning') as log: h = x.reaction(foo, 'sub*.!b:meh') assert log assert 'Exclamation mark' in log[0] y._Component__handlers.pop('b') # Position of * with capture_log('warning') as log: h = x.reaction(foo, 'sub*.a') assert not log with capture_log('warning') as log: h = x.reaction(foo, 'sub.*.a') assert log with raises(ValueError): h = x.reaction(foo, 'sub.*a') # fail # No star, no connection, fail! with raises(RuntimeError): h = x.reaction(foo, 'sub.b') # y.a is not a list, fail! with raises(RuntimeError): h = y.reaction(foo, 'a*.b') # Mix it with capture_log('warning') as log: h = x.reaction(foo, '!aa**') with capture_log('warning') as log: h = x.reaction(foo, '!aa*') assert not log with capture_log('warning') as log: h = y.reaction(foo, '!aa*') assert not log with capture_log('warning') as log: h = x.reaction(foo, '!aa**') assert not log with capture_log('warning') as log: h = x.reaction(foo, '!aa**:meh') # why not assert not log
def test_exceptions(self): raises(JSError, py2js, "foo(**kwargs)")
def test_fail(): with raises(StdoutMismatchError): func_fail()
def test_raw_js(): with raises(TypeError): RawJS() with raises(TypeError): RawJS(3) # Empty r1 = RawJS('') assert str(r1) == '' assert r1.get_code() == '' assert r1.get_code(4) == '' assert '0' in repr(r1) assert r1.__module__.endswith(__name__) # Short single line r2 = RawJS('require("foobar")') assert 'require(' in repr(r2) assert 'require(' in str(r2) assert r2.get_code().startswith('require') assert r2.get_code(4).startswith(' require') assert r2.get_code(2).startswith(' require') assert '\n' not in r2.get_code() # Long single line r2b = RawJS('require("foobar")' * 10) assert 'require(' not in repr(r2b) assert '1' in repr(r2b) # Multiline, start at first line r3 = RawJS("""for ... { yyyy } """) assert 'lines' in repr(r3) assert 'for ...' in str(r3) assert str(r3).endswith('}\n') assert r3.get_code().count('\n') == 3 assert r3.get_code().startswith('for') assert r3.get_code(4).startswith(' for') assert '\n yyyy\n' in r3.get_code(0) assert '\n yyyy\n' in r3.get_code(4) # Multiline, exactly the same, but start at second line; same results r4 = RawJS(""" for ... { yyyy } """) assert 'lines' in repr(r4) assert 'for ...' in str(r4) assert str(r4).endswith('}\n') assert r4.get_code().count('\n') == 3 assert r4.get_code().startswith('for') assert r4.get_code(4).startswith(' for') assert '\n yyyy\n' in r4.get_code(0) assert '\n yyyy\n' in r4.get_code(4) # Multiline, now newline at the ned r5 = RawJS(""" for ... { yyyy }""") assert r5.get_code().count('\n') == 2 assert str(r5).endswith('}')
def test_read_file(): # Prepare config files filename1 = os.path.join(tempfile.gettempdir(), 'flexx_config_test1.cfg') with open(filename1, 'wb') as f: f.write(SAMPLE1.encode()) filename2 = os.path.join(tempfile.gettempdir(), 'flexx_config_test2.cfg') with open(filename2, 'wb') as f: f.write(SAMPLE2.encode()) filename3 = os.path.join(tempfile.gettempdir(), 'flexx_config_test3.cfg') with open(filename3, 'wb') as f: f.write(SAMPLE3.encode()) filename4 = os.path.join(tempfile.gettempdir(), 'flexx_config_test4.cfg') with open(filename4, 'wb') as f: f.write(b'\x00\xff') # Config without sources c = Config('testconfig', foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == False assert c.bar == 1 # Config with filename, implicit section c = Config('testconfig', filename1, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == True assert c.bar == 3 assert c.eggs == 'bla bla' # Config with filename, explicit section c = Config('testconfig', filename2, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == True assert c.bar == 4 assert c.eggs == 'bla bla bla' # Config with string, implicit section c = Config('testconfig', SAMPLE1, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == True assert c.bar == 3 assert c.eggs == 'bla bla' # Config with string, explicit section c = Config('testconfig', SAMPLE2, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == True assert c.bar == 4 assert c.eggs == 'bla bla bla' # Config with string, implicit section, different name c = Config('aaaa', SAMPLE1, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == True assert c.bar == 3 # Config with string, explicit section, different name (no section match) c = Config('aaaa', SAMPLE2, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.foo == False assert c.bar == 1 # Config with both, and filenames can be nonexistent c = Config('testconfig', SAMPLE1, filename2, filename1 + '.cfg', foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.bar == 4 # c = Config('testconfig', filename2, filename1 + '.cfg', SAMPLE1, foo=(False, bool, ''), bar=(1, int, ''), spam=(0.0, float, ''), eggs=('', str, '')) assert c.bar == 3 # Config from invalid string is ignored (logged) c = Config('testconfig', SAMPLE3, bar=(1, int, '')) assert c.bar == 1 # Config from invalid file is ignored (logged) c = Config('testconfig', filename3, bar=(1, int, '')) assert c.bar == 1 # Config from invalid unidocde file is ignored (logged) c = Config('testconfig', filename4, bar=(1, int, '')) assert c.bar == 1 # Fails with raises(ValueError): c = Config('testconfig', []) with raises(ValueError): c = Config('testconfig', 3)
def test_base_runtime_must_have_url_in_kwargs(): with raises(KeyError) as excinfo: BaseRuntime() assert 'url' in str(excinfo.value)
def test_emitter(): class MyObject(event.HasEvents): @event.emitter def foo(self, v): return dict(value=float(v)) @event.emitter def bar(self, v): return dict(value=float(v) + 1) # note plus 1 def on_foo(self, *events): self.the_val = events[0].value # so we can test it def on_bar(self, *events): self.the_val = events[0].value # so we can test it m = MyObject() the_vals = [] @m.connect('foo', 'bar') def handle_foo(*events): the_vals.append(events[0].value) with event.loop: m.foo(3.2) assert m.the_val == 3.2 assert the_vals[-1] == 3.2 with event.loop: m.foo('9.1') assert m.the_val == 9.1 assert the_vals[-1] == 9.1 with event.loop: m.bar(3.2) assert m.the_val == 4.2 assert the_vals[-1] == 4.2 # Fail with raises(ValueError): m.foo('bla') with raises(TypeError): event.emitter(3) # emitter decorator needs callable with raises(AttributeError): del m.foo # cannot delete an emitter with raises(AttributeError): m.foo = None # cannot set an emitter class MyObject2(event.HasEvents): @event.emitter def foo(self, v): return float(v) with raises(TypeError): m = MyObject2() m.foo(3.2) # return value of emitter must be a dict
def test_component_instance_attributes2(): # Py only with raises(TypeError): class X(Component): a = event.Attribute(doc=3)