def test_getitem(self): assert Container('x')['foo', 'bar', 'baz'].children == ['foo', 'bar', 'baz'] pytest.raises_str(TypeError, 'argument', lambda: Container['foo']) assert tags.p['foo'].children == ['foo'] assert tags.p[('foo', 'bar')] == tags.p['foo', 'bar'] assert tags.p['x', expr('y'), tags.hr, IO()].children == ['x', expr('y'), tags.hr, IO()] pytest.raises_str('unexpected child element: []', lambda: tags.p[[]])
def test_expr(self): pytest.raises_str('invalid expr: 1', expr, 1) pytest.raises_str("invalid expr: ''", expr, '') assert expr(expr('foo')) == expr('foo') assert str(expr('bar')) == 'bar' assert repr(expr('bar')) == "expr('bar')" assert expr('baz').code == 'baz' assert {expr('foo'): 1} == {expr('foo'): 1}
def test_attributes(self): for attr in tags._ATTRIBUTES: if attr == 'style': continue py_attr = attr + '_' * keyword.iskeyword(attr) js_attr = re.sub(r'_([a-z])', lambda s: s.group(1).upper(), attr) element = tags.p(**{py_attr: 'foo'})['baz'] assert element.to_dict() == { '__element__': { 'name': 'p', 'children': ['baz'], 'props': { js_attr: 'foo' } } } assert element == tags.p['baz'](**{py_attr: 'foo'}) assert tags.p(is_=expr('z')).props['is'] == expr('z')
def test_tags(self, all_tags): for tag in all_tags: assert issubclass(tag['cls'], Element) assert tag['cls'].allow_children == (not tag['void']) assert tag['cls'].__doc__ == '<{}> HTML tag.'.format(tag['name']) element = tag['cls'](is_='foo', form_enc_type='bar', alt='baz', inputMode='qwe', href=expr('x'), style={ 'line-height': 1, 'align_self': 'no', 'flexFlow': 'yes', 'flex': 0 }) assert element.to_dict() == { '__element__': { 'name': tag['name'], 'props': { 'is': 'foo', 'formEncType': 'bar', 'alt': 'baz', 'inputMode': 'qwe', 'href': { '__expr__': 'x' }, 'style': { 'lineHeight': 1, 'alignSelf': 'no', 'flexFlow': 'yes', 'flex': 0 } } } } assert element.name == tag['name'] assert element.inputs == [] assert element.outputs == [] assert element.children == [] assert element.props['href'] == expr('x')
def test_styles(self): for style in tags._STYLES: element = tags.p(style={style: 'foo'}) js_style = re.sub(r'[\-_]([a-z])', lambda s: s.group(1).upper(), style) assert element.to_dict() == { '__element__': { 'name': 'p', 'props': { 'style': { js_style: 'foo' } } } } assert tags.p(style={'z-index': 1.2}).props['style']['zIndex'] == 1.2 assert tags.p(style={'z_index': 42}).props['style']['zIndex'] == 42 assert tags.p(style={ 'zIndex': expr('y') }).props['style']['zIndex'] == expr('y') assert tags.p(style={ 'filter': 'foo' }).props['style']['filter'] == 'foo'
class TestElement(object): def test_expr(self): pytest.raises_str('invalid expr: 1', expr, 1) pytest.raises_str("invalid expr: ''", expr, '') assert expr(expr('foo')) == expr('foo') assert str(expr('bar')) == 'bar' assert repr(expr('bar')) == "expr('bar')" assert expr('baz').code == 'baz' assert {expr('foo'): 1} == {expr('foo'): 1} def test_repr(self): assert repr(tags.del_()) == '<Element: del>' assert repr(Container(['a'])['foo']) == '<Element: Container>' def test_basic(self): assert not Tag.allow_children tag = Tag('id', 'a') assert tag.name == 'Tag' assert tag.inputs == ['id'] assert tag.outputs == [] assert tag.children == [] assert tag.props == {'_a': 'a'} container = Container('x', outputs=['b'], foo=1)[tags.p(href='foo'), Container('y')] assert Container.allow_children assert container.name == 'Container' assert container.inputs == [] assert container.outputs == ['b'] assert container.props == {'foo': 1, 'x': 'x'} assert container.children == [tags.p(href='foo'), Container('y')] def test_allow_children(self): pytest.raises_str('not a container: Tag', lambda: Tag('i', 'a')['foo']) pytest.raises_str('not a container: hr', lambda: tags.hr['foo']) pytest.raises_str('not a container: hr', lambda: tags.hr(href='bar')['foo']) def test_getitem(self): assert Container('x')['foo', 'bar', 'baz'].children == ['foo', 'bar', 'baz'] pytest.raises_str(TypeError, 'argument', lambda: Container['foo']) assert tags.p['foo'].children == ['foo'] assert tags.p[('foo', 'bar')] == tags.p['foo', 'bar'] assert tags.p['x', expr('y'), tags.hr, IO()].children == ['x', expr('y'), tags.hr, IO()] pytest.raises_str('unexpected child element: []', lambda: tags.p[[]]) def test_input_overlap(self): with pytest.raises_str("overlapping inputs: ['j']"): tags.p[ Container('x', inputs=['a'])[ Tag('i', 'a', b={'foo': Tag('j', 'b')}), 'foo' ], Container('y', inputs=['j']) ] with pytest.raises_str("overlapping inputs: ['i']"): tags.p[IO, IO()] def test_all_inputs(self): element = Container('x', inputs=['a', 'b'])[ IO, Tag('j', a={'x': [1, Tag('k', 'foo')]}) ] assert element.all_inputs == ['a', 'b', 'i', 'j', 'k'] def test_all_outputs(self): element = Container('x', outputs=['a', 'b'])[ Tag('j', a={'x': [1, IO]}), Container('y', outputs=['a', 'b', 'c'])['foo'] ] assert element.all_outputs == ['a', 'b', 'c', 'o'] @pytest.mark.parametrize('element, expected', [ ( tags.p(), {'name': 'p'} ), ( tags.p[tags.hr, tags.br()], { 'name': 'p', 'children': [ {'__element__': {'name': 'hr'}}, {'__element__': {'name': 'br'}} ] } ), ( Container('x', inputs=['a'], outputs=['b'], foo='bar')[ IO, Tag('j', 'a', b='b'), tags.p(style={'z-index': 1}, class_='baz')[expr('x'), 'y'] ], { 'name': 'Container', 'inputs': ['a'], 'outputs': ['b'], 'props': {'x': 'x', 'foo': 'bar'}, 'children': [ {'__element__': { 'name': 'IO', 'inputs': ['i'], 'outputs': ['o'] }}, {'__element__': { 'name': 'Tag', 'inputs': ['j'], 'props': {'_a': 'a', '_b': 'b'} }}, {'__element__': { 'name': 'p', 'props': {'style': {'zIndex': 1}, 'className': 'baz'}, 'children': [{'__expr__': 'x'}, 'y'] }} ] } ) ], ids=list(map(str, range(3)))) def test_to_json_or_dict(self, element, expected): assert element.to_dict()['__element__'] == expected assert element.to_json() == json.dumps({'__element__': expected}, indent=4, sort_keys=True) def test_encode_invalid(self): pytest.raises_str('not JSON serializable', Container(object()).to_json) pytest.raises_str('not JSON serializable', Container(object()).to_dict)