aboutsummaryrefslogtreecommitdiff
blob: d0d57683e37188b08288ae35d527bfcdae601013 (plain)
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
141
142
143
144
145
146
147
148
149
import operator

import pytest
from snakeoil.iterables import caching_iter, expandable_chain, iter_sort, partition


class TestPartition:
    def test_empty(self):
        a, b = partition(())
        assert list(a) == []
        assert list(b) == []

    def test_split(self):
        a, b = partition(range(10))
        assert list(a) == [0]
        assert list(b) == list(range(1, 10))

        a, b = partition(range(10), lambda x: x >= 5)
        assert list(a) == [0, 1, 2, 3, 4]
        assert list(b) == [5, 6, 7, 8, 9]


class TestExpandableChain:
    def test_normal_function(self):
        i = [iter(range(100)) for x in range(3)]
        e = expandable_chain()
        e.extend(i)
        assert list(e) == list(range(100)) * 3
        for x in i + [e]:
            pytest.raises(StopIteration, x.__next__)

    def test_extend(self):
        e = expandable_chain()
        e.extend(range(100) for i in (1, 2))
        assert list(e) == list(range(100)) * 2
        with pytest.raises(StopIteration):
            e.extend([[]])

    def test_extendleft(self):
        e = expandable_chain(range(20, 30))
        e.extendleft([range(10, 20), range(10)])
        assert list(e) == list(range(30))
        with pytest.raises(StopIteration):
            e.extendleft([[]])

    def test_append(self):
        e = expandable_chain()
        e.append(range(100))
        assert list(e) == list(range(100))
        with pytest.raises(StopIteration):
            e.append([])

    def test_appendleft(self):
        e = expandable_chain(range(10, 20))
        e.appendleft(range(10))
        assert list(e) == list(range(20))
        with pytest.raises(StopIteration):
            e.appendleft([])


class TestCachingIter:
    def test_iter_consumption(self):
        i = iter(range(100))
        c = caching_iter(i)
        i2 = iter(c)
        for _ in range(20):
            next(i2)
        assert next(i) == 20
        # note we consumed one ourselves
        assert c[20] == 21
        list(c)
        pytest.raises(StopIteration, i.__next__)
        assert list(c) == list(range(20)) + list(range(21, 100))

    def test_init(self):
        assert caching_iter(list(range(100)))[0] == 0

    def test_full_consumption(self):
        i = iter(range(100))
        c = caching_iter(i)
        assert list(c) == list(range(100))
        # do it twice, to verify it returns properly
        assert list(c) == list(range(100))

    def test_len(self):
        assert 100 == len(caching_iter(range(100)))

    def test_hash(self):
        assert hash(caching_iter(range(100))) == hash(tuple(range(100)))

    def test_bool(self):
        c = caching_iter(range(100))
        assert bool(c)
        # repeat to check if it works when cached.
        assert bool(c)
        assert not bool(caching_iter(iter([])))

    def test_cmp(self):
        assert tuple(caching_iter(range(100))) == tuple(range(100))
        assert tuple(caching_iter(range(90))) != tuple(range(100))
        assert tuple(caching_iter(range(100))) > tuple(range(90))
        assert not tuple(caching_iter(range(90))) > tuple(range(100))
        assert tuple(caching_iter(range(100))) >= tuple(range(100))
        assert tuple(caching_iter(range(90))) < tuple(range(100))
        assert not tuple(caching_iter(range(100))) < tuple(range(90))
        assert tuple(caching_iter(range(90))) <= tuple(range(100))

    def test_sorter(self):
        assert tuple(caching_iter(range(100, 0, -1), sorted)) == tuple(range(1, 101))
        c = caching_iter(range(100, 0, -1), sorted)
        assert c
        assert tuple(iter(c)) == tuple(range(1, 101))
        c = caching_iter(range(50, 0, -1), sorted)
        assert c[10] == 11
        assert tuple(iter(c)) == tuple(range(1, 51))

    def test_getitem(self):
        c = caching_iter(range(20))
        assert c[-1] == 19
        with pytest.raises(IndexError):
            operator.getitem(c, -21)
        with pytest.raises(IndexError):
            operator.getitem(c, 21)

    def test_edgecase(self):
        c = caching_iter(range(5))
        assert c[0] == 0
        # do an off by one access- this actually has broke before
        assert c[2] == 2
        assert c[1] == 1
        assert list(c) == list(range(5))

    def test_setitem(self):
        with pytest.raises(TypeError):
            operator.setitem(caching_iter(range(10)), 3, 4)

    def test_str(self):
        # Just make sure this works at all.
        assert str(caching_iter(range(10)))


class Test_iter_sort:
    def test_ordering(self):
        def f(l):
            return sorted(l, key=operator.itemgetter(0))

        result = list(iter_sort(f, *[iter(range(x, x + 10)) for x in (30, 20, 0, 10)]))
        expected = list(range(40))
        assert result == expected