/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
19
import gc
4679.3.2 by John Arbash Meinel
Add a get_key() function, which then returns tuples for the given items.
20
import sys
21
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
22
from bzrlib import (
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
23
    _static_tuple_py,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
24
    errors,
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
25
    osutils,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
26
    static_tuple,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
27
    tests,
28
    )
29
30
31
def load_tests(standard_tests, module, loader):
32
    """Parameterize tests for all versions of groupcompress."""
33
    scenarios = [
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
34
        ('python', {'module': _static_tuple_py}),
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
35
    ]
36
    suite = loader.suiteClass()
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
37
    if CompiledStaticTuple.available():
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
38
        from bzrlib import _static_tuple_c
39
        scenarios.append(('C', {'module': _static_tuple_c}))
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
40
    else:
41
        # the compiled module isn't available, so we add a failing test
42
        class FailWithoutFeature(tests.TestCase):
43
            def test_fail(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
44
                self.requireFeature(CompiledStaticTuple)
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
45
        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
46
    result = tests.multiply_tests(standard_tests, scenarios, suite)
47
    return result
48
49
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
50
class _CompiledStaticTuple(tests.Feature):
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
51
52
    def _probe(self):
53
        try:
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
54
            import bzrlib._static_tuple_c
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
55
        except ImportError:
56
            return False
57
        return True
58
59
    def feature_name(self):
4679.3.74 by John Arbash Meinel
Revert back to before I started trying to move to pyrex/cython code.
60
        return 'bzrlib._static_tuple_c'
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
61
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
62
CompiledStaticTuple = _CompiledStaticTuple()
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
63
64
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
65
class _Meliae(tests.Feature):
66
67
    def _probe(self):
68
        try:
69
            from meliae import scanner
70
        except ImportError:
71
            return False
72
        return True
73
74
    def feature_name(self):
75
        return "Meliae - python memory debugger"
76
77
Meliae = _Meliae()
78
79
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
80
class TestStaticTuple(tests.TestCase):
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
81
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
82
    def assertRefcount(self, count, obj):
83
        """Assert that the refcount for obj is what we expect.
84
85
        Note that this automatically adjusts for the fact that calling
86
        assertRefcount actually creates a new pointer, as does calling
87
        sys.getrefcount. So pass the expected value *before* the call.
88
        """
89
        # I don't understand why it is getrefcount()-3 here, but it seems to be
90
        # correct. If I check in the calling function, with:
91
        # self.assertEqual(count, sys.getrefcount(obj)-1)
92
        # Then it works fine. Something about passing it to assertRefcount is
93
        # actually double-incrementing (and decrementing) the refcount
94
        self.assertEqual(count, sys.getrefcount(obj)-3)
95
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
96
    def test_create(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
97
        k = self.module.StaticTuple('foo')
98
        k = self.module.StaticTuple('foo', 'bar')
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
99
100
    def test_create_bad_args(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
101
        args_256 = ['a']*256
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
102
        # too many args
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
103
        self.assertRaises(ValueError, self.module.StaticTuple, *args_256)
104
        args_300 = ['a']*300
105
        self.assertRaises(ValueError, self.module.StaticTuple, *args_300)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
106
        # not a string
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
107
        self.assertRaises(TypeError, self.module.StaticTuple, 10)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
108
        
109
    def test_as_tuple(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
110
        k = self.module.StaticTuple('foo')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
111
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
112
        self.assertEqual(('foo',), t)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
113
        k = self.module.StaticTuple('foo', 'bar')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
114
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
115
        self.assertEqual(('foo', 'bar'), t)
116
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
117
    def test_len(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
118
        k = self.module.StaticTuple()
119
        self.assertEqual(0, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
120
        k = self.module.StaticTuple('foo')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
121
        self.assertEqual(1, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
122
        k = self.module.StaticTuple('foo', 'bar')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
123
        self.assertEqual(2, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
124
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
125
        self.assertEqual(7, len(k))
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
126
        args = ['foo']*255
127
        k = self.module.StaticTuple(*args)
128
        self.assertEqual(255, len(k))
129
130
    def test_hold_other_static_tuples(self):
131
        k = self.module.StaticTuple('foo', 'bar')
132
        k2 = self.module.StaticTuple(k, k)
133
        self.assertEqual(2, len(k2))
134
        self.assertIs(k, k2[0])
135
        self.assertIs(k, k2[1])
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
136
137
    def test_getitem(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
138
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
139
        self.assertEqual('foo', k[0])
140
        self.assertEqual('foo', k[0])
141
        self.assertEqual('foo', k[0])
142
        self.assertEqual('z', k[6])
143
        self.assertEqual('z', k[-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
144
        self.assertRaises(IndexError, k.__getitem__, 7)
145
        self.assertRaises(IndexError, k.__getitem__, 256+7)
146
        self.assertRaises(IndexError, k.__getitem__, 12024)
147
        # Python's [] resolver handles the negative arguments, so we can't
148
        # really test StaticTuple_item() with negative values.
149
        self.assertRaises(TypeError, k.__getitem__, 'not-an-int')
150
        self.assertRaises(TypeError, k.__getitem__, '5')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
151
152
    def test_refcount(self):
153
        f = 'fo' + 'oo'
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
154
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
155
        k = self.module.StaticTuple(f)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
156
        self.assertRefcount(num_refs + 1, f)
157
        b = k[0]
158
        self.assertRefcount(num_refs + 2, f)
159
        b = k[0]
160
        self.assertRefcount(num_refs + 2, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
161
        c = k[0]
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
162
        self.assertRefcount(num_refs + 3, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
163
        del b, c
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
164
        self.assertRefcount(num_refs + 1, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
165
        del k
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
166
        self.assertRefcount(num_refs, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
167
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
168
    def test__repr__(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
169
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.79 by John Arbash Meinel
Change the repr to print out 'StaticTuple'
170
        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.
171
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
172
    def assertCompareEqual(self, k1, k2):
173
        self.assertTrue(k1 == k2)
174
        self.assertTrue(k1 <= k2)
175
        self.assertTrue(k1 >= k2)
176
        self.assertFalse(k1 != k2)
177
        self.assertFalse(k1 < k2)
178
        self.assertFalse(k1 > k2)
179
180
    def test_compare_same_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
181
        k1 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
182
        self.assertCompareEqual(k1, k1)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
183
        k2 = self.module.StaticTuple(k1, k1)
184
        self.assertCompareEqual(k2, k2)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
185
186
    def test_compare_equivalent_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
187
        k1 = self.module.StaticTuple('foo', 'bar')
188
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
189
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
190
        k3 = self.module.StaticTuple(k1, k2)
191
        k4 = self.module.StaticTuple(k2, k1)
192
        self.assertCompareEqual(k1, k2)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
193
194
    def test_compare_similar_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
195
        k1 = self.module.StaticTuple('foo' + ' bar', 'bar' + ' baz')
196
        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.
197
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
198
        k3 = self.module.StaticTuple('foo ' + 'bar', 'bar ' + 'baz')
199
        k4 = self.module.StaticTuple('f' + 'oo bar', 'b' + 'ar baz')
200
        k5 = self.module.StaticTuple(k1, k2)
201
        k6 = self.module.StaticTuple(k3, k4)
202
        self.assertCompareEqual(k5, k6)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
203
204
    def assertCompareDifferent(self, k_small, k_big):
205
        self.assertFalse(k_small == k_big)
206
        self.assertFalse(k_small >= k_big)
207
        self.assertFalse(k_small > k_big)
208
        self.assertTrue(k_small != k_big)
209
        self.assertTrue(k_small <= k_big)
210
        self.assertTrue(k_small < k_big)
211
4679.5.8 by John Arbash Meinel
Add some tests that we *can* compare to strings, even if we don't care
212
    def assertCompareNoRelation(self, k1, k2):
213
        """Run the comparison operators, make sure they do something.
214
215
        However, we don't actually care what comes first or second. This is
216
        stuff like cross-class comparisons. We don't want to segfault/raise an
217
        exception, but we don't care about the sort order.
218
        """
219
        self.assertFalse(k1 == k2)
220
        self.assertTrue(k1 != k2)
221
        # Do the comparison, but we don't care about the result
222
        k1 >= k2
223
        k1 > k2
224
        k1 <= k2
225
        k1 < k2
226
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
227
    def test_compare_vs_none(self):
228
        k1 = self.module.StaticTuple('baz', 'bing')
229
        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
230
    
231
    def test_compare_cross_class(self):
232
        k1 = self.module.StaticTuple('baz', 'bing')
233
        self.assertCompareNoRelation(10, k1)
234
        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.
235
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
236
    def test_compare_all_different_same_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
237
        k1 = self.module.StaticTuple('baz', 'bing')
238
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
239
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
240
        k3 = self.module.StaticTuple(k1, k2)
241
        k4 = self.module.StaticTuple(k2, k1)
242
        self.assertCompareDifferent(k3, k4)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
243
244
    def test_compare_some_different(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
245
        k1 = self.module.StaticTuple('foo', 'bar')
246
        k2 = self.module.StaticTuple('foo', 'zzz')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
247
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
248
        k3 = self.module.StaticTuple(k1, k1)
249
        k4 = self.module.StaticTuple(k1, k2)
250
        self.assertCompareDifferent(k3, k4)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
251
252
    def test_compare_diff_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
253
        k1 = self.module.StaticTuple('foo')
254
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
255
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
256
        k3 = self.module.StaticTuple(k1)
257
        k4 = self.module.StaticTuple(k1, k2)
258
        self.assertCompareDifferent(k3, k4)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
259
260
    def test_compare_to_tuples(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
261
        k1 = self.module.StaticTuple('foo')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
262
        self.assertCompareEqual(k1, ('foo',))
263
        self.assertCompareEqual(('foo',), k1)
264
        self.assertCompareDifferent(k1, ('foo', 'bar'))
265
        self.assertCompareDifferent(k1, ('foo', 10))
266
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
267
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
268
        self.assertCompareEqual(k2, ('foo', 'bar'))
269
        self.assertCompareEqual(('foo', 'bar'), k2)
270
        self.assertCompareDifferent(k2, ('foo', 'zzz'))
271
        self.assertCompareDifferent(('foo',), k2)
272
        self.assertCompareDifferent(('foo', 'aaa'), k2)
273
        self.assertCompareDifferent(('baz', 'bing'), k2)
274
        self.assertCompareDifferent(('foo', 10), k2)
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
275
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
276
        k3 = self.module.StaticTuple(k1, k2)
277
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
278
        self.assertCompareEqual((('foo',), ('foo', 'bar')), k3)
279
        self.assertCompareEqual(k3, (k1, ('foo', 'bar')))
280
        self.assertCompareEqual((k1, ('foo', 'bar')), k3)
281
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
282
    def test_compare_mixed_depths(self):
283
        stuple = self.module.StaticTuple
4679.8.13 by John Arbash Meinel
clean up the test case a little bit.
284
        k1 = stuple(stuple('a',), stuple('b',))
285
        k2 = stuple(stuple(stuple('c',), stuple('d',)),
286
                    stuple('b',))
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
287
        # This requires comparing a StaticTuple to a 'string', and then
288
        # interpreting that value in the next higher StaticTuple. This used to
289
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
290
        self.assertCompareNoRelation(k1, k2)
291
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
292
    def test_hash(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
293
        k = self.module.StaticTuple('foo')
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
294
        self.assertEqual(hash(k), hash(('foo',)))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
295
        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.
296
        as_tuple = ('foo', 'bar', 'baz', 'bing')
297
        self.assertEqual(hash(k), hash(as_tuple))
298
        x = {k: 'foo'}
299
        # Because k == , it replaces the slot, rather than having both
300
        # present in the dict.
301
        self.assertEqual('foo', x[as_tuple])
302
        x[as_tuple] = 'bar'
303
        self.assertEqual({as_tuple: 'bar'}, x)
304
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
305
        k2 = self.module.StaticTuple(k)
306
        as_tuple2 = (('foo', 'bar', 'baz', 'bing'),)
307
        self.assertEqual(hash(k2), hash(as_tuple2))
308
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
309
    def test_slice(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
310
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
311
        self.assertEqual(('foo', 'bar'), k[:2])
312
        self.assertEqual(('baz',), k[2:-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
313
        try:
314
            val = k[::2]
315
        except TypeError:
316
            # C implementation raises a TypeError, we don't need the
317
            # implementation yet, so allow this to pass
318
            pass
319
        else:
320
            # Python implementation uses a regular Tuple, so make sure it gives
321
            # the right result
322
            self.assertEqual(('foo', 'baz'), val)
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
323
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
324
    def test_referents(self):
325
        # We implement tp_traverse so that things like 'meliae' can measure the
326
        # amount of referenced memory. Unfortunately gc.get_referents() first
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
327
        # checks the IS_GC flag before it traverses anything. We could write a
328
        # 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.
329
        self.requireFeature(Meliae)
330
        from meliae import scanner
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
331
        strs = ['foo', 'bar', 'baz', 'bing']
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
332
        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.
333
        if self.module is _static_tuple_py:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
334
            refs = strs + [self.module.StaticTuple]
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
335
        else:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
336
            refs = strs
337
        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.
338
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
339
    def test_nested_referents(self):
340
        self.requireFeature(Meliae)
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
341
        from meliae import scanner
342
        strs = ['foo', 'bar', 'baz', 'bing']
343
        k1 = self.module.StaticTuple(*strs[:2])
344
        k2 = self.module.StaticTuple(*strs[2:])
345
        k3 = self.module.StaticTuple(k1, k2)
346
        refs = [k1, k2]
347
        if self.module is _static_tuple_py:
348
            refs.append(self.module.StaticTuple)
349
        self.assertEqual(sorted(refs),
350
                         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.
351
4679.3.44 by John Arbash Meinel
Special case the empty tuple as a singleton.
352
    def test_empty_is_singleton(self):
353
        key = self.module.StaticTuple()
354
        self.assertIs(key, self.module._empty_tuple)
355
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
356
    def test_intern(self):
357
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
358
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
359
        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.
360
        self.assertFalse(key in self.module._interned_tuples)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
361
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
362
        self.assertEqual(key, key2)
363
        self.assertIsNot(key, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
364
        key3 = key.intern()
365
        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.
366
        self.assertTrue(key in self.module._interned_tuples)
367
        self.assertEqual(key, self.module._interned_tuples[key])
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
368
        key2 = key2.intern()
369
        self.assertIs(key, key2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
370
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
371
    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.
372
        if self.module is _static_tuple_py:
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
373
            return # Not applicable
374
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
375
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
376
        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.
377
        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.
378
        self.assertFalse(key in self.module._interned_tuples)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
379
        self.assertFalse(key._is_interned())
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
380
        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.
381
        self.assertRefcount(1, key)
382
        self.assertRefcount(1, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
383
        self.assertEqual(key, key2)
384
        self.assertIsNot(key, key2)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
385
386
        key3 = key.intern()
387
        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.
388
        self.assertTrue(key in self.module._interned_tuples)
389
        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.
390
        # key and key3, but we 'hide' the one in _interned_tuples
391
        self.assertRefcount(2, key)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
392
        del key3
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
393
        self.assertRefcount(1, key)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
394
        self.assertTrue(key._is_interned())
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
395
        self.assertRefcount(1, key2)
396
        key3 = key2.intern()
397
        # key3 now points to key as well, and *not* to key2
398
        self.assertRefcount(2, key)
399
        self.assertRefcount(1, key2)
400
        self.assertIs(key, key3)
401
        self.assertIsNot(key3, key2)
402
        del key2
403
        del key3
404
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
405
406
    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.
407
        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.
408
            return # Not applicable
409
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
410
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
411
        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.
412
        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.
413
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
414
        key = key.intern()
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
415
        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.
416
        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.
417
        self.assertTrue(key._is_interned())
418
        del key
419
        # Create a new entry, which would point to the same location
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
420
        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.
421
        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.
422
        # This old entry in _interned_tuples should be gone
423
        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.
424
        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.
425
426
    def test__c_has_C_API(self):
427
        if self.module is _static_tuple_py:
428
            return
429
        self.assertIsNot(None, self.module._C_API)
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
430
4739.4.1 by John Arbash Meinel
Implement StaticTuple.from_sequence()
431
    def test_from_sequence_tuple(self):
432
        st = self.module.StaticTuple.from_sequence(('foo', 'bar'))
433
        self.assertIsInstance(st, self.module.StaticTuple)
434
        self.assertEqual(('foo', 'bar'), st)
435
436
    def test_from_sequence_str(self):
437
        st = self.module.StaticTuple.from_sequence('foo')
438
        self.assertIsInstance(st, self.module.StaticTuple)
439
        self.assertEqual(('f', 'o', 'o'), st)
440
441
    def test_from_sequence_list(self):
442
        st = self.module.StaticTuple.from_sequence(['foo', 'bar'])
443
        self.assertIsInstance(st, self.module.StaticTuple)
444
        self.assertEqual(('foo', 'bar'), st)
445
446
    def test_from_sequence_static_tuple(self):
447
        st = self.module.StaticTuple('foo', 'bar')
448
        st2 = self.module.StaticTuple.from_sequence(st)
449
        # If the source is a StaticTuple already, we return the exact object
450
        self.assertIs(st, st2)
451
452
    def test_from_sequence_not_sequence(self):
453
        self.assertRaises(TypeError,
454
                          self.module.StaticTuple.from_sequence, object())
455
456
    def test_from_sequence_incorrect_args(self):
457
        self.assertRaises(TypeError,
458
                          self.module.StaticTuple.from_sequence, object(), 'a')
459
        self.assertRaises(TypeError,
460
                          self.module.StaticTuple.from_sequence, foo='a')
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
461
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
462
    def test_static_tuple_thunk(self):
463
        # Make sure the right implementation is available from
464
        # bzrlib.static_tuple.StaticTuple.
465
        if self.module is _static_tuple_py:
466
            if CompiledStaticTuple.available():
467
                # We will be using the C version
468
                return
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
469
        self.assertIs(static_tuple.StaticTuple,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
470
                      self.module.StaticTuple)