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