~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__static_tuple.py

Finish switching the naming to StaticTuple.

This also means stripping out the Keys type, in favor of a StaticTuple that
can reference yet another StaticTuple.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Tests for the Keys type."""
 
17
"""Tests for the StaticTuple type."""
18
18
 
19
19
import gc
20
20
import sys
33
33
        ('python', {'module': _static_tuple_py}),
34
34
    ]
35
35
    suite = loader.suiteClass()
36
 
    if CompiledKeysType.available():
 
36
    if CompiledStaticTuple.available():
37
37
        from bzrlib import _static_tuple_c
38
38
        scenarios.append(('C', {'module': _static_tuple_c}))
39
39
    else:
40
40
        # the compiled module isn't available, so we add a failing test
41
41
        class FailWithoutFeature(tests.TestCase):
42
42
            def test_fail(self):
43
 
                self.requireFeature(CompiledKeysType)
 
43
                self.requireFeature(CompiledStaticTuple)
44
44
        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
45
45
    result = tests.multiply_tests(standard_tests, scenarios, suite)
46
46
    return result
47
47
 
48
48
 
49
 
class _CompiledKeysType(tests.Feature):
 
49
class _CompiledStaticTuple(tests.Feature):
50
50
 
51
51
    def _probe(self):
52
52
        try:
58
58
    def feature_name(self):
59
59
        return 'bzrlib._static_tuple_c'
60
60
 
61
 
CompiledKeysType = _CompiledKeysType()
 
61
CompiledStaticTuple = _CompiledStaticTuple()
62
62
 
63
63
 
64
64
class _Meliae(tests.Feature):
76
76
Meliae = _Meliae()
77
77
 
78
78
 
79
 
class TestKeyType(tests.TestCase):
 
79
class TestStaticTuple(tests.TestCase):
80
80
 
81
81
    def test_create(self):
82
 
        k = self.module.Key('foo')
83
 
        k = self.module.Key('foo', 'bar')
 
82
        k = self.module.StaticTuple('foo')
 
83
        k = self.module.StaticTuple('foo', 'bar')
84
84
 
85
85
    def test_create_bad_args(self):
86
 
        self.assertRaises(ValueError, self.module.Key)
 
86
        self.assertRaises(ValueError, self.module.StaticTuple)
87
87
        lots_of_args = ['a']*300
88
88
        # too many args
89
 
        self.assertRaises(ValueError, self.module.Key, *lots_of_args)
 
89
        self.assertRaises(ValueError, self.module.StaticTuple, *lots_of_args)
90
90
        # not a string
91
 
        self.assertRaises(TypeError, self.module.Key, 10)
 
91
        self.assertRaises(TypeError, self.module.StaticTuple, 10)
92
92
        
93
93
    def test_as_tuple(self):
94
 
        k = self.module.Key('foo')
 
94
        k = self.module.StaticTuple('foo')
95
95
        t = k.as_tuple()
96
96
        self.assertEqual(('foo',), t)
97
 
        k = self.module.Key('foo', 'bar')
 
97
        k = self.module.StaticTuple('foo', 'bar')
98
98
        t = k.as_tuple()
99
99
        self.assertEqual(('foo', 'bar'), t)
100
100
 
101
101
    def test_len(self):
102
 
        k = self.module.Key('foo')
 
102
        k = self.module.StaticTuple('foo')
103
103
        self.assertEqual(1, len(k))
104
 
        k = self.module.Key('foo', 'bar')
 
104
        k = self.module.StaticTuple('foo', 'bar')
105
105
        self.assertEqual(2, len(k))
106
 
        k = self.module.Key('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
 
106
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
107
107
        self.assertEqual(7, len(k))
108
108
 
109
109
    def test_getitem(self):
110
 
        k = self.module.Key('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
 
110
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
111
111
        self.assertEqual('foo', k[0])
112
112
        self.assertEqual('foo', k[0])
113
113
        self.assertEqual('foo', k[0])
117
117
    def test_refcount(self):
118
118
        f = 'fo' + 'oo'
119
119
        num_refs = sys.getrefcount(f)
120
 
        k = self.module.Key(f)
 
120
        k = self.module.StaticTuple(f)
121
121
        self.assertEqual(num_refs + 1, sys.getrefcount(f))
122
122
        b = k[0]
123
123
        self.assertEqual(num_refs + 2, sys.getrefcount(f))
131
131
        self.assertEqual(num_refs, sys.getrefcount(f))
132
132
 
133
133
    def test__repr__(self):
134
 
        k = self.module.Key('foo', 'bar', 'baz', 'bing')
 
134
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
135
135
        self.assertEqual("('foo', 'bar', 'baz', 'bing')", repr(k))
136
136
 
137
137
    def assertCompareEqual(self, k1, k2):
143
143
        self.assertFalse(k1 > k2)
144
144
 
145
145
    def test_compare_same_obj(self):
146
 
        k1 = self.module.Key('foo', 'bar')
 
146
        k1 = self.module.StaticTuple('foo', 'bar')
147
147
        self.assertCompareEqual(k1, k1)
148
148
 
149
149
    def test_compare_equivalent_obj(self):
150
 
        k1 = self.module.Key('foo', 'bar')
151
 
        k2 = self.module.Key('foo', 'bar')
 
150
        k1 = self.module.StaticTuple('foo', 'bar')
 
151
        k2 = self.module.StaticTuple('foo', 'bar')
152
152
        self.assertCompareEqual(k1, k2)
153
153
 
154
154
    def test_compare_similar_obj(self):
155
 
        k1 = self.module.Key('foo' + ' bar', 'bar' + ' baz')
156
 
        k2 = self.module.Key('fo' + 'o bar', 'ba' + 'r baz')
 
155
        k1 = self.module.StaticTuple('foo' + ' bar', 'bar' + ' baz')
 
156
        k2 = self.module.StaticTuple('fo' + 'o bar', 'ba' + 'r baz')
157
157
        self.assertCompareEqual(k1, k2)
158
158
 
159
159
    def assertCompareDifferent(self, k_small, k_big):
165
165
        self.assertTrue(k_small < k_big)
166
166
 
167
167
    def test_compare_all_different_same_width(self):
168
 
        k1 = self.module.Key('baz', 'bing')
169
 
        k2 = self.module.Key('foo', 'bar')
 
168
        k1 = self.module.StaticTuple('baz', 'bing')
 
169
        k2 = self.module.StaticTuple('foo', 'bar')
170
170
        self.assertCompareDifferent(k1, k2)
171
171
 
172
172
    def test_compare_some_different(self):
173
 
        k1 = self.module.Key('foo', 'bar')
174
 
        k2 = self.module.Key('foo', 'zzz')
 
173
        k1 = self.module.StaticTuple('foo', 'bar')
 
174
        k2 = self.module.StaticTuple('foo', 'zzz')
175
175
        self.assertCompareDifferent(k1, k2)
176
176
 
177
177
    def test_compare_diff_width(self):
178
 
        k1 = self.module.Key('foo')
179
 
        k2 = self.module.Key('foo', 'bar')
 
178
        k1 = self.module.StaticTuple('foo')
 
179
        k2 = self.module.StaticTuple('foo', 'bar')
180
180
        self.assertCompareDifferent(k1, k2)
181
181
 
182
182
    def test_compare_to_tuples(self):
183
 
        k1 = self.module.Key('foo')
 
183
        k1 = self.module.StaticTuple('foo')
184
184
        self.assertCompareEqual(k1, ('foo',))
185
185
        self.assertCompareEqual(('foo',), k1)
186
186
        self.assertCompareDifferent(k1, ('foo', 'bar'))
187
187
        self.assertCompareDifferent(k1, ('foo', 10))
188
188
 
189
 
        k2 = self.module.Key('foo', 'bar')
 
189
        k2 = self.module.StaticTuple('foo', 'bar')
190
190
        self.assertCompareEqual(k2, ('foo', 'bar'))
191
191
        self.assertCompareEqual(('foo', 'bar'), k2)
192
192
        self.assertCompareDifferent(k2, ('foo', 'zzz'))
196
196
        self.assertCompareDifferent(('foo', 10), k2)
197
197
 
198
198
    def test_hash(self):
199
 
        k = self.module.Key('foo')
 
199
        k = self.module.StaticTuple('foo')
200
200
        self.assertEqual(hash(k), hash(('foo',)))
201
 
        k = self.module.Key('foo', 'bar', 'baz', 'bing')
 
201
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
202
202
        as_tuple = ('foo', 'bar', 'baz', 'bing')
203
203
        self.assertEqual(hash(k), hash(as_tuple))
204
204
        x = {k: 'foo'}
209
209
        self.assertEqual({as_tuple: 'bar'}, x)
210
210
 
211
211
    def test_slice(self):
212
 
        k = self.module.Key('foo', 'bar', 'baz', 'bing')
 
212
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
213
213
        self.assertEqual(('foo', 'bar'), k[:2])
214
214
        self.assertEqual(('baz',), k[2:-1])
215
215
 
221
221
        self.requireFeature(Meliae)
222
222
        from meliae import scanner
223
223
        strs = ['foo', 'bar', 'baz', 'bing']
224
 
        k = self.module.Key(*strs)
225
 
        if isinstance(k, _static_tuple_py.Key):
 
224
        k = self.module.StaticTuple(*strs)
 
225
        if isinstance(k, _static_tuple_py.StaticTuple):
226
226
            # The python version references objects slightly different than the
227
227
            # compiled version
228
 
            self.assertEqual([k._tuple, _static_tuple_py.Key],
 
228
            self.assertEqual([k._tuple, _static_tuple_py.StaticTuple],
229
229
                             scanner.get_referents(k))
230
230
        else:
231
231
            self.assertEqual(sorted(strs), sorted(scanner.get_referents(k)))
232
232
 
233
 
 
234
 
class TestKeysType(tests.TestCase):
235
 
 
236
 
    def test_create(self):
237
 
        k = self.module.Keys(1, 'foo', 'bar')
238
 
        k = self.module.Keys(2, 'foo', 'bar')
239
 
 
240
 
    def test_create_bad_args(self):
241
 
        self.assertRaises(TypeError, self.module.Keys)
242
 
        self.assertRaises(TypeError, self.module.Keys, 'foo')
243
 
        self.assertRaises(ValueError, self.module.Keys, 0)
244
 
        self.assertRaises(ValueError, self.module.Keys, -1)
245
 
        self.assertRaises(ValueError, self.module.Keys, -200)
246
 
        self.assertRaises(ValueError, self.module.Keys, 2, 'foo')
247
 
        self.assertRaises(ValueError, self.module.Keys, 257)
248
 
        lots_of_args = ['a']*300
249
 
        # too many args
250
 
        self.assertRaises(ValueError, self.module.Keys, 1, *lots_of_args)
251
 
        self.assertRaises(TypeError, self.module.Keys, 1, 'foo', 10)
252
 
 
253
 
    def test_create_and_del_correct_refcount(self):
254
 
        s = 'my custom' + ' foo bar'
255
 
        n_ref = sys.getrefcount(s)
256
 
        k = self.module.Keys(1, s)
257
 
        self.assertEqual(n_ref + 1, sys.getrefcount(s))
258
 
        del k
259
 
        self.assertEqual(n_ref, sys.getrefcount(s))
260
 
 
261
 
    def test_getitem(self):
262
 
        f = 'fo' + 'o'
263
 
        k = self.module.Keys(1, f, 'bar')
264
 
        self.assertEqual(('foo',), k[0])
265
 
        self.assertEqual(('bar',), k[1])
266
 
        self.assertRaises(IndexError, k.__getitem__, 2)
267
 
        n_refs = sys.getrefcount(f)
268
 
        f_key = k[0]
269
 
        # The pure-python version returns a tuple it already created, rather
270
 
        # than creating a new one, so the refcount doesn't change
271
 
        self.assertTrue(n_refs + 1 >= sys.getrefcount(f) >= n_refs)
272
 
        del f_key
273
 
        # This is the important check, that the final refcount should be
274
 
        # unchanged
275
 
        self.assertEqual(n_refs, sys.getrefcount(f))
276
 
        self.assertEqual(2, len(k))
277
 
 
278
 
    def test_get_wide_key(self):
279
 
        k = self.module.Keys(2, 'foo', 'bar', 'baz', 'bing')
280
 
        self.assertEqual(('foo', 'bar'), k[0])
281
 
        self.assertEqual(('baz', 'bing'), k[1])
282
 
        self.assertRaises(IndexError, k.__getitem__, 2)
283
 
        self.assertEqual(2, len(k))
284
 
 
285
 
    def test_as_tuple(self):
286
 
        k = self.module.Keys(2, 'foo', 'bar', 'baz', 'bing')
287
 
        if getattr(k, 'as_tuple', None) is not None:
288
 
            t = k.as_tuple()
289
 
        else:
290
 
            t = k # The pure-python form is in tuples already
291
 
        self.assertEqual((('foo', 'bar'), ('baz', 'bing')), t)
292
 
 
293
 
    def test_repr(self):
294
 
        k = self.module.Keys(2, 'foo', 'bar', 'baz', 'bing')
295
 
        self.assertEqual("(('foo', 'bar'), ('baz', 'bing'))", repr(k))
296
 
 
297
 
    def test_compare(self):
298
 
        k1 = self.module.Keys(2, 'foo', 'bar')
299
 
        k2 = self.module.Keys(2, 'baz', 'bing')
300
 
        k3 = self.module.Keys(2, 'foo', 'zzz')
301
 
        k4 = self.module.Keys(2, 'foo', 'bar')
302
 
        # Comparison should be done on the keys themselves, and not based on
303
 
        # object id, etc.
304
 
        self.assertTrue(k1 == k1)
305
 
        self.assertTrue(k1 == k4)
306
 
        self.assertTrue(k2 < k1)
307
 
        self.assertTrue(k2 < k4)
308
 
        self.assertTrue(k3 > k1)
309
 
        self.assertTrue(k3 > k4)
310
 
        # We should also be able to compare against raw tuples
311
 
        self.assertTrue(k1 == (('foo', 'bar'),))
312
 
 
313
 
    def test_sorted(self):
314
 
        k1 = self.module.Keys(2, 'foo', 'bar', 'baz', 'bing', 'foo', 'zzz')
315
 
        self.assertEqual([('baz', 'bing'), ('foo', 'bar'), ('foo', 'zzz')],
316
 
                         sorted(k1))
317
 
 
318
 
        k1 = self.module.Keys(2, 'foo', 'bar')
319
 
        k2 = self.module.Keys(2, 'baz', 'bing')
320
 
        k3 = self.module.Keys(2, 'foo', 'zzz')
321
 
        self.assertEqual([(('baz', 'bing'),), (('foo', 'bar'),),
322
 
                          (('foo', 'zzz'),)], sorted([k1, k2, k3]))
323
 
 
324
 
    def test_hash(self):
325
 
        k1 = self.module.Keys(2, 'foo', 'bar', 'baz', 'bing', 'foo', 'zzz')
326
 
        as_tuple =(('foo', 'bar'), ('baz', 'bing'), ('foo', 'zzz')) 
327
 
        self.assertEqual(hash(k1), hash(as_tuple))
328
 
        x = {k1: 'foo'}
329
 
        # Because k1 == as_tuple, it replaces the slot, rather than having both
330
 
        # present in the dict.
331
 
        self.assertEqual('foo', x[as_tuple])
332
 
        x[as_tuple] = 'bar'
333
 
        self.assertEqual({as_tuple: 'bar'}, x)
334
 
 
335
 
    def test_referents(self):
336
 
        # We implement tp_traverse so that things like 'meliae' can measure the
337
 
        # amount of referenced memory. Unfortunately gc.get_referents() first
338
 
        # checks the IS_GC flag before it traverses anything. So there isn't a
339
 
        # way to expose it that I can see.
340
 
        self.requireFeature(Meliae)
341
 
        from meliae import scanner
342
 
        strs = ['foo', 'bar', 'baz', 'bing']
343
 
        k = self.module.Keys(2, *strs)
344
 
        if type(k) == tuple:
345
 
            self.assertEqual(sorted([('foo', 'bar'), ('baz', 'bing')]),
346
 
                             sorted(scanner.get_referents(k)))
347
 
        else:
348
 
            self.assertEqual(sorted(strs), sorted(scanner.get_referents(k)))
349
 
 
350
233
    def test_intern(self):
351
234
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
352
235
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
353
 
        key = self.module.Key(unique_str1, unique_str2)
 
236
        key = self.module.StaticTuple(unique_str1, unique_str2)
354
237
        self.assertFalse(key in self.module._interned_keys)
355
 
        key2 = self.module.Key(unique_str1, unique_str2)
 
238
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
356
239
        self.assertEqual(key, key2)
357
240
        self.assertIsNot(key, key2)
358
241
        key3 = key.intern()
367
250
            return # Not applicable
368
251
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
369
252
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
370
 
        key = self.module.Key(unique_str1, unique_str2)
 
253
        key = self.module.StaticTuple(unique_str1, unique_str2)
371
254
        self.assertFalse(key in self.module._interned_keys)
372
255
        self.assertFalse(key._is_interned())
373
 
        key2 = self.module.Key(unique_str1, unique_str2)
 
256
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
374
257
        self.assertEqual(key, key2)
375
258
        self.assertIsNot(key, key2)
376
259
        refcount = sys.getrefcount(key)
394
277
            return # Not applicable
395
278
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
396
279
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
397
 
        key = self.module.Key(unique_str1, unique_str2)
 
280
        key = self.module.StaticTuple(unique_str1, unique_str2)
398
281
        self.assertFalse(key in self.module._interned_keys)
399
282
        self.assertEqual(2, sys.getrefcount(key))
400
283
        key = key.intern()
403
286
        self.assertTrue(key._is_interned())
404
287
        del key
405
288
        # Create a new entry, which would point to the same location
406
 
        key = self.module.Key(unique_str1, unique_str2)
 
289
        key = self.module.StaticTuple(unique_str1, unique_str2)
407
290
        self.assertEqual(2, sys.getrefcount(key))
408
291
        # This old entry in _interned_keys should be gone
409
292
        self.assertFalse(key in self.module._interned_keys)