Completed
Push — develop ( dc0fdb...f662c0 )
by Jace
02:19
created

TestAliases.test_custom_init_is_invoked()   A

Complexity

Conditions 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 2
1
"""Integration tests for nested attributes."""
2
# pylint: disable=missing-docstring,no-self-use,attribute-defined-outside-init,no-member,misplaced-comparison-constant
0 ignored issues
show
introduced by
Bad option value 'misplaced-comparison-constant'
Loading history...
3
4
5
from unittest.mock import patch
6
import logging
7
8
from expecter import expect
0 ignored issues
show
Configuration introduced by
The import expecter could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
9
10
import yorm
11
12
from . import strip
13
14
15
@yorm.attr(status=yorm.types.Boolean)
16
@yorm.attr(checked=yorm.types.Integer)
17
class StatusDictionary(yorm.types.Dictionary):
18
19
    def __init__(self, status, checked):
20
        self.status = status
21
        self.checked = checked
22
        if self.checked == 42:
23
            raise RuntimeError
24
25
26
@yorm.attr(all=yorm.types.Float)
27
class NestedList3(yorm.types.List):
28
29
    def __repr__(self):
30
        return "<nested-list-3 {}>".format((id(self)))
31
32
33
@yorm.attr(nested_list_3=NestedList3)
34
@yorm.attr(number=yorm.types.Float)
35
class NestedDictionary3(yorm.types.AttributeDictionary):
36
37
    def __init__(self):
38
        super().__init__()
39
        self.number = 0
40
        self.nested_list_3 = []
41
42
    def __repr__(self):
43
        print(self.number)  # trigger a potential recursion issue
44
        return "<nested-dictionary-3 {}>".format((id(self)))
45
46
47
@yorm.attr(all=yorm.types.Float)
48
class NestedList2(yorm.types.List):
49
50
    def __repr__(self):
51
        return "<nested-list-2 {}>".format((id(self)))
52
53
54
@yorm.attr(nested_dict_3=NestedDictionary3)
55
@yorm.attr(number=yorm.types.Float)
56
class NestedDictionary2(yorm.types.AttributeDictionary):
57
58
    def __init__(self):
59
        super().__init__()
60
        self.number = 0
61
62
    def __repr__(self):
63
        print(self.number)  # trigger a potential recursion issue
64
        return "<nested-dictionary-2 {}>".format((id(self)))
65
66
67
@yorm.attr(nested_list_2=NestedList2)
68
@yorm.attr(number=yorm.types.Float)
69
class NestedDictionary(yorm.types.AttributeDictionary):
70
71
    def __init__(self):
72
        super().__init__()
73
        self.number = 0
74
        self.nested_list_2 = []
75
76
    def __repr__(self):
77
        return "<nested-dictionary {}>".format((id(self)))
78
79
80
@yorm.attr(all=NestedDictionary2)
81
class NestedList(yorm.types.List):
82
83
    def __repr__(self):
84
        return "<nested-list {}>".format((id(self)))
85
86
87
@yorm.attr(nested_dict=NestedDictionary)
88
@yorm.attr(nested_list=NestedList)
89
@yorm.sync("sample.yml")
90
class Top:
91
92
    def __init__(self):
93
        self.nested_list = []
94
        self.nested_dict = {}
95
96
    def __repr__(self):
97
        return "<top {}>".format((id(self)))
98
99
100
@patch('yorm.settings.fake', True)
101
class TestNestedOnce:
102
103
    def test_append_triggers_save(self):
104
        top = Top()
105
        logging.info("Appending dictionary to list...")
106
        top.nested_list.append({'number': 1})
107
        assert strip("""
108
        nested_dict:
109
          nested_list_2: []
110
          number: 0.0
111
        nested_list:
112
        - nested_dict_3:
113
            nested_list_3: []
114
            number: 0.0
115
          number: 1.0
116
        """) == top.__mapper__.text
117
118
    def test_set_by_index_triggers_save(self):
119
        top = Top()
120
        top.nested_list = [{'number': 1.5}]
121
        assert strip("""
122
        nested_dict:
123
          nested_list_2: []
124
          number: 0.0
125
        nested_list:
126
        - nested_dict_3:
127
            nested_list_3: []
128
            number: 0.0
129
          number: 1.5
130
        """) == top.__mapper__.text
131
        top.nested_list[0] = {'number': 1.6}
132
        assert strip("""
133
        nested_dict:
134
          nested_list_2: []
135
          number: 0.0
136
        nested_list:
137
        - nested_dict_3:
138
            nested_list_3: []
139
            number: 0.0
140
          number: 1.6
141
        """) == top.__mapper__.text
142
143
    def test_get_by_index_triggers_load(self):
144
        top = Top()
145
        top.__mapper__.text = strip("""
146
        nested_list:
147
        - number: 1.7
148
        """)
149
        assert 1.7 == top.nested_list[0].number
150
151
    def test_delete_index_triggers_save(self):
152
        top = Top()
153
        top.nested_list = [{'number': 1.8}, {'number': 1.9}]
154
        assert strip("""
155
        nested_dict:
156
          nested_list_2: []
157
          number: 0.0
158
        nested_list:
159
        - nested_dict_3:
160
            nested_list_3: []
161
            number: 0.0
162
          number: 1.8
163
        - nested_dict_3:
164
            nested_list_3: []
165
            number: 0.0
166
          number: 1.9
167
        """) == top.__mapper__.text
168
        del top.nested_list[0]
169
        assert strip("""
170
        nested_dict:
171
          nested_list_2: []
172
          number: 0.0
173
        nested_list:
174
        - nested_dict_3:
175
            nested_list_3: []
176
            number: 0.0
177
          number: 1.9
178
        """) == top.__mapper__.text
179
180
    def test_set_dict_as_attribute_triggers_save(self):
181
        top = Top()
182
        top.nested_dict.number = 2
183
        assert strip("""
184
        nested_dict:
185
          nested_list_2: []
186
          number: 2.0
187
        nested_list: []
188
        """) == top.__mapper__.text
189
190
191
@patch('yorm.settings.fake', True)
192
class TestNestedTwice:
193
194
    def test_nested_list_item_value_change_triggers_save(self):
195
        top = Top()
196
        top.nested_list = [{'number': 3}]
197
        assert strip("""
198
        nested_dict:
199
          nested_list_2: []
200
          number: 0.0
201
        nested_list:
202
        - nested_dict_3:
203
            nested_list_3: []
204
            number: 0.0
205
          number: 3.0
206
        """) == top.__mapper__.text
207
        top.nested_list[0].number = 4
208
        assert strip("""
209
        nested_dict:
210
          nested_list_2: []
211
          number: 0.0
212
        nested_list:
213
        - nested_dict_3:
214
            nested_list_3: []
215
            number: 0.0
216
          number: 4.0
217
        """) == top.__mapper__.text
218
219
    def test_nested_dict_item_value_change_triggers_save(self):
220
        top = Top()
221
        top.nested_dict = {'nested_list_2': [5]}
222
        assert strip("""
223
        nested_dict:
224
          nested_list_2:
225
          - 5.0
226
          number: 0.0
227
        nested_list: []
228
        """) == top.__mapper__.text
229
        top.nested_dict.nested_list_2.append(6)
230
        assert strip("""
231
        nested_dict:
232
          nested_list_2:
233
          - 5.0
234
          - 6.0
235
          number: 0.0
236
        nested_list: []
237
        """) == top.__mapper__.text
238
239
    def test_dict_in_list_value_change_triggers_save(self):
240
        top = Top()
241
        top.nested_list.append(None)
242
        top.nested_list[0].nested_dict_3.number = 8
243
        assert strip("""
244
        nested_dict:
245
          nested_list_2: []
246
          number: 0.0
247
        nested_list:
248
        - nested_dict_3:
249
            nested_list_3: []
250
            number: 8.0
251
          number: 0.0
252
        """) == top.__mapper__.text
253
254
    def test_list_in_dict_append_triggers_save(self):
255
        top = Top()
256
        top.nested_list.append(None)
257
        top.nested_list.append(None)
258
        for nested_dict_2 in top.nested_list:
259
            nested_dict_2.number = 9
260
            nested_dict_2.nested_dict_3.nested_list_3.append(10)
261
        assert strip("""
262
        nested_dict:
263
          nested_list_2: []
264
          number: 0.0
265
        nested_list:
266
        - nested_dict_3:
267
            nested_list_3:
268
            - 10.0
269
            number: 0.0
270
          number: 9.0
271
        - nested_dict_3:
272
            nested_list_3:
273
            - 10.0
274
            number: 0.0
275
          number: 9.0
276
        """) == top.__mapper__.text
277
278
279
@patch('yorm.settings.fake', True)
280
class TestAliases:
281
282
    @yorm.attr(var4=NestedList3)
283
    @yorm.attr(var5=StatusDictionary)
284
    @yorm.sync("fake/path")
285
    class Sample:
286
287
        def __repr__(self):
288
            return "<sample {}>".format(id(self))
289
290
    def setup_method(self, _):
291
        self.sample = self.Sample()
292
293
    @staticmethod
294
    def _log_ref(name, var, ref):
295
        logging.info("%s: %r", name, var)
296
        logging.info("%s_ref: %r", name, ref)
297
        logging.info("%s ID: %s", name, id(var))
298
        logging.info("%s_ref ID: %s", name, id(ref))
299
        assert id(ref) == id(var)
300
        assert ref == var
301
302
    def test_alias_list(self):
303
        var4_ref = self.sample.var4
304
        self._log_ref('var4', self.sample.var4, var4_ref)
305
        assert [] == self.sample.var4
306
307
        logging.info("Appending 42 to var4_ref...")
308
        var4_ref.append(42)
309
        self._log_ref('var4', self.sample.var4, var4_ref)
310
        assert [42] == self.sample.var4
311
312
        logging.info("Appending 2015 to var4_ref...")
313
        var4_ref.append(2015)
314
        assert [42, 2015] == self.sample.var4
315
316
    def test_alias_dict(self):
317
        var5_ref = self.sample.var5
318
        self._log_ref('var5', self.sample.var5, var5_ref)
319
        assert {'status': False, 'checked': 0} == self.sample.var5
320
321
        logging.info("Setting status=True in var5_ref...")
322
        var5_ref['status'] = True
323
        self._log_ref('var5', self.sample.var5, var5_ref)
324
        assert {'status': True, 'checked': 0} == self.sample.var5
325
326
        logging.info("Setting status=False in var5_ref...")
327
        var5_ref['status'] = False
328
        self._log_ref('var5', self.sample.var5, var5_ref)
329
        assert {'status': False, 'checked': 0} == self.sample.var5
330
331
    def test_alias_dict_in_list(self):
332
        top = Top()
333
        top.nested_list.append(None)
334
        ref1 = top.nested_list[0]
335
        ref2 = top.nested_list[0].nested_dict_3
336
        ref3 = top.nested_list[0].nested_dict_3.nested_list_3
337
        assert id(ref1) == id(top.nested_list[0])
338
        assert id(ref2) == id(top.nested_list[0].nested_dict_3)
339
        assert id(ref3) == id(top.nested_list[0].nested_dict_3.nested_list_3)
340
341
    def test_alias_list_in_dict(self):
342
        top = Top()
343
        logging.info("Updating nested attribute...")
344
        top.nested_dict.number = 1
345
        logging.info("Grabbing refs...")
346
        ref1 = top.nested_dict
347
        ref2 = top.nested_dict.nested_list_2
348
        assert id(ref1) == id(top.nested_dict)
349
        assert id(ref2) == id(top.nested_dict.nested_list_2)
350
351
    def test_custom_init_is_invoked(self):
352
        self.sample.__mapper__.text = "var5:\n  checked: 42"
353
        with expect.raises(RuntimeError):
354
            print(self.sample.var5)
355