~bzr-pqm/bzr/bzr.dev

4679.3.1 by John Arbash Meinel
Start working on a Keys type.
1
# Copyright (C) 2009 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
17
"""Tests for the StaticTuple type."""
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
18
4759.2.16 by Matt Nordhoff
Add a test
19
import cPickle
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
20
import gc
4679.3.2 by John Arbash Meinel
Add a get_key() function, which then returns tuples for the given items.
21
import sys
22
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
23
from bzrlib import (
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
24
    _static_tuple_py,
4668.3.1 by John Arbash Meinel
Fix bug #471193, allow tuples into the CHK code.
25
    debug,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
26
    errors,
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
27
    osutils,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
28
    static_tuple,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
29
    tests,
30
    )
31
32
33
def load_tests(standard_tests, module, loader):
34
    """Parameterize tests for all versions of groupcompress."""
35
    scenarios = [
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
36
        ('python', {'module': _static_tuple_py}),
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
37
    ]
38
    suite = loader.suiteClass()
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
39
    if CompiledStaticTuple.available():
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
40
        from bzrlib import _static_tuple_c
41
        scenarios.append(('C', {'module': _static_tuple_c}))
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
42
    else:
43
        # the compiled module isn't available, so we add a failing test
44
        class FailWithoutFeature(tests.TestCase):
45
            def test_fail(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
46
                self.requireFeature(CompiledStaticTuple)
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
47
        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
48
    result = tests.multiply_tests(standard_tests, scenarios, suite)
49
    return result
50
51
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
52
class _CompiledStaticTuple(tests.Feature):
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
53
54
    def _probe(self):
55
        try:
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
56
            import bzrlib._static_tuple_c
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
57
        except ImportError:
58
            return False
59
        return True
60
61
    def feature_name(self):
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
62
        return 'bzrlib._static_tuple_c'
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
63
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
64
CompiledStaticTuple = _CompiledStaticTuple()
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
65
66
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
67
class _Meliae(tests.Feature):
68
69
    def _probe(self):
70
        try:
71
            from meliae import scanner
72
        except ImportError:
73
            return False
74
        return True
75
76
    def feature_name(self):
77
        return "Meliae - python memory debugger"
78
79
Meliae = _Meliae()
80
81
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
82
class TestStaticTuple(tests.TestCase):
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
83
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
84
    def assertRefcount(self, count, obj):
85
        """Assert that the refcount for obj is what we expect.
86
87
        Note that this automatically adjusts for the fact that calling
88
        assertRefcount actually creates a new pointer, as does calling
89
        sys.getrefcount. So pass the expected value *before* the call.
90
        """
91
        # I don't understand why it is getrefcount()-3 here, but it seems to be
92
        # correct. If I check in the calling function, with:
93
        # self.assertEqual(count, sys.getrefcount(obj)-1)
94
        # Then it works fine. Something about passing it to assertRefcount is
95
        # actually double-incrementing (and decrementing) the refcount
96
        self.assertEqual(count, sys.getrefcount(obj)-3)
97
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
98
    def test_create(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
99
        k = self.module.StaticTuple('foo')
100
        k = self.module.StaticTuple('foo', 'bar')
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
101
102
    def test_create_bad_args(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
103
        args_256 = ['a']*256
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
104
        # too many args
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
105
        self.assertRaises(ValueError, self.module.StaticTuple, *args_256)
106
        args_300 = ['a']*300
107
        self.assertRaises(ValueError, self.module.StaticTuple, *args_300)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
108
        # not a string
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
109
        self.assertRaises(TypeError, self.module.StaticTuple, object())
4759.2.2 by John Arbash Meinel
Update _static_tuple_py.py with the same concatenation behavior
110
111
    def test_concat(self):
112
        st1 = self.module.StaticTuple('foo')
113
        st2 = self.module.StaticTuple('bar')
114
        st3 = self.module.StaticTuple('foo', 'bar')
115
        st4 = st1 + st2
116
        self.assertEqual(st3, st4)
117
        self.assertIsInstance(st4, self.module.StaticTuple)
118
119
    def test_concat_with_tuple(self):
120
        st1 = self.module.StaticTuple('foo')
121
        t2 = ('bar',)
122
        st3 = self.module.StaticTuple('foo', 'bar')
123
        st4 = self.module.StaticTuple('bar', 'foo')
124
        st5 = st1 + t2
125
        st6 = t2 + st1
126
        self.assertEqual(st3, st5)
127
        self.assertIsInstance(st5, self.module.StaticTuple)
128
        self.assertEqual(st4, st6)
129
        if self.module is _static_tuple_py:
130
            # _static_tuple_py has StaticTuple(tuple), so tuple thinks it
131
            # already knows how to concatenate, as such we can't "inject" our
132
            # own concatenation...
133
            self.assertIsInstance(st6, tuple)
134
        else:
135
            self.assertIsInstance(st6, self.module.StaticTuple)
136
137
    def test_concat_with_bad_tuple(self):
138
        st1 = self.module.StaticTuple('foo')
139
        t2 = (object(),)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
140
        # Using st1.__add__ doesn't give the same results as doing the '+' form
141
        self.assertRaises(TypeError, lambda: st1 + t2)
4759.2.5 by John Arbash Meinel
Add a bit more tests.
142
143
    def test_concat_with_non_tuple(self):
144
        st1 = self.module.StaticTuple('foo')
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
145
        self.assertRaises(TypeError, lambda: st1 + 10)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
146
        
147
    def test_as_tuple(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
148
        k = self.module.StaticTuple('foo')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
149
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
150
        self.assertEqual(('foo',), t)
4789.28.3 by John Arbash Meinel
Add a static_tuple.as_tuples() helper.
151
        self.assertIsInstance(t, tuple)
152
        self.assertFalse(isinstance(t, self.module.StaticTuple))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
153
        k = self.module.StaticTuple('foo', 'bar')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
154
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
155
        self.assertEqual(('foo', 'bar'), t)
4789.28.3 by John Arbash Meinel
Add a static_tuple.as_tuples() helper.
156
        k2 = self.module.StaticTuple(1, k)
157
        t = k2.as_tuple()
158
        self.assertIsInstance(t, tuple)
159
        # For pickling to work, we need to keep the sub-items as StaticTuple so
160
        # that it knows that they also need to be converted.
161
        self.assertIsInstance(t[1], self.module.StaticTuple)
162
        self.assertEqual((1, ('foo', 'bar')), t)
163
164
    def test_as_tuples(self):
165
        k1 = self.module.StaticTuple('foo', 'bar')
166
        t = static_tuple.as_tuples(k1)
167
        self.assertIsInstance(t, tuple)
168
        self.assertEqual(('foo', 'bar'), t)
169
        k2 = self.module.StaticTuple(1, k1)
170
        t = static_tuple.as_tuples(k2)
171
        self.assertIsInstance(t, tuple)
172
        self.assertIsInstance(t[1], tuple)
173
        self.assertEqual((1, ('foo', 'bar')), t)
174
        mixed = (1, k1)
175
        t = static_tuple.as_tuples(mixed)
176
        self.assertIsInstance(t, tuple)
177
        self.assertIsInstance(t[1], tuple)
178
        self.assertEqual((1, ('foo', 'bar')), t)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
179
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
180
    def test_len(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
181
        k = self.module.StaticTuple()
182
        self.assertEqual(0, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
183
        k = self.module.StaticTuple('foo')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
184
        self.assertEqual(1, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
185
        k = self.module.StaticTuple('foo', 'bar')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
186
        self.assertEqual(2, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
187
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
188
        self.assertEqual(7, len(k))
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
189
        args = ['foo']*255
190
        k = self.module.StaticTuple(*args)
191
        self.assertEqual(255, len(k))
192
193
    def test_hold_other_static_tuples(self):
194
        k = self.module.StaticTuple('foo', 'bar')
195
        k2 = self.module.StaticTuple(k, k)
196
        self.assertEqual(2, len(k2))
197
        self.assertIs(k, k2[0])
198
        self.assertIs(k, k2[1])
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
199
200
    def test_getitem(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
201
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
202
        self.assertEqual('foo', k[0])
203
        self.assertEqual('foo', k[0])
204
        self.assertEqual('foo', k[0])
205
        self.assertEqual('z', k[6])
206
        self.assertEqual('z', k[-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
207
        self.assertRaises(IndexError, k.__getitem__, 7)
208
        self.assertRaises(IndexError, k.__getitem__, 256+7)
209
        self.assertRaises(IndexError, k.__getitem__, 12024)
210
        # Python's [] resolver handles the negative arguments, so we can't
211
        # really test StaticTuple_item() with negative values.
212
        self.assertRaises(TypeError, k.__getitem__, 'not-an-int')
213
        self.assertRaises(TypeError, k.__getitem__, '5')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
214
215
    def test_refcount(self):
216
        f = 'fo' + 'oo'
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
217
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
218
        k = self.module.StaticTuple(f)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
219
        self.assertRefcount(num_refs + 1, f)
220
        b = k[0]
221
        self.assertRefcount(num_refs + 2, f)
222
        b = k[0]
223
        self.assertRefcount(num_refs + 2, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
224
        c = k[0]
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
225
        self.assertRefcount(num_refs + 3, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
226
        del b, c
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
227
        self.assertRefcount(num_refs + 1, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
228
        del k
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
229
        self.assertRefcount(num_refs, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
230
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
231
    def test__repr__(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
232
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.79 by John Arbash Meinel
Change the repr to print out 'StaticTuple'
233
        self.assertEqual("StaticTuple('foo', 'bar', 'baz', 'bing')", repr(k))
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
234
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
235
    def assertCompareEqual(self, k1, k2):
236
        self.assertTrue(k1 == k2)
237
        self.assertTrue(k1 <= k2)
238
        self.assertTrue(k1 >= k2)
239
        self.assertFalse(k1 != k2)
240
        self.assertFalse(k1 < k2)
241
        self.assertFalse(k1 > k2)
242
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
243
    def test_holds_None(self):
244
        k1 = self.module.StaticTuple(None)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
245
        # You cannot subclass None anyway
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
246
247
    def test_holds_int(self):
248
        k1 = self.module.StaticTuple(1)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
249
        class subint(int):
250
            pass
251
        # But not a subclass, because subint could introduce refcycles
252
        self.assertRaises(TypeError, self.module.StaticTuple, subint(2))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
253
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
254
    def test_holds_long(self):
255
        k1 = self.module.StaticTuple(2L**65)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
256
        class sublong(long):
257
            pass
258
        # But not a subclass
259
        self.assertRaises(TypeError, self.module.StaticTuple, sublong(1))
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
260
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
261
    def test_holds_float(self):
262
        k1 = self.module.StaticTuple(1.2)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
263
        class subfloat(float):
264
            pass
265
        self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5))
266
267
    def test_holds_str(self):
268
        k1 = self.module.StaticTuple('astring')
269
        class substr(str):
270
            pass
271
        self.assertRaises(TypeError, self.module.StaticTuple, substr('a'))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
272
273
    def test_holds_unicode(self):
274
        k1 = self.module.StaticTuple(u'\xb5')
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
275
        class subunicode(unicode):
276
            pass
277
        self.assertRaises(TypeError, self.module.StaticTuple,
278
                          subunicode(u'\xb5'))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
279
280
    def test_hold_bool(self):
281
        k1 = self.module.StaticTuple(True)
282
        k2 = self.module.StaticTuple(False)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
283
        # Cannot subclass bool
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
284
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
285
    def test_compare_same_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
286
        k1 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
287
        self.assertCompareEqual(k1, k1)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
288
        k2 = self.module.StaticTuple(k1, k1)
289
        self.assertCompareEqual(k2, k2)
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
290
        k3 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
291
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
292
        self.assertCompareEqual(k3, k3)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
293
294
    def test_compare_equivalent_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
295
        k1 = self.module.StaticTuple('foo', 'bar')
296
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
297
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
298
        k3 = self.module.StaticTuple(k1, k2)
299
        k4 = self.module.StaticTuple(k2, k1)
300
        self.assertCompareEqual(k1, k2)
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
301
        k5 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
302
                                     k1)
303
        k6 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
304
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
305
        self.assertCompareEqual(k5, k6)
306
        k7 = self.module.StaticTuple(None)
307
        k8 = self.module.StaticTuple(None)
308
        self.assertCompareEqual(k7, k8)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
309
310
    def test_compare_similar_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
311
        k1 = self.module.StaticTuple('foo' + ' bar', 'bar' + ' baz')
312
        k2 = self.module.StaticTuple('fo' + 'o bar', 'ba' + 'r baz')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
313
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
314
        k3 = self.module.StaticTuple('foo ' + 'bar', 'bar ' + 'baz')
315
        k4 = self.module.StaticTuple('f' + 'oo bar', 'b' + 'ar baz')
316
        k5 = self.module.StaticTuple(k1, k2)
317
        k6 = self.module.StaticTuple(k3, k4)
318
        self.assertCompareEqual(k5, k6)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
319
320
    def assertCompareDifferent(self, k_small, k_big):
321
        self.assertFalse(k_small == k_big)
322
        self.assertFalse(k_small >= k_big)
323
        self.assertFalse(k_small > k_big)
324
        self.assertTrue(k_small != k_big)
325
        self.assertTrue(k_small <= k_big)
326
        self.assertTrue(k_small < k_big)
327
4679.5.8 by John Arbash Meinel
Add some tests that we *can* compare to strings, even if we don't care
328
    def assertCompareNoRelation(self, k1, k2):
329
        """Run the comparison operators, make sure they do something.
330
331
        However, we don't actually care what comes first or second. This is
332
        stuff like cross-class comparisons. We don't want to segfault/raise an
333
        exception, but we don't care about the sort order.
334
        """
335
        self.assertFalse(k1 == k2)
336
        self.assertTrue(k1 != k2)
337
        # Do the comparison, but we don't care about the result
338
        k1 >= k2
339
        k1 > k2
340
        k1 <= k2
341
        k1 < k2
342
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
343
    def test_compare_vs_none(self):
344
        k1 = self.module.StaticTuple('baz', 'bing')
345
        self.assertCompareDifferent(None, k1)
4679.5.8 by John Arbash Meinel
Add some tests that we *can* compare to strings, even if we don't care
346
    
347
    def test_compare_cross_class(self):
348
        k1 = self.module.StaticTuple('baz', 'bing')
349
        self.assertCompareNoRelation(10, k1)
350
        self.assertCompareNoRelation('baz', k1)
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
351
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
352
    def test_compare_all_different_same_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
353
        k1 = self.module.StaticTuple('baz', 'bing')
354
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
355
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
356
        k3 = self.module.StaticTuple(k1, k2)
357
        k4 = self.module.StaticTuple(k2, k1)
358
        self.assertCompareDifferent(k3, k4)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
359
        k5 = self.module.StaticTuple(1)
360
        k6 = self.module.StaticTuple(2)
361
        self.assertCompareDifferent(k5, k6)
362
        k7 = self.module.StaticTuple(1.2)
363
        k8 = self.module.StaticTuple(2.4)
364
        self.assertCompareDifferent(k7, k8)
365
        k9 = self.module.StaticTuple(u's\xb5')
366
        k10 = self.module.StaticTuple(u's\xe5')
367
        self.assertCompareDifferent(k9, k10)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
368
369
    def test_compare_some_different(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
370
        k1 = self.module.StaticTuple('foo', 'bar')
371
        k2 = self.module.StaticTuple('foo', 'zzz')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
372
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
373
        k3 = self.module.StaticTuple(k1, k1)
374
        k4 = self.module.StaticTuple(k1, k2)
375
        self.assertCompareDifferent(k3, k4)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
376
        k5 = self.module.StaticTuple('foo', None)
377
        self.assertCompareDifferent(k5, k1)
378
        self.assertCompareDifferent(k5, k2)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
379
380
    def test_compare_diff_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
381
        k1 = self.module.StaticTuple('foo')
382
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
383
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
384
        k3 = self.module.StaticTuple(k1)
385
        k4 = self.module.StaticTuple(k1, k2)
386
        self.assertCompareDifferent(k3, k4)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
387
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
388
    def test_compare_different_types(self):
389
        k1 = self.module.StaticTuple('foo', 'bar')
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
390
        k2 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
391
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
392
        self.assertCompareNoRelation(k1, k2)
393
        k3 = self.module.StaticTuple('foo')
394
        self.assertCompareDifferent(k3, k1)
395
        k4 = self.module.StaticTuple(None)
396
        self.assertCompareDifferent(k4, k1)
397
        k5 = self.module.StaticTuple(1)
398
        self.assertCompareNoRelation(k1, k5)
399
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
400
    def test_compare_to_tuples(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
401
        k1 = self.module.StaticTuple('foo')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
402
        self.assertCompareEqual(k1, ('foo',))
403
        self.assertCompareEqual(('foo',), k1)
404
        self.assertCompareDifferent(k1, ('foo', 'bar'))
405
        self.assertCompareDifferent(k1, ('foo', 10))
406
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
407
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
408
        self.assertCompareEqual(k2, ('foo', 'bar'))
409
        self.assertCompareEqual(('foo', 'bar'), k2)
410
        self.assertCompareDifferent(k2, ('foo', 'zzz'))
411
        self.assertCompareDifferent(('foo',), k2)
412
        self.assertCompareDifferent(('foo', 'aaa'), k2)
413
        self.assertCompareDifferent(('baz', 'bing'), k2)
414
        self.assertCompareDifferent(('foo', 10), k2)
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
415
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
416
        k3 = self.module.StaticTuple(k1, k2)
417
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
418
        self.assertCompareEqual((('foo',), ('foo', 'bar')), k3)
419
        self.assertCompareEqual(k3, (k1, ('foo', 'bar')))
420
        self.assertCompareEqual((k1, ('foo', 'bar')), k3)
421
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
422
    def test_compare_mixed_depths(self):
423
        stuple = self.module.StaticTuple
4679.8.13 by John Arbash Meinel
clean up the test case a little bit.
424
        k1 = stuple(stuple('a',), stuple('b',))
425
        k2 = stuple(stuple(stuple('c',), stuple('d',)),
426
                    stuple('b',))
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
427
        # This requires comparing a StaticTuple to a 'string', and then
428
        # interpreting that value in the next higher StaticTuple. This used to
429
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
430
        self.assertCompareNoRelation(k1, k2)
431
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
432
    def test_hash(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
433
        k = self.module.StaticTuple('foo')
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
434
        self.assertEqual(hash(k), hash(('foo',)))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
435
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
436
        as_tuple = ('foo', 'bar', 'baz', 'bing')
437
        self.assertEqual(hash(k), hash(as_tuple))
438
        x = {k: 'foo'}
439
        # Because k == , it replaces the slot, rather than having both
440
        # present in the dict.
441
        self.assertEqual('foo', x[as_tuple])
442
        x[as_tuple] = 'bar'
443
        self.assertEqual({as_tuple: 'bar'}, x)
444
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
445
        k2 = self.module.StaticTuple(k)
446
        as_tuple2 = (('foo', 'bar', 'baz', 'bing'),)
447
        self.assertEqual(hash(k2), hash(as_tuple2))
448
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
449
        k3 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
450
                                     k)
451
        as_tuple3 = ('foo', 1, None, u'\xb5', 1.2, 2**65, True, k)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
452
        self.assertEqual(hash(as_tuple3), hash(k3))
453
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
454
    def test_slice(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
455
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
456
        self.assertEqual(('foo', 'bar'), k[:2])
457
        self.assertEqual(('baz',), k[2:-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
458
        try:
459
            val = k[::2]
460
        except TypeError:
461
            # C implementation raises a TypeError, we don't need the
462
            # implementation yet, so allow this to pass
463
            pass
464
        else:
465
            # Python implementation uses a regular Tuple, so make sure it gives
466
            # the right result
467
            self.assertEqual(('foo', 'baz'), val)
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
468
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
469
    def test_referents(self):
470
        # We implement tp_traverse so that things like 'meliae' can measure the
471
        # amount of referenced memory. Unfortunately gc.get_referents() first
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
472
        # checks the IS_GC flag before it traverses anything. We could write a
473
        # helper func, but that won't work for the generic implementation...
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
474
        self.requireFeature(Meliae)
475
        from meliae import scanner
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
476
        strs = ['foo', 'bar', 'baz', 'bing']
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
477
        k = self.module.StaticTuple(*strs)
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
478
        if self.module is _static_tuple_py:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
479
            refs = strs + [self.module.StaticTuple]
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
480
        else:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
481
            refs = strs
482
        self.assertEqual(sorted(refs), sorted(scanner.get_referents(k)))
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
483
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
484
    def test_nested_referents(self):
485
        self.requireFeature(Meliae)
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
486
        from meliae import scanner
487
        strs = ['foo', 'bar', 'baz', 'bing']
488
        k1 = self.module.StaticTuple(*strs[:2])
489
        k2 = self.module.StaticTuple(*strs[2:])
490
        k3 = self.module.StaticTuple(k1, k2)
491
        refs = [k1, k2]
492
        if self.module is _static_tuple_py:
493
            refs.append(self.module.StaticTuple)
494
        self.assertEqual(sorted(refs),
495
                         sorted(scanner.get_referents(k3)))
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
496
4679.3.44 by John Arbash Meinel
Special case the empty tuple as a singleton.
497
    def test_empty_is_singleton(self):
498
        key = self.module.StaticTuple()
499
        self.assertIs(key, self.module._empty_tuple)
500
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
501
    def test_intern(self):
502
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
503
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
504
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
505
        self.assertFalse(key in self.module._interned_tuples)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
506
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
507
        self.assertEqual(key, key2)
508
        self.assertIsNot(key, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
509
        key3 = key.intern()
510
        self.assertIs(key, key3)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
511
        self.assertTrue(key in self.module._interned_tuples)
512
        self.assertEqual(key, self.module._interned_tuples[key])
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
513
        key2 = key2.intern()
514
        self.assertIs(key, key2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
515
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
516
    def test__c_intern_handles_refcount(self):
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
517
        if self.module is _static_tuple_py:
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
518
            return # Not applicable
519
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
520
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
521
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
522
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
523
        self.assertFalse(key in self.module._interned_tuples)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
524
        self.assertFalse(key._is_interned())
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
525
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
526
        self.assertRefcount(1, key)
527
        self.assertRefcount(1, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
528
        self.assertEqual(key, key2)
529
        self.assertIsNot(key, key2)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
530
531
        key3 = key.intern()
532
        self.assertIs(key, key3)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
533
        self.assertTrue(key in self.module._interned_tuples)
534
        self.assertEqual(key, self.module._interned_tuples[key])
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
535
        # key and key3, but we 'hide' the one in _interned_tuples
536
        self.assertRefcount(2, key)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
537
        del key3
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
538
        self.assertRefcount(1, key)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
539
        self.assertTrue(key._is_interned())
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
540
        self.assertRefcount(1, key2)
541
        key3 = key2.intern()
542
        # key3 now points to key as well, and *not* to key2
543
        self.assertRefcount(2, key)
544
        self.assertRefcount(1, key2)
545
        self.assertIs(key, key3)
546
        self.assertIsNot(key3, key2)
547
        del key2
548
        del key3
549
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
550
551
    def test__c_keys_are_not_immortal(self):
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
552
        if self.module is _static_tuple_py:
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
553
            return # Not applicable
554
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
555
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
556
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
557
        self.assertFalse(key in self.module._interned_tuples)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
558
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
559
        key = key.intern()
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
560
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
561
        self.assertTrue(key in self.module._interned_tuples)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
562
        self.assertTrue(key._is_interned())
563
        del key
564
        # Create a new entry, which would point to the same location
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
565
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
566
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
567
        # This old entry in _interned_tuples should be gone
568
        self.assertFalse(key in self.module._interned_tuples)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
569
        self.assertFalse(key._is_interned())
4679.3.47 by John Arbash Meinel
Work out how to expose the C api using the Python PyCObject interface.
570
571
    def test__c_has_C_API(self):
572
        if self.module is _static_tuple_py:
573
            return
574
        self.assertIsNot(None, self.module._C_API)
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
575
4739.4.1 by John Arbash Meinel
Implement StaticTuple.from_sequence()
576
    def test_from_sequence_tuple(self):
577
        st = self.module.StaticTuple.from_sequence(('foo', 'bar'))
578
        self.assertIsInstance(st, self.module.StaticTuple)
579
        self.assertEqual(('foo', 'bar'), st)
580
581
    def test_from_sequence_str(self):
582
        st = self.module.StaticTuple.from_sequence('foo')
583
        self.assertIsInstance(st, self.module.StaticTuple)
584
        self.assertEqual(('f', 'o', 'o'), st)
585
586
    def test_from_sequence_list(self):
587
        st = self.module.StaticTuple.from_sequence(['foo', 'bar'])
588
        self.assertIsInstance(st, self.module.StaticTuple)
589
        self.assertEqual(('foo', 'bar'), st)
590
591
    def test_from_sequence_static_tuple(self):
592
        st = self.module.StaticTuple('foo', 'bar')
593
        st2 = self.module.StaticTuple.from_sequence(st)
594
        # If the source is a StaticTuple already, we return the exact object
595
        self.assertIs(st, st2)
596
597
    def test_from_sequence_not_sequence(self):
598
        self.assertRaises(TypeError,
599
                          self.module.StaticTuple.from_sequence, object())
4771.2.2 by John Arbash Meinel
Clean up the C code a bit, using a goto.
600
        self.assertRaises(TypeError,
601
                          self.module.StaticTuple.from_sequence, 10)
4739.4.1 by John Arbash Meinel
Implement StaticTuple.from_sequence()
602
603
    def test_from_sequence_incorrect_args(self):
604
        self.assertRaises(TypeError,
605
                          self.module.StaticTuple.from_sequence, object(), 'a')
606
        self.assertRaises(TypeError,
607
                          self.module.StaticTuple.from_sequence, foo='a')
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
608
4771.2.1 by Matt Nordhoff
_static_tuple_c.StaticTuple.from_sequence() now supports arbitrary iterables (by converting them to tuples first).
609
    def test_from_sequence_iterable(self):
4771.2.2 by John Arbash Meinel
Clean up the C code a bit, using a goto.
610
        st = self.module.StaticTuple.from_sequence(iter(['foo', 'bar']))
611
        self.assertIsInstance(st, self.module.StaticTuple)
612
        self.assertEqual(('foo', 'bar'), st)
613
614
    def test_from_sequence_generator(self):
615
        def generate_tuple():
616
            yield 'foo'
617
            yield 'bar'
618
        st = self.module.StaticTuple.from_sequence(generate_tuple())
4771.2.1 by Matt Nordhoff
_static_tuple_c.StaticTuple.from_sequence() now supports arbitrary iterables (by converting them to tuples first).
619
        self.assertIsInstance(st, self.module.StaticTuple)
620
        self.assertEqual(('foo', 'bar'), st)
621
4759.2.16 by Matt Nordhoff
Add a test
622
    def test_pickle(self):
623
        st = self.module.StaticTuple('foo', 'bar')
624
        pickled = cPickle.dumps(st)
625
        unpickled = cPickle.loads(pickled)
626
        self.assertEqual(unpickled, st)
4759.2.20 by Matt Nordhoff
Review: Add a Py_INCREF, and test pickling a nested StaticTuple.
627
628
    def test_pickle_empty(self):
4759.2.17 by Matt Nordhoff
Test pickling the empty StaticTuple too
629
        st = self.module.StaticTuple()
630
        pickled = cPickle.dumps(st)
631
        unpickled = cPickle.loads(pickled)
632
        self.assertIs(st, unpickled)
4759.2.16 by Matt Nordhoff
Add a test
633
4759.2.20 by Matt Nordhoff
Review: Add a Py_INCREF, and test pickling a nested StaticTuple.
634
    def test_pickle_nested(self):
635
        st = self.module.StaticTuple('foo', self.module.StaticTuple('bar'))
636
        pickled = cPickle.dumps(st)
637
        unpickled = cPickle.loads(pickled)
638
        self.assertEqual(unpickled, st)
639
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
640
    def test_static_tuple_thunk(self):
641
        # Make sure the right implementation is available from
642
        # bzrlib.static_tuple.StaticTuple.
643
        if self.module is _static_tuple_py:
644
            if CompiledStaticTuple.available():
645
                # We will be using the C version
646
                return
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
647
        self.assertIs(static_tuple.StaticTuple,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
648
                      self.module.StaticTuple)
4668.3.1 by John Arbash Meinel
Fix bug #471193, allow tuples into the CHK code.
649
650
651
class TestEnsureStaticTuple(tests.TestCase):
652
653
    def test_is_static_tuple(self):
654
        st = static_tuple.StaticTuple('foo')
655
        st2 = static_tuple.expect_static_tuple(st)
656
        self.assertIs(st, st2)
657
658
    def test_is_tuple(self):
659
        t = ('foo',)
660
        st = static_tuple.expect_static_tuple(t)
661
        self.assertIsInstance(st, static_tuple.StaticTuple)
662
        self.assertEqual(t, st)
663
664
    def test_flagged_is_static_tuple(self):
665
        debug.debug_flags.add('static_tuple')
666
        st = static_tuple.StaticTuple('foo')
667
        st2 = static_tuple.expect_static_tuple(st)
668
        self.assertIs(st, st2)
669
670
    def test_flagged_is_tuple(self):
671
        debug.debug_flags.add('static_tuple')
672
        t = ('foo',)
673
        self.assertRaises(TypeError, static_tuple.expect_static_tuple, t)