-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtest_fup.py
More file actions
110 lines (91 loc) · 3.84 KB
/
test_fup.py
File metadata and controls
110 lines (91 loc) · 3.84 KB
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
# -*- coding: utf-8 -*-
from ..syntax import macros, test, test_raises, the # noqa: F401
from ..test.fixtures import session, testset
from itertools import repeat
from collections import namedtuple
from ..fup import fupdate
from ..collections import frozendict
def runtests():
with testset("mutable sequence"):
lst = [1, 2, 3]
out = fupdate(lst, 1, 42)
test[lst == [1, 2, 3]]
test[out == [1, 42, 3]]
test[type(out) is type(lst)]
with testset("immutable sequence"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(1, 5, 2), tuple(repeat(10, 2)))
test[tup == (1, 2, 3, 4, 5)]
test[out == (1, 10, 3, 10, 5)]
test[type(out) is type(tup)]
test[the[fupdate(tup)] == the[tup]] # no indices, no bindings --> copy
with testset("namedtuple"):
A = namedtuple("A", "p q")
a = A(17, 23)
out = fupdate(a, 0, 42)
test[a == A(17, 23)]
test[out == A(42, 23)]
test[the[type(out)] is the[type(a)]]
with testset("mutable mapping"):
d1 = {'foo': 'bar', 'fruit': 'apple'}
d2 = fupdate(d1, foo='tavern')
test[sorted(d1.items()) == [('foo', 'bar'), ('fruit', 'apple')]]
test[sorted(d2.items()) == [('foo', 'tavern'), ('fruit', 'apple')]]
test[the[type(d2)] is the[type(d1)]]
with testset("immutable mapping (unpythonic.collections.frozendict)"):
d3 = frozendict({'a': 1, 'b': 2})
d4 = fupdate(d3, a=23)
test[the[d4['a']] == 23 and the[d4['b']] == 2]
test[d3['a'] == 1]
test[the[type(d4)] is the[type(d3)]]
with testset("negative index"):
lst = [1, 2, 3]
out = fupdate(lst, -1, 42)
test[lst == [1, 2, 3]]
test[out == [1, 2, 42]]
with testset("no start index"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(None, 5, 2), tuple(repeat(10, 3)))
test[tup == (1, 2, 3, 4, 5)]
test[out == (10, 2, 10, 4, 10)]
with testset("no stop index"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(1, None, 2), tuple(repeat(10, 2)))
test[tup == (1, 2, 3, 4, 5)]
test[out == (1, 10, 3, 10, 5)]
with testset("no start or stop index, just step"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(None, None, 2), tuple(repeat(10, 3)))
test[tup == (1, 2, 3, 4, 5)]
test[out == (10, 2, 10, 4, 10)]
with testset("just step, backwards"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(None, None, -1), tuple(range(5)))
test[tup == (1, 2, 3, 4, 5)]
test[out == (4, 3, 2, 1, 0)]
with testset("multiple individual items"):
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, (1, 2, 3), (17, 23, 42))
test[tup == (1, 2, 3, 4, 5)]
test[out == (1, 17, 23, 42, 5)]
with testset("multiple slices and sequences"):
tup = tuple(range(10))
out = fupdate(tup, (slice(0, 10, 2), slice(1, 10, 2)),
(tuple(repeat(2, 5)), tuple(repeat(3, 5))))
test[tup == tuple(range(10))]
test[out == (2, 3, 2, 3, 2, 3, 2, 3, 2, 3)]
with testset("mix and match"):
tup = tuple(range(10))
out = fupdate(tup, (slice(0, 10, 2), slice(1, 10, 2), 6),
(tuple(repeat(2, 5)), tuple(repeat(3, 5)), 42))
test[tup == tuple(range(10))]
test[out == (2, 3, 2, 3, 2, 3, 42, 3, 2, 3)]
with testset("error cases"):
with test_raises[IndexError, "should detect replacement sequence too short"]:
tup = (1, 2, 3, 4, 5)
out = fupdate(tup, slice(1, None, 2), (10,)) # need 2 items, have 1
# cannot specify both indices and bindings
test_raises[ValueError, fupdate(tup, slice(1, None, 2), (10,), somename="some value")]
if __name__ == '__main__': # pragma: no cover
with session(__file__):
runtests()