1from PyObjCTools.TestSupport import *
2from test import list_tests, seq_tests
3import objc
4import sys
5
6# Import some of the stdlib tests
7from test import mapping_tests
8
9NSArray = objc.lookUpClass('NSArray')
10NSMutableArray = objc.lookUpClass('NSMutableArray')
11
12class ArrayTests (seq_tests.CommonTest):
13    type2test = NSArray
14
15    @onlyIf(0, "Not relevant for NSArray")
16    def test_pickle(self):
17        pass
18
19    def test_constructors(self):
20
21        self.assertEqual(NSArray(), ())
22        t0_3 = (0, 1, 2, 3)
23        t0_3_bis = NSArray(t0_3)
24        self.assertEqual(t0_3, t0_3_bis)
25
26        self.assertEqual(NSArray("hello"), NSArray(["h", "e", "l", "l", "o"]))
27
28    def test_truth(self):
29        super(ArrayTests, self).test_truth()
30        self.assertTrue(not NSArray())
31        self.assertTrue(NSArray([1, 2]))
32
33    def test_len(self):
34        super(ArrayTests, self).test_len()
35
36    def test_count(self):
37        # Disable test_count because NSArray.count
38        # does not conform the right interface
39        pass
40
41    def test_index(self):
42        # This duplicates the tests in seq_tests, but
43        # disables the 'count' test because NSArray.count
44        # is not the regular python one.
45
46        u = self.type2test([0, 1])
47        self.assertEqual(u.index(0), 0)
48        self.assertEqual(u.index(1), 1)
49        self.assertRaises(ValueError, u.index, 2)
50
51        u = self.type2test([-2, -1, 0, 0, 1, 2])
52        #self.assertEqual(u.count(0), 2)
53        self.assertEqual(u.index(0), 2)
54        self.assertEqual(u.index(0, 2), 2)
55        self.assertEqual(u.index(-2, -10), 0)
56        self.assertEqual(u.index(0, 3), 3)
57        self.assertEqual(u.index(0, 3, 4), 3)
58        self.assertRaises(ValueError, u.index, 2, 0, -10)
59
60        self.assertRaises(TypeError, u.index)
61
62
63    def test_addmul(self):
64        # Same as the one in our superclass, but disables subclassing tests
65        u1 = self.type2test([0])
66        u2 = self.type2test([0, 1])
67        self.assertEqual(u1, u1 + self.type2test())
68        self.assertEqual(u1, self.type2test() + u1)
69        self.assertEqual(u1 + self.type2test([1]), u2)
70        self.assertEqual(self.type2test([-1]) + u1, self.type2test([-1, 0]))
71        self.assertEqual(self.type2test(), u2*0)
72        self.assertEqual(self.type2test(), 0*u2)
73        self.assertEqual(self.type2test(), u2*0)
74        self.assertEqual(self.type2test(), 0*u2)
75        self.assertEqual(u2, u2*1)
76        self.assertEqual(u2, 1*u2)
77        self.assertEqual(u2, u2*1)
78        self.assertEqual(u2, 1*u2)
79        self.assertEqual(u2+u2, u2*2)
80        self.assertEqual(u2+u2, 2*u2)
81        self.assertEqual(u2+u2, u2*2)
82        self.assertEqual(u2+u2, 2*u2)
83        self.assertEqual(u2+u2+u2, u2*3)
84        self.assertEqual(u2+u2+u2, 3*u2)
85
86
87    # Disable a couple of tests that are not relevant for us.
88
89    def test_bigrepeat(self): pass
90    def test_getitemoverwriteiter(self): pass
91    def test_contains_fake(self):
92        # Disabled because the test seems to make use of an
93        # implementation detail of sequences, it assumes
94        # that "X in SEQ" is implemented as:
95        #
96        #   for value in SEQ:
97        #       if X == value:   # (1)
98        #           return True
99        #   return False
100        #
101        # NSArray seems to have the test on (1) in a
102        # different order: 'if value == X', which causes
103        # this test to fail.
104        pass
105    def test_contains_order(self):
106        # See test_contains_fake
107        pass
108
109class MutableArrayTest (list_tests.CommonTest):
110    type2test = NSMutableArray
111
112    @onlyIf(0, "test irrelevant for NSMutableArray")
113    def test_copy(self):
114        pass
115
116    @onlyIf(0, "Not relevant for NSArray")
117    def test_pickle(self):
118        pass
119
120    def test_init(self):
121        # Removed tests that are not relevant
122
123
124        # Iterable arg is optional
125        self.assertEqual(self.type2test([]), self.type2test())
126
127        if 0:
128            # Invalid assumption
129
130            # Init clears previous values
131            a = self.type2test([1, 2, 3])
132            a.__init__()
133            self.assertEqual(a, self.type2test([]))
134
135            # Init overwrites previous values
136            a = self.type2test([1, 2, 3])
137            a.__init__([4, 5, 6])
138            self.assertEqual(a, self.type2test([4, 5, 6]))
139
140        # Mutables always return a new object
141        a = self.type2test([1, 2, 3])
142        b = self.type2test(a)
143        self.assertNotEqual(id(a), id(b))
144        self.assertEqual(a, b)
145
146
147
148
149
150
151    def test_index(self):
152        # As superclass, but without calls to u.count
153        u = self.type2test([0, 1])
154        self.assertEqual(u.index(0), 0)
155        self.assertEqual(u.index(1), 1)
156        self.assertRaises(ValueError, u.index, 2)
157
158        u = self.type2test([-2, -1, 0, 0, 1, 2])
159        #self.assertEqual(u.count(0), 2)
160        self.assertEqual(u.index(0), 2)
161        self.assertEqual(u.index(0, 2), 2)
162        self.assertEqual(u.index(-2, -10), 0)
163        self.assertEqual(u.index(0, 3), 3)
164        self.assertEqual(u.index(0, 3, 4), 3)
165        self.assertRaises(ValueError, u.index, 2, 0, -10)
166
167        self.assertRaises(TypeError, u.index)
168
169
170        if 0:
171            # Disabled due to dependency on the
172            # order of arguments in the '==' expression
173            # used to test if an item matches.
174            class BadExc(Exception):
175                pass
176
177            class BadCmp:
178                def __eq__(self, other):
179                    if other == 2:
180                        raise BadExc()
181                    return False
182
183            a = self.type2test([0, 1, 2, 3])
184            self.assertRaises(BadExc, a.index, BadCmp())
185
186        a = self.type2test([-2, -1, 0, 0, 1, 2])
187        self.assertEqual(a.index(0), 2)
188        self.assertEqual(a.index(0, 2), 2)
189        self.assertEqual(a.index(0, -4), 2)
190        self.assertEqual(a.index(-2, -10), 0)
191        self.assertEqual(a.index(0, 3), 3)
192        self.assertEqual(a.index(0, -3), 3)
193        self.assertEqual(a.index(0, 3, 4), 3)
194        self.assertEqual(a.index(0, -3, -2), 3)
195        self.assertEqual(a.index(0, -4*sys.maxsize, 4*sys.maxsize), 2)
196        self.assertRaises(ValueError, a.index, 0, 4*sys.maxsize,-4*sys.maxsize)
197        self.assertRaises(ValueError, a.index, 2, 0, -10)
198        a.remove(0)
199        self.assertRaises(ValueError, a.index, 2, 0, 4)
200        self.assertEqual(a, self.type2test([-2, -1, 0, 1, 2]))
201
202        if 0:
203            # See above
204            # Test modifying the list during index's iteration
205            class EvilCmp:
206                def __init__(self, victim):
207                    self.victim = victim
208                def __eq__(self, other):
209                    del self.victim[:]
210                return False
211            a = self.type2test()
212            a[:] = [EvilCmp(a) for _ in range(100)]
213            # This used to seg fault before patch #1005778
214            self.assertRaises(ValueError, a.index, None)
215
216    def test_remove(self):
217        # Same as the test inherited from the superclass,
218        # but without the tests that  are dependent on
219        # the way 'in' tests if an element matches.
220        a = self.type2test([0, 0, 1])
221        a.remove(1)
222        self.assertEqual(a, [0, 0])
223        a.remove(0)
224        self.assertEqual(a, [0])
225        a.remove(0)
226        self.assertEqual(a, [])
227
228        self.assertRaises(ValueError, a.remove, 0)
229
230        self.assertRaises(TypeError, a.remove)
231
232        d = self.type2test('abcdefghcij')
233        d.remove('c')
234        self.assertEqual(d, self.type2test('abdefghcij'))
235        d.remove('c')
236        self.assertEqual(d, self.type2test('abdefghij'))
237        self.assertRaises(ValueError, d.remove, 'c')
238        self.assertEqual(d, self.type2test('abdefghij'))
239
240
241
242
243    # Disable a couple of tests that are not relevant for us.
244    def test_bigrepeat(self): pass
245    def test_repr(self): pass
246    def test_contains_fake(self): pass
247    def test_print(self): pass
248    def test_contains_order(self): pass
249    def test_getitemoverwriteiter(self): pass
250
251    # Disable inplace operation tests ( += and *= ) because
252    # we cannot support true inplace operations: most NSArray
253    # and NSMutable array instances are actually instances of
254    # NSCFArray and we cannot (and shouldn't detect whether or
255    # not a value is mutable)
256    def test_imul(self): pass
257    def test_iadd(self): pass
258
259
260    def test_count(self):
261        # Disabled because NSArray.count has a different
262        # interface than list.count
263        pass
264
265
266    # Disabled for now due to crash:
267    def test_sort(self): pass
268
269if __name__ == "__main__":
270    main()
271