1"""
2Tests for the proxy of Python sets
3"""
4import sys
5from PyObjCTools.TestSupport import *
6from PyObjCTest.fnd import NSSet, NSMutableSet, NSPredicate, NSObject, NSNull
7from PyObjCTest.pythonset import OC_TestSet
8import objc
9
10import os
11
12if sys.version_info[0] == 3:
13    unicode = str
14
15onLeopard = int(os.uname()[2].split('.')[0]) >= 9
16
17OC_PythonSet = objc.lookUpClass("OC_PythonSet")
18
19class OC_SetPredicate (NSPredicate):
20    # A simple test predicate class
21    def initWithFunction_(self, pred):
22        self = super(OC_SetPredicate, self).init()
23        if self is None:
24            return None
25
26        self.pred = pred
27        return self
28
29    def evaluateWithObject_(self, object):
30        return self.pred(object)
31
32class OC_TestElem(NSObject):
33
34    def __new__(self, k):
35        return self.alloc().initWithK_(k)
36
37    def initWithK_(self, k):
38        super(OC_TestElem, self).init()
39        self.k = k
40        return self
41
42    def __eq__(self, other):
43        return self.k == other.k
44
45    def __hash__(self):
46        return hash(self.k)
47
48
49class BasicSetTests:
50    # Tests for sets that don't try to mutate the set.
51    # Shared between tests for set() and frozenset()
52    setClass = None
53
54    def testProxyClass(self):
55        # Ensure that the right class is used to proxy sets
56        self.assertIs(OC_TestSet.classOf_(self.setClass()), OC_PythonSet)
57
58    def testMutableCopy(self):
59
60        s = self.setClass(range(20))
61        o = OC_TestSet.set_mutableCopyWithZone_(s, None)
62        self.assertEqual(s, o)
63        self.assertIsNot(s, o)
64        self.assertIsInstance(o, set)
65
66        s = self.setClass()
67        o = OC_TestSet.set_mutableCopyWithZone_(s, None)
68        self.assertEqual(s, o)
69        self.assertIsNot(s, o)
70        self.assertIsInstance(o, set)
71
72
73    def testAllObject(self):
74        s = self.setClass()
75        self.assertEqual(OC_TestSet.allObjectsOfSet_(s), [])
76
77        s = self.setClass([1,2,3])
78        o = OC_TestSet.allObjectsOfSet_(s)
79        o.sort()
80        self.assertEqual(o, [1,2,3])
81
82    def testCount(self):
83        s = self.setClass()
84        self.assertEqual(OC_TestSet.countOfSet_(s), 0)
85
86        s = self.setClass([1,2,3])
87        self.assertEqual(OC_TestSet.countOfSet_(s), 3)
88
89    def testAnyObject(self):
90        s = self.setClass()
91        self.assertEqual(OC_TestSet.anyObjectOfSet_(s), None)
92
93        s = self.setClass([1,2,3,4])
94        self.assertIn(OC_TestSet.anyObjectOfSet_(s), s)
95
96    def testContainsObject_(self):
97        s = self.setClass([1,2,3])
98
99        self.assertFalse(OC_TestSet.set_containsObject_(s, 4))
100        self.assertTrue(OC_TestSet.set_containsObject_(s, 2))
101
102    if onLeopard:
103        def testFilteredSetUsingPredicate(self):
104            s = self.setClass(range(10))
105            p = OC_SetPredicate.alloc().initWithFunction_(lambda x: x % 2 == 0)
106
107            o = OC_TestSet.set_filteredSetUsingPredicate_(s, p)
108            self.assertEqual(o, self.setClass([0, 2, 4, 6, 8]))
109            self.assertEqual(len(s), 10)
110
111    def testMakeObjectsPerform(self):
112        o1 = OC_TestElem(1)
113        o2 = OC_TestElem(2)
114        o3 = OC_TestElem(3)
115        s = self.setClass([o1, o2, o3])
116
117        o = OC_TestSet.set_member_(s, OC_TestElem(4))
118        self.assertIsNone(o)
119
120        o = OC_TestSet.set_member_(s, OC_TestElem(2))
121        self.assertIs(o, o2)
122
123    def testObjectEnumerator(self):
124        s = self.setClass(range(10))
125
126        enum = OC_TestSet.objectEnumeratorOfSet_(s)
127        l = []
128        v = enum.nextObject()
129        while v is not None:
130            l.append(v)
131            v = enum.nextObject()
132        self.assertEqual(l, list(range(10)))
133
134        s = self.setClass([1, 2, None, 3])
135        enum = OC_TestSet.objectEnumeratorOfSet_(s)
136        l = []
137        v = enum.nextObject()
138        while v is not None:
139            l.append(v)
140            v = enum.nextObject()
141
142
143        self.assertEqual(dict.fromkeys(l), dict.fromkeys([1,2,NSNull.null(),3]))
144
145    def testIsSubSet(self):
146        s1 = self.setClass(range(10))
147        s2 = self.setClass(range(5))
148
149        self.assertTrue(OC_TestSet.set_isSubsetOfSet_(s2, s1))
150        self.assertTrue(OC_TestSet.set_isSubsetOfSet_(s2, s2))
151        self.assertFalse(OC_TestSet.set_isSubsetOfSet_(s1, s2))
152
153    def testIntersects(self):
154        s1 = self.setClass([1,2,3,4])
155        s2 = self.setClass([3,4,5,6])
156        s3 = self.setClass([5,6,7,8])
157
158        self.assertTrue(OC_TestSet.set_intersectsSet_(s1, s2))
159        self.assertTrue(OC_TestSet.set_intersectsSet_(s2, s3))
160        self.assertFalse(OC_TestSet.set_intersectsSet_(s1, s3))
161
162    def testDescription(self):
163        s = self.setClass([OC_TestElem(1), 2])
164        o = OC_TestSet.descriptionOfSet_(s)
165        self.assertIsInstance(o, unicode)
166
167
168class TestImmutableSet (TestCase, BasicSetTests):
169    setClass = frozenset
170
171    def testCopy(self):
172        s = self.setClass()
173        o = OC_TestSet.set_copyWithZone_(s, None)
174        self.assertEqual(s, o)
175
176        s = self.setClass(range(20))
177        o = OC_TestSet.set_copyWithZone_(s, None)
178        self.assertEqual(s, o)
179
180    def testNotMutable(self):
181        # Ensure that a frozenset cannot be mutated
182        o = self.setClass([1,2,3])
183        self.assertRaises((TypeError, AttributeError),
184                OC_TestSet.set_addObject_, o, 4)
185
186        self.assertRaises(TypeError,
187                OC_TestSet.set_removeObject_, o, 2)
188
189        self.assertRaises(TypeError,
190                OC_TestSet.set_addObjectsFromArray_, o, [4, 5, 6])
191
192        if onLeopard:
193            self.assertRaises(TypeError,
194                    OC_TestSet.set_filterUsingPredicate_, o,
195                    NSPredicate.predicateWithValue_(True))
196
197        self.assertRaises(TypeError,
198                OC_TestSet.set_intersectSet_, o, self.setClass([2,3,4]))
199
200        self.assertRaises(TypeError,
201                OC_TestSet.set_minusSet_, o, self.setClass([2,3,4]))
202
203        self.assertRaises(TypeError,
204                OC_TestSet.set_setSet_, o, self.setClass([2,3,4]))
205
206        self.assertRaises(TypeError,
207                OC_TestSet.set_minusSet_, o, self.setClass([2,3,4]))
208
209        self.assertRaises(TypeError,
210                OC_TestSet.removeAllObjecsFromSet_, o)
211
212
213class TestMutableSet (TestCase, BasicSetTests):
214    setClass = set
215
216    def testCopy(self):
217        s = self.setClass()
218        o = OC_TestSet.set_copyWithZone_(s, None)
219        self.assertEqual(s, o)
220        self.assertIsNot(s, o)
221
222        s = self.setClass(range(20))
223        o = OC_TestSet.set_copyWithZone_(s, None)
224        self.assertEqual(s, o)
225        self.assertIsNot(s, o)
226
227    def testUnionSet(self):
228        s1 = self.setClass([1,2,3])
229        s2 = self.setClass([3,4,5])
230
231        OC_TestSet.set_unionSet_(s1, s2)
232        self.assertEqual(s1, self.setClass([1,2,3,4,5]))
233
234    def testSetSet(self):
235        s1 = self.setClass([1,2,3])
236        s2 = self.setClass([3,4,5])
237
238        OC_TestSet.set_setSet_(s1, s2)
239        self.assertEqual(s1, self.setClass([3,4,5]))
240
241    def testMinusSet(self):
242        s1 = self.setClass([1,2,3])
243        s2 = self.setClass([3,4,5])
244
245        OC_TestSet.set_minusSet_(s1, s2)
246        self.assertEqual(s1, self.setClass([1, 2]))
247
248    def testIntersectSet(self):
249        s1 = self.setClass([1,2,3])
250        s2 = self.setClass([3,4,5])
251
252        OC_TestSet.set_intersectSet_(s1, s2)
253        self.assertEqual(s1, self.setClass([3]))
254
255    if onLeopard:
256        def testFilterSet(self):
257            s = self.setClass(range(10))
258            p = OC_SetPredicate.alloc().initWithFunction_(lambda x: x % 2 == 0)
259
260            OC_TestSet.set_filterUsingPredicate_(s, p)
261            self.assertEqual(s, self.setClass([0, 2, 4, 6, 8]))
262
263    def testAddObject(self):
264        s = self.setClass([1,2,3])
265
266        OC_TestSet.set_addObject_(s, 1)
267        self.assertEqual(s, self.setClass([1,2,3]))
268
269        OC_TestSet.set_addObject_(s, 9)
270        self.assertEqual(s, self.setClass([1,2,3,9]))
271
272    def testAddObjectsFromArray(self):
273        s = self.setClass([1,2,3])
274
275        OC_TestSet.set_addObjectsFromArray_(s, [1,2])
276        self.assertEqual(s, self.setClass([1,2,3]))
277
278        OC_TestSet.set_addObjectsFromArray_(s, [9,5,4])
279        self.assertEqual(s, self.setClass([1,2,3,9,5,4]))
280
281    def testRemoveObject(self):
282        s = self.setClass([1,2,3])
283
284        OC_TestSet.set_removeObject_(s, 1)
285        self.assertEqual(s, self.setClass([2,3]))
286
287        OC_TestSet.set_removeObject_(s, 9)
288        self.assertEqual(s, self.setClass([2,3]))
289
290    def testRemoveAllObjects(self):
291        s = self.setClass([1,2,3])
292
293        OC_TestSet.removeAllObjecsFromSet_(s)
294        self.assertEqual(s, self.setClass())
295
296
297
298if __name__ == "__main__":
299    main()
300