27
from bzrlib.tests import (
31
from bzrlib import _simple_set_pyx as _module
35
from bzrlib._static_tuple_c import StaticTuple
37
from bzrlib._static_tuple_py import StaticTuple
28
from bzrlib import _simple_set_pyx
30
_simple_set_pyx = None
40
33
# Even though this is an extension, we don't permute the tests for a python
41
34
# version. As the plain python version is just a dict or set
43
class _CompiledStaticTupleInterned(tests.Feature):
36
class _CompiledSimpleSet(tests.Feature):
39
if _simple_set_pyx is None:
50
43
def feature_name(self):
51
44
return 'bzrlib._simple_set_pyx'
53
CompiledStaticTupleInterned = _CompiledStaticTupleInterned()
56
class TestStaticTupleInterned(tests.TestCase):
58
_test_needs_features = [CompiledStaticTupleInterned,
59
test__static_tuple.CompiledStaticTuple]
46
CompiledSimpleSet = _CompiledSimpleSet()
49
class TestSimpleSet(tests.TestCase):
51
_test_needs_features = [CompiledSimpleSet]
52
module = _simple_set_pyx
61
54
def assertIn(self, obj, container):
62
55
self.assertTrue(obj in container,
76
69
assertRefcount actually creates a new pointer, as does calling
77
70
sys.getrefcount. So pass the expected value *before* the call.
79
# I don't understand why it is count+3 here, but it seems to be
80
# correct. If I check in the calling function, with:
81
# self.assertEqual(count+1, sys.getrefcount(obj))
82
# Then it works fine. Something about passing it to assertRefcount is
83
# actually double-incrementing (and decrementing) the refcount
84
self.assertEqual(count+3, sys.getrefcount(obj))
72
# I'm not sure why the offset is 3, but I've check that in the caller,
73
# an offset of 1 works, which is expected. Not sure why assertRefcount
74
# is incrementing/decrementing 2 times
75
self.assertEqual(count, sys.getrefcount(obj)-3)
86
77
def test_initial(self):
87
obj = _module.SimpleSet()
78
obj = self.module.SimpleSet()
88
79
self.assertEqual(0, len(obj))
89
st = StaticTuple('foo', 'bar')
90
81
self.assertFillState(0, 0, 0x3ff, obj)
92
83
def test__lookup(self):
98
89
# ('a', 'a'), ('f', '4'), ('p', 'r'), ('q', '1'), ('F', 'T'),
99
90
# ('Q', 'Q'), ('V', 'd'), ('7', 'C')
100
91
# all collide @ 643
101
obj = _module.SimpleSet()
102
offset, val = obj._test_lookup(StaticTuple('a', 'a'))
103
self.assertEqual(643, offset)
104
self.assertEqual('<null>', val)
105
offset, val = obj._test_lookup(StaticTuple('f', '4'))
106
self.assertEqual(643, offset)
107
self.assertEqual('<null>', val)
108
offset, val = obj._test_lookup(StaticTuple('p', 'r'))
92
obj = self.module.SimpleSet()
93
offset, val = obj._test_lookup(('a', 'a'))
94
self.assertEqual(643, offset)
95
self.assertEqual('<null>', val)
96
offset, val = obj._test_lookup(('f', '4'))
97
self.assertEqual(643, offset)
98
self.assertEqual('<null>', val)
99
offset, val = obj._test_lookup(('p', 'r'))
109
100
self.assertEqual(643, offset)
110
101
self.assertEqual('<null>', val)
112
103
def test_get_set_del_with_collisions(self):
113
obj = _module.SimpleSet()
114
k1 = StaticTuple('a', 'a')
115
k2 = StaticTuple('f', '4') # collides
116
k3 = StaticTuple('p', 'r')
117
k4 = StaticTuple('q', '1')
104
obj = self.module.SimpleSet()
106
k2 = ('f', '4') # collides
118
109
self.assertEqual((643, '<null>'), obj._test_lookup(k1))
119
110
self.assertEqual((643, '<null>'), obj._test_lookup(k2))
120
111
self.assertEqual((643, '<null>'), obj._test_lookup(k3))
160
151
self.assertNotIn(k4, obj)
162
153
def test_add(self):
163
obj = _module.SimpleSet()
154
obj = self.module.SimpleSet()
164
155
self.assertFillState(0, 0, 0x3ff, obj)
165
k1 = StaticTuple('foo')
156
# We use this clumsy notation, because otherwise the refcounts are off.
157
# I'm guessing the python compiler sees it is a static tuple, and adds
158
# it to the function variables, or somesuch
166
160
self.assertRefcount(1, k1)
167
161
self.assertIs(k1, obj.add(k1))
168
162
self.assertFillState(1, 1, 0x3ff, obj)
189
183
self.assertFillState(0, 1, 0x3ff, obj)
190
184
self.assertRefcount(1, k1)
191
k3 = StaticTuple('bar')
192
186
self.assertRefcount(1, k3)
193
187
self.assertIs(k3, obj.add(k3))
194
188
self.assertFillState(1, 2, 0x3ff, obj)
200
194
self.assertRefcount(2, k3)
202
196
def test_discard(self):
203
obj = _module.SimpleSet()
204
k1 = StaticTuple('foo')
205
k2 = StaticTuple('foo')
206
k3 = StaticTuple('bar')
197
obj = self.module.SimpleSet()
207
201
self.assertRefcount(1, k1)
208
202
self.assertRefcount(1, k2)
209
203
self.assertRefcount(1, k3)
217
211
self.assertRefcount(1, k3)
219
213
def test__delitem__(self):
220
obj = _module.SimpleSet()
221
k1 = StaticTuple('foo')
222
k2 = StaticTuple('foo')
223
k3 = StaticTuple('bar')
214
obj = self.module.SimpleSet()
224
218
self.assertRefcount(1, k1)
225
219
self.assertRefcount(1, k2)
226
220
self.assertRefcount(1, k3)
264
258
self.assertEqual((591, '<null>'), obj._test_lookup(k2))
266
260
def test_add_and_remove_lots_of_items(self):
267
obj = _module.SimpleSet()
261
obj = self.module.SimpleSet()
268
262
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
271
k = StaticTuple(i, j)
273
267
num = len(chars)*len(chars)
274
268
self.assertFillState(num, num, 0x1fff, obj)
275
269
# Now delete all of the entries and it should shrink again
278
k = StaticTuple(i, j)
280
274
# It should be back to 1024 wide mask, though there may still be some
281
275
# dummy values in there