File: test_selection.py

package info (click to toggle)
python-echo 0.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 368 kB
  • sloc: python: 2,421; makefile: 148
file content (140 lines) | stat: -rw-r--r-- 4,404 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import pytest
from unittest.mock import MagicMock

from ..core import HasCallbackProperties, delay_callback
from ..selection import SelectionCallbackProperty, ChoiceSeparator


class Example(HasCallbackProperties):
    a = SelectionCallbackProperty()
    b = SelectionCallbackProperty(default_index=1)
    c = SelectionCallbackProperty(default_index=-1)


class TestSelectionCallbackProperty():

    def setup_method(self, method):
        self.state = Example()
        self.a = Example.a
        self.b = Example.b
        self.c = Example.c

    def test_set_choices(self):
        # make sure that default_index is respected
        self.a.set_choices(self.state, [1, 2])
        self.b.set_choices(self.state, [1, 2])
        self.c.set_choices(self.state, [1, 2, 3])
        assert self.state.a == 1
        assert self.state.b == 2
        assert self.state.c == 3
        self.a.set_choices(self.state, None)
        assert self.state.a is None

    def test_set_value(self):

        # Since there are no choices set yet, the properties cannot be set to
        # any values yet.
        with pytest.raises(ValueError) as exc:
            self.state.a = 1
        assert exc.value.args[0] == "value 1 is not in valid choices: []"

        self.a.set_choices(self.state, [1, 2])

        # The following should work since it is a valid choice
        self.state.a = 2

        # Again if we try and set to an invalid value, things break
        with pytest.raises(ValueError) as exc:
            self.state.a = 3
        assert exc.value.args[0] == "value 3 is not in valid choices: [1, 2]"

    def test_value_constant(self):

        # Make sure that the value is preserved if possible

        self.a.set_choices(self.state, [1, 2])
        self.state.a = 2

        self.a.set_choices(self.state, [2, 5, 3])
        assert self.state.a == 2

        self.a.set_choices(self.state, [1, 4, 5])
        assert self.state.a == 1

        self.a.set_choices(self.state, [4, 2, 1])
        assert self.state.a == 1

    def test_get_choices(self):

        self.a.set_choices(self.state, [1, 2])
        self.a.get_choices == [1, 2]

        self.a.set_choices(self.state, [2, 5, 3])
        self.a.get_choices == [2, 5, 3]

    def test_display_func(self):

        separator = ChoiceSeparator('header')

        self.a.set_choices(self.state, [separator, 1, 2])
        self.a.get_choice_labels(self.state) == ['header', '1', '2']
        assert self.a.get_display_func(self.state) is None
        assert self.b.get_display_func(self.state) is None

        def val(x):
            return 'val{0}'.format(x)

        self.a.set_display_func(self.state, val)
        self.a.get_choice_labels(self.state) == ['header', 'val1', 'val2']
        assert self.a.get_display_func(self.state) is val
        assert self.b.get_display_func(self.state) is None

    def test_callbacks(self):

        # Make sure that callbacks are called when either choices or selection
        # are changed

        func = MagicMock()
        self.state.add_callback('a', func)

        self.a.set_choices(self.state, [1, 2, 3])
        func.assert_called_with(1)

        self.state.a = 2
        func.assert_called_with(2)

        self.a.set_choices(self.state, [4, 5, 6])
        func.assert_called_with(4)

    def test_choice_separator(self):

        separator = ChoiceSeparator('header')
        self.a.set_choices(self.state, [separator, 1, 2])

        assert self.state.a == 1

        separator = ChoiceSeparator('header')
        self.a.set_choices(self.state, [separator])

        assert self.state.a is None

    def test_delay(self):

        func = MagicMock()
        self.state.add_callback('a', func)

        # Here we set the choices and as a result the selection changes from
        # None to a value, so the callback is called after the delay block
        with delay_callback(self.state, 'a'):
            self.a.set_choices(self.state, [4, 5, 6])
            assert func.call_count == 0
        func.assert_called_once_with(4)
        func.reset_mock()

        # Check that the callback gets called even if only the choices
        # but not the selection are changed in a delay block
        with delay_callback(self.state, 'a'):
            self.a.set_choices(self.state, [1, 2, 4])
            assert func.call_count == 0
        func.assert_called_once_with(4)
        func.reset_mock()