Completed
Push — develop ( a507ee...3acc4d )
by Jace
03:08
created

TestText.test_dump_yaml_space_before_newline()   A

Complexity

Conditions 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
1
"""Unit tests for the doorstop.core.types module."""
2
3
import unittest
4
import yaml
5
6
from doorstop.common import DoorstopError
7
from doorstop.core.types import Prefix, UID, Text, Level, Stamp, Reference
8
9
10
class TestPrefix(unittest.TestCase):
11
    """Unit tests for the Prefix class."""  # pylint: disable=W0212
12
13
    def setUp(self):
14
        self.prefix1 = Prefix('REQ')
15
        self.prefix2 = Prefix('TST (@/tst)')
16
17
    def test_init_empty(self):
18
        """Verify prefixes are parsed correctly (empty)."""
19
        self.assertEqual(Prefix(''), Prefix())
20
        self.assertEqual(Prefix(''), Prefix(None))
21
22
    def test_init_instance(self):
23
        """Verify prefixes are parsed correctly (instance)."""
24
        self.assertIs(self.prefix1, Prefix(self.prefix1))
25
        self.assertEqual(Prefix(''), Prefix(None))
26
        self.assertEqual(Prefix(''), Prefix(''))
27
28
    def test_init_reseved(self):
29
        """Verify an exception is raised for a reserved word."""
30
        self.assertRaises(DoorstopError, Prefix, 'ALL')
31
32
    def test_repr(self):
33
        """Verify prefixes can be represented."""
34
        self.assertEqual("Prefix('REQ')", repr(self.prefix1))
35
        self.assertEqual("Prefix('TST')", repr(self.prefix2))
36
37
    def test_str(self):
38
        """Verify prefixes can be converted to strings."""
39
        self.assertEqual('REQ', str(self.prefix1))
40
        self.assertEqual('TST', str(self.prefix2))
41
42
    def test_eq(self):
43
        """Verify prefixes can be equated."""
44
        self.assertEqual(Prefix('REQ'), self.prefix1)
45
        self.assertNotEqual(self.prefix1, self.prefix2)
46
        self.assertEqual(Prefix('req'), self.prefix1)
47
        self.assertEqual('Req', self.prefix1)
48
        self.assertNotEqual(None, self.prefix1)
49
        self.assertNotEqual('all', self.prefix1)
50
51
    def test_sort(self):
52
        """Verify prefixes can be sorted."""
53
        prefixes = [Prefix('a'), Prefix('B'), Prefix('c')]
54
        self.assertListEqual(prefixes, sorted(prefixes))
55
56
    def test_short(self):
57
        """Verify the short representation of prefixes is correct."""
58
        self.assertEqual('req', self.prefix1.short)
59
        self.assertEqual('tst', self.prefix2.short)
60
61
62
class TestUID(unittest.TestCase):
63
    """Unit tests for the UID class."""  # pylint: disable=W0212
64
65
    def setUp(self):
66
        self.uid1 = UID('REQ001')
67
        self.uid2 = UID('TST-02')
68
        self.uid3 = UID('SYS', '-', 3, 5)
69
        self.uid4 = UID('REQ001', stamp='abc123')
70
71
    def test_init_str(self):
72
        """Verify UIDs are parsed correctly (string)."""
73
        uid = UID('REQ')
74
        self.assertRaises(DoorstopError, getattr, uid, 'prefix')
75
        uid = UID('REQ-?')
76
        self.assertRaises(DoorstopError, getattr, uid, 'number')
77
78
    def test_init_dict(self):
79
        """Verify UIDs are parsed correctly (dictionary)."""
80
        uid = UID({'REQ001': 'abc123'})
81
        self.assertEqual('REQ', uid.prefix)
82
        self.assertEqual(1, uid.number)
83
        self.assertEqual('abc123', uid.stamp)
84
85
    def test_init_values(self):
86
        """Verify UIDs are parsed correctly (values)."""
87
        self.assertRaises(TypeError, UID, 'REQ', '-')
88
        self.assertRaises(TypeError, UID, 'REQ', '-', 42)
89
        self.assertRaises(TypeError, UID, 'REQ', '-', 42, 3, 'extra')
90
91
    def test_init_empty(self):
92
        """Verify UIDs are parsed correctly (empty)."""
93
        self.assertEqual(UID(''), UID())
94
        self.assertEqual(UID(''), UID(None))
95
96
    def test_init_instance(self):
97
        """Verify UIDs are parsed correctly (instance)."""
98
        self.assertIs(self.uid1, UID(self.uid1))
99
        self.assertIs(self.uid4, UID(self.uid4))
100
101
    def test_repr(self):
102
        """Verify UIDs can be represented."""
103
        self.assertEqual("UID('REQ001')", repr(self.uid1))
104
        self.assertEqual("UID('TST-02')", repr(self.uid2))
105
        self.assertEqual("UID('SYS-00003')", repr(self.uid3))
106
        self.assertEqual("UID('REQ001', stamp='abc123')", repr(self.uid4))
107
108
    def test_str(self):
109
        """Verify UIDs can be converted to strings."""
110
        self.assertEqual('REQ001', str(self.uid1))
111
        self.assertEqual('TST-02', str(self.uid2))
112
        self.assertEqual('SYS-00003', str(self.uid3))
113
114
    def test_eq(self):
115
        """Verify UIDs can be equated."""
116
        self.assertEqual(UID('REQ.001'), UID('req', '', 1, 3))
117
        self.assertEqual(UID('REQ1'), UID('REQ', '', 1, 3))
118
        self.assertNotEqual(UID('REQ.2'), UID('REQ', '-', 1, 3))
119
        self.assertEqual(UID('REQ1'), UID('REQ001 (@/req1.yml)'))
120
        self.assertEqual('req1', UID('REQ001'))
121
        self.assertNotEqual(None, UID('REQ001'))
122
        self.assertEqual(self.uid1, self.uid4)
123
124
    def test_sort(self):
125
        """Verify UIDs can be sorted."""
126
        uids = [UID('a'), UID('a1'), UID('a2'), UID('b')]
127
        self.assertListEqual(uids, sorted(uids))
128
129
    def test_prefix(self):
130
        """Verify UIDs have prefixes."""
131
        self.assertEqual('REQ', self.uid1.prefix)
132
        self.assertEqual('TST', self.uid2.prefix)
133
        self.assertEqual('SYS', self.uid3.prefix)
134
135
    def test_number(self):
136
        """Verify UIDs have numbers."""
137
        self.assertEqual(1, self.uid1.number)
138
        self.assertEqual(2, self.uid2.number)
139
        self.assertEqual(3, self.uid3.number)
140
141
    def test_short(self):
142
        """Verify the short representation of IDs is correct."""
143
        self.assertEqual('req1', self.uid1.short)
144
        self.assertEqual('tst2', self.uid2.short)
145
        self.assertEqual('sys3', self.uid3.short)
146
147
    def test_string(self):
148
        """Verify UIDs can be converted to string including stamps."""
149
        self.assertEqual("REQ001", self.uid1.string)
150
        self.assertEqual("REQ001:abc123", self.uid4.string)
151
152
    def test_stamp(self):
153
        """Verify stamps are stored correctly."""
154
        self.assertEqual('abc123', self.uid4.stamp)
155
        self.assertEqual('abc123', UID(self.uid4).stamp)
156
        self.assertEqual('def456', UID(self.uid4, stamp='def456').stamp)
157
        self.assertEqual(True, UID({'REQ001': 1}).stamp)
158
        self.assertEqual(True, UID("REQ001:1").stamp)
159
160
161
class TestText(unittest.TestCase):
162
    """Unit tests for the Text class."""  # pylint: disable=W0212
163
164
    def setUp(self):
165
        self.text = Text("Hello, \nworld! ")
166
167
    def test_init(self):
168
        """Verify Text is parsed correctly."""
169
        self.assertEqual(Text(""), Text())
170
        self.assertEqual(Text(""), Text(None))
171
        self.assertEqual(Text(""), Text(""))
172
173
    def test_repr(self):
174
        """Verify text can be represented."""
175
        self.assertEqual("'Hello,\\nworld!'", repr(self.text))
176
177
    def test_str(self):
178
        """Verify text can be converted to strings."""
179
        self.assertEqual("Hello,\nworld!", str(self.text))
180
181
    def test_eq(self):
182
        """Verify text can be equated."""
183
        self.assertEqual(Text("Hello,\nworld!"), self.text)
184
185
    def test_yaml(self):
186
        """Verify levels can be converted to their YAML representation."""
187
        self.assertEqual('Hello,\nworld!\n', self.text.yaml)
188
189
    def test_dump_yaml(self):
190
        """Verify levels can be converted to their YAML representation."""
191
        text = Text('Hello,\n World!\n')
192
        self.assertEqual('|\n  Hello,\n   World!\n', yaml.dump(text.yaml))
193
194
    def test_dump_yaml_space(self):
195
        """Text starting with a space is encoded to a yaml literal string
196
        with a hint as to the indent."""
197
        text = Text(' abc ')
198
        self.assertEqual('|2\n   abc\n', yaml.dump(text.yaml))
199
200
    def test_dump_yaml_space_before_newline(self):
201
        """Text starting with a space is encoded to a yaml literal string
202
        with a hint as to the indent."""
203
        text = Text('hello \nworld\n')
204
        self.assertEqual('|\n  hello\n  world\n', yaml.dump(text.yaml))
205
206
207
class TestLevel(unittest.TestCase):
208
    """Unit tests for the Level class."""  # pylint: disable=W0212
209
210
    def setUp(self):
211
        self.level_1 = Level('1')
212
        self.level_1_2 = Level('1.2')
213
        self.level_1_2_heading = Level('1.2.0')
214
        self.level_1_2_3 = Level('1.2.3')
215
216
    def test_init(self):
217
        """Verify levels can be parsed."""
218
        self.assertEqual((1, 0), Level((1, 0)).value)
219
        self.assertEqual((1,), Level((1)).value)
220
        self.assertEqual((1, 0), Level(Level('1.0')).value)
221
        self.assertEqual((1, 0), Level(1, heading=True).value)
222
        self.assertEqual((1,), Level((1, 0), heading=False).value)
223
        self.assertEqual((1,), Level())
224
        self.assertEqual((1,), Level(None))
225
        self.assertEqual((1,), Level(()).value)
226
        self.assertEqual((1,), Level(0).value)
227
        self.assertEqual((1,), Level('').value)
228
        self.assertEqual((0,), Level((0,)).value)
229
        self.assertEqual((0,), Level('0').value)
230
        self.assertEqual((0,), Level('0.0').value)
231
232
    def test_repr(self):
233
        """Verify levels can be represented."""
234
        self.assertEqual("Level('1')", repr(self.level_1))
235
        self.assertEqual("Level('1.2')", repr(self.level_1_2))
236
        self.assertEqual("Level('1.2', heading=True)",
237
                         repr(self.level_1_2_heading))
238
        self.assertEqual("Level('1.2.3')", repr(self.level_1_2_3))
239
240
    def test_str(self):
241
        """Verify levels can be converted to strings."""
242
        self.assertEqual('1', str(self.level_1))
243
        self.assertEqual('1.2', str(self.level_1_2))
244
        self.assertEqual('1.2.0', str(self.level_1_2_heading))
245
        self.assertEqual('1.2.3', str(self.level_1_2_3))
246
247
    def test_len(self):
248
        """Verify a level length is equal to number of non-heading parts."""
249
        self.assertEqual(1, len(self.level_1))
250
        self.assertEqual(2, len(self.level_1_2))
251
        self.assertEqual(2, len(self.level_1_2_heading))
252
        self.assertEqual(3, len(self.level_1_2_3))
253
254
    def test_eq(self):
255
        """Verify levels can be equated."""
256
        self.assertNotEqual(self.level_1, self.level_1_2)
257
        self.assertEqual(self.level_1_2, Level([1, 2]))
258
        self.assertEqual(self.level_1_2, (1, 2))
259
        self.assertEqual(self.level_1_2, self.level_1_2_heading)
260
261
    def test_eq_other(self):
262
        """Verify levels can be equated with non-levels."""
263
        self.assertNotEqual(self.level_1, None)
264
        self.assertEqual((1, 2, 0), self.level_1_2_heading)
265
        self.assertEqual((1, 2), self.level_1_2_heading)
266
267
    def test_compare(self):
268
        """Verify levels can be compared."""
269
        self.assertLess(self.level_1, self.level_1_2)
270
        self.assertLessEqual(self.level_1, self.level_1)
271
        self.assertLessEqual(self.level_1, self.level_1_2)
272
        self.assertLess(self.level_1_2, [1, 3])
273
        self.assertGreater(self.level_1_2_3, self.level_1_2)
274
        self.assertGreaterEqual(self.level_1_2_3, self.level_1_2)
275
        self.assertGreaterEqual(self.level_1_2_3, self.level_1_2_3)
276
277
    def test_hash(self):
278
        """Verify level's can be hashed."""
279
        levels = {Level('1.2'): 1, Level('1.2.3'): 2}
280
        self.assertIn(self.level_1_2, levels)
281
        self.assertNotIn(self.level_1_2_heading, levels)
282
283
    def test_add(self):
284
        """Verify levels can be incremented."""
285
        level = self.level_1_2
286
        level += 1
287
        self.assertEqual(Level('1.3'), level)
288
        self.assertEqual(Level('1.5'), level + 2)
289
290
    def test_add_heading(self):
291
        """Verify (heading) levels can be incremented."""
292
        level = self.level_1_2_heading
293
        level += 2
294
        self.assertEqual(Level('1.4.0'), level)
295
296
    def test_sub(self):
297
        """Verify levels can be decremented."""
298
        level = self.level_1_2_3
299
        level -= 1
300
        self.assertEqual(Level('1.2.2'), level)
301
        self.assertEqual(Level('1.2.1'), level - 1)
302
303
    def test_sub_heading(self):
304
        """Verify (heading) levels can be decremented."""
305
        level = self.level_1_2_heading
306
        level -= 1
307
        self.assertEqual(Level('1.1.0'), level)
308
309
    def test_sub_zero(self):
310
        """Verify levels cannot be decremented to zero."""
311
        level = self.level_1_2
312
        level -= 2
313
        self.assertEqual(Level('1.1'), level)
314
315
    def test_rshift(self):
316
        """Verify levels can be indented."""
317
        level = self.level_1_2
318
        level >>= 1
319
        self.assertEqual(Level('1.2.1'), level)
320
        self.assertEqual(Level('1.2.1.1'), level >> 1)
321
322
    def test_rshift_heading(self):
323
        """Verify (heading) levels can be indented."""
324
        level = self.level_1_2_heading
325
        level >>= 2
326
        self.assertEqual(Level('1.2.1.1.0'), level)
327
328
    def test_rshift_negative(self):
329
        """Verify levels can be indented negatively."""
330
        level = self.level_1_2_3
331
        level >>= -1
332
        self.assertEqual(Level('1.2'), level)
333
        self.assertEqual(Level('1'), level >> -1)
334
335
    def test_lshift(self):
336
        """Verify levels can be dedented."""
337
        level = self.level_1_2_3
338
        level <<= 1
339
        self.assertEqual(Level('1.2'), level)
340
        self.assertEqual(Level('1'), level << 1)
341
342
    def test_lshift_heading(self):
343
        """Verify (heading) levels can be dedented."""
344
        level = self.level_1_2_heading
345
        level <<= 1
346
        self.assertEqual(Level('1.0'), level)
347
348
    def test_lshift_negative(self):
349
        """Verify levels can be dedented negatively."""
350
        level = self.level_1_2_3
351
        level <<= -1
352
        self.assertEqual(Level('1.2.3.1'), level)
353
        self.assertEqual(Level('1.2.3.1.1'), level << -1)
354
355
    def test_lshift_empty(self):
356
        """Verify levels can be dedented."""
357
        level = self.level_1_2_3
358
        level <<= 4
359
        self.assertEqual(Level('1'), level)
360
361
    def test_lshift_zero(self):
362
        """Verify detenting levels by zero has no effect.."""
363
        level = self.level_1_2_3
364
        level <<= 0
365
        self.assertEqual(Level('1.2.3'), level)
366
367
    def test_value(self):
368
        """Verify levels can be converted to their values."""
369
        self.assertEqual((1,), self.level_1.value)
370
        self.assertEqual((1, 2), self.level_1_2.value)
371
        self.assertEqual((1, 2, 0), self.level_1_2_heading.value)
372
        self.assertEqual((1, 2, 3), self.level_1_2_3.value)
373
374
    def test_yaml(self):
375
        """Verify levels can be converted to their YAML representation."""
376
        self.assertEqual(1, self.level_1.yaml)
377
        self.assertEqual(1.2, self.level_1_2.yaml)
378
        self.assertEqual('1.2.0', self.level_1_2_heading.yaml)
379
        self.assertEqual('1.2.3', self.level_1_2_3.yaml)
380
381
    def test_copy(self):
382
        """Verify levels can be copied."""
383
        level = self.level_1_2.copy()
384
        self.assertEqual(level, self.level_1_2)
385
        level += 1
386
        self.assertNotEqual(level, self.level_1_2)
387
388
389
class TestStamp(unittest.TestCase):
390
    """Unit tests for the Stamp class."""  # pylint: disable=W0212
391
392
    def setUp(self):
393
        self.stamp1 = Stamp('abc123')
394
        self.stamp2 = Stamp("Hello, world!", 42, False)
395
        self.stamp3 = Stamp(True)
396
        self.stamp4 = Stamp(False)
397
        self.stamp5 = Stamp()
398
399
    def test_repr(self):
400
        """Verify stamps can be represented."""
401
        self.assertEqual("Stamp('abc123')", repr(self.stamp1))
402
        self.assertEqual("Stamp('2645439971b8090da05c7403320afcfa')",
403
                         repr(self.stamp2))
404
        self.assertEqual("Stamp(True)", repr(self.stamp3))
405
        self.assertEqual("Stamp(None)", repr(self.stamp4))
406
        self.assertEqual("Stamp(None)", repr(self.stamp5))
407
408
    def test_str(self):
409
        """Verify stamps can be converted to strings."""
410
        self.assertEqual('abc123', str(self.stamp1))
411
        self.assertEqual('2645439971b8090da05c7403320afcfa', str(self.stamp2))
412
        self.assertEqual('', str(self.stamp3))
413
        self.assertEqual('', str(self.stamp4))
414
        self.assertEqual('', str(self.stamp5))
415
416
    def test_bool(self):
417
        """Verify stamps can be converted to boolean."""
418
        self.assertTrue(self.stamp1)
419
        self.assertTrue(self.stamp2)
420
        self.assertTrue(self.stamp3)
421
        self.assertFalse(self.stamp4)
422
        self.assertFalse(self.stamp5)
423
424
    def test_eq(self):
425
        """Verify stamps can be equated."""
426
        self.assertEqual('abc123', self.stamp1)
427
        self.assertEqual('2645439971b8090da05c7403320afcfa', self.stamp2)
428
        self.assertEqual(True, self.stamp3)
429
        self.assertEqual(None, self.stamp4)
430
        self.assertNotEqual(self.stamp1, self.stamp2)
431
        self.assertNotEqual(self.stamp3, self.stamp4)
432
        self.assertEqual(self.stamp4, self.stamp5)
433
434
    def test_yaml(self):
435
        """Verify stamps can be converted to their YAML dump format."""
436
        self.assertEqual('abc123', self.stamp1.yaml)
437
        self.assertEqual('2645439971b8090da05c7403320afcfa', self.stamp2.yaml)
438
        self.assertEqual(True, self.stamp3.yaml)
439
        self.assertEqual(None, self.stamp4.yaml)
440
        self.assertEqual(None, self.stamp5.yaml)
441
442
443
class TestReference(unittest.TestCase):
444
    """Unit tests for the Reference class."""
445
446
    def setUp(self):
447
        self.ref1 = Reference('abc123')
448
        self.ref2 = Reference('path/to/external.txt', 5, 10)
449
        self.ref2 = Reference('path/to/external.dat', None, None)
450
        self.ref3 = Reference()
451