Example #1
0
    def test_container_rendering(self):
        parent = Core(container=Core())
        child = Core(parent=parent)

        render_result = parent._render()
        for view_id in (parent.id, parent.container.id, child.id):
            assert view_id in render_result
Example #2
0
    def test_style_fill(self):
        class TestCore(Core):
            pass

        TestCore.text_color = Core._css_color_prop('text_color', 'color')
        TestCore.background_color = Core._css_color_prop(
            'background_color', 'background-color')

        class SomeStyle(Style):
            background_color = theme.background

        class OtherTheme(Theme):
            background = Color('indigo')

        Style.current_theme = OtherTheme

        TestCore.style = SomeStyle

        view = TestCore()
        view.text_color = 'black'

        assert 'color' in view._css_properties
        assert len(view._css_properties) == 1

        css_properties = view._set_position_and_fill_from_theme()

        assert 'background-color' in css_properties
        assert len(css_properties) == 2
        assert css_properties['background-color'] == Color('indigo').css
Example #3
0
    def test_container_hierarchy(self):
        parent = Core(container=Core())
        child = Core(parent=parent)

        assert child.parent == parent
        assert child._parent == parent.container
        assert parent.children == (child, )
        assert parent._children == [parent.container]
Example #4
0
    def test_properties__color(self):
        Core.text_color = Core._css_color_prop('text_color', 'color')

        view = Core()

        view.text_color = 'cyan'
        assert view.text_color.name == 'cyan'
        assert view._css_properties['color'] == 'rgba(0,255,255,255)'
Example #5
0
    def test_properties__bool(self):
        Core.bold = Core._css_bool_prop('bold', 'font-weight', 'bold')

        view = Core()

        view.bold = True
        assert view._css_properties['font-weight'] == 'bold'

        view.bold = False
        assert view._css_properties['font-weight'] is None
Example #6
0
    def test_event_generator(self):
        view = Core()
        assert view._animation_id is None

        @view
        def on_click(data):
            data.value = 1
            yield
            data.value = 2

        # First click
        update = view._process_event('click', view)

        assert view.value == 1
        assert len(Events._animation_generators) == 1

        # Return after animation complete
        animation_id = next(iter(Events._animation_generators.keys()))
        view._process_event_loop(animation_id)

        assert view.value == 2
        assert len(Events._animation_generators) == 0

        # Restart
        view._process_event('click', view)
        assert view.value == 1
        animation_id = next(iter(Events._animation_generators.keys()))
        view._process_event_loop(animation_id)
        assert view.value == 2
Example #7
0
    def test_identity(self, is_view_id):
        view1 = Core()
        view2 = Core()

        class NotView:
            id = 'foobar'

        assert NotView().id != is_view_id
        assert view1.id == is_view_id
        assert view2.id == is_view_id
        assert view1.id != view2.id

        assert Core.get_view(view2.id) == view2
Example #8
0
    def test_animated_css_properties(self):
        view = Core()

        with animation():
            view._set_css_property(
                'corner_radius',
                '50%',
                'border-radius',
                '50%',
            )
        with animation(
                duration=2.0,
                ease='ease-func',
                direction='alternate',
                iterations='forever',
                start_delay=1,
                end_delay=2,
        ):
            view._set_css_property(
                'alpha',
                0.5,
                'opacity',
                '50%',
            )
        view._animation_id = 'abc123'

        rendered = view._render_props()

        assert rendered == {
            'style':
            'border-radius:50%;opacity:50%',
            'ui4style':
            'border-radius:50%:0.3s;opacity:50%:2.0s,ease-func,alternate,1s,2s,inf',
        }
Example #9
0
    def test_properties__mapping(self):
        Core.scrollable = Core._css_mapping_prop('scrollable', 'overflow', {
            True: 'auto',
            'horizontal': 'auto hidden',
            'vertical': 'hidden auto',
        })

        view = Core()

        view.scrollable = True
        assert view._css_properties['overflow'] == 'auto'

        view.scrollable = False
        assert view._css_properties['overflow'] == None
Example #10
0
    def test_properties__generic(self):
        Core.corner_radius = Core._css_plain_prop('corner_radius',
                                                  'border-radius')

        view = Core()
        view.corner_radius = '25%'
        assert view._properties['corner_radius'] == '25%'
        assert view._css_properties['border-radius'] == '25%'
        assert view.corner_radius == '25%'

        view.corner_radius = 8
        assert view._properties['corner_radius'] == 8
        assert view._css_properties['border-radius'] == '8px'
        assert view.corner_radius == 8
Example #11
0
    def test_event_handler_decorator(self):
        view = Core()

        with pytest.raises(ValueError):

            @view
            def on_nonexistent_event(_):
                pass

        @view
        def on_click(_):
            pass

        assert inspect.isfunction(
            view.on_click)  # noqa: Too clever for PyCharm
        assert view._render_events() == {
            'hx-post': '/event',
            'hx-trigger': 'click'
        }
Example #12
0
    def test_base_setter_and_render(self, anchor_view):
        view = anchor_view()

        assert view not in Core._get_dirties()

        view._set_css_property(
            'text_color',
            (1, 1, 1, 1),
            'color',
            'rgba(255,255,255,255)',
        )

        assert view in Core._get_dirties()

        view.left = 100  # Triggers position: absolute

        rendered = view._render_props()

        assert rendered == {
            'style': 'color:rgba(255,255,255,255);position:absolute',
        }
Example #13
0
class Select(View):

    _template = Template('<select id="$id" name="$id" class="$viewclass" '
                         '$rendered_attributes $oob hx-swap="none">'
                         '$options</select>')

    def __init__(self, options=None, **kwargs):
        super().__init__(**kwargs)
        self.options = options or []

    options = Core._prop('options')

    def _render_options(self):
        """
Example #14
0
    def test_event_handler_option_decorator(self):
        view = Core()

        @view
        @delay
        def on_click(_):
            pass

        @view
        @delay
        def on_change(_):
            pass

        assert view._render_events(
        )['hx-trigger'] == 'change delay:0.5s,click delay:0.5s'

        view.remove_event('change')

        assert view._render_events()['hx-trigger'] == 'click delay:0.5s'
Example #15
0
    def test_hierarchy(self):
        view1 = Core()
        view2 = Core(parent=view1)

        assert view2 in view1.children

        view3 = Core()

        with pytest.raises(AttributeError):
            view1.children.append(view3)

        view2.parent = view3

        assert view2 not in view1.children

        view4 = Core(children=[view1, view2])

        assert view1 in view4.children
        assert view2 in view4.children
        assert not view3.children
Example #16
0
def clean_state():
    Core._clean_state()
Example #17
0
    def test_renderer_registration(self):
        view = Core()

        assert len(view._renderers) == 3
Example #18
0
    def test_get_roots(self):
        view1 = Core()
        view2 = Core(parent=view1)
        view3 = Core(parent=view2)
        view4 = Core(parent=view1)

        assert Core._get_roots() == set()

        view4._mark_dirty()
        assert Core._get_roots() == {view4}

        view3._mark_dirty()
        assert Core._get_roots() == {view3, view4}

        view2._mark_dirty()
        assert Core._get_roots() == {view2, view4}

        view1._mark_dirty()
        assert Core._get_roots() == {view1}
Example #19
0
class View(Core):

    style = BaseStyle

    # Layout properties
    left = Core._anchorprop('left')
    x = left
    right = Core._anchorprop('right')
    top = Core._anchorprop('top')
    y = top
    bottom = Core._anchorprop('bottom')
    width = Core._anchorprop('width')
    height = Core._anchorprop('height')
    center_x = Core._anchorprop('centerX')
    center_y = Core._anchorprop('centerY')

    # Composite properties
    center = Core._anchorprops('center_x', 'center_y')
    position = Core._anchorprops('left', 'top')
    size = Core._anchorprops('width', 'height')
    frame = Core._anchorprops('left', 'top', 'width', 'height')

    # Dock to parent
    top_left = Core._anchordock('top_left')
    top_right = Core._anchordock('top_right')
    bottom_left = Core._anchordock('bottom_left')
    bottom_right = Core._anchordock('bottom_right')
    top_center = Core._anchordock('top_center')
    bottom_center = Core._anchordock('bottom_center')
    left_center = Core._anchordock('left_center')
    right_center = Core._anchordock('right_center')
    sides = Core._anchordock('sides')
    top_and_bottom = Core._anchordock('top_and_bottom')
    all = Core._anchordock('all')

    # Dock to sibling
    above = Core._anchordock('above')
    below = Core._anchordock('below')
    left_of = Core._anchordock('left_of')
    right_of = Core._anchordock('right_of')

    # Dock to content
    fit_width = Core._anchordock('fit_width')
    fit_height = Core._anchordock('fit_height')

    # Appearance properties
    align = Core._css_plain_prop('align', 'text-align')
    alpha = Core._css_plain_prop('alpha', 'opacity')
    background_color = Core._css_color_prop('background_color',
                                            'background-color')
    border_color = Core._css_color_prop('border_color', 'border-color')
    border_style = Core._css_plain_prop('border_style', 'border-style')
    border_width = Core._css_plain_prop('border_width', 'border-width')
    corner_radius = Core._css_plain_prop('corner_radius', 'border-radius')
    margin = Core._css_plain_prop('margin', 'margin')
    padding = Core._css_plain_prop('padding', 'padding')
    scrollable = Core._css_mapping_prop('scrollable', 'overflow', {
        True: 'auto',
        'horizontal': 'auto hidden',
        'vertical': 'hidden auto',
    })
    shadow = Core._css_plain_prop('shadow', 'box-shadow')
    z = Core._css_plain_prop('z', 'z-index')

    # Text properties
    text = Core._prop('text')

    bold = Core._css_bool_prop('bold', 'font-weight', 'bold')
    font = Core._css_plain_prop('font', 'font-family')
    text_color = Core._css_color_prop('text_color', 'color')
    font_size = Core._css_plain_prop('font_size', 'font-size')