/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__static_tuple.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
 
1
# Copyright (C) 2009, 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""Tests for the StaticTuple type."""
18
18
 
19
 
try:
20
 
    import cPickle as pickle
21
 
except ImportError:
22
 
    import pickle
23
 
import operator
 
19
import cPickle
 
20
import gc
24
21
import sys
25
22
 
26
 
from breezy import (
 
23
from bzrlib import (
27
24
    _static_tuple_py,
28
25
    debug,
 
26
    errors,
29
27
    osutils,
30
28
    static_tuple,
31
29
    tests,
32
30
    )
33
 
from breezy.sixish import (
34
 
    PY3,
35
 
    text_type,
36
 
    )
37
 
from breezy.tests import (
38
 
    features,
39
 
    )
40
 
 
41
 
 
42
 
def load_tests(loader, standard_tests, pattern):
 
31
 
 
32
 
 
33
def load_tests(standard_tests, module, loader):
43
34
    """Parameterize tests for all versions of groupcompress."""
44
35
    global compiled_static_tuple_feature
45
36
    suite, compiled_static_tuple_feature = tests.permute_tests_for_extension(
46
 
        standard_tests, loader, 'breezy._static_tuple_py',
47
 
        'breezy._static_tuple_c')
 
37
        standard_tests, loader, 'bzrlib._static_tuple_py',
 
38
        'bzrlib._static_tuple_c')
48
39
    return suite
49
40
 
50
41
 
 
42
class _Meliae(tests.Feature):
 
43
 
 
44
    def _probe(self):
 
45
        try:
 
46
            from meliae import scanner
 
47
        except ImportError:
 
48
            return False
 
49
        return True
 
50
 
 
51
    def feature_name(self):
 
52
        return "Meliae - python memory debugger"
 
53
 
 
54
Meliae = _Meliae()
 
55
 
 
56
 
51
57
class TestStaticTuple(tests.TestCase):
52
58
 
53
59
    def assertRefcount(self, count, obj):
62
68
        # self.assertEqual(count, sys.getrefcount(obj)-1)
63
69
        # Then it works fine. Something about passing it to assertRefcount is
64
70
        # actually double-incrementing (and decrementing) the refcount
65
 
        self.assertEqual(count, sys.getrefcount(obj) - 3)
 
71
        self.assertEqual(count, sys.getrefcount(obj)-3)
66
72
 
67
73
    def test_create(self):
68
74
        k = self.module.StaticTuple('foo')
69
75
        k = self.module.StaticTuple('foo', 'bar')
70
76
 
71
77
    def test_create_bad_args(self):
72
 
        args_256 = ['a'] * 256
 
78
        args_256 = ['a']*256
73
79
        # too many args
74
80
        self.assertRaises(TypeError, self.module.StaticTuple, *args_256)
75
 
        args_300 = ['a'] * 300
 
81
        args_300 = ['a']*300
76
82
        self.assertRaises(TypeError, self.module.StaticTuple, *args_300)
77
83
        # not a string
78
84
        self.assertRaises(TypeError, self.module.StaticTuple, object())
112
118
    def test_concat_with_non_tuple(self):
113
119
        st1 = self.module.StaticTuple('foo')
114
120
        self.assertRaises(TypeError, lambda: st1 + 10)
115
 
 
 
121
        
116
122
    def test_as_tuple(self):
117
123
        k = self.module.StaticTuple('foo')
118
124
        t = k.as_tuple()
155
161
        self.assertEqual(2, len(k))
156
162
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
157
163
        self.assertEqual(7, len(k))
158
 
        args = ['foo'] * 255
 
164
        args = ['foo']*255
159
165
        k = self.module.StaticTuple(*args)
160
166
        self.assertEqual(255, len(k))
161
167
 
174
180
        self.assertEqual('z', k[6])
175
181
        self.assertEqual('z', k[-1])
176
182
        self.assertRaises(IndexError, k.__getitem__, 7)
177
 
        self.assertRaises(IndexError, k.__getitem__, 256 + 7)
 
183
        self.assertRaises(IndexError, k.__getitem__, 256+7)
178
184
        self.assertRaises(IndexError, k.__getitem__, 12024)
179
185
        # Python's [] resolver handles the negative arguments, so we can't
180
186
        # really test StaticTuple_item() with negative values.
183
189
 
184
190
    def test_refcount(self):
185
191
        f = 'fo' + 'oo'
186
 
        num_refs = sys.getrefcount(f) - 1  # sys.getrefcount() adds one
 
192
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
187
193
        k = self.module.StaticTuple(f)
188
194
        self.assertRefcount(num_refs + 1, f)
189
195
        b = k[0]
215
221
 
216
222
    def test_holds_int(self):
217
223
        k1 = self.module.StaticTuple(1)
218
 
 
219
224
        class subint(int):
220
225
            pass
221
226
        # But not a subclass, because subint could introduce refcycles
222
227
        self.assertRaises(TypeError, self.module.StaticTuple, subint(2))
223
228
 
224
229
    def test_holds_long(self):
225
 
        if PY3:
226
 
            self.skipTest("No long type on Python 3")
227
 
        k1 = self.module.StaticTuple(2**65)
228
 
 
 
230
        k1 = self.module.StaticTuple(2L**65)
229
231
        class sublong(long):
230
232
            pass
231
233
        # But not a subclass
233
235
 
234
236
    def test_holds_float(self):
235
237
        k1 = self.module.StaticTuple(1.2)
236
 
 
237
238
        class subfloat(float):
238
239
            pass
239
240
        self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5))
240
241
 
241
 
    def test_holds_bytes(self):
242
 
        k1 = self.module.StaticTuple(b'astring')
243
 
 
244
 
        class substr(bytes):
 
242
    def test_holds_str(self):
 
243
        k1 = self.module.StaticTuple('astring')
 
244
        class substr(str):
245
245
            pass
246
 
        self.assertRaises(TypeError, self.module.StaticTuple, substr(b'a'))
 
246
        self.assertRaises(TypeError, self.module.StaticTuple, substr('a'))
247
247
 
248
248
    def test_holds_unicode(self):
249
249
        k1 = self.module.StaticTuple(u'\xb5')
250
 
 
251
 
        class subunicode(text_type):
 
250
        class subunicode(unicode):
252
251
            pass
253
252
        self.assertRaises(TypeError, self.module.StaticTuple,
254
253
                          subunicode(u'\xb5'))
293
292
        k6 = self.module.StaticTuple(k3, k4)
294
293
        self.assertCompareEqual(k5, k6)
295
294
 
296
 
    def check_strict_compare(self, k1, k2, mismatched_types):
297
 
        """True if on Python 3 and stricter comparison semantics are used."""
298
 
        if PY3 and mismatched_types:
299
 
            for op in ("ge", "gt", "le", "lt"):
300
 
                self.assertRaises(TypeError, getattr(operator, op), k1, k2)
301
 
            return True
302
 
        return False
303
 
 
304
 
    def assertCompareDifferent(self, k_small, k_big, mismatched_types=False):
 
295
    def assertCompareDifferent(self, k_small, k_big):
305
296
        self.assertFalse(k_small == k_big)
 
297
        self.assertFalse(k_small >= k_big)
 
298
        self.assertFalse(k_small > k_big)
306
299
        self.assertTrue(k_small != k_big)
307
 
        if not self.check_strict_compare(k_small, k_big, mismatched_types):
308
 
            self.assertFalse(k_small >= k_big)
309
 
            self.assertFalse(k_small > k_big)
310
 
            self.assertTrue(k_small <= k_big)
311
 
            self.assertTrue(k_small < k_big)
 
300
        self.assertTrue(k_small <= k_big)
 
301
        self.assertTrue(k_small < k_big)
312
302
 
313
 
    def assertCompareNoRelation(self, k1, k2, mismatched_types=False):
 
303
    def assertCompareNoRelation(self, k1, k2):
314
304
        """Run the comparison operators, make sure they do something.
315
305
 
316
306
        However, we don't actually care what comes first or second. This is
319
309
        """
320
310
        self.assertFalse(k1 == k2)
321
311
        self.assertTrue(k1 != k2)
322
 
        if not self.check_strict_compare(k1, k2, mismatched_types):
323
 
            # Do the comparison, but we don't care about the result
324
 
            k1 >= k2
325
 
            k1 > k2
326
 
            k1 <= k2
327
 
            k1 < k2
 
312
        # Do the comparison, but we don't care about the result
 
313
        k1 >= k2
 
314
        k1 > k2
 
315
        k1 <= k2
 
316
        k1 < k2
328
317
 
329
318
    def test_compare_vs_none(self):
330
319
        k1 = self.module.StaticTuple('baz', 'bing')
331
 
        self.assertCompareDifferent(None, k1, mismatched_types=True)
332
 
 
 
320
        self.assertCompareDifferent(None, k1)
 
321
    
333
322
    def test_compare_cross_class(self):
334
323
        k1 = self.module.StaticTuple('baz', 'bing')
335
 
        self.assertCompareNoRelation(10, k1, mismatched_types=True)
336
 
        self.assertCompareNoRelation('baz', k1, mismatched_types=True)
 
324
        self.assertCompareNoRelation(10, k1)
 
325
        self.assertCompareNoRelation('baz', k1)
337
326
 
338
327
    def test_compare_all_different_same_width(self):
339
328
        k1 = self.module.StaticTuple('baz', 'bing')
360
349
        k4 = self.module.StaticTuple(k1, k2)
361
350
        self.assertCompareDifferent(k3, k4)
362
351
        k5 = self.module.StaticTuple('foo', None)
363
 
        self.assertCompareDifferent(k5, k1, mismatched_types=True)
364
 
        self.assertCompareDifferent(k5, k2, mismatched_types=True)
 
352
        self.assertCompareDifferent(k5, k1)
 
353
        self.assertCompareDifferent(k5, k2)
365
354
 
366
355
    def test_compare_diff_width(self):
367
356
        k1 = self.module.StaticTuple('foo')
375
364
        k1 = self.module.StaticTuple('foo', 'bar')
376
365
        k2 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
377
366
                                     k1)
378
 
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
 
367
        self.assertCompareNoRelation(k1, k2)
379
368
        k3 = self.module.StaticTuple('foo')
380
369
        self.assertCompareDifferent(k3, k1)
381
370
        k4 = self.module.StaticTuple(None)
382
 
        self.assertCompareDifferent(k4, k1, mismatched_types=True)
 
371
        self.assertCompareDifferent(k4, k1)
383
372
        k5 = self.module.StaticTuple(1)
384
 
        self.assertCompareNoRelation(k1, k5, mismatched_types=True)
 
373
        self.assertCompareNoRelation(k1, k5)
385
374
 
386
375
    def test_compare_to_tuples(self):
387
376
        k1 = self.module.StaticTuple('foo')
397
386
        self.assertCompareDifferent(('foo',), k2)
398
387
        self.assertCompareDifferent(('foo', 'aaa'), k2)
399
388
        self.assertCompareDifferent(('baz', 'bing'), k2)
400
 
        self.assertCompareDifferent(('foo', 10), k2, mismatched_types=True)
 
389
        self.assertCompareDifferent(('foo', 10), k2)
401
390
 
402
391
        k3 = self.module.StaticTuple(k1, k2)
403
392
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
413
402
        # This requires comparing a StaticTuple to a 'string', and then
414
403
        # interpreting that value in the next higher StaticTuple. This used to
415
404
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
416
 
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
 
405
        self.assertCompareNoRelation(k1, k2)
417
406
 
418
407
    def test_hash(self):
419
408
        k = self.module.StaticTuple('foo')
441
430
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
442
431
        self.assertEqual(('foo', 'bar'), k[:2])
443
432
        self.assertEqual(('baz',), k[2:-1])
444
 
        self.assertEqual(('foo', 'baz',), k[::2])
445
 
        self.assertRaises(TypeError, k.__getitem__, 'not_slice')
 
433
        try:
 
434
            val = k[::2]
 
435
        except TypeError:
 
436
            # C implementation raises a TypeError, we don't need the
 
437
            # implementation yet, so allow this to pass
 
438
            pass
 
439
        else:
 
440
            # Python implementation uses a regular Tuple, so make sure it gives
 
441
            # the right result
 
442
            self.assertEqual(('foo', 'baz'), val)
446
443
 
447
444
    def test_referents(self):
448
445
        # We implement tp_traverse so that things like 'meliae' can measure the
449
446
        # amount of referenced memory. Unfortunately gc.get_referents() first
450
447
        # checks the IS_GC flag before it traverses anything. We could write a
451
448
        # helper func, but that won't work for the generic implementation...
452
 
        self.requireFeature(features.meliae)
 
449
        self.requireFeature(Meliae)
453
450
        from meliae import scanner
454
451
        strs = ['foo', 'bar', 'baz', 'bing']
455
452
        k = self.module.StaticTuple(*strs)
460
457
        self.assertEqual(sorted(refs), sorted(scanner.get_referents(k)))
461
458
 
462
459
    def test_nested_referents(self):
463
 
        self.requireFeature(features.meliae)
 
460
        self.requireFeature(Meliae)
464
461
        from meliae import scanner
465
462
        strs = ['foo', 'bar', 'baz', 'bing']
466
463
        k1 = self.module.StaticTuple(*strs[:2])
493
490
 
494
491
    def test__c_intern_handles_refcount(self):
495
492
        if self.module is _static_tuple_py:
496
 
            return  # Not applicable
 
493
            return # Not applicable
497
494
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
498
495
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
499
496
        key = self.module.StaticTuple(unique_str1, unique_str2)
528
525
 
529
526
    def test__c_keys_are_not_immortal(self):
530
527
        if self.module is _static_tuple_py:
531
 
            return  # Not applicable
 
528
            return # Not applicable
532
529
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
533
530
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
534
531
        key = self.module.StaticTuple(unique_str1, unique_str2)
599
596
 
600
597
    def test_pickle(self):
601
598
        st = self.module.StaticTuple('foo', 'bar')
602
 
        pickled = pickle.dumps(st)
603
 
        unpickled = pickle.loads(pickled)
 
599
        pickled = cPickle.dumps(st)
 
600
        unpickled = cPickle.loads(pickled)
604
601
        self.assertEqual(unpickled, st)
605
602
 
606
603
    def test_pickle_empty(self):
607
604
        st = self.module.StaticTuple()
608
 
        pickled = pickle.dumps(st)
609
 
        unpickled = pickle.loads(pickled)
 
605
        pickled = cPickle.dumps(st)
 
606
        unpickled = cPickle.loads(pickled)
610
607
        self.assertIs(st, unpickled)
611
608
 
612
609
    def test_pickle_nested(self):
613
610
        st = self.module.StaticTuple('foo', self.module.StaticTuple('bar'))
614
 
        pickled = pickle.dumps(st)
615
 
        unpickled = pickle.loads(pickled)
 
611
        pickled = cPickle.dumps(st)
 
612
        unpickled = cPickle.loads(pickled)
616
613
        self.assertEqual(unpickled, st)
617
614
 
618
615
    def test_static_tuple_thunk(self):
619
616
        # Make sure the right implementation is available from
620
 
        # breezy.static_tuple.StaticTuple.
 
617
        # bzrlib.static_tuple.StaticTuple.
621
618
        if self.module is _static_tuple_py:
622
619
            if compiled_static_tuple_feature.available():
623
620
                # We will be using the C version