File: test_looper.py

package info (click to toggle)
python-enaml 0.19.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,284 kB
  • sloc: python: 31,443; cpp: 4,499; makefile: 140; javascript: 68; lisp: 53; sh: 20
file content (119 lines) | stat: -rw-r--r-- 3,636 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#------------------------------------------------------------------------------
# Copyright (c) 2019-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
import pytest
from textwrap import dedent
from utils import compile_source, wait_for_window_displayed

from enaml.core.api import Looper
from enaml.widgets.api import Label


def test_looper_refresh(enaml_qtbot, enaml_sleep):
    """ Test that the loop index is valid when items are reordered.

    """
    source = dedent("""\
    from enaml.core.api import Looper
    from enaml.widgets.api import Window, Container, Label, PushButton


    enamldef Main(Window): window:
        attr data: list = []
        alias container
        Container: container:
            Looper:
                iterable << window.data
                Label:
                    text << '{} {}'.format(loop.index, loop.item)


    """)
    tester = compile_source(source, 'Main')()
    tester.show()
    wait_for_window_displayed(enaml_qtbot, tester)

    for data in (
                # Set initial
                ['a', 'b', 'c'],

                # Resort order data and ensure it matches
                ['b', 'c', 'a'],

                # Remove and resort ensure it still matches
                ['a', 'b']
            ):
        enaml_qtbot.wait(enaml_sleep)
        tester.data = data
        expected = ['{} {}'.format(*it) for it in enumerate(data)]
        assert [c.text for c in tester.container.children
                if isinstance(c, Label)] == expected


def test_looper_refresh_iterator(enaml_qtbot, enaml_sleep):
    """ Test that a looper properly refreshes when given an iterator.

    """
    source = dedent("""\
    from enaml.core.api import Looper, Conditional
    from enaml.widgets.api import Window, Container, Label, ObjectCombo


    enamldef Main(Window): window:
        attr data: list = []
        attr flag: str = 'a'
        attr show_more: bool << flag == 'b' or flag == 'c'
        alias container
        Container: container:
            ObjectCombo: combo:
                items = ['a', 'b', 'c']
                selected := window.flag
            Conditional:
                condition << show_more
                # Nested loop forces re-eval twice
                Conditional:
                    condition << flag == 'c'
                    Looper:
                        iterable << reversed(data)
                        Label:
                            text << '{} {}'.format(loop.index, loop.item)

    """)
    tester = compile_source(source, 'Main')()
    tester.show()
    wait_for_window_displayed(enaml_qtbot, tester)

    enaml_qtbot.wait(enaml_sleep)
    data = [1, 2, 3]
    tester.data = data

    # Conditional is still hiding it
    assert not any(
        c for c in tester.container.children if isinstance(c, Label))

    # Now they should all be shown
    tester.flag = 'c'
    enaml_qtbot.wait(enaml_sleep)
    expected = ['{} {}'.format(*it) for it in enumerate(reversed(data))]
    assert [c.text for c in tester.container.children
            if isinstance(c, Label)] == expected


def test_looper_iterable():
    """ Test that a looper validates the iterator properly.

    """
    looper = Looper()
    looper.iterable = {1, 2, 3}
    looper.iterable = {'a': 1, 'b': 2}
    looper.iterable = 'abc'

    with pytest.raises(TypeError):
        looper.iterable = 1

    with pytest.raises(TypeError):
        looper.iterable = None